@snowcone-app/canvas 0.29.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ERROR_CONTRACT.md +13 -0
- package/STYLING_CONTRACT.md +2 -2
- package/dist/{CanvasRenderer-_lFoIoz5.js → CanvasRenderer-hpJ05JGO.js} +4 -4
- package/dist/{CanvasRenderer-_lFoIoz5.js.map → CanvasRenderer-hpJ05JGO.js.map} +1 -1
- package/dist/{CanvasStateV1-BMxr6xb8.js → CanvasStateV1-jLOibojY.js} +876 -844
- package/dist/{CanvasStateV1-BMxr6xb8.js.map → CanvasStateV1-jLOibojY.js.map} +1 -1
- package/dist/ContextualToolbars-DRbuUE7W.js +6061 -0
- package/dist/ContextualToolbars-DRbuUE7W.js.map +1 -0
- package/dist/{EditorCanvasImpl-BNz8TPFs.js → EditorCanvasImpl-P2GHPNA3.js} +19 -20
- package/dist/{EditorCanvasImpl-BNz8TPFs.js.map → EditorCanvasImpl-P2GHPNA3.js.map} +1 -1
- package/dist/{ExportManager-B8Td7uR5.js → ExportManager-Bkzzyxgw.js} +973 -576
- package/dist/ExportManager-Bkzzyxgw.js.map +1 -0
- package/dist/{FontAnalyzer-D4Sg-P6_.js → FontAnalyzer-BYhwxDhe.js} +542 -477
- package/dist/FontAnalyzer-BYhwxDhe.js.map +1 -0
- package/dist/{ImagePanel-CN2Bu3hf.js → ImagePanel-CEr0_FYy.js} +38 -38
- package/dist/{ImagePanel-CN2Bu3hf.js.map → ImagePanel-CEr0_FYy.js.map} +1 -1
- package/dist/SnowconeCanvas-Fa0isFpO.js +1192 -0
- package/dist/SnowconeCanvas-Fa0isFpO.js.map +1 -0
- package/dist/advanced.mjs +14 -14
- package/dist/api/embed.d.ts +2 -0
- package/dist/api/stable.d.ts +2 -0
- package/dist/components/CanvasContextMenu.d.ts +15 -0
- package/dist/components/CanvasEditor/hooks/useCanvasInteraction.d.ts +27 -0
- package/dist/components/CanvasEditor.d.ts +8 -0
- package/dist/components/ImageToolbar.d.ts +4 -0
- package/dist/components/embed/SnowconeCanvas.d.ts +13 -0
- package/dist/components/embed/kernel.d.ts +8 -0
- package/dist/components/toolbars/EmbeddedToolbarLayout.d.ts +2 -0
- package/dist/components/toolbars/SecondaryPanels.d.ts +17 -1
- package/dist/components/toolbars/index.d.ts +2 -2
- package/dist/components/ui/SliderRow.d.ts +6 -0
- package/dist/components/ui/icons.d.ts +2 -0
- package/dist/components/ui/toolbar-button.d.ts +2 -2
- package/dist/contexts/CanvasServicesContext.d.ts +17 -0
- package/dist/contexts/EditorContext.d.ts +7 -0
- package/dist/core/image-adjustments.d.ts +32 -0
- package/dist/{custom-icons-B5TRC1Ed.js → custom-icons-Co4rcW0S.js} +7 -7
- package/dist/{custom-icons-B5TRC1Ed.js.map → custom-icons-Co4rcW0S.js.map} +1 -1
- package/dist/design-builder-CBG2hKc8.js +1672 -0
- package/dist/design-builder-CBG2hKc8.js.map +1 -0
- package/dist/{embed-BTRtoktw.js → embed-D4TIzO7g.js} +20 -20
- package/dist/{embed-BTRtoktw.js.map → embed-D4TIzO7g.js.map} +1 -1
- package/dist/embed.mjs +51 -46
- package/dist/embed.mjs.map +1 -1
- package/dist/errors/editorError.d.ts +8 -0
- package/dist/{guards-uQtEQJbs.js → guards-DgZuwVgu.js} +2 -2
- package/dist/{guards-uQtEQJbs.js.map → guards-DgZuwVgu.js.map} +1 -1
- package/dist/hooks/elementPatch.d.ts +7 -2
- package/dist/hooks/useKeyboardShortcuts.d.ts +15 -2
- package/dist/hooks/useLayers.d.ts +2 -0
- package/dist/index.mjs +57 -52
- package/dist/index.mjs.map +1 -1
- package/dist/internals.mjs +201 -132
- package/dist/internals.mjs.map +1 -1
- package/dist/rendering/element-painters.d.ts +0 -13
- package/dist/rendering/element-serializer.d.ts +3 -1
- package/dist/rendering/image-adjustments.d.ts +24 -0
- package/dist/rendering/renderer-types.d.ts +8 -1
- package/dist/state/CanvasStateV1.d.ts +36 -3
- package/dist/state/index.d.ts +2 -2
- package/dist/template-fields-CvFcr5zy.js +505 -0
- package/dist/template-fields-CvFcr5zy.js.map +1 -0
- package/dist/testing.mjs +46 -47
- package/dist/testing.mjs.map +1 -1
- package/dist/types/index.d.ts +21 -0
- package/dist/{UnifiedFontService-CgYnYTj7.js → useCommands-bPXY9rCh.js} +2429 -2145
- package/dist/useCommands-bPXY9rCh.js.map +1 -0
- package/dist/{usePieceGuideBundle-CTQszfKA.js → usePieceGuideBundle-Bj98nPk0.js} +2 -2
- package/dist/{usePieceGuideBundle-CTQszfKA.js.map → usePieceGuideBundle-Bj98nPk0.js.map} +1 -1
- package/dist/utils/custom-fonts.d.ts +99 -0
- package/dist/utils/featureApplied.d.ts +2 -0
- package/dist/validation-CsTlSvJJ.js +8686 -0
- package/dist/validation-CsTlSvJJ.js.map +1 -0
- package/dist/workers/export-protocol.d.ts +13 -0
- package/dist/workers/export-worker.bundle.string.d.ts +1 -1
- package/example/package.json +1 -1
- package/package.json +1 -1
- package/dist/ContextualToolbars-0jWvnQgp.js +0 -5833
- package/dist/ContextualToolbars-0jWvnQgp.js.map +0 -1
- package/dist/ExportManager-B8Td7uR5.js.map +0 -1
- package/dist/FontAnalyzer-D4Sg-P6_.js.map +0 -1
- package/dist/SnowconeCanvas-CR_LdRFP.js +0 -1173
- package/dist/SnowconeCanvas-CR_LdRFP.js.map +0 -1
- package/dist/UnifiedFontService-CgYnYTj7.js.map +0 -1
- package/dist/design-builder-COj0zkxu.js +0 -470
- package/dist/design-builder-COj0zkxu.js.map +0 -1
- package/dist/editorErrors-CCvoKj_P.js +0 -1219
- package/dist/editorErrors-CCvoKj_P.js.map +0 -1
- package/dist/template-fields-BLRp84Ny.js +0 -716
- package/dist/template-fields-BLRp84Ny.js.map +0 -1
- package/dist/validation-eCebhplp.js +0 -8402
- package/dist/validation-eCebhplp.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ExportManager-B8Td7uR5.js","sources":["../src/core/preview-registry.ts","../src/utils/TextureManager.ts","../src/utils/ElementPreviewRenderer.ts","../src/rendering/stroke-utils.ts","../src/rendering/StrokeRenderer.ts","../src/utils/GlyphRenderer.ts","../src/rendering/rich-text-renderer.ts","../src/rendering/text-renderer.ts","../src/rendering/transform-renderer.ts","../src/rendering/element-painters.ts","../src/rendering/ElementRenderUtils.ts","../src/rendering/CompositingRenderer.ts","../src/rendering/mask-utils.ts","../src/effects/mask-presets.ts","../src/rendering/MaskRenderer.ts","../src/effects/DistressGenerator.ts","../src/effects/distress-textures.ts","../src/effects/DistressTextureCache.ts","../src/rendering/DistressTextureRenderer.ts","../src/core/ElementFactory.ts","../src/utils/ImportManager.ts","../src/rendering/element-serializer.ts","../src/workers/export-worker.bundle.string.js","../src/utils/WorkerExportManager.ts","../src/utils/ExportManager.ts"],"sourcesContent":["/**\n * Layer-preview registry — the dependency-inversion seam between the layer\n * panels (always-mountable chrome: `Editor.Layers` / `embed/LayersPanel`) and\n * the rendering engine, extending the P1 element/renderer split\n * (`core/paint-registry.ts`).\n *\n * `useLayers` / `useLayerPreview` used to statically import\n * `utils/ElementPreviewRenderer`, dragging the whole paint pipeline into any\n * graph that shows a layers panel — which would put the renderer in\n * `Editor.Layers`' always-mounted graph (CI-gated renderer-free by\n * scripts/check-import-graph.mjs). Inversion: the panels look the preview\n * painter up HERE at preview time; the heavy side\n * (`src/rendering/element-painters.ts`, inside `Editor.Canvas`'s lazy chunk)\n * registers it at module evaluation.\n *\n * Contract difference from the paint registry: a MISS here is a legitimate\n * state, not a wiring bug. Thumbnails are an enhancement that needs the\n * rendering engine — a canvas-free composition (no `Editor.Canvas` mounted)\n * has no painter and the panels fall back to their icon placeholder. So the\n * getter returns `null` instead of throwing.\n */\n\nexport interface ElementPreviewOptions {\n width?: number;\n height?: number;\n padding?: number;\n backgroundColor?: string;\n}\n\n/** Renders a thumbnail data-URL for one live editor element. Structural\n * `object` on purpose so this module never imports an element class. */\nexport type ElementPreviewPainter = (element: object, options?: ElementPreviewOptions) => string;\n\nlet elementPreviewPainter: ElementPreviewPainter | null = null;\n\nexport function registerElementPreviewPainter(painter: ElementPreviewPainter): void {\n elementPreviewPainter = painter;\n}\n\n/** The registered preview painter, or `null` while the rendering engine is\n * not loaded (the canvas-free fallback — render the icon placeholder). */\nexport function getElementPreviewPainter(): ElementPreviewPainter | null {\n return elementPreviewPainter;\n}\n","/**\n * TextureManager - Loads and caches background textures\n * Provides texture loading for artboard backgrounds\n */\n\nimport { createLogger } from './logger';\n\nconst logger = createLogger('TextureManager');\n\nexport interface TextureInfo {\n id: string;\n name: string;\n url: string;\n category?: string;\n presetColor: string; // Base color for this texture preset\n}\n\nexport class TextureManager {\n private static cache = new Map<string, HTMLImageElement>();\n private static loading = new Map<string, Promise<HTMLImageElement>>();\n\n /**\n * Available built-in textures\n */\n static readonly TEXTURES: TextureInfo[] = [\n {\n id: 'glass-frame',\n name: 'Glass Frame',\n url: '/textures/glass-frame.svg',\n category: 'glass',\n presetColor: '#ccc', // Light gray\n },\n ];\n\n /**\n * Load a texture by ID or URL\n */\n static async loadTexture(idOrUrl: string): Promise<HTMLImageElement> {\n\n // Check if already cached\n if (this.cache.has(idOrUrl)) {\n return this.cache.get(idOrUrl)!;\n }\n\n // Check if already loading\n if (this.loading.has(idOrUrl)) {\n return this.loading.get(idOrUrl)!;\n }\n\n // Resolve URL from ID if needed\n const url = this.resolveTextureUrl(idOrUrl);\n\n // Create loading promise\n const loadingPromise = new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n\n img.onload = () => {\n // Cache the loaded image\n this.cache.set(idOrUrl, img);\n this.cache.set(url, img);\n this.loading.delete(idOrUrl);\n this.loading.delete(url);\n resolve(img);\n };\n\n img.onerror = () => {\n logger.error('Failed to load texture:', url);\n this.loading.delete(idOrUrl);\n this.loading.delete(url);\n reject(new Error(`Failed to load texture: ${url}`));\n };\n\n img.src = url;\n });\n\n // Store loading promise\n this.loading.set(idOrUrl, loadingPromise);\n if (url !== idOrUrl) {\n this.loading.set(url, loadingPromise);\n }\n\n return loadingPromise;\n }\n\n /**\n * Get a texture synchronously (returns null if not loaded)\n */\n static getTexture(idOrUrl: string): HTMLImageElement | null {\n const url = this.resolveTextureUrl(idOrUrl);\n return this.cache.get(idOrUrl) || this.cache.get(url) || null;\n }\n\n /**\n * Preload multiple textures\n */\n static async preloadTextures(idsOrUrls: string[]): Promise<void> {\n await Promise.all(idsOrUrls.map((id) => this.loadTexture(id)));\n }\n\n /**\n * Preload all built-in textures\n */\n static async preloadAllTextures(): Promise<void> {\n await this.preloadTextures(this.TEXTURES.map((t) => t.id));\n }\n\n /**\n * Clear cache\n */\n static clearCache(): void {\n this.cache.clear();\n this.loading.clear();\n }\n\n /**\n * Resolve texture URL from ID\n */\n private static resolveTextureUrl(idOrUrl: string): string {\n // If it's already a URL, return as-is\n if (\n idOrUrl.startsWith('http://') ||\n idOrUrl.startsWith('https://') ||\n idOrUrl.startsWith('/') ||\n idOrUrl.startsWith('data:')\n ) {\n return idOrUrl;\n }\n\n // Look up built-in texture by ID\n const texture = this.TEXTURES.find((t) => t.id === idOrUrl);\n if (texture) {\n return texture.url;\n }\n\n // Default: treat as relative URL\n return `/textures/${idOrUrl}`;\n }\n\n /**\n * Get texture info by ID\n */\n static getTextureInfo(id: string): TextureInfo | undefined {\n return this.TEXTURES.find((t) => t.id === id);\n }\n\n /**\n * Get all available textures\n */\n static getAllTextures(): TextureInfo[] {\n return [...this.TEXTURES];\n }\n\n /**\n * Get textures by category\n */\n static getTexturesByCategory(category: string): TextureInfo[] {\n return this.TEXTURES.filter((t) => t.category === category);\n }\n\n /**\n * Get preset color for a texture\n * Each texture has a fixed color that's part of its preset\n */\n static getTexturePresetColor(textureId: string): string {\n const texture = this.TEXTURES.find((t) => t.id === textureId);\n return texture?.presetColor || '#ffffff';\n }\n}\n","/**\n * ElementPreviewRenderer - Generates thumbnail previews for layer panel\n * Creates small canvas thumbnails of elements for display in the layers panel\n * Uses the element's actual renderContent method for accurate previews\n */\n\n// Element painting goes through the paint registry (P1 element/renderer\n// split); installing the painters guarantees they are registered before any\n// element.render() this module drives. Explicit call, not a bare side-effect\n// import — see the note in core/CanvasRenderer.ts (bundlers prune bare\n// imports under the package `sideEffects` allowlist). Unlike the other paint\n// drivers this module sits INSIDE the deliberate element-painters cycle, so\n// the call happens lazily in generateElementPreview, never at module eval —\n// a top-level call here runs mid-cycle and hits the TDZ on the painters'\n// `installed` flag.\nimport { installElementPainters } from '../rendering/element-painters.js';\nimport { TextElement } from '../core/TextElement.js';\nimport { ImageElement } from '../core/ImageElement.js';\nimport { GroupElement } from '../core/GroupElement.js';\nimport { ShapeElement } from '../core/ShapeElement.js';\nimport { PathElement } from '../core/PathElement.js';\nimport { createLogger } from './logger';\n\nconst logger = createLogger('ElementPreviewRenderer');\n\ntype LayerElement = TextElement | ImageElement | GroupElement | ShapeElement | PathElement;\n\nexport interface PreviewOptions {\n width?: number;\n height?: number;\n padding?: number;\n backgroundColor?: string;\n}\n\nconst DEFAULT_OPTIONS: Required<PreviewOptions> = {\n width: 40,\n height: 40,\n padding: 4,\n backgroundColor: 'transparent',\n};\n\n/**\n * Generate a thumbnail preview for an element\n * Returns a data URL that can be used as an image src\n * Uses the element's actual renderContent method for accurate representation\n */\nexport function generateElementPreview(\n element: LayerElement,\n options: PreviewOptions = {}\n): string {\n installElementPainters();\n const opts = { ...DEFAULT_OPTIONS, ...options };\n\n // Create a small canvas for the thumbnail\n const canvas = document.createElement('canvas');\n canvas.width = opts.width;\n canvas.height = opts.height;\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n return '';\n }\n\n // Clear with background\n if (opts.backgroundColor !== 'transparent') {\n ctx.fillStyle = opts.backgroundColor;\n ctx.fillRect(0, 0, opts.width, opts.height);\n }\n\n // Save context state\n ctx.save();\n\n try {\n // Use actual element rendering for accurate preview\n if (element instanceof GroupElement) {\n renderGroupPreview(ctx, element, opts);\n } else {\n renderElementUsingActualRenderer(ctx, element, opts);\n }\n } catch (error) {\n logger.warn('Failed to generate preview:', error);\n }\n\n // Restore context state\n ctx.restore();\n\n // Return data URL\n return canvas.toDataURL('image/png');\n}\n\n/**\n * Render element using its actual render method\n * This ensures the preview matches exactly what's on the canvas\n */\nfunction renderElementUsingActualRenderer(\n ctx: CanvasRenderingContext2D,\n element: LayerElement,\n opts: Required<PreviewOptions>\n): void {\n // Get the element's bounding box\n const bbox = element.getBoundingBox?.() || { x: 0, y: 0, width: 100, height: 100 };\n const elementWidth = bbox.width;\n const elementHeight = bbox.height;\n\n if (elementWidth === 0 || elementHeight === 0) {\n // Fallback for empty elements\n renderFallbackPreview(ctx, element, opts);\n return;\n }\n\n // Calculate scale to fit in preview with padding\n const availableWidth = opts.width - opts.padding * 2;\n const availableHeight = opts.height - opts.padding * 2;\n const scale = Math.min(\n availableWidth / elementWidth,\n availableHeight / elementHeight,\n 1 // Don't scale up, only down\n );\n\n // Calculate centered position\n const scaledWidth = elementWidth * scale;\n const scaledHeight = elementHeight * scale;\n const offsetX = opts.padding + (availableWidth - scaledWidth) / 2;\n const offsetY = opts.padding + (availableHeight - scaledHeight) / 2;\n\n // Apply transformations for preview\n ctx.save();\n ctx.translate(offsetX - bbox.x * scale, offsetY - bbox.y * scale);\n ctx.scale(scale, scale);\n\n // Render the element using its actual render method\n // Elements have render(ctx, isSelected, isHovered) method\n if (typeof element.render === 'function') {\n element.render(ctx, false, false);\n } else {\n // Fallback if no render method\n renderFallbackPreview(ctx, element, opts);\n }\n\n ctx.restore();\n}\n\n/**\n * Fallback preview renderer for elements without render method\n */\nfunction renderFallbackPreview(\n ctx: CanvasRenderingContext2D,\n element: LayerElement,\n opts: Required<PreviewOptions>\n): void {\n // Draw placeholder\n ctx.fillStyle = '#888888';\n ctx.font = '10px Arial';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n const label = element.transformType || 'Element';\n ctx.fillText(label, opts.width / 2, opts.height / 2);\n}\n\n/**\n * Render group element preview\n */\nfunction renderGroupPreview(\n ctx: CanvasRenderingContext2D,\n element: GroupElement,\n opts: Required<PreviewOptions>\n): void {\n // Draw a simple folder/group icon\n const availableWidth = opts.width - opts.padding * 2;\n const availableHeight = opts.height - opts.padding * 2;\n const x = opts.padding;\n const y = opts.padding;\n\n ctx.fillStyle = '#888888';\n ctx.strokeStyle = '#666666';\n ctx.lineWidth = 1;\n\n // Draw folder shape\n const folderHeight = availableHeight * 0.7;\n const folderY = y + availableHeight * 0.3;\n const tabWidth = availableWidth * 0.4;\n const tabHeight = availableHeight * 0.2;\n\n // Draw folder body\n ctx.fillRect(x, folderY, availableWidth, folderHeight);\n\n // Draw folder tab\n ctx.fillRect(x, folderY - tabHeight, tabWidth, tabHeight);\n\n // Optional: Draw children count if group has children\n if (element.children && element.children.length > 0) {\n ctx.fillStyle = '#FFFFFF';\n ctx.font = 'bold 10px Arial';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(\n element.children.length.toString(),\n x + availableWidth / 2,\n folderY + folderHeight / 2\n );\n }\n}\n","/**\n * Stroke utility functions for path creation\n */\n\nimport type { AnyElementConfig, BaseTextElementConfig, ImageElementConfig, CustomElementConfig, RenderingContext } from '../types/index.js';\nimport { buildFontString, measureTextWidth } from '../core/TextMetrics.js';\n\n/**\n * Create text path for stroking\n * Handles all text transform types\n */\nexport function createTextPath(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig,\n _renderingContext?: RenderingContext\n): void {\n // Position and rotate\n ctx.translate(element.x || 0, element.y || 0);\n ctx.rotate((-(element.rotation || 0) * Math.PI) / 180);\n\n // Narrow to text element config to access text properties\n const textElement = element as BaseTextElementConfig;\n\n // Set font for text measurement\n const fontSize = textElement.fontSize || 24;\n const fontFamily = textElement.fontFamily || 'Arial';\n const bold = textElement.bold || false;\n const italic = textElement.italic || false;\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\n\n const text = textElement.text || '';\n\n // For straight text (custom transform), stroke the bounding box\n if (element.transformType === 'custom') {\n const customElement = element as CustomElementConfig;\n const width = customElement.transformData?.width || 200;\n\n // Create rectangle path around text bounds\n const textWidth = measureTextWidth(text, fontSize, fontFamily, bold, italic);\n const actualWidth = Math.min(textWidth, width);\n const height = fontSize * 1.2;\n\n ctx.rect(-actualWidth / 2, -height / 2, actualWidth, height);\n }\n // For text on path transforms, stroke the text outline\n else {\n // For curved/transformed text, we'll stroke along the text baseline\n // This is a simplified approach - full text outline requires more complex path generation\n\n // Approximate by drawing along baseline\n const textWidth = ctx.measureText(text).width;\n\n ctx.beginPath();\n ctx.moveTo(-textWidth / 2, 0);\n ctx.lineTo(textWidth / 2, 0);\n ctx.moveTo(-textWidth / 2, -fontSize);\n ctx.lineTo(textWidth / 2, -fontSize);\n ctx.moveTo(-textWidth / 2, fontSize * 0.2);\n ctx.lineTo(textWidth / 2, fontSize * 0.2);\n }\n}\n\n/**\n * Create image boundary path for stroking\n */\nexport function createImagePath(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: ImageElementConfig\n): void {\n if (!element.transformData) return;\n\n const { borderRadius = 0 } = element.transformData;\n const width = element.transformData.width ?? 100;\n const height = element.transformData.height ?? 100;\n\n // Position and rotate\n ctx.translate(element.x || 0, element.y || 0);\n ctx.rotate((-(element.rotation || 0) * Math.PI) / 180);\n\n // Create path with border radius\n ctx.beginPath();\n\n if (borderRadius > 0) {\n // Rounded rectangle\n const maxRadius = Math.min(width, height) / 2;\n const radius = Math.min(borderRadius, maxRadius);\n\n const x = -width / 2;\n const y = -height / 2;\n\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.arcTo(x + width, y, x + width, y + radius, radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);\n ctx.lineTo(x + radius, y + height);\n ctx.arcTo(x, y + height, x, y + height - radius, radius);\n ctx.lineTo(x, y + radius);\n ctx.arcTo(x, y, x + radius, y, radius);\n ctx.closePath();\n } else {\n // Simple rectangle\n ctx.rect(-width / 2, -height / 2, width, height);\n }\n}\n\n/**\n * Create circular path (for circle transform or shapes)\n */\nexport function createCirclePath(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n x: number,\n y: number,\n radius: number\n): void {\n ctx.beginPath();\n ctx.arc(x, y, radius, 0, Math.PI * 2);\n ctx.closePath();\n}\n\n/**\n * Create rectangular path\n */\nexport function createRectPath(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.beginPath();\n ctx.rect(x, y, width, height);\n ctx.closePath();\n}\n","/**\n * StrokeRenderer - Universal stroke rendering for all element types\n *\n * IMPORTANT: This renders the ELEMENT STROKE EFFECT (element.stroke property)\n * This is NOT the hover ring effect (see CanvasRenderer.ts for hover rings)\n *\n * This renderer is ONLY used when:\n * - User explicitly enables stroke in the effects panel\n * - element.stroke.enabled = true\n *\n * Provides stroke rendering capabilities for:\n * - Text elements (all transform types)\n * - Image elements\n * - Shape elements\n * - Groups\n */\n\nimport type {\n StrokeConfig,\n AnyElementConfig,\n ImageElementConfig,\n RenderingContext,\n CustomElementConfig,\n BaseTextElementConfig,\n} from '../types/index.js';\nimport { createImagePath } from './stroke-utils.js';\nimport { getFontMetrics, calculateVisualBoundsWithSpaceCollapsing } from '../core/TextMetrics.js';\nimport { strokeTextWithSpacing } from '../core/text-spacing.js';\nimport { HORIZONTAL_PADDING, LINE_HEIGHT_MULTIPLIER } from '../constants.js';\n\n/**\n * Apply stroke style to canvas context\n */\nexport function applyStrokeStyle(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n stroke: StrokeConfig\n): void {\n ctx.strokeStyle = stroke.color;\n ctx.lineWidth = stroke.width;\n ctx.lineCap = stroke.lineCap || 'butt';\n ctx.lineJoin = stroke.lineJoin || 'miter';\n\n if (stroke.miterLimit !== undefined) {\n ctx.miterLimit = stroke.miterLimit;\n }\n\n if (stroke.dashArray && stroke.dashArray.length > 0) {\n ctx.setLineDash(stroke.dashArray);\n } else {\n ctx.setLineDash([]);\n }\n\n if (stroke.opacity !== undefined) {\n ctx.globalAlpha = stroke.opacity;\n }\n}\n\n/**\n * Create an offscreen canvas compatible with both main thread and Web Worker.\n * Uses OffscreenCanvas when available, falls back to document.createElement.\n */\nfunction createOffscreenCanvas(\n width: number,\n height: number\n): HTMLCanvasElement | OffscreenCanvas {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\n/**\n * Render stroke for text element\n * Uses ctx.strokeText() for proper text outline stroking\n * Now supports text wrapping for CustomTransform elements\n *\n * When stroke.opacity < 1, renders the entire stroke to a temporary canvas at\n * full opacity, then composites that layer onto the main canvas at the desired\n * opacity. This prevents darkening where adjacent characters' strokes overlap.\n */\nexport function renderTextStroke(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig,\n renderingContext?: RenderingContext\n): void {\n if (!element.stroke?.enabled) return;\n\n // This function is only called for text elements; narrow to access text properties\n const textElement = element as BaseTextElementConfig;\n const text = textElement.text || '';\n if (!text) return;\n\n // Check if this is for a knockout operation (rendering to offscreen canvas)\n const isKnockoutRender = renderingContext?.isKnockout === true;\n\n // When stroke has sub-1 opacity (and this isn't a knockout render), render the\n // entire stroke to a temp canvas at full opacity, then composite at the target\n // opacity. This avoids overlap darkening between adjacent characters' strokes.\n const strokeOpacity = element.stroke.opacity ?? 1;\n const needsOffscreen = !isKnockoutRender && strokeOpacity < 1;\n\n if (needsOffscreen) {\n try {\n renderTextStrokeViaOffscreen(ctx, element, textElement, renderingContext, strokeOpacity);\n } catch {\n // Fallback: render directly if offscreen approach fails\n // (e.g., getTransform() not available in test mocks)\n renderTextStrokeDirect(ctx, element, textElement, renderingContext, false);\n }\n } else {\n renderTextStrokeDirect(ctx, element, textElement, renderingContext, isKnockoutRender);\n }\n}\n\n/**\n * Render stroke via an offscreen canvas to apply opacity uniformly.\n * Draws all stroke paths at full opacity on a temp canvas, then composites\n * that canvas onto the main canvas at the desired opacity.\n */\nfunction renderTextStrokeViaOffscreen(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig,\n textElement: BaseTextElementConfig,\n renderingContext: RenderingContext | undefined,\n strokeOpacity: number\n): void {\n const text = textElement.text || '';\n\n // Estimate the bounds we need for the offscreen canvas\n const fontSize = textElement.fontSize || 24;\n const strokeWidth = element.stroke!.width;\n const feather = element.stroke!.feather || 0;\n const isCustomTransform = element.transformType === 'custom' &&\n (element as CustomElementConfig).transformData?.width;\n const customWidth = isCustomTransform\n ? ((element as CustomElementConfig).transformData?.width ?? 200)\n : 0;\n\n // Estimate element dimensions in world space\n const estWidth = isCustomTransform\n ? customWidth + strokeWidth * 2 + feather * 2 + 40\n : fontSize * text.length * 0.7 + strokeWidth * 2 + feather * 2 + 40;\n const estHeight = fontSize * 3 + strokeWidth * 2 + feather * 2 + 40;\n\n // Account for current canvas scale to ensure crisp rendering\n const transform = ctx.getTransform();\n const scale = Math.max(Math.abs(transform.a), Math.abs(transform.d), 1);\n\n // Use even dimensions so that offW/2 and offH/2 are integers, avoiding\n // fractional pixel offsets that cause sub-pixel rendering differences\n // between main thread and worker (the 0.21% export parity diff).\n const offW = Math.ceil(estWidth * scale / 2) * 2;\n const offH = Math.ceil(estHeight * scale / 2) * 2;\n\n // Guard against invalid canvas dimensions\n if (offW <= 0 || offH <= 0) {\n // Fallback: render directly with per-character opacity\n renderTextStrokeDirect(ctx, element, textElement, renderingContext, false);\n return;\n }\n\n const offCanvas = createOffscreenCanvas(offW, offH);\n const offCtx = offCanvas.getContext('2d') as\n | CanvasRenderingContext2D\n | OffscreenCanvasRenderingContext2D\n | null;\n\n if (!offCtx) {\n // Fallback: render directly with per-character opacity\n renderTextStrokeDirect(ctx, element, textElement, renderingContext, false);\n return;\n }\n\n // Set up the offscreen canvas transform so the element center maps to the\n // center of the offscreen canvas. We replicate the main canvas transform\n // but shift the translation so the element is centered in the temp canvas.\n const elemX = element.x || 0;\n const elemY = element.y || 0;\n\n // Where the element center would be in pixel space on the main canvas\n const centerPixelX = transform.a * elemX + transform.c * elemY + transform.e;\n const centerPixelY = transform.b * elemX + transform.d * elemY + transform.f;\n\n // Shift so element center maps to offscreen center\n offCtx.setTransform(\n transform.a, transform.b,\n transform.c, transform.d,\n offW / 2 - centerPixelX + transform.e,\n offH / 2 - centerPixelY + transform.f\n );\n\n // Render the stroke at full opacity onto the offscreen canvas.\n // Override stroke opacity to 1.0 for this render.\n const originalOpacity = element.stroke!.opacity;\n element.stroke!.opacity = 1.0;\n renderTextStrokeDirect(offCtx, element, textElement, renderingContext, false);\n element.stroke!.opacity = originalOpacity;\n\n // Composite the offscreen canvas onto the main canvas at the desired opacity.\n // Round the draw-back coordinates to avoid sub-pixel positioning differences\n // between main thread and worker environments.\n ctx.save();\n ctx.resetTransform();\n ctx.globalAlpha = strokeOpacity;\n ctx.drawImage(\n offCanvas as CanvasImageSource,\n Math.round(centerPixelX - offW / 2),\n Math.round(centerPixelY - offH / 2)\n );\n ctx.restore();\n}\n\n/**\n * Render stroke directly onto the provided canvas context.\n * This is the original rendering logic, used both for full-opacity strokes\n * and as the inner renderer for the offscreen opacity approach.\n */\nfunction renderTextStrokeDirect(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig,\n textElement: BaseTextElementConfig,\n renderingContext: RenderingContext | undefined,\n isKnockoutRender: boolean\n): void {\n const text = textElement.text || '';\n\n ctx.save();\n\n // Position and rotate - match main text rendering\n // Skip if the caller (e.g. ElementRenderUtils.renderElement) already applied positioning\n if (!renderingContext?.positionApplied) {\n ctx.translate(element.x || 0, element.y || 0);\n ctx.rotate((-(element.rotation || 0) * Math.PI) / 180);\n }\n\n // Set font - match exactly how main text is rendered\n const fontSize = textElement.fontSize || 24;\n const fontFamily = textElement.fontFamily || 'Arial';\n const bold = textElement.bold || false;\n const italic = textElement.italic || false;\n const textAlign = textElement.textAlign || 'center';\n\n ctx.font = `${italic ? 'italic ' : ''}${bold ? 'bold ' : ''}${fontSize}px ${fontFamily}`;\n ctx.textAlign = textAlign as CanvasTextAlign;\n ctx.textBaseline = 'alphabetic'; // MATCH main text rendering baseline\n\n // Apply stroke style\n if (isKnockoutRender) {\n // For knockout, render with full opacity black - color doesn't matter for destination-out\n ctx.strokeStyle = '#000000';\n ctx.globalAlpha = 1.0;\n } else {\n ctx.strokeStyle = element.stroke!.color;\n if (element.stroke!.opacity !== undefined) {\n ctx.globalAlpha = element.stroke!.opacity;\n }\n }\n\n ctx.lineWidth = element.stroke!.width;\n ctx.lineCap = element.stroke!.lineCap || 'round';\n ctx.lineJoin = element.stroke!.lineJoin || 'round';\n\n if (element.stroke!.miterLimit !== undefined) {\n ctx.miterLimit = element.stroke!.miterLimit;\n }\n\n // Feathering (blur) - only supported in regular canvas context\n // Don't apply feather for knockout renders\n if (!isKnockoutRender && element.stroke!.feather && element.stroke!.feather > 0) {\n if ('filter' in ctx) {\n (ctx as CanvasRenderingContext2D).filter = `blur(${element.stroke!.feather}px)`;\n }\n }\n\n // Calculate font metrics\n const fontMetrics = getFontMetrics(fontSize, fontFamily, bold, italic);\n\n // Check if this is a CustomTransform with width (needs text wrapping)\n const isCustomTransform = element.transformType === 'custom' &&\n (element as CustomElementConfig).transformData?.width;\n\n if (isCustomTransform) {\n // CustomTransform: Handle text wrapping\n const transformData = (element as CustomElementConfig).transformData;\n const width = transformData?.width ?? 200;\n const availableWidth = width - HORIZONTAL_PADDING * 2;\n\n // Typography knobs — must match the fill renderer or the outline drifts\n const letterSpacing = textElement.letterSpacing ?? 0;\n\n // CRITICAL FIX: Use calculateVisualBoundsWithSpaceCollapsing to match selection box exactly\n // This ensures stroke wraps the same way as the bounding box and main rendering\n const { lines, height: visualHeight } = calculateVisualBoundsWithSpaceCollapsing(\n text,\n availableWidth,\n fontSize,\n fontFamily,\n bold,\n italic,\n undefined, // No locked line count for stroke\n true, // strict: wrap exactly at maxWidth\n { letterSpacing, lineHeight: textElement.lineHeight }\n );\n\n // Calculate top-left position (same as fill rendering)\n const topLeftX = -width / 2;\n const topLeftY = -visualHeight / 2;\n\n // Stroke each line (matching renderMultilineText positioning)\n // CRITICAL: We must stroke at the correct Y position even when lines are empty\n // Example: [\" \", \"Foo\", \"Bar\"] - line 0 is empty but occupies space, so \"Foo\" renders at line 0 position\n const lineSpacing = fontSize * (textElement.lineHeight ?? LINE_HEIGHT_MULTIPLIER);\n lines.forEach((line: string, index: number) => {\n // Apply space layout rules (matching renderRichTextFillOnly logic)\n // For wrapped text (not explicit newlines), first line is paragraph start, last is paragraph end\n const isParagraphStart = index === 0;\n const isParagraphEnd = index === lines.length - 1;\n\n // Apply space collapsing to match visual rendering\n let visibleText = line;\n\n // Hide leading spaces when NOT at paragraph start\n if (!isParagraphStart) {\n const leadingSpacesMatch = line.match(/^ +/);\n const leadingSpacesCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;\n if (leadingSpacesCount > 0) {\n visibleText = visibleText.substring(leadingSpacesCount);\n }\n }\n\n // Hide trailing spaces when NOT at paragraph end\n if (!isParagraphEnd) {\n const trailingSpacesMatch = visibleText.match(/ +$/);\n const trailingSpacesCount = trailingSpacesMatch ? trailingSpacesMatch[0].length : 0;\n if (trailingSpacesCount > 0) {\n visibleText = visibleText.substring(0, visibleText.length - trailingSpacesCount);\n }\n }\n\n // CRITICAL: Stroke ALL lines, even empty ones!\n // Even though strokeText(\" \") won't draw anything visible, we MUST call it\n // to maintain correct layout positions. Otherwise the 2 visible lines get\n // vertically centered within the 3-line height container.\n let xPos = topLeftX + HORIZONTAL_PADDING;\n\n if (textAlign === 'center') {\n xPos = topLeftX + width / 2;\n } else if (textAlign === 'right') {\n xPos = topLeftX + width - HORIZONTAL_PADDING;\n }\n\n // Use index (not a visual line counter) to match the actual line position\n const yPos = topLeftY + fontMetrics.ascent + index * lineSpacing;\n // Letter-spacing-aware (single strokeText when spacing is 0).\n // Stroke even if empty for correct positioning.\n strokeTextWithSpacing(ctx, visibleText, xPos, yPos, letterSpacing);\n });\n } else {\n // Other transforms: Single line rendering (original behavior)\n const visualHeight = fontMetrics.height;\n const topLeftY = -visualHeight / 2;\n const yPos = topLeftY + fontMetrics.ascent;\n ctx.strokeText(text, 0, yPos);\n }\n\n ctx.restore();\n}\n\n/**\n * Render stroke for image element\n */\nexport function renderImageStroke(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: ImageElementConfig,\n renderingContext?: RenderingContext\n): void {\n if (!element.stroke?.enabled) return;\n if (!element.transformData) return;\n\n const isKnockoutRender = renderingContext?.isKnockout === true;\n\n ctx.save();\n\n // Apply stroke style\n if (isKnockoutRender) {\n // For knockout, render with full opacity\n ctx.strokeStyle = '#000000';\n ctx.lineWidth = element.stroke.width;\n ctx.lineCap = element.stroke.lineCap || 'butt';\n ctx.lineJoin = element.stroke.lineJoin || 'miter';\n ctx.globalAlpha = 1.0;\n if (element.stroke.miterLimit !== undefined) {\n ctx.miterLimit = element.stroke.miterLimit;\n }\n } else {\n applyStrokeStyle(ctx, element.stroke);\n }\n\n // Feathering (blur) - only supported in regular canvas context\n // Don't apply feather for knockout renders\n if (!isKnockoutRender && element.stroke.feather && element.stroke.feather > 0) {\n if ('filter' in ctx) {\n (ctx as CanvasRenderingContext2D).filter = `blur(${element.stroke.feather}px)`;\n }\n }\n\n // Create image boundary path and stroke it\n createImagePath(ctx, element);\n ctx.stroke();\n\n ctx.restore();\n}\n\n/**\n * Render stroke for arbitrary path\n * Used for custom shapes and transforms\n */\nexport function renderPathStroke(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n stroke: StrokeConfig,\n pathFn: () => void\n): void {\n if (!stroke.enabled) return;\n\n ctx.save();\n\n // Apply stroke style\n applyStrokeStyle(ctx, stroke);\n\n // Feathering (blur) - only supported in regular canvas context\n if (stroke.feather && stroke.feather > 0) {\n if ('filter' in ctx) {\n (ctx as CanvasRenderingContext2D).filter = `blur(${stroke.feather}px)`;\n }\n }\n\n // Execute path function and stroke it\n ctx.beginPath();\n pathFn();\n ctx.stroke();\n\n ctx.restore();\n}\n","/**\n * GlyphRenderer - Utility for rendering text with glyph overrides and OpenType features\n *\n * This provides enhanced text rendering that supports:\n * - Per-character glyph substitution\n * - OpenType feature application\n */\n\nimport type { GlyphOverride, OpenTypeFeatures } from '../types';\nimport type { FontkitFont } from './FontAnalyzer';\nimport { FontAnalyzer } from './FontAnalyzer';\nimport { createLogger } from './logger';\n\nconst logger = createLogger('GlyphRenderer');\n\n/**\n * Build CSS font-feature-settings string from OpenTypeFeatures\n */\nexport function buildFontFeatureSettings(features?: OpenTypeFeatures): string {\n if (!features) return '';\n\n const settings: string[] = [];\n\n Object.entries(features).forEach(([tag, enabled]) => {\n if (enabled) {\n settings.push(`\"${tag}\" 1`);\n }\n });\n\n return settings.join(', ');\n}\n\n/**\n * Apply OpenType features to canvas context via font string\n * Note: Browser support for font-feature-settings in canvas is limited\n * This works in Chrome 99+, Firefox 105+, Safari 16.4+\n */\nexport function applyOpenTypeFeaturestoContext(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n features?: OpenTypeFeatures\n): void {\n if (!features || Object.keys(features).length === 0) return;\n\n // Use fontVariantCaps for small caps (better browser support)\n if (features.smcp || features.c2sc) {\n (ctx as CanvasRenderingContext2D & { fontVariantCaps?: string }).fontVariantCaps = 'small-caps';\n }\n\n // Note: Direct font-feature-settings support in canvas is limited\n // For full support, text would need to be rendered to DOM first, then drawn to canvas\n}\n\n/**\n * Render text with OpenType features using fontkit (synchronous version)\n * This method renders glyphs as paths with features applied\n * Requires font to be pre-loaded and passed as parameter\n */\nexport function renderTextWithOpenTypeFeaturesSync(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n font: FontkitFont,\n text: string,\n x: number,\n y: number,\n fontSize: number,\n features: OpenTypeFeatures,\n options: {\n color?: string;\n align?: 'left' | 'center' | 'right';\n } = {}\n): void {\n try {\n // Build feature array for fontkit\n const featureArray: string[] = [];\n Object.entries(features).forEach(([tag, enabled]) => {\n if (enabled) {\n featureArray.push(tag);\n }\n });\n\n\n // Check available GSUB features\n const availableFeatures: string[] = [];\n if (font.GSUB && font.GSUB.featureList) {\n font.GSUB.featureList.forEach((feat: { tag: string }) => {\n availableFeatures.push(feat.tag);\n });\n }\n\n\n\n // Use fontkit's layout engine to apply OpenType features\n // fontkit.layout(text, features, script, language, direction)\n\n // Build features object (fontkit prefers object format)\n const featuresObject: Record<string, boolean> = {};\n\n // Always enable required features for proper text shaping\n // These are the \"default\" features that should always be on\n featuresObject.ccmp = true; // Glyph composition/decomposition (required)\n featuresObject.locl = true; // Localized forms\n featuresObject.kern = true; // Kerning\n\n // Add user-selected features on top of defaults\n featureArray.forEach((tag) => {\n featuresObject[tag] = true;\n });\n\n // For script/cursive fonts, if calt is enabled, also enable related features\n // that work together to create proper connections\n if (featuresObject.calt) {\n featuresObject.liga = true; // Standard ligatures (needed for connections)\n featuresObject.init = true; // Initial forms\n featuresObject.fina = true; // Final forms\n // Note: These features work TOGETHER - calt triggers contextual substitutions,\n // while init/fina/liga provide the alternate glyphs\n }\n\n\n\n // Try layout with features and script tag\n // Script tag 'latn' is required for proper Latin font shaping\n const run = font.layout(text, featuresObject, 'latn');\n\n\n // Calculate scale from font units to pixels\n const scale = fontSize / font.unitsPerEm;\n\n // Calculate total width for alignment\n let totalWidth = 0;\n run.glyphs.forEach((glyph) => {\n totalWidth += glyph.advanceWidth * scale;\n });\n\n // Adjust starting x position based on alignment\n let startX = x;\n if (options.align === 'center') {\n startX = x - totalWidth / 2;\n } else if (options.align === 'right') {\n startX = x - totalWidth;\n }\n\n // Render each glyph\n ctx.save();\n ctx.fillStyle = options.color || '#000000';\n\n let currentX = startX;\n run.glyphs.forEach((glyph, index: number) => {\n const position = run.positions[index];\n\n // Get the path data - try multiple approaches\n let pathData: string | null = null;\n\n try {\n // Method 1: Try toPath() for d attribute (standard fontkit)\n if (glyph.path && typeof glyph.path.toPath === 'function') {\n pathData = glyph.path.toPath();\n }\n // Method 2: Try toSVG() and extract or use directly\n else if (glyph.path && typeof glyph.path.toSVG === 'function') {\n const svgPath = glyph.path.toSVG();\n\n // Check if it's already path data (starts with M, L, C, etc.)\n if (svgPath && /^[MmLlHhVvCcSsQqTtAaZz]/.test(svgPath)) {\n pathData = svgPath;\n } else {\n // Try to extract d attribute\n const dMatch = svgPath?.match(/\\bd=[\"']([^\"']+)[\"']/);\n pathData = dMatch ? dMatch[1] : null;\n }\n }\n } catch (e) {\n logger.warn('Error getting path for glyph:', glyph.name, e);\n }\n\n if (index === 0) {\n }\n\n if (pathData) {\n // Create Path2D from path data\n const path2D = new Path2D(pathData);\n\n // Apply transformations for position and scale\n ctx.save();\n ctx.translate(currentX + position.xOffset * scale, y + position.yOffset * scale);\n ctx.scale(scale, -scale); // Flip Y axis for proper rendering\n ctx.fill(path2D);\n ctx.restore();\n }\n\n currentX += glyph.advanceWidth * scale;\n });\n\n ctx.restore();\n } catch (error) {\n logger.error('Error rendering with fontkit:', error);\n // Fallback to standard rendering\n ctx.fillStyle = options.color || '#000000';\n ctx.textAlign = options.align || 'left';\n ctx.fillText(text, x, y);\n }\n}\n\n/**\n * Render text with OpenType features using fontkit (async version)\n * This method renders glyphs as paths with features applied\n */\nexport async function renderTextWithOpenTypeFeatures(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n fontSize: number,\n fontFamily: string,\n features: OpenTypeFeatures,\n options: {\n color?: string;\n bold?: boolean;\n italic?: boolean;\n align?: 'left' | 'center' | 'right';\n } = {}\n): Promise<void> {\n // Load font using FontAnalyzer\n const font = await FontAnalyzer.loadFont(fontFamily, options.bold ? 700 : 400);\n if (!font) {\n // Fallback to standard rendering\n ctx.fillStyle = options.color || '#000000';\n ctx.textAlign = options.align || 'left';\n ctx.fillText(text, x, y);\n return;\n }\n\n // Use the synchronous version with the loaded font\n renderTextWithOpenTypeFeaturesSync(ctx, font, text, x, y, fontSize, features, options);\n}\n\n/**\n * Render text with glyph overrides using fontkit (synchronous version)\n * Requires font to be pre-loaded and passed as parameter\n */\nexport function renderTextWithGlyphOverridesSync(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n font: FontkitFont,\n text: string,\n x: number,\n y: number,\n fontSize: number,\n glyphOverrides?: GlyphOverride[],\n options: {\n color?: string;\n align?: 'left' | 'center' | 'right';\n } = {}\n): void {\n // Helper to detect PUA characters\n const containsPUA = (str: string): boolean => {\n for (const char of str) {\n const cp = char.codePointAt(0);\n if (cp && cp >= 0xf0000 && cp <= 0xffffd) return true;\n }\n return false;\n };\n\n const hasPUA = containsPUA(text);\n\n // If no glyph overrides AND no PUA characters, use standard canvas text rendering\n if ((!glyphOverrides || glyphOverrides.length === 0) && !hasPUA) {\n ctx.fillStyle = options.color || '#000000';\n ctx.textAlign = options.align || 'left';\n ctx.fillText(text, x, y);\n return;\n }\n\n\n // Create a map of character indices to glyph overrides\n const overrideMap = new Map<number, number>();\n if (glyphOverrides) {\n glyphOverrides.forEach((override) => {\n overrideMap.set(override.charIndex, override.glyphIndex);\n });\n }\n\n // Calculate scale from font units to pixels\n const scale = fontSize / font.unitsPerEm;\n\n const chars = Array.from(text); // Use Array.from to handle multi-byte chars\n\n // Calculate total width for alignment\n let totalWidth = 0;\n chars.forEach((char, index) => {\n const codePoint = char.codePointAt(0) || 0;\n let glyphId: number | undefined;\n\n // Check if character is in our PUA range (U+F0000 to U+FFFFD)\n if (codePoint >= 0xf0000 && codePoint <= 0xffffd) {\n // Extract glyph ID from PUA codepoint\n glyphId = codePoint - 0xf0000;\n } else {\n // Check for override (legacy system)\n glyphId = overrideMap.get(index);\n\n if (glyphId === undefined) {\n const defaultGlyph = font.glyphForCodePoint(codePoint);\n glyphId = defaultGlyph ? defaultGlyph.id : 0;\n }\n }\n\n const glyph = font.getGlyph(glyphId);\n if (glyph) {\n totalWidth += glyph.advanceWidth * scale;\n }\n });\n\n // Adjust starting x position based on alignment\n let startX = x;\n if (options.align === 'center') {\n startX = x - totalWidth / 2;\n } else if (options.align === 'right') {\n startX = x - totalWidth;\n }\n\n // Render each character\n ctx.save();\n ctx.fillStyle = options.color || '#000000';\n\n let currentX = startX;\n\n chars.forEach((char, index) => {\n // Get the glyph ID\n const codePoint = char.codePointAt(0) || 0;\n let glyphId: number | undefined;\n\n // Check if character is in our PUA range (U+F0000 to U+FFFFD)\n // These are our mapped alternate glyphs\n if (codePoint >= 0xf0000 && codePoint <= 0xffffd) {\n // Extract glyph ID from PUA codepoint\n glyphId = codePoint - 0xf0000;\n } else {\n // Check for override (legacy system)\n glyphId = overrideMap.get(index);\n\n if (glyphId === undefined) {\n // Use default glyph\n const defaultGlyph = font.glyphForCodePoint(codePoint);\n glyphId = defaultGlyph ? defaultGlyph.id : 0;\n }\n }\n\n // Get the glyph\n const glyph = font.getGlyph(glyphId);\n\n if (codePoint >= 0xf0000 && codePoint <= 0xffffd) {\n }\n\n if (glyph) {\n // Get SVG path\n const svgPath = glyph.path.toSVG();\n\n if (svgPath) {\n const path2D = new Path2D(svgPath);\n\n ctx.save();\n ctx.translate(currentX, y);\n ctx.scale(scale, -scale);\n ctx.fill(path2D);\n ctx.restore();\n }\n\n currentX += glyph.advanceWidth * scale;\n }\n });\n\n ctx.restore();\n}\n\n/**\n * Render text with glyph overrides using fontkit (async version)\n * Loads the font and calls the synchronous version\n */\nexport async function renderTextWithGlyphOverrides(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n fontSize: number,\n fontFamily: string,\n glyphOverrides?: GlyphOverride[],\n options: {\n color?: string;\n bold?: boolean;\n italic?: boolean;\n align?: 'left' | 'center' | 'right';\n } = {}\n): Promise<void> {\n // Load font using FontAnalyzer\n const font = await FontAnalyzer.loadFont(fontFamily, options.bold ? 700 : 400);\n if (!font) {\n // Fallback to standard rendering\n ctx.fillStyle = options.color || '#000000';\n ctx.textAlign = options.align || 'left';\n ctx.fillText(text, x, y);\n return;\n }\n\n // Use the synchronous version with the loaded font\n renderTextWithGlyphOverridesSync(ctx, font, text, x, y, fontSize, glyphOverrides, options);\n}\n\n/**\n * Calculate text width with glyph overrides using fontkit API\n */\nfunction calculateTextWidthWithOverrides(\n font: FontkitFont,\n text: string,\n overrideMap: Map<number, number>,\n scale: number\n): number {\n const chars = Array.from(text);\n let totalWidth = 0;\n\n chars.forEach((char, index) => {\n const codePoint = char.codePointAt(0) || 0;\n let glyphId: number | undefined;\n\n // Check if character is in the PUA range (U+F0000 to U+FFFFD)\n if (codePoint >= 0xf0000 && codePoint <= 0xffffd) {\n glyphId = codePoint - 0xf0000;\n } else {\n glyphId = overrideMap.get(index);\n if (glyphId === undefined) {\n const defaultGlyph = font.glyphForCodePoint(codePoint);\n glyphId = defaultGlyph ? defaultGlyph.id : 0;\n }\n }\n\n const glyph = font.getGlyph(glyphId);\n if (glyph) {\n totalWidth += glyph.advanceWidth * scale;\n }\n });\n\n return totalWidth;\n}\n\n/**\n * Measure text width with glyph overrides\n */\nexport async function measureTextWithGlyphOverrides(\n text: string,\n fontSize: number,\n fontFamily: string,\n glyphOverrides?: GlyphOverride[],\n options: {\n bold?: boolean;\n } = {}\n): Promise<number> {\n // If no glyph overrides, use standard measurement\n if (!glyphOverrides || glyphOverrides.length === 0) {\n // Create a temporary canvas context for measurement\n const canvas =\n typeof OffscreenCanvas !== 'undefined' ? new OffscreenCanvas(1, 1) : document.createElement('canvas');\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return 0;\n\n const weight = options.bold ? 'bold' : 'normal';\n ctx.font = `${weight} ${fontSize}px ${fontFamily}`;\n return ctx.measureText(text).width;\n }\n\n // Load font and calculate with overrides\n const font = await FontAnalyzer.loadFont(fontFamily, options.bold ? 700 : 400);\n if (!font) {\n // Fallback\n const canvas =\n typeof OffscreenCanvas !== 'undefined' ? new OffscreenCanvas(1, 1) : document.createElement('canvas');\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return 0;\n\n const weight = options.bold ? 'bold' : 'normal';\n ctx.font = `${weight} ${fontSize}px ${fontFamily}`;\n return ctx.measureText(text).width;\n }\n\n const overrideMap = new Map<number, number>();\n glyphOverrides.forEach((override) => {\n overrideMap.set(override.charIndex, override.glyphIndex);\n });\n\n const scale = fontSize / font.unitsPerEm;\n return calculateTextWidthWithOverrides(font, text, overrideMap, scale);\n}\n","/**\n * Rich Text Renderer - Multi-line rich text rendering with per-span styling.\n *\n * Handles word wrapping, line splitting, and rendering of styled text spans\n * with support for mixed fonts, sizes, colors, and text decorations.\n */\n\nimport { LINE_HEIGHT_MULTIPLIER } from '../constants.js';\nimport type { TextAlign, CharacterStyle } from '../types/index.js';\nimport { RichText } from '../types/index.js';\nimport type { RenderContext } from './renderer-types.js';\nimport { buildFontString, getFontMetrics } from './text-renderer.js';\nimport { fillTextWithSpacing, spacedTextWidth } from '../core/text-spacing.js';\n\n// Rich-text LAYOUT (line splitting / word wrapping) moved to\n// `src/core/rich-text-layout.ts` (P1 element/renderer split): the element\n// model needs it for geometry, so it lives outside the paint pipeline's\n// import graph. Re-exported here for the renderer's existing callers.\nimport { splitRichTextIntoLines, wrapRichTextSpans } from '../core/rich-text-layout.js';\n\nexport { splitRichTextIntoLines, wrapRichTextSpans };\n\n/**\n * Render rich text with per-span styling (fill only, no effects)\n * Supports multi-line text with line breaks and word wrapping\n */\nexport function renderRichTextFillOnly(\n ctx: RenderContext,\n richText: RichText,\n element: {\n fontSize: number;\n fontFamily: string;\n color: string;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n textAlign?: TextAlign;\n /** Element-level letter-spacing default (px/char); spans may override. */\n letterSpacing?: number;\n /** Line-height multiplier; undefined = LINE_HEIGHT_MULTIPLIER (1.2). */\n lineHeight?: number;\n },\n maxWidth?: number,\n lockedLineCount?: number\n): void {\n // FIX: Set default fill color at start to prevent inheritance issues\n // This ensures text is rendered in the correct color even if first spans are empty\n ctx.fillStyle = element.color;\n\n const textAlign = element.textAlign || 'center';\n /** Per-span letter-spacing: span override → element default → 0. */\n const resolveSpacing = (style: CharacterStyle): number =>\n style.letterSpacing !== undefined ? style.letterSpacing : element.letterSpacing ?? 0;\n\n // Split into lines by explicit newlines first\n const explicitLines = splitRichTextIntoLines(richText);\n\n // Then apply word wrapping to each line if maxWidth is specified\n // Track paragraph boundaries (which lines are paragraph starts/ends)\n let lines: Array<{ text: string; style: CharacterStyle }[]>;\n let paragraphMetadata: Array<{ isParagraphStart: boolean; isParagraphEnd: boolean }>;\n\n if (maxWidth !== undefined && maxWidth > 0 && !lockedLineCount) {\n // Only wrap if no locked line count (during corner resize, bypass wrapping)\n lines = [];\n paragraphMetadata = [];\n explicitLines.forEach((lineSpans) => {\n const wrappedLines = wrapRichTextSpans(lineSpans, maxWidth, element);\n // Mark first wrapped line as paragraph start, last as paragraph end\n wrappedLines.forEach((wrappedLine, idx) => {\n lines.push(wrappedLine);\n paragraphMetadata.push({\n isParagraphStart: idx === 0,\n isParagraphEnd: idx === wrappedLines.length - 1,\n });\n });\n });\n } else {\n // No wrapping if locked line count is set or maxWidth not specified\n lines = explicitLines;\n // Each explicit line is both a paragraph start and end\n paragraphMetadata = explicitLines.map(() => ({\n isParagraphStart: true,\n isParagraphEnd: true,\n }));\n }\n\n // Calculate metrics for each line\n const lineMetrics: Array<{\n spans: { text: string; style: CharacterStyle }[];\n width: number;\n height: number;\n ascent: number;\n spanWidths: number[];\n isParagraphStart: boolean;\n isParagraphEnd: boolean;\n }> = [];\n\n let maxLineHeight = 0;\n\n lines.forEach((lineSpans, lineIndex) => {\n let lineWidth = 0;\n const spanWidths: number[] = [];\n let lineHeight = 0;\n let lineAscent = 0;\n\n // Get paragraph boundary metadata for space layout rules\n const isParagraphStart = paragraphMetadata[lineIndex].isParagraphStart;\n const isParagraphEnd = paragraphMetadata[lineIndex].isParagraphEnd;\n\n lineSpans.forEach((span) => {\n const fontSize = span.style.fontSize !== undefined ? span.style.fontSize : element.fontSize;\n const fontFamily = span.style.fontFamily !== undefined ? span.style.fontFamily : element.fontFamily;\n const bold = span.style.bold !== undefined ? span.style.bold : element.bold || false;\n const italic = span.style.italic !== undefined ? span.style.italic : element.italic || false;\n\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\n const width = spacedTextWidth(ctx.measureText(span.text).width, span.text, resolveSpacing(span.style));\n spanWidths.push(width);\n lineWidth += width;\n\n // Get metrics for this span\n const metrics = getFontMetrics(fontSize, fontFamily, bold, italic);\n lineHeight = Math.max(lineHeight, metrics.height);\n lineAscent = Math.max(lineAscent, metrics.ascent);\n });\n\n // Apply space layout rules to line width for alignment calculation\n // Calculate actual rendered width by summing visible characters in each span\n const fullLineText = lineSpans.map((span) => span.text).join('');\n const leadingSpacesMatch = fullLineText.match(/^ +/);\n const trailingSpacesMatch = fullLineText.match(/ +$/);\n const leadingSpacesCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;\n const trailingSpacesCount = trailingSpacesMatch ? trailingSpacesMatch[0].length : 0;\n\n // Calculate adjusted width by measuring only visible characters\n let adjustedLineWidth = 0;\n let charIndexInLine = 0;\n\n lineSpans.forEach((span) => {\n const fontSize = span.style.fontSize !== undefined ? span.style.fontSize : element.fontSize;\n const fontFamily = span.style.fontFamily !== undefined ? span.style.fontFamily : element.fontFamily;\n const bold = span.style.bold !== undefined ? span.style.bold : element.bold || false;\n const italic = span.style.italic !== undefined ? span.style.italic : element.italic || false;\n\n // Determine which part of this span is visible\n let visibleText = span.text;\n const spanStartIndex = charIndexInLine;\n const spanEndIndex = charIndexInLine + span.text.length;\n\n // Check if this span contains leading spaces that should be hidden\n // Leading spaces are hidden when NOT at paragraph start\n if (!isParagraphStart && leadingSpacesCount > 0 && spanStartIndex < leadingSpacesCount) {\n const hiddenCharsInSpan = Math.min(leadingSpacesCount - spanStartIndex, span.text.length);\n visibleText = visibleText.substring(hiddenCharsInSpan);\n }\n\n // Check if this span contains trailing spaces that should be hidden\n // Trailing spaces are hidden when NOT at paragraph end\n if (!isParagraphEnd && trailingSpacesCount > 0) {\n const trailingSpaceStartIndex = fullLineText.length - trailingSpacesCount;\n if (spanEndIndex > trailingSpaceStartIndex) {\n // Calculate how many characters from the START of the already-trimmed visibleText we should keep\n const leadingTrimAmount =\n !isParagraphStart && leadingSpacesCount > 0 && spanStartIndex < leadingSpacesCount\n ? Math.min(leadingSpacesCount - spanStartIndex, span.text.length)\n : 0;\n const visibleCharsInSpan = Math.max(0, trailingSpaceStartIndex - spanStartIndex - leadingTrimAmount);\n visibleText = visibleText.substring(0, visibleCharsInSpan);\n }\n }\n\n charIndexInLine += span.text.length;\n\n // Measure the visible text with this span's font (letter-spacing-aware)\n if (visibleText.length > 0) {\n ctx.save();\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\n adjustedLineWidth += spacedTextWidth(\n ctx.measureText(visibleText).width,\n visibleText,\n resolveSpacing(span.style)\n );\n ctx.restore();\n }\n });\n\n // CRITICAL FIX: Don't skip whitespace-only lines\n // We need to count them for cursor positions and selection bounds to align\n // Example: \" Foo\" wrapping to [\" \", \"Foo\"] has 2 lines, cursor can be on line 0 or 1\n // Even though line 0 renders as empty (trailing space hidden), it still occupies vertical space\n lineMetrics.push({\n spans: lineSpans,\n width: adjustedLineWidth, // Use adjusted width for alignment (may be 0 for empty lines)\n height: lineHeight,\n ascent: lineAscent,\n spanWidths,\n isParagraphStart, // Store metadata with line\n isParagraphEnd,\n });\n\n maxLineHeight = Math.max(maxLineHeight, lineHeight);\n });\n\n // CRITICAL FIX: Use consistent height calculation with TextMetrics to ensure Fill matches Stroke\n // TextMetrics uses element.fontSize * LINE_HEIGHT_MULTIPLIER for spacing\n // and element font metrics for the height component.\n // We must use the SAME model here to avoid ghosting/misalignment.\n const elementFontMetrics = getFontMetrics(element.fontSize, element.fontFamily, element.bold, element.italic);\n const lineSpacing = element.fontSize * (element.lineHeight ?? LINE_HEIGHT_MULTIPLIER);\n\n let totalHeight;\n if (lineMetrics.length === 0) {\n totalHeight = 0;\n } else if (lineMetrics.length === 1) {\n // For single line, use element metrics to match stroke\n totalHeight = elementFontMetrics.height;\n } else {\n // For multi-line, match TextMetrics formula\n totalHeight = (lineMetrics.length - 1) * lineSpacing + elementFontMetrics.height;\n }\n\n // Start from top of text block (vertically centered)\n const topLeftY = -totalHeight / 2;\n\n // Render each line\n lineMetrics.forEach((lineData, lineIndex) => {\n const { spans, width: lineWidth, isParagraphStart, isParagraphEnd } = lineData;\n\n // Calculate starting X position based on alignment.\n //\n // The element box is centered at (0, 0), so it spans [-w/2, +w/2]\n // where `w` is the available inner width (`maxWidth`). Aligning\n // text to the *bounding box edges* — not to x=0 — is what the\n // stroke renderer does (StrokeRenderer.ts ~line 342) and what\n // users expect: \"left aligned\" means flush with the left edge of\n // the box, \"right aligned\" means flush with the right edge.\n //\n // Earlier this anchored every alignment at x=0 (center), so for\n // left/right alignment the fill text stayed near center while the\n // stroke moved to the box edges — they diverged visibly. With\n // `maxWidth` undefined (legacy paths without an explicit box) we\n // fall back to the old anchor-at-zero behaviour, since there's no\n // box edge to align to.\n let currentX: number;\n if (textAlign === 'center') {\n currentX = -lineWidth / 2;\n } else if (textAlign === 'right') {\n currentX = maxWidth !== undefined ? maxWidth / 2 - lineWidth : -lineWidth;\n } else {\n // left\n currentX = maxWidth !== undefined ? -maxWidth / 2 : 0;\n }\n\n // Baseline Y position for this line\n // Match TextMetrics positioning: topLeftY + ascent + index * spacing\n const baselineY = topLeftY + elementFontMetrics.ascent + lineIndex * lineSpacing;\n\n // Note: We use elementFontMetrics.ascent for the line position,\n // but individual spans might have different ascents.\n // We align them to this common baseline.\n\n // Apply space layout rules: determine which spaces to hide\n const fullLineText = spans.map((s) => s.text).join('');\n const leadingSpacesMatch = fullLineText.match(/^ +/);\n const trailingSpacesMatch = fullLineText.match(/ +$/);\n const leadingSpacesCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;\n const trailingSpacesCount = trailingSpacesMatch ? trailingSpacesMatch[0].length : 0;\n\n // Track character position in full line to identify spaces\n let charIndexInLine = 0;\n\n // Render each span in this line\n spans.forEach((span) => {\n const fontSize = span.style.fontSize !== undefined ? span.style.fontSize : element.fontSize;\n const fontFamily = span.style.fontFamily !== undefined ? span.style.fontFamily : element.fontFamily;\n // Use explicit undefined check for color (consistent with bold/italic pattern)\n // Falsy check would incorrectly fall back if color is empty string\n const color = span.style.color !== undefined ? span.style.color : element.color;\n const bold = span.style.bold !== undefined ? span.style.bold : element.bold || false;\n const italic = span.style.italic !== undefined ? span.style.italic : element.italic || false;\n const underline = span.style.underline !== undefined ? span.style.underline : element.underline || false;\n const strikethrough = span.style.strikethrough !== undefined ? span.style.strikethrough : element.strikethrough || false;\n\n // Apply space layout rules to this span's text\n let renderText = span.text;\n let spanStartIndex = charIndexInLine;\n let spanEndIndex = charIndexInLine + span.text.length;\n\n // Check if this span contains leading spaces that should be hidden\n // Leading spaces are hidden when NOT at paragraph start\n if (!isParagraphStart && leadingSpacesCount > 0 && spanStartIndex < leadingSpacesCount) {\n // This span overlaps with hidden leading spaces\n const hiddenCharsInSpan = Math.min(leadingSpacesCount - spanStartIndex, span.text.length);\n renderText = renderText.substring(hiddenCharsInSpan);\n }\n\n // Check if this span contains trailing spaces that should be hidden\n // Trailing spaces are hidden when NOT at paragraph end\n if (!isParagraphEnd && trailingSpacesCount > 0) {\n const trailingSpaceStartIndex = fullLineText.length - trailingSpacesCount;\n if (spanEndIndex > trailingSpaceStartIndex) {\n // Calculate how many characters from the START of the already-trimmed renderText we should keep\n const leadingTrimAmount =\n !isParagraphStart && leadingSpacesCount > 0 && spanStartIndex < leadingSpacesCount\n ? Math.min(leadingSpacesCount - spanStartIndex, span.text.length)\n : 0;\n const visibleCharsInSpan = Math.max(0, trailingSpaceStartIndex - spanStartIndex - leadingTrimAmount);\n renderText = renderText.substring(0, visibleCharsInSpan);\n }\n }\n\n charIndexInLine += span.text.length;\n\n // Only render if there's visible text\n if (renderText.length > 0) {\n const letterSpacing = resolveSpacing(span.style);\n\n // Set font and color for this span\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\n ctx.fillStyle = color;\n ctx.textBaseline = 'alphabetic';\n ctx.textAlign = 'left'; // We handle alignment manually\n\n // Render this span at the common baseline\n // With textBaseline='alphabetic', canvas automatically aligns text to the baseline\n // All spans should use the SAME Y coordinate for proper baseline alignment\n // (per-character when letter-spaced; single fillText when spacing is 0)\n fillTextWithSpacing(ctx, renderText, currentX, baselineY, letterSpacing);\n\n // Measure the rendered text width for positioning (letter-spacing-aware\n // — the SAME advance the paint used, so the next span lands flush)\n const renderedWidth = spacedTextWidth(ctx.measureText(renderText).width, renderText, letterSpacing);\n\n // Draw underline if enabled\n if (underline) {\n const underlineY = baselineY + fontSize * 0.1;\n ctx.beginPath();\n ctx.moveTo(currentX, underlineY);\n ctx.lineTo(currentX + renderedWidth, underlineY);\n ctx.lineWidth = Math.max(1, fontSize * 0.05);\n ctx.strokeStyle = color;\n ctx.stroke();\n }\n\n // Draw strikethrough if enabled\n if (strikethrough) {\n const strikethroughY = baselineY - fontSize * 0.25;\n ctx.beginPath();\n ctx.moveTo(currentX, strikethroughY);\n ctx.lineTo(currentX + renderedWidth, strikethroughY);\n ctx.lineWidth = Math.max(1, fontSize * 0.05);\n ctx.strokeStyle = color;\n ctx.stroke();\n }\n\n // Move X position for next span (using rendered width, not original span width)\n currentX += renderedWidth;\n }\n });\n\n // Move Y position for next line\n // currentY += lineHeight; // No longer needed with absolute positioning\n /*\n if (lineIndex < lineMetrics.length - 1) {\n currentY += maxLineHeight * (lineSpacing - 1);\n }\n */\n });\n}\n\n// ============================================================================\n// Private helpers\n// ============================================================================\n\n","/**\n * Text Renderer - Text measurement utilities and plain text rendering functions.\n *\n * Worker-compatible: uses OffscreenCanvas instead of DOM APIs.\n * These functions are NOT duplicates of src/core/TextMetrics.ts — see the note\n * in canvas-renderer.ts for the distinction.\n */\n\nimport { LINE_HEIGHT_MULTIPLIER, HORIZONTAL_PADDING } from '../constants.js';\nimport type {\n AnyElementConfig,\n CustomElementConfig,\n TextAlign,\n OpenTypeFeatures,\n} from '../types/index.js';\nimport { RichText } from '../types/index.js';\nimport {\n renderCircleTransform,\n renderWaveTransform,\n renderArchTransform,\n renderAscendTransform,\n renderLeanTransform,\n renderFlagTransform,\n} from './transform-renderer.js';\nimport { renderTextStroke } from './StrokeRenderer.js';\nimport { calculateVisualBoundsWithSpaceCollapsing } from '../core/TextMetrics.js';\nimport { fillTextWithSpacing, spacedTextWidth } from '../core/text-spacing.js';\nimport { FontAnalyzer } from '../utils/FontAnalyzer.js';\nimport {\n renderTextWithGlyphOverridesSync,\n renderTextWithOpenTypeFeaturesSync,\n} from '../utils/GlyphRenderer.js';\nimport { createLogger } from '../utils/logger.js';\nimport type { RenderContext, SerializedTextElement } from './renderer-types.js';\nimport { renderRichTextFillOnly } from './rich-text-renderer.js';\n\nconst logger = createLogger('canvas-renderer');\n\n// ============================================================================\n// Text Measurement Utilities (Worker-Compatible)\n// ============================================================================\n//\n// IMPORTANT: These functions are NOT duplicates of src/core/TextMetrics.ts!\n//\n// This file is used in Web Workers (see src/workers/export-worker.ts) which\n// don't have access to the DOM (no `document.createElement`).\n//\n// - **TextMetrics.ts** - Main thread only (uses HTMLCanvasElement via document.createElement)\n// - **text-renderer.ts** - Worker-compatible (uses OffscreenCanvas)\n//\n// Files that run ONLY in main thread (CanvasRenderer.ts, StrokeRenderer.ts, etc.)\n// should import from TextMetrics.ts to avoid confusion.\n//\n// Files that run in WORKERS (this file, transform-renderer.ts) must use these\n// OffscreenCanvas-compatible versions.\n// ============================================================================\n\n// Use a global measurement context that works in both environments\nlet _measureCtx: RenderContext | null = null;\n\n/**\n * Get or create a measurement context\n * Works in both main thread (HTMLCanvasElement) and worker (OffscreenCanvas)\n */\nfunction getMeasureContext(): RenderContext {\n if (!_measureCtx) {\n if (typeof OffscreenCanvas !== 'undefined') {\n // In worker or modern browser\n const canvas = new OffscreenCanvas(1, 1);\n _measureCtx = canvas.getContext('2d') as OffscreenCanvasRenderingContext2D;\n } else if (typeof document !== 'undefined') {\n // In main thread, old browser\n const canvas = document.createElement('canvas');\n _measureCtx = canvas.getContext('2d')!;\n } else {\n throw new Error('No canvas context available');\n }\n }\n return _measureCtx;\n}\n\n/**\n * Build font string with optional bold and italic\n */\nexport function buildFontString(\n fontSize: number,\n fontFamily: string,\n bold: boolean = false,\n italic: boolean = false\n): string {\n const parts: string[] = [];\n\n if (italic) {\n parts.push('italic');\n }\n\n if (bold) {\n parts.push('bold');\n }\n\n parts.push(`${fontSize}px`);\n parts.push(fontFamily);\n\n return parts.join(' ');\n}\n\n/**\n * Measure text width\n * @param letterSpacing - Extra advance per character in px (default 0 — legacy width)\n */\nexport function measureTextWidth(\n text: string,\n fontSize: number,\n fontFamily: string,\n bold: boolean = false,\n italic: boolean = false,\n letterSpacing: number = 0\n): number {\n const ctx = getMeasureContext();\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\n return spacedTextWidth(ctx.measureText(text).width, text, letterSpacing);\n}\n\n/**\n * Get font metrics for accurate text positioning\n */\nexport function getFontMetrics(\n fontSize: number,\n fontFamily: string,\n bold: boolean = false,\n italic: boolean = false\n): { ascent: number; descent: number; height: number } {\n const ctx = getMeasureContext();\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\n\n const sampleText = 'ÁÉÍgjpqy';\n const metrics = ctx.measureText(sampleText);\n\n const ascent = metrics.actualBoundingBoxAscent || fontSize * 0.8;\n const descent = metrics.actualBoundingBoxDescent || fontSize * 0.2;\n const height = ascent + descent;\n\n return { ascent, descent, height };\n}\n\n/**\n * Apply space layout rules to text lines for rendering\n * Hides leading/trailing spaces based on paragraph boundaries to match HTML/CSS text rendering\n *\n * Rules (matching browser text rendering behavior):\n * - Leading spaces are hidden when NOT at paragraph start\n * - Trailing spaces are hidden when NOT at paragraph end\n * - Paragraph = text separated by explicit \\n characters\n *\n * Example:\n * Input: [\"Foo \", \"Bar\"] (from wrapping \"Foo Bar\", no explicit \\n)\n * Output: [\"Foo\", \"Bar\"] (trailing space on line 1 hidden)\n *\n * @param lines - Array of text lines (from wrapText or split by \\n)\n * @param hasExplicitNewlines - Whether original text contained \\n characters\n * @returns Lines with space collapsing applied for rendering\n */\nexport function applySpaceLayoutRules(lines: string[], hasExplicitNewlines: boolean): string[] {\n // If no explicit newlines, all lines are from one paragraph\n // First line = paragraph start, last line = paragraph end\n const paragraphMetadata = lines.map((_, index) => ({\n isParagraphStart: !hasExplicitNewlines && index === 0,\n isParagraphEnd: !hasExplicitNewlines && index === lines.length - 1,\n }));\n\n const collapsedLines = lines.map((line, index) => {\n // Edge case: If line is ALL whitespace, collapse to empty regardless of paragraph position\n // This handles cases like \" Foo Bar\" wrapping to [\" \", \"Foo\", \"Bar\"] where line 1 should be hidden\n if (line.trim().length === 0) {\n return '';\n }\n\n const isParagraphStart = paragraphMetadata[index].isParagraphStart;\n const isParagraphEnd = paragraphMetadata[index].isParagraphEnd;\n\n let visibleText = line;\n\n // Hide leading spaces when NOT at paragraph start\n if (!isParagraphStart) {\n visibleText = visibleText.replace(/^ +/, '');\n }\n\n // Hide trailing spaces when NOT at paragraph end\n if (!isParagraphEnd) {\n visibleText = visibleText.replace(/ +$/, '');\n }\n\n return visibleText;\n });\n\n // CRITICAL: Filter out empty lines to prevent gaps in layout\n // Without this, height calculations and Y positioning include the empty line\n return collapsedLines.filter((line) => line.length > 0);\n}\n\n/**\n * Render text fill only (without transforms or effects)\n * Shared utility used by main rendering and knockout compositing\n *\n * IMPORTANT: This renders ONLY the fill, positioned and transformed correctly\n * It does NOT render strokes, masks, or other effects\n */\nexport function renderTextFillOnly(\n ctx: RenderContext,\n element: {\n text: string;\n fontSize: number;\n fontFamily: string;\n bold?: boolean;\n italic?: boolean;\n textAlign?: TextAlign;\n color: string;\n /** Extra advance per character in px (custom transform only). */\n letterSpacing?: number;\n }\n): void {\n const fontSize = element.fontSize;\n const fontFamily = element.fontFamily;\n const bold = element.bold || false;\n const italic = element.italic || false;\n const textAlign = element.textAlign || 'center';\n const text = element.text;\n\n // Set up font\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\n ctx.textAlign = textAlign as CanvasTextAlign;\n ctx.textBaseline = 'alphabetic';\n ctx.fillStyle = element.color;\n\n // Calculate Y position using font metrics for perfect alignment\n const fontMetrics = getFontMetrics(fontSize, fontFamily, bold, italic);\n const visualHeight = fontMetrics.height;\n const topLeftY = -visualHeight / 2;\n const yPos = topLeftY + fontMetrics.ascent;\n\n // Render fill only (letter-spacing-aware; single fillText when spacing is 0)\n fillTextWithSpacing(ctx, text, 0, yPos, element.letterSpacing);\n}\n\n/**\n * Word wrap text to fit within a given width\n */\nexport function wrapText(\n text: string,\n maxWidth: number,\n fontSize: number,\n fontFamily: string,\n bold: boolean = false,\n italic: boolean = false,\n lockedLineCount?: number\n): string[] {\n const ctx = getMeasureContext();\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\n\n // If text is all whitespace, return as-is (no wrapping needed)\n if (text.trim().length === 0) {\n return [text];\n }\n\n // Handle explicit newlines: split by \\n first, wrap each line separately, then rejoin\n // This preserves multi-line structure like \" Foo\\nBar\"\n if (text.includes('\\n')) {\n const explicitLines = text.split('\\n');\n const allWrappedLines: string[] = [];\n\n for (let i = 0; i < explicitLines.length; i++) {\n const line = explicitLines[i];\n // Recursively wrap each line (without locked line count, as that applies to the whole text)\n const wrappedLine = wrapText(line, maxWidth, fontSize, fontFamily, bold, italic);\n allWrappedLines.push(...wrappedLine);\n }\n\n return allWrappedLines;\n }\n\n // Preserve leading and trailing spaces to prevent character loss\n // Example: \" Hello World \" -> leadingSpaces=\" \", trimmedText=\"Hello World\", trailingSpaces=\" \"\n const leadingSpacesMatch = text.match(/^\\s*/);\n const trailingSpacesMatch = text.match(/\\s*$/);\n const leadingSpaces = leadingSpacesMatch ? leadingSpacesMatch[0] : '';\n const trailingSpaces = trailingSpacesMatch ? trailingSpacesMatch[0] : '';\n const trimmedText = text.substring(leadingSpaces.length, text.length - trailingSpaces.length);\n\n const words = trimmedText.split(' ');\n\n // If line count is locked (during corner resize), force that exact number of lines\n if (lockedLineCount !== undefined && lockedLineCount > 0) {\n if (lockedLineCount === 1) {\n return [leadingSpaces + words.join(' ') + trailingSpaces];\n }\n\n // Distribute words as evenly as possible across locked line count\n const lines: string[] = [];\n const wordsPerLine = Math.ceil(words.length / lockedLineCount);\n\n for (let i = 0; i < words.length; i += wordsPerLine) {\n const lineWords = words.slice(i, i + wordsPerLine);\n const lineText = lineWords.join(' ');\n\n // Add leading spaces to first line, trailing spaces to last line\n if (i === 0 && i + wordsPerLine >= words.length) {\n // Single line result\n lines.push(leadingSpaces + lineText + trailingSpaces);\n } else if (i === 0) {\n // First line\n lines.push(leadingSpaces + lineText);\n } else if (i + wordsPerLine >= words.length) {\n // Last line\n lines.push(lineText + trailingSpaces);\n } else {\n // Middle lines\n lines.push(lineText);\n }\n }\n\n return lines;\n }\n\n // Normal wrapping logic (no lock)\n // First pass: check if all text fits on one line with generous tolerance\n const allText = words.join(' ');\n const allTextWithSpaces = leadingSpaces + allText + trailingSpaces;\n const allTextWidth = ctx.measureText(allTextWithSpaces).width;\n\n const isSmallSize = maxWidth < 200;\n const wrapTolerancePercent = isSmallSize ? 0.08 : 0.05;\n const wrapTolerance = Math.max(20, maxWidth * wrapTolerancePercent);\n\n if (allTextWidth <= maxWidth + wrapTolerance) {\n return [allTextWithSpaces];\n }\n\n // Otherwise, perform word wrapping\n const lines: string[] = [];\n let currentLine = words[0];\n const lineTolerancePercent = isSmallSize ? 0.05 : 0.03;\n const lineTolerance = Math.max(15, maxWidth * lineTolerancePercent);\n\n for (let i = 1; i < words.length; i++) {\n const word = words[i];\n const testLine = currentLine + ' ' + word;\n const metrics = ctx.measureText(testLine);\n\n if (metrics.width > maxWidth + lineTolerance) {\n lines.push(currentLine);\n currentLine = word;\n } else {\n currentLine = testLine;\n }\n }\n lines.push(currentLine);\n\n // Add leading spaces to first line and trailing spaces to last line\n if (lines.length > 0) {\n lines[0] = leadingSpaces + lines[0];\n lines[lines.length - 1] = lines[lines.length - 1] + trailingSpaces;\n }\n\n return lines;\n}\n\n/**\n * Render multi-line text with alignment and text decorations\n * Works with both CanvasRenderingContext2D and OffscreenCanvasRenderingContext2D\n */\nexport function renderMultilineText(\n ctx: RenderContext,\n lines: string[],\n x: number,\n y: number,\n fontSize: number,\n fontFamily: string,\n alignment: CanvasTextAlign = 'left',\n containerWidth: number = 0,\n horizontalPadding: number = 0,\n lineHeight: number = 1.2,\n bold: boolean = false,\n italic: boolean = false,\n underline: boolean = false,\n strikethrough: boolean = false,\n openTypeFeatures?: OpenTypeFeatures,\n glyphOverrides?: import('../types/index.js').GlyphOverride[]\n): void {\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\n ctx.textBaseline = 'alphabetic';\n ctx.textAlign = alignment;\n\n // Helper function to detect PUA characters (U+F0000 to U+FFFFD)\n const containsPUACharacters = (text: string): boolean => {\n for (const char of text) {\n const codePoint = char.codePointAt(0);\n if (codePoint && codePoint >= 0xf0000 && codePoint <= 0xffffd) {\n return true;\n }\n }\n return false;\n };\n\n // Check if we should use fontkit rendering for OpenType features, glyph overrides, OR PUA characters\n const hasOpenTypeFeatures = openTypeFeatures && Object.values(openTypeFeatures).some((enabled) => enabled);\n const hasGlyphOverrides = glyphOverrides && glyphOverrides.length > 0;\n const allText = lines.join(' ');\n const hasPUACharacters = containsPUACharacters(allText);\n const needsFontkitRendering = hasOpenTypeFeatures || hasGlyphOverrides || hasPUACharacters;\n\n const fontkitFont = needsFontkitRendering ? FontAnalyzer.getFontSync(fontFamily, bold ? 700 : 400) : null;\n\n // If we need fontkit rendering but font isn't loaded, try to load it\n // (This shouldn't happen if fonts are pre-loaded properly, but provides a fallback)\n if (needsFontkitRendering && !fontkitFont) {\n logger.warn(\n `[renderMultilineText] Font ${fontFamily} not loaded for fontkit rendering. Text may not render correctly. Has PUA: ${hasPUACharacters}, Text: \"${allText}\"`\n );\n // Try to load it asynchronously for next render\n FontAnalyzer.loadFont(fontFamily, bold ? 700 : 400).catch((err) => {\n logger.error('[renderMultilineText] Error loading font:', err);\n });\n }\n\n const fontMetrics = getFontMetrics(fontSize, fontFamily, bold, italic);\n const lineSpacing = fontSize * lineHeight;\n\n // Calculate character offset for each line (for glyph overrides)\n let charOffset = 0;\n\n lines.forEach((line: string, lineIndex: number) => {\n let xPos = x + horizontalPadding;\n\n if (alignment === 'center') {\n xPos = x + containerWidth / 2;\n } else if (alignment === 'right') {\n xPos = x + containerWidth - horizontalPadding;\n }\n\n const yPos = y + fontMetrics.ascent + lineIndex * lineSpacing;\n\n // Filter glyph overrides for this line\n const lineLength = Array.from(line).length; // Handle multi-byte characters\n const lineGlyphOverrides = hasGlyphOverrides\n ? glyphOverrides!\n .filter((override) => {\n const relativeIndex = override.charIndex - charOffset;\n return relativeIndex >= 0 && relativeIndex < lineLength;\n })\n .map((override) => ({\n ...override,\n charIndex: override.charIndex - charOffset, // Adjust to line-relative index\n }))\n : [];\n\n // Use fontkit rendering if needed and font is loaded\n if (fontkitFont && (hasOpenTypeFeatures || lineGlyphOverrides.length > 0 || hasPUACharacters)) {\n // If we have glyph overrides OR PUA characters for this line, use glyph override rendering\n // (The renderTextWithGlyphOverridesSync function handles both)\n if (lineGlyphOverrides.length > 0 || containsPUACharacters(line)) {\n renderTextWithGlyphOverridesSync(ctx, fontkitFont, line, xPos, yPos, fontSize, lineGlyphOverrides, {\n color: ctx.fillStyle as string,\n align: (alignment === 'start' || alignment === 'end' ? 'left' : alignment) as 'left' | 'right' | 'center',\n });\n }\n // Otherwise use OpenType features rendering\n else if (openTypeFeatures) {\n renderTextWithOpenTypeFeaturesSync(ctx, fontkitFont, line, xPos, yPos, fontSize, openTypeFeatures, {\n color: ctx.fillStyle as string,\n align: (alignment === 'start' || alignment === 'end' ? 'left' : alignment) as 'left' | 'right' | 'center',\n });\n }\n } else {\n ctx.fillText(line, xPos, yPos);\n }\n\n // Update character offset for next line (include line break)\n charOffset += lineLength + 1; // +1 for the line break/space\n\n // Draw underline if enabled\n if (underline) {\n const lineWidth = measureTextWidth(line, fontSize, fontFamily, bold, italic);\n let underlineX = xPos;\n\n if (alignment === 'center') {\n underlineX = xPos - lineWidth / 2;\n } else if (alignment === 'right') {\n underlineX = xPos - lineWidth;\n }\n\n const underlineY = yPos + fontSize * 0.1;\n ctx.beginPath();\n ctx.moveTo(underlineX, underlineY);\n ctx.lineTo(underlineX + lineWidth, underlineY);\n ctx.lineWidth = Math.max(1, fontSize * 0.05);\n ctx.strokeStyle = ctx.fillStyle as string;\n ctx.stroke();\n }\n\n // Draw strikethrough if enabled\n if (strikethrough) {\n const lineWidth = measureTextWidth(line, fontSize, fontFamily, bold, italic);\n let strikethroughX = xPos;\n\n if (alignment === 'center') {\n strikethroughX = xPos - lineWidth / 2;\n } else if (alignment === 'right') {\n strikethroughX = xPos - lineWidth;\n }\n\n const strikethroughY = yPos - fontSize * 0.25;\n ctx.beginPath();\n ctx.moveTo(strikethroughX, strikethroughY);\n ctx.lineTo(strikethroughX + lineWidth, strikethroughY);\n ctx.lineWidth = Math.max(1, fontSize * 0.05);\n ctx.strokeStyle = ctx.fillStyle as string;\n ctx.stroke();\n }\n });\n}\n\n// ============================================================================\n// Element Rendering Functions\n// ============================================================================\n\n/**\n * Render a CustomTransform (straight text) element\n * Pure function that works in both main thread and worker\n */\nexport function renderCustomTransform(ctx: RenderContext, elementData: SerializedTextElement): void {\n // Knockout compositing is handled in CompositingRenderer.ts\n renderCustomTransformNormal(ctx, elementData);\n}\n\nfunction renderCustomTransformNormal(ctx: RenderContext, elementData: SerializedTextElement): void {\n // Render stroke BEFORE fill for outer-stroke effect.\n // Canvas strokeText draws centered on the glyph outline; drawing fill on top\n // covers the inner half, leaving only the outer half visible as an outline.\n if (elementData.stroke?.enabled) {\n renderTextStroke(ctx, elementData as unknown as AnyElementConfig);\n }\n\n ctx.save();\n\n // Translate to center (x, y), rotate\n ctx.translate(elementData.x, elementData.y);\n // Use negative angle for clockwise rotation (matching UI convention)\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n\n const transformData = elementData.transformData as CustomElementConfig['transformData'];\n const availableWidth = (transformData?.width ?? 100) - HORIZONTAL_PADDING * 2;\n\n // Check if we have rich text\n if (elementData.richText) {\n // Rich text rendering with word wrapping support\n const richText = RichText.fromJSON(elementData.richText);\n\n ctx.save();\n // Position at center\n ctx.translate(0, 0);\n\n // Check for locked line count in element data (set during corner resize)\n const lockedLineCount = elementData._lockedLineCount;\n\n // Render with word wrapping based on available width\n renderRichTextFillOnly(\n ctx,\n richText,\n {\n fontSize: elementData.fontSize,\n fontFamily: elementData.fontFamily,\n color: elementData.color,\n bold: elementData.bold,\n italic: elementData.italic,\n underline: elementData.underline,\n strikethrough: elementData.strikethrough,\n textAlign: elementData.textAlign,\n letterSpacing: elementData.letterSpacing,\n lineHeight: elementData.lineHeight,\n },\n availableWidth,\n lockedLineCount\n );\n\n ctx.restore();\n } else {\n // Plain text rendering - fall back to old behavior\n if (elementData.text) {\n ctx.fillStyle = elementData.color;\n\n const lockedLineCount = elementData._lockedLineCount;\n const letterSpacing = elementData.letterSpacing ?? 0;\n\n // CRITICAL: Use calculateVisualBoundsWithSpaceCollapsing with strict: true to match\n // the selection box (getBoundingBox) and stroke rendering (renderTextStroke).\n // This ensures the fill text aligns perfectly with the stroke/highlight.\n const { lines, height: visualHeight } = calculateVisualBoundsWithSpaceCollapsing(\n elementData.text,\n availableWidth,\n elementData.fontSize,\n elementData.fontFamily,\n elementData.bold,\n elementData.italic,\n lockedLineCount,\n true, // strict: true\n { letterSpacing, lineHeight: elementData.lineHeight }\n );\n\n const fontMetrics = getFontMetrics(\n elementData.fontSize,\n elementData.fontFamily,\n elementData.bold,\n elementData.italic\n );\n\n const topLeftX = -(transformData?.width ?? 100) / 2;\n const topLeftY = -visualHeight / 2;\n const lineSpacing = elementData.fontSize * (elementData.lineHeight ?? LINE_HEIGHT_MULTIPLIER);\n\n // Render lines with space collapsing logic matching renderTextStroke\n ctx.font = `${elementData.italic ? 'italic ' : ''}${elementData.bold ? 'bold ' : ''}${elementData.fontSize}px ${elementData.fontFamily}`;\n ctx.textBaseline = 'alphabetic';\n ctx.textAlign = elementData.textAlign as CanvasTextAlign;\n\n lines.forEach((line, index) => {\n // Match space collapsing logic from renderTextStroke\n const isParagraphStart = index === 0;\n const isParagraphEnd = index === lines.length - 1;\n\n let visibleText = line;\n\n // Hide leading spaces when NOT at paragraph start\n if (!isParagraphStart) {\n const leadingSpacesMatch = line.match(/^ +/);\n const leadingSpacesCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;\n if (leadingSpacesCount > 0) {\n visibleText = visibleText.substring(leadingSpacesCount);\n }\n }\n\n // Hide trailing spaces when NOT at paragraph end\n if (!isParagraphEnd) {\n const trailingSpacesMatch = visibleText.match(/ +$/);\n const trailingSpacesCount = trailingSpacesMatch ? trailingSpacesMatch[0].length : 0;\n if (trailingSpacesCount > 0) {\n visibleText = visibleText.substring(0, visibleText.length - trailingSpacesCount);\n }\n }\n\n let xPos = topLeftX + HORIZONTAL_PADDING;\n if (elementData.textAlign === 'center') {\n xPos = topLeftX + (transformData?.width ?? 100) / 2;\n } else if (elementData.textAlign === 'right') {\n xPos = topLeftX + (transformData?.width ?? 100) - HORIZONTAL_PADDING;\n }\n\n const yPos = topLeftY + fontMetrics.ascent + index * lineSpacing;\n fillTextWithSpacing(ctx, visibleText, xPos, yPos, letterSpacing);\n\n // Draw underline/strikethrough if needed (simplified, only if visible text)\n if (visibleText.length > 0) {\n const lineWidth = spacedTextWidth(ctx.measureText(visibleText).width, visibleText, letterSpacing);\n let decorationX = xPos;\n if (elementData.textAlign === 'center') decorationX -= lineWidth / 2;\n else if (elementData.textAlign === 'right') decorationX -= lineWidth;\n\n if (elementData.underline) {\n const underlineY = yPos + elementData.fontSize * 0.1;\n ctx.fillRect(decorationX, underlineY, lineWidth, Math.max(1, elementData.fontSize * 0.05));\n }\n if (elementData.strikethrough) {\n const strikeY = yPos - fontMetrics.ascent * 0.4;\n ctx.fillRect(decorationX, strikeY, lineWidth, Math.max(1, elementData.fontSize * 0.05));\n }\n }\n });\n }\n }\n\n ctx.restore();\n}\n\n/**\n * Render a text element based on its type\n * This is the main entry point for rendering text elements in the worker\n */\nexport function renderTextElement(ctx: RenderContext, elementData: SerializedTextElement): void {\n const elementOpacity = elementData.opacity ?? 1;\n const hasStroke = !!elementData.stroke?.enabled;\n\n // When element has opacity < 1 AND a stroke, render to an offscreen canvas\n // at full opacity, then composite at the element's opacity. This prevents\n // the inner half of the stroke from showing through the semi-transparent fill\n // (canvas strokeText draws centered on the glyph outline).\n //\n // ONLY for 'custom' transforms: non-custom transforms (arch, circle, wave,\n // etc.) render stroke per-character inside the transform renderer, and their\n // main-thread render() method just sets globalAlpha directly without offscreen\n // compositing. Using offscreen here for those types produces a different\n // result (uniform composite vs per-draw globalAlpha), causing export diffs.\n const isCustomTransform = elementData.type === 'custom';\n if (elementOpacity < 1 && hasStroke && isCustomTransform) {\n renderTextElementWithOffscreen(ctx, elementData, elementOpacity);\n return;\n }\n\n // Apply opacity if specified\n const previousAlpha = ctx.globalAlpha;\n if (elementOpacity !== 1) {\n ctx.globalAlpha = elementOpacity;\n }\n\n renderTextElementInner(ctx, elementData);\n\n // Restore previous alpha\n ctx.globalAlpha = previousAlpha;\n}\n\n/**\n * Render text via offscreen canvas to avoid stroke/fill opacity compounding.\n */\nfunction renderTextElementWithOffscreen(\n ctx: RenderContext,\n elementData: SerializedTextElement,\n elementOpacity: number\n): void {\n // Estimate bounds for the offscreen canvas\n const td = elementData.transformData as { width?: number } | undefined;\n const fontSize = elementData.fontSize || 24;\n const strokeWidth = elementData.stroke?.width || 0;\n const estWidth = (td?.width ?? fontSize * elementData.text.length * 0.7) + strokeWidth * 2 + 40;\n const estHeight = fontSize * 3 + strokeWidth * 2 + 40; // generous for multi-line\n\n const transform = ctx.getTransform();\n const scale = Math.max(Math.abs(transform.a), Math.abs(transform.d), 1);\n\n const offW = Math.ceil(estWidth * scale);\n const offH = Math.ceil(estHeight * scale);\n\n let offCanvas: HTMLCanvasElement | OffscreenCanvas;\n if (typeof OffscreenCanvas !== 'undefined') {\n offCanvas = new OffscreenCanvas(offW, offH);\n } else {\n offCanvas = document.createElement('canvas');\n offCanvas.width = offW;\n offCanvas.height = offH;\n }\n\n const offCtx = offCanvas.getContext('2d') as RenderContext;\n if (!offCtx) {\n // Fallback: render directly with compounding\n const prev = ctx.globalAlpha;\n ctx.globalAlpha = elementOpacity;\n renderTextElementInner(ctx, elementData);\n ctx.globalAlpha = prev;\n return;\n }\n\n // Replicate the main canvas transform, shifted so the element center maps\n // to the center of the offscreen canvas\n const centerPixelX = transform.a * elementData.x + transform.e;\n const centerPixelY = transform.d * elementData.y + transform.f;\n\n offCtx.setTransform(\n transform.a, transform.b,\n transform.c, transform.d,\n transform.e - centerPixelX + offW / 2,\n transform.f - centerPixelY + offH / 2,\n );\n\n // Render at full opacity on offscreen\n renderTextElementInner(offCtx, elementData);\n\n // Composite onto main canvas at element opacity\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.globalAlpha = elementOpacity;\n ctx.drawImage(offCanvas, centerPixelX - offW / 2, centerPixelY - offH / 2);\n ctx.restore();\n}\n\n/**\n * Inner render dispatch — renders at whatever globalAlpha is currently set.\n */\nfunction renderTextElementInner(ctx: RenderContext, elementData: SerializedTextElement): void {\n // Non-custom transforms handle stroke internally (per-character along the path).\n // Custom transform handles stroke in renderCustomTransformNormal.\n switch (elementData.type) {\n case 'custom':\n renderCustomTransform(ctx, elementData);\n break;\n case 'circle':\n renderCircleTransform(ctx, elementData);\n break;\n case 'wave':\n renderWaveTransform(ctx, elementData);\n break;\n case 'arch':\n renderArchTransform(ctx, elementData);\n break;\n case 'ascend':\n renderAscendTransform(ctx, elementData);\n break;\n case 'lean':\n renderLeanTransform(ctx, elementData);\n break;\n case 'flag':\n renderFlagTransform(ctx, elementData);\n break;\n default:\n logger.warn(`[canvas-renderer] Unsupported transform type: ${elementData.type}`);\n // Fallback: render as CustomTransform\n renderCustomTransform(ctx, elementData);\n }\n}\n","/**\n * Transform Renderer - Pure rendering functions for all text transform types\n * Works with both CanvasRenderingContext2D and OffscreenCanvasRenderingContext2D\n */\n\nimport { buildFontString } from './canvas-renderer.js';\nimport { WAVE_SKEW_FACTOR } from '../constants.js';\nimport type {\n AnyTransformData,\n CircleTransformData,\n WaveTransformData,\n ArchTransformData,\n AscendTransformData,\n LeanTransformData,\n FlagTransformData,\n} from '../types/index.js';\n\ntype RenderContext = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\nexport interface SerializedTextTransformElement {\n id: string;\n type: string;\n text: string;\n x: number;\n y: number;\n rotation: number;\n fontSize: number;\n fontFamily: string;\n color: string;\n bold: boolean;\n italic: boolean;\n transformData: AnyTransformData;\n stroke?: {\n enabled: boolean;\n color: string;\n width: number;\n opacity?: number;\n lineCap?: CanvasLineCap;\n lineJoin?: CanvasLineJoin;\n miterLimit?: number;\n feather?: number;\n };\n}\n\n/**\n * Create an offscreen canvas compatible with both main thread and Web Worker.\n * Uses OffscreenCanvas when available, falls back to document.createElement.\n */\nfunction createOffscreenCanvas(\n width: number,\n height: number\n): HTMLCanvasElement | OffscreenCanvas {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\n/**\n * Apply stroke style to context and call strokeText before fillText.\n * This creates an outer-stroke effect: fill drawn on top covers the inner half.\n *\n * When called via the offscreen approach (stroke opacity < 1), opacity has\n * already been stripped so this renders at full alpha per character.\n */\nfunction applyStrokeToChar(ctx: RenderContext, char: string, stroke: SerializedTextTransformElement['stroke']): void {\n if (!stroke?.enabled) return;\n ctx.strokeStyle = stroke.color;\n ctx.lineWidth = stroke.width;\n ctx.lineCap = stroke.lineCap || 'round';\n ctx.lineJoin = stroke.lineJoin || 'round';\n if (stroke.miterLimit !== undefined) ctx.miterLimit = stroke.miterLimit;\n if (stroke.opacity !== undefined) {\n const prevAlpha = ctx.globalAlpha;\n ctx.globalAlpha = stroke.opacity;\n ctx.strokeText(char, 0, 0);\n ctx.globalAlpha = prevAlpha;\n } else {\n ctx.strokeText(char, 0, 0);\n }\n}\n\n/**\n * Wrap a transform render function with offscreen compositing when stroke\n * opacity < 1. Renders all strokes at full opacity on a temp canvas, then\n * composites the temp canvas onto the main canvas at the desired opacity.\n * This prevents overlap darkening where adjacent characters' strokes overlap.\n *\n * The renderFn is called twice when offscreen is needed:\n * 1. On the offscreen canvas with stroke.opacity = 1 (stroke-only pass)\n * 2. On the main canvas with stroke disabled (fill-only pass)\n * When offscreen is NOT needed, renderFn is called once normally.\n */\nfunction renderTransformWithOffscreenStroke(\n ctx: RenderContext,\n elementData: SerializedTextTransformElement,\n renderFn: (ctx: RenderContext, data: SerializedTextTransformElement) => void\n): void {\n const stroke = elementData.stroke;\n const strokeOpacity = stroke?.opacity ?? 1;\n const elementAlpha = ctx.globalAlpha;\n const hasStrokeOpacity = stroke?.enabled && strokeOpacity < 1;\n const hasElementOpacity = stroke?.enabled && elementAlpha < 1;\n const needsOffscreen = hasStrokeOpacity || hasElementOpacity;\n\n if (!needsOffscreen) {\n // No offscreen needed — render normally\n renderFn(ctx, elementData);\n return;\n }\n\n // Estimate bounds for the offscreen canvas — be generous to avoid clipping.\n // Characters can extend well beyond the transform width/radius, especially\n // for arch/circle transforms where text measured width exceeds the container.\n const fontSize = elementData.fontSize || 24;\n const strokeWidth = stroke!.width || 0;\n const td = elementData.transformData as { width?: number; radius?: number; archHeight?: number };\n const textEstimate = fontSize * elementData.text.length * 0.7;\n const containerSpan = td.width ?? (td.radius ? (td.radius * 2) : 0);\n // Use the larger of container span and text estimate — text can overflow container\n const estimatedSpan = Math.max(containerSpan, textEstimate);\n const featherPad = (stroke!.feather || 0) * 2;\n const padding = strokeWidth * 4 + featherPad + fontSize + 40;\n const estWidth = estimatedSpan + padding;\n // Arch/circle transforms need extra height for curvature\n const archExtra = td.archHeight ? Math.abs(td.archHeight) * fontSize * 2 : 0;\n const radiusExtra = td.radius ? td.radius : 0;\n const estHeight = fontSize * 3 + padding + archExtra + radiusExtra;\n\n // Account for current canvas scale\n const transform = ctx.getTransform();\n const scale = Math.max(Math.abs(transform.a), Math.abs(transform.d), 1);\n\n // Use even dimensions to avoid fractional half-offsets\n const offW = Math.ceil(estWidth * scale / 2) * 2;\n const offH = Math.ceil(estHeight * scale / 2) * 2;\n\n if (offW <= 0 || offH <= 0) {\n renderFn(ctx, elementData);\n return;\n }\n\n const offCanvas = createOffscreenCanvas(offW, offH);\n const offCtx = offCanvas.getContext('2d') as RenderContext | null;\n\n if (!offCtx) {\n renderFn(ctx, elementData);\n return;\n }\n\n // Replicate the main canvas transform, shifted so the element center\n // maps to the center of the offscreen canvas.\n const elemX = elementData.x || 0;\n const elemY = elementData.y || 0;\n const centerPixelX = transform.a * elemX + transform.c * elemY + transform.e;\n const centerPixelY = transform.b * elemX + transform.d * elemY + transform.f;\n\n // Use rounded draw-back coordinates for pixel-perfect compositing\n const drawBackX = Math.round(centerPixelX - offW / 2);\n const drawBackY = Math.round(centerPixelY - offH / 2);\n\n offCtx.setTransform(\n transform.a, transform.b,\n transform.c, transform.d,\n offW / 2 - centerPixelX + transform.e,\n offH / 2 - centerPixelY + transform.f\n );\n\n // When element opacity is involved, render the entire element (stroke + fill)\n // at full opacity on the offscreen canvas, then composite everything at once.\n // This prevents overlap darkening where adjacent characters' strokes overlap.\n if (hasElementOpacity) {\n // Render at full alpha on offscreen canvas\n offCtx.globalAlpha = 1.0;\n const savedStrokeOpa = stroke!.opacity;\n if (hasStrokeOpacity) stroke!.opacity = 1.0;\n renderFn(offCtx, elementData);\n if (hasStrokeOpacity) stroke!.opacity = savedStrokeOpa;\n\n // Composite entire offscreen result at element opacity\n ctx.save();\n ctx.resetTransform();\n ctx.globalAlpha = elementAlpha;\n ctx.drawImage(offCanvas as CanvasImageSource, drawBackX, drawBackY);\n ctx.restore();\n return;\n }\n\n // Stroke opacity only (no element opacity) — original behavior:\n // Render stroke at full opacity on offscreen, fill-only on main canvas.\n const savedOpacity = stroke!.opacity;\n stroke!.opacity = 1.0;\n renderFn(offCtx, elementData);\n stroke!.opacity = savedOpacity;\n\n // Now render fill-only on the main canvas (disable stroke temporarily).\n const savedEnabled = stroke!.enabled;\n stroke!.enabled = false;\n renderFn(ctx, elementData);\n stroke!.enabled = savedEnabled;\n\n // Composite the offscreen stroke layer onto the main canvas at desired opacity.\n ctx.save();\n ctx.resetTransform();\n ctx.globalAlpha = strokeOpacity;\n ctx.drawImage(\n offCanvas as CanvasImageSource,\n drawBackX,\n drawBackY\n );\n ctx.restore();\n}\n\n// ============================================================================\n// Circle Transform\n// ============================================================================\n\nexport function renderCircleTransform(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n renderTransformWithOffscreenStroke(ctx, elementData, renderCircleTransformDirect);\n}\n\nfunction renderCircleTransformDirect(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n const transformData = elementData.transformData as CircleTransformData;\n\n ctx.save();\n\n // Move to center\n ctx.translate(elementData.x, elementData.y);\n // Use negative angle for clockwise rotation\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n\n // Now apply scale for rendering\n ctx.scale(transformData.scale, transformData.scale);\n\n // Set up rendering at base font size in scaled coordinate space\n const weight = elementData.bold ? 'bold' : 'normal';\n const style = elementData.italic ? 'italic' : 'normal';\n ctx.font = `${style} ${weight} ${elementData.fontSize}px ${elementData.fontFamily}`;\n ctx.fillStyle = elementData.color;\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n // Measure text widths in the current (scaled) coordinate space\n // This gives us measurements that are already in scaled units\n const chars = elementData.text.split('');\n const charWidths = chars.map((char) => ctx.measureText(char).width);\n const totalWidth = charWidths.reduce((sum, w) => sum + w, 0);\n\n if (transformData.reverse) {\n // Bottom text: start from right side and go left\n let currentAngle = Math.PI / 2 + totalWidth / (2 * transformData.radius);\n\n chars.forEach((char, i) => {\n const charWidth = charWidths[i];\n const angleStep = charWidth / transformData.radius;\n\n const x = Math.cos(currentAngle - angleStep / 2) * transformData.radius;\n const y = Math.sin(currentAngle - angleStep / 2) * transformData.radius;\n\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(currentAngle - angleStep / 2 - Math.PI / 2);\n applyStrokeToChar(ctx, char, elementData.stroke);\n ctx.fillText(char, 0, 0);\n ctx.restore();\n\n currentAngle -= angleStep;\n });\n } else {\n // Top text: start from left side and go right\n let currentAngle = -Math.PI / 2 - totalWidth / (2 * transformData.radius);\n\n chars.forEach((char, i) => {\n const charWidth = charWidths[i];\n const angleStep = charWidth / transformData.radius;\n\n const x = Math.cos(currentAngle + angleStep / 2) * transformData.radius;\n const y = Math.sin(currentAngle + angleStep / 2) * transformData.radius;\n\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(currentAngle + angleStep / 2 + Math.PI / 2);\n applyStrokeToChar(ctx, char, elementData.stroke);\n ctx.fillText(char, 0, 0);\n ctx.restore();\n\n currentAngle += angleStep;\n });\n }\n\n ctx.restore();\n}\n\n// ============================================================================\n// Wave Transform\n// ============================================================================\n\nexport function renderWaveTransform(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n renderTransformWithOffscreenStroke(ctx, elementData, renderWaveTransformDirect);\n}\n\nfunction renderWaveTransformDirect(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n const transformData = elementData.transformData as WaveTransformData;\n\n ctx.save();\n\n // Draw text along wave path\n ctx.translate(elementData.x, elementData.y);\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n\n // Set font to element's fontSize (canvas transform will handle zoom)\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\n ctx.fillStyle = elementData.color;\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n const chars = elementData.text.split('');\n const totalWidth = chars.reduce((sum, char) => sum + ctx.measureText(char).width, 0);\n\n // Draw each character along the wave with proper perspective/skew\n let currentX = -totalWidth / 2;\n chars.forEach((char) => {\n const charWidth = ctx.measureText(char).width;\n const x = currentX + charWidth / 2;\n const normalizedX = x / (transformData.width / 2);\n\n // Calculate y position on sine wave\n const y = transformData.amplitude * elementData.fontSize * Math.sin(transformData.frequency * Math.PI * normalizedX);\n\n // Calculate the slope of the sine wave at this point for skew\n const slope =\n transformData.amplitude *\n transformData.frequency *\n Math.PI *\n Math.cos(transformData.frequency * Math.PI * normalizedX);\n\n ctx.save();\n ctx.translate(x, y);\n\n // Apply vertical skew based on the slope\n ctx.transform(1, slope * WAVE_SKEW_FACTOR, 0, 1, 0, 0);\n\n applyStrokeToChar(ctx, char, elementData.stroke);\n ctx.fillText(char, 0, 0);\n ctx.restore();\n\n currentX += charWidth;\n });\n\n ctx.restore();\n}\n\n// ============================================================================\n// Arch Transform\n// ============================================================================\n\nexport function renderArchTransform(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n renderTransformWithOffscreenStroke(ctx, elementData, renderArchTransformDirect);\n}\n\nfunction renderArchTransformDirect(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n const transformData = elementData.transformData as ArchTransformData;\n\n ctx.save();\n\n // Draw text along arch path\n ctx.translate(elementData.x, elementData.y);\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n\n // Set font to element's fontSize (canvas transform will handle zoom)\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\n ctx.fillStyle = elementData.color;\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n const chars = elementData.text.split('');\n const totalWidth = chars.reduce((sum, char) => sum + ctx.measureText(char).width, 0);\n const radius = transformData.width / 2;\n\n // Draw each character along the arch with proper perspective/skew\n let currentX = -totalWidth / 2;\n chars.forEach((char) => {\n const charWidth = ctx.measureText(char).width;\n const x = currentX + charWidth / 2;\n const normalizedX = x / radius;\n\n // Calculate y position on parabola\n const y = (Math.pow(normalizedX, 2) - 1) * transformData.archHeight * elementData.fontSize;\n\n // Calculate the slope of the curve at this point for skew\n const slope = 2 * normalizedX * transformData.archHeight;\n\n // Apply skew transformation to create perspective effect\n ctx.save();\n ctx.translate(x, y);\n\n // Apply vertical skew based on the slope\n const skewFactor = 0.3;\n ctx.transform(1, slope * skewFactor, 0, 1, 0, 0);\n\n applyStrokeToChar(ctx, char, elementData.stroke);\n ctx.fillText(char, 0, 0);\n ctx.restore();\n\n currentX += charWidth;\n });\n\n ctx.restore();\n}\n\n// ============================================================================\n// Ascend Transform\n// ============================================================================\n\nexport function renderAscendTransform(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n renderTransformWithOffscreenStroke(ctx, elementData, renderAscendTransformDirect);\n}\n\nfunction renderAscendTransformDirect(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n const transformData = elementData.transformData as AscendTransformData;\n\n ctx.save();\n\n // Draw text along diagonal path\n ctx.translate(elementData.x, elementData.y);\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n\n // Set font to element's fontSize (canvas transform will handle zoom)\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\n ctx.fillStyle = elementData.color;\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n const chars = elementData.text.split('');\n const totalWidth = chars.reduce((sum, char) => sum + ctx.measureText(char).width, 0);\n const angleRad = (transformData.ascendAngle * Math.PI) / 180;\n\n // Draw each character along the diagonal line with skew perspective\n let currentX = -totalWidth / 2;\n chars.forEach((char) => {\n const charWidth = ctx.measureText(char).width;\n const x = currentX + charWidth / 2;\n\n // Calculate y position on straight diagonal line\n const y = x * Math.tan(angleRad);\n\n // Calculate the slope of the diagonal line for skew\n const slope = Math.tan(angleRad);\n\n // Apply skew transformation to create perspective effect\n ctx.save();\n ctx.translate(x, y);\n\n // Apply vertical skew based on the slope\n const skewFactor = 1.0;\n ctx.transform(1, slope * skewFactor, 0, 1, 0, 0);\n\n applyStrokeToChar(ctx, char, elementData.stroke);\n ctx.fillText(char, 0, 0);\n ctx.restore();\n\n currentX += charWidth;\n });\n\n ctx.restore();\n}\n\n// ============================================================================\n// Lean Transform\n// ============================================================================\n\nexport function renderLeanTransform(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n renderTransformWithOffscreenStroke(ctx, elementData, renderLeanTransformDirect);\n}\n\nfunction renderLeanTransformDirect(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n const transformData = elementData.transformData as LeanTransformData;\n\n ctx.save();\n\n // Draw text with skew/slant\n ctx.translate(elementData.x, elementData.y);\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n\n // Apply skew transform based on leanAmount\n const skewAngle = (-transformData.leanAmount * Math.PI) / 4;\n ctx.transform(1, 0, Math.tan(skewAngle), 1, 0, 0);\n\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\n ctx.fillStyle = elementData.color;\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n // Draw text normally - skew transform handles the slant\n // Stroke before fill for outer-stroke effect\n if (elementData.stroke?.enabled) {\n ctx.save();\n ctx.strokeStyle = elementData.stroke.color;\n ctx.lineWidth = elementData.stroke.width;\n ctx.lineCap = elementData.stroke.lineCap || 'round';\n ctx.lineJoin = elementData.stroke.lineJoin || 'round';\n if (elementData.stroke.opacity !== undefined) ctx.globalAlpha = elementData.stroke.opacity;\n ctx.strokeText(elementData.text, 0, 0);\n ctx.restore();\n }\n ctx.fillText(elementData.text, 0, 0);\n\n ctx.restore();\n}\n\n// ============================================================================\n// Flag Transform\n// ============================================================================\n\nexport function renderFlagTransform(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n renderTransformWithOffscreenStroke(ctx, elementData, renderFlagTransformDirect);\n}\n\nfunction renderFlagTransformDirect(ctx: RenderContext, elementData: SerializedTextTransformElement): void {\n const transformData = elementData.transformData as FlagTransformData;\n\n ctx.save();\n\n // Draw text along flag wave path\n ctx.translate(elementData.x, elementData.y);\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n\n // Set font to element's fontSize (canvas transform will handle zoom)\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\n ctx.fillStyle = elementData.color;\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n const chars = elementData.text.split('');\n const totalWidth = chars.reduce((sum, char) => sum + ctx.measureText(char).width, 0);\n\n // Draw each character along the flag wave with proper perspective/skew\n let currentX = -totalWidth / 2;\n chars.forEach((char) => {\n const charWidth = ctx.measureText(char).width;\n const x = currentX + charWidth / 2;\n const normalizedX = x / (transformData.width / 2);\n\n // Flag effect: amplitude increases from center to edges\n const distanceFromCenter = Math.abs(normalizedX);\n const flagAmplitude = transformData.amplitude * distanceFromCenter;\n\n // Calculate y position on flag wave\n const y = flagAmplitude * elementData.fontSize * Math.sin(transformData.frequency * Math.PI * normalizedX);\n\n // Calculate the slope for skew\n const cosComponent =\n flagAmplitude * transformData.frequency * Math.PI * Math.cos(transformData.frequency * Math.PI * normalizedX);\n const sinComponent =\n transformData.amplitude * Math.sign(normalizedX) * Math.sin(transformData.frequency * Math.PI * normalizedX);\n const slope = cosComponent + sinComponent;\n\n ctx.save();\n ctx.translate(x, y);\n\n // Apply vertical skew based on the slope\n const skewFactor = 0.3;\n ctx.transform(1, slope * skewFactor, 0, 1, 0, 0);\n\n applyStrokeToChar(ctx, char, elementData.stroke);\n ctx.fillText(char, 0, 0);\n ctx.restore();\n\n currentX += charWidth;\n });\n\n ctx.restore();\n}\n","/**\n * Element painters — the heavy half of the paint registry\n * (`src/core/paint-registry.ts`, P1 element/renderer split).\n *\n * Registers the shared paint functions the element model delegates to at\n * paint time. This module statically imports the paint pipeline\n * (transform-renderer / canvas-renderer), so it must only ever be reachable\n * through renderer-side code: every paint DRIVER (CanvasRenderer,\n * ExportManager, ElementPreviewRenderer) imports it, which keeps the\n * registration a static guarantee of \"the renderer is loaded\" without the\n * model graph ever touching `src/rendering/*`. CI-gated by\n * scripts/check-import-graph.mjs.\n */\n\nimport {\n registerGroupClippingPainter,\n registerTextTransformPainter,\n type PaintableChild,\n type TextTransformPainter,\n} from '../core/paint-registry.js';\nimport { registerElementPreviewPainter } from '../core/preview-registry.js';\n// Deliberate import cycle (ElementPreviewRenderer side-effect-imports this\n// module to guarantee painters before any preview paint) — safe because the\n// registration below wraps the live binding in an arrow and only calls it at\n// preview time, never at module evaluation. Same accepted shape as the\n// DistressTextureCache ↔ distress-textures cycle.\nimport { generateElementPreview } from '../utils/ElementPreviewRenderer.js';\nimport {\n renderArchTransform,\n renderAscendTransform,\n renderCircleTransform,\n renderFlagTransform,\n renderLeanTransform,\n renderWaveTransform,\n type SerializedTextTransformElement,\n} from './transform-renderer.js';\nimport { renderCustomTransform, type SerializedTextElement } from './canvas-renderer.js';\n\nfunction asTransformPainter(\n paint: (ctx: CanvasRenderingContext2D, serialized: SerializedTextTransformElement) => void,\n): TextTransformPainter {\n return (ctx, serialized) => paint(ctx, serialized as unknown as SerializedTextTransformElement);\n}\n\n/**\n * Composite a group's children honoring `isClipping` masks (moved verbatim\n * from `GroupElement._renderWithClipping` — the 'destination-in' compositing\n * is paint-pipeline code).\n */\nfunction renderGroupWithClipping(ctx: CanvasRenderingContext2D, children: PaintableChild[]): void {\n ctx.save();\n\n const canvas = ctx.canvas;\n const width = canvas.width;\n const height = canvas.height;\n const transform = ctx.getTransform();\n\n // Group children into clipping segments\n // Each segment has content elements and optionally a clipping mask\n const segments: {\n content: PaintableChild[];\n mask?: PaintableChild;\n }[] = [];\n let currentContent: PaintableChild[] = [];\n\n // Iterate through children (bottom to top in visual order)\n for (const child of children) {\n if (child.isClipping) {\n // This element clips everything we've collected so far\n if (currentContent.length > 0) {\n segments.push({ content: currentContent, mask: child });\n currentContent = [];\n } else {\n // Clipping mask with no content below it - just render the mask normally\n segments.push({ content: [child] });\n }\n } else {\n currentContent.push(child);\n }\n }\n\n // Add remaining content without clipping\n if (currentContent.length > 0) {\n segments.push({ content: currentContent });\n }\n\n // Render each segment\n for (const segment of segments) {\n if (!segment.mask) {\n // No mask - render normally\n segment.content.forEach((child) => child.render(ctx, false, false));\n } else {\n // Render with clipping mask\n\n const contentCanvas = document.createElement('canvas');\n contentCanvas.width = width;\n contentCanvas.height = height;\n const contentCtx = contentCanvas.getContext('2d');\n if (!contentCtx) continue;\n\n contentCtx.setTransform(transform);\n\n // Render content\n segment.content.forEach((child) => {\n child.render(contentCtx, false, false);\n });\n\n // Create mask\n const maskCanvas = document.createElement('canvas');\n maskCanvas.width = width;\n maskCanvas.height = height;\n const maskCtx = maskCanvas.getContext('2d');\n if (!maskCtx) continue;\n\n maskCtx.setTransform(transform);\n segment.mask.render(maskCtx, false, false);\n\n // Fallback for empty text elements\n if (segment.mask.transformType !== 'image' && segment.mask.transformType !== 'shape') {\n const bbox = segment.mask.getBoundingBox();\n maskCtx.save();\n maskCtx.fillStyle = '#FFFFFF';\n maskCtx.fillRect(bbox.x, bbox.y, bbox.width, bbox.height);\n maskCtx.restore();\n }\n\n // Apply mask\n contentCtx.globalCompositeOperation = 'destination-in';\n contentCtx.setTransform(1, 0, 0, 1, 0, 0);\n contentCtx.drawImage(maskCanvas, 0, 0);\n\n // Draw to main canvas\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.drawImage(contentCanvas, 0, 0);\n ctx.setTransform(transform);\n }\n }\n\n ctx.restore();\n}\n\n// `var`, not `let`, deliberately: paint drivers call installElementPainters()\n// at THEIR module eval, and this module's import cycle with\n// ElementPreviewRenderer means such a call can land before this module's body\n// runs. A `let` is in its temporal dead zone then (crashes with \"Cannot\n// access 'installed' before initialization\"); `var` hoists to undefined and\n// the install proceeds. Registrations are Map.set overwrites, so the body\n// re-running them after a mid-cycle install is harmless.\n// eslint-disable-next-line no-var\nvar installed = false;\n\n/** Idempotent; also runs at module evaluation — but do NOT rely on a plain\n * side-effect import (`import './element-painters.js'`) reaching it:\n * bundlers honoring the package `sideEffects` allowlist prune bare imports.\n * Paint drivers must CALL this (see core/CanvasRenderer.ts). */\nexport function installElementPainters(): void {\n if (installed) return;\n installed = true;\n\n registerTextTransformPainter('arch', asTransformPainter(renderArchTransform));\n registerTextTransformPainter('ascend', asTransformPainter(renderAscendTransform));\n registerTextTransformPainter('circle', asTransformPainter(renderCircleTransform));\n registerTextTransformPainter('flag', asTransformPainter(renderFlagTransform));\n registerTextTransformPainter('lean', asTransformPainter(renderLeanTransform));\n registerTextTransformPainter('wave', asTransformPainter(renderWaveTransform));\n registerTextTransformPainter('custom', (ctx, serialized) =>\n renderCustomTransform(ctx, serialized as unknown as SerializedTextElement),\n );\n registerGroupClippingPainter(renderGroupWithClipping);\n // Layer-panel thumbnails (core/preview-registry.ts): an enhancement that\n // needs the renderer, looked up at preview time by useLayers/useLayerPreview\n // so the panels' static graphs stay renderer-free (Editor.Layers, D9).\n registerElementPreviewPainter((element, options) =>\n generateElementPreview(element as Parameters<typeof generateElementPreview>[0], options),\n );\n\n // Artifact-level gate marker: scripts/check-dist-painters.mjs greps the\n // built dist for this PROPERTY NAME (identifiers minify away, property\n // names on globalThis don't). It can only ship if this function shipped —\n // i.e. some live module actually calls the registration. Also handy at\n // runtime: a console probe for \"did the painters install?\".\n (globalThis as { __scElementPaintersInstalled?: boolean }).__scElementPaintersInstalled = true;\n}\n\ninstallElementPainters();\n","/**\n * ElementRenderUtils - Centralized rendering for all element types\n *\n * Provides consistent element rendering across mask, knockout, and export systems.\n * Supports rendering any element type (text, image, shape) with control over\n * fill-only, stroke-only, or both rendering modes.\n */\n\nimport type {\n AnyElementConfig,\n BaseTextElementConfig,\n ImageElementConfig,\n ShapeElementConfig,\n ShapeTransformData,\n RenderingContext,\n} from '../types/index.js';\nimport { renderTextStroke, renderImageStroke } from './StrokeRenderer.js';\nimport { renderTextFillOnly } from './canvas-renderer.js';\n\n/**\n * Rendering mode options\n */\nexport type RenderMode = 'fill' | 'stroke' | 'both';\n\n/**\n * Options for element rendering\n */\nexport interface ElementRenderOptions {\n mode?: RenderMode;\n renderingContext?: RenderingContext;\n // For images: optional loaded image object (avoids re-loading)\n loadedImage?: HTMLImageElement;\n}\n\n/**\n * Main dispatcher: Render any element type based on its transformType\n */\nexport function renderElement(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig,\n options: ElementRenderOptions = {}\n): void {\n const mode = options.mode || 'both';\n\n\n // Position and rotate the element\n ctx.save();\n ctx.translate(element.x || 0, element.y || 0);\n ctx.rotate((-(element.rotation || 0) * Math.PI) / 180);\n\n // Dispatch to appropriate renderer based on transformType\n switch (element.transformType) {\n case 'image':\n renderImageElement(ctx, element as ImageElementConfig, mode, options);\n break;\n\n case 'shape':\n renderShapeElement(ctx, element as ShapeElementConfig, mode, options);\n break;\n\n case 'group':\n // Groups don't render content themselves\n // In mask/knockout context, skip group rendering\n break;\n\n default:\n // All text transform types (custom, circle, arch, lean, ascend, wave, flag, etc.)\n renderTextElement(ctx, element, mode, options);\n break;\n }\n\n ctx.restore();\n}\n\n/**\n * Render text element (all text transform types)\n */\nfunction renderTextElement(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig,\n mode: RenderMode,\n options: ElementRenderOptions\n): void {\n // Narrow to text element config to access text properties\n const textElement = element as BaseTextElementConfig;\n const text = textElement.text || '';\n if (!text) return;\n\n // Render stroke BEFORE fill for outer-stroke effect.\n // Canvas strokeText draws centered on the glyph outline; drawing fill on top\n // covers the inner half, leaving only the outer half visible as a clean outline.\n if ((mode === 'stroke' || mode === 'both') && element.stroke?.enabled) {\n ctx.save();\n renderTextStroke(ctx, element, { ...options.renderingContext, positionApplied: true });\n ctx.restore();\n }\n\n // Render fill (on top of stroke, covering the inner half)\n if (mode === 'fill' || mode === 'both') {\n ctx.save();\n renderTextFillOnly(ctx, {\n text,\n fontSize: textElement.fontSize || 24,\n fontFamily: textElement.fontFamily || 'Arial',\n bold: textElement.bold || false,\n italic: textElement.italic || false,\n textAlign: textElement.textAlign || 'center',\n color: textElement.color || '#000000',\n letterSpacing: textElement.letterSpacing,\n });\n ctx.restore();\n }\n}\n\n/**\n * Render image element\n */\nfunction renderImageElement(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: ImageElementConfig,\n mode: RenderMode,\n options: ElementRenderOptions\n): void {\n if (!element.transformData) return;\n\n const transformData = element.transformData;\n\n // For fill mode, we need to render the actual image\n // This is simplified - in production you'd need to handle image loading\n if (mode === 'fill' || mode === 'both') {\n // Create image path for clipping\n createImagePath(ctx, element);\n\n // If we have a loaded image, draw it\n if (options.loadedImage) {\n ctx.save();\n ctx.clip();\n\n // Apply flip transformations\n const flipH = transformData.flipHorizontal ? -1 : 1;\n const flipV = transformData.flipVertical ? -1 : 1;\n ctx.scale(flipH, flipV);\n\n // Draw the image\n const width = transformData.width ?? 100;\n const height = transformData.height ?? 100;\n\n ctx.drawImage(options.loadedImage, -width / 2, -height / 2, width, height);\n\n ctx.restore();\n } else {\n // No loaded image - just fill the shape with placeholder color\n ctx.fillStyle = '#cccccc';\n ctx.fill();\n }\n }\n\n // Render stroke\n if ((mode === 'stroke' || mode === 'both') && element.stroke?.enabled) {\n ctx.save();\n renderImageStroke(ctx, element, options.renderingContext);\n ctx.restore();\n }\n}\n\n/**\n * Render shape element\n */\nfunction renderShapeElement(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: ShapeElementConfig,\n mode: RenderMode,\n options: ElementRenderOptions\n): void {\n if (!element.transformData) return;\n\n const transformData = element.transformData;\n const isKnockoutRender = options.renderingContext?.isKnockout === true;\n\n // Create the shape path\n ctx.beginPath();\n renderShapePath(ctx, transformData);\n\n // Render fill\n if (mode === 'fill' || mode === 'both') {\n ctx.fillStyle = isKnockoutRender ? '#000000' : transformData.fillColor || '#3b82f6';\n ctx.globalAlpha = isKnockoutRender ? 1.0 : (transformData.fillOpacity ?? 1);\n ctx.fill();\n }\n\n // Render stroke\n if ((mode === 'stroke' || mode === 'both') && element.stroke?.enabled) {\n ctx.save();\n renderShapeStroke(ctx, element, options.renderingContext);\n ctx.restore();\n }\n}\n\n/**\n * Create shape path based on shapeType\n * This is extracted from ShapeElement.render() for reusability\n */\nfunction renderShapePath(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n transformData: Partial<ShapeTransformData>\n): void {\n const { shapeType } = transformData;\n const width = transformData.width ?? 100;\n const height = transformData.height ?? 100;\n\n switch (shapeType) {\n case 'rectangle':\n renderRectanglePath(ctx, transformData as ShapeTransformData, width, height);\n break;\n case 'circle':\n renderCirclePath(ctx, Math.min(width, height) / 2);\n break;\n case 'ellipse':\n renderEllipsePath(ctx, width / 2, height / 2);\n break;\n case 'star':\n renderStarPath(ctx, transformData as ShapeTransformData, Math.min(width, height) / 2);\n break;\n default:\n // Fallback to rectangle for unsupported shapes\n renderRectanglePath(ctx, transformData as ShapeTransformData, width, height);\n }\n}\n\n/**\n * Rectangle path (with optional border radius)\n */\nfunction renderRectanglePath(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n transformData: ShapeTransformData,\n width: number,\n height: number\n): void {\n const borderRadius = transformData.borderRadius || 0;\n const x = -width / 2;\n const y = -height / 2;\n\n if (borderRadius > 0) {\n const radius = Math.min((borderRadius / 100) * Math.min(width, height), width / 2, height / 2);\n ctx.roundRect(x, y, width, height, radius);\n } else {\n ctx.rect(x, y, width, height);\n }\n}\n\n/**\n * Circle path\n */\nfunction renderCirclePath(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, radius: number): void {\n ctx.arc(0, 0, radius, 0, Math.PI * 2);\n}\n\n/**\n * Ellipse path\n */\nfunction renderEllipsePath(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n radiusX: number,\n radiusY: number\n): void {\n ctx.ellipse(0, 0, radiusX, radiusY, 0, 0, Math.PI * 2);\n}\n\n/**\n * Star path\n */\nfunction renderStarPath(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n transformData: ShapeTransformData,\n outerRadius: number\n): void {\n const points = Math.max(3, Math.min(20, transformData.points || 5));\n const innerRadiusRatio = Math.max(0.1, Math.min(0.9, transformData.innerRadius || 0.4));\n const innerRadius = outerRadius * innerRadiusRatio;\n const angleStep = Math.PI / points;\n const startAngle = -Math.PI / 2; // Start at top\n\n for (let i = 0; i < points * 2; i++) {\n const angle = startAngle + angleStep * i;\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\n const x = Math.cos(angle) * radius;\n const y = Math.sin(angle) * radius;\n\n if (i === 0) {\n ctx.moveTo(x, y);\n } else {\n ctx.lineTo(x, y);\n }\n }\n\n ctx.closePath();\n}\n\n/**\n * Render stroke for shape element\n */\nfunction renderShapeStroke(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: ShapeElementConfig,\n renderingContext?: RenderingContext\n): void {\n if (!element.stroke?.enabled || !element.transformData) return;\n\n const isKnockoutRender = renderingContext?.isKnockout === true;\n\n ctx.save();\n\n // Apply stroke style\n if (isKnockoutRender) {\n ctx.strokeStyle = '#000000';\n ctx.lineWidth = element.stroke.width;\n ctx.lineCap = element.stroke.lineCap || 'butt';\n ctx.lineJoin = element.stroke.lineJoin || 'miter';\n ctx.globalAlpha = 1.0;\n } else {\n ctx.strokeStyle = element.stroke.color;\n ctx.lineWidth = element.stroke.width;\n ctx.lineCap = element.stroke.lineCap || 'butt';\n ctx.lineJoin = element.stroke.lineJoin || 'miter';\n\n if (element.stroke.opacity !== undefined) {\n ctx.globalAlpha = element.stroke.opacity;\n }\n }\n\n if (element.stroke.miterLimit !== undefined) {\n ctx.miterLimit = element.stroke.miterLimit;\n }\n\n if (element.stroke.dashArray && element.stroke.dashArray.length > 0) {\n ctx.setLineDash(element.stroke.dashArray);\n }\n\n // Apply feathering (blur) - only for non-knockout renders\n if (!isKnockoutRender && element.stroke.feather && element.stroke.feather > 0) {\n if ('filter' in ctx) {\n (ctx as CanvasRenderingContext2D).filter = `blur(${element.stroke.feather}px)`;\n }\n }\n\n // Create and stroke the shape path\n ctx.beginPath();\n renderShapePath(ctx, element.transformData);\n ctx.stroke();\n\n ctx.restore();\n}\n\n/**\n * Create image path for clipping/stroking\n * Handles border radius and image bounds\n */\nfunction createImagePath(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: ImageElementConfig\n): void {\n if (!element.transformData) return;\n\n const { borderRadius } = element.transformData;\n const width = element.transformData.width ?? 100;\n const height = element.transformData.height ?? 100;\n const x = -width / 2;\n const y = -height / 2;\n\n ctx.beginPath();\n\n if (borderRadius && borderRadius > 0) {\n const radius = Math.min((borderRadius / 100) * Math.min(width, height), width / 2, height / 2);\n ctx.roundRect(x, y, width, height, radius);\n } else {\n ctx.rect(x, y, width, height);\n }\n}\n","/**\n * CompositingRenderer - Compositing system with dual scope\n *\n * Supports two compositing modes:\n * - 'destination-out' (knockout): Cuts through affected content\n * - 'destination-in' (clip): Keeps only content within the element shape\n *\n * Supports two scopes:\n * - 'group': Compositing affects only siblings within the same group (DEFAULT)\n * - 'artboard': Compositing cuts through ALL layers to artboard background\n *\n * Use cases:\n * - Pillow/Pattern: Pattern layer + group with knockout text (scope: 'group')\n * - T-Shirt: Text with knockout stroke reveals shirt color (scope: 'artboard')\n * - Clip: Content below is masked to element shape (destination-in)\n */\n\nimport type { AnyElementConfig, KnockoutScope } from '../types/index.js';\nimport { renderElement } from './ElementRenderUtils.js';\n\n/** Supported composite operations */\nexport type CompositeOp = 'destination-out' | 'destination-in';\n\n/**\n * Render element with compositing (knockout or clip)\n * This is the main entry point for compositing rendering\n */\nexport function renderWithCompositing(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n compositingElement: AnyElementConfig,\n allElements: AnyElementConfig[],\n renderElementFn: (\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig\n ) => void,\n artboardBackgroundColor?: string,\n artboard?: { x: number; y: number; width: number; height: number },\n compositeOp: CompositeOp = 'destination-out'\n): void {\n if (!compositingElement.knockoutParts) return;\n\n // Skip if no parts are actually enabled\n const hasAnyParts = compositingElement.knockoutParts.fill || compositingElement.knockoutParts.stroke;\n\n if (!hasAnyParts) {\n renderElementFn(ctx, compositingElement);\n return;\n }\n\n // Save the context state\n const savedTransform = ctx.getTransform();\n ctx.save();\n\n const scope = compositingElement.knockoutParts.scope || 'group';\n const affectedElements = getAffectedElements(compositingElement, scope, allElements);\n\n // For artboard scope with no affected elements, just render non-compositing parts\n if (affectedElements.length === 0 && scope === 'artboard') {\n renderNonCompositingParts(ctx, compositingElement, renderElementFn);\n ctx.restore();\n return;\n }\n\n // For group scope with no affected elements, render normally\n if (affectedElements.length === 0) {\n renderElementFn(ctx, compositingElement);\n ctx.restore();\n return;\n }\n\n // Use offscreen compositing to preserve artboard background\n const canvas = ctx.canvas;\n const mainTransform = ctx.getTransform();\n const dpr = mainTransform.a;\n\n const offscreen = createOffscreenCanvas(canvas.width, canvas.height);\n const offCtx = offscreen.getContext('2d');\n if (!offCtx) return;\n\n offCtx.scale(dpr, dpr);\n\n // Fill offscreen with artboard background\n if (artboardBackgroundColor && artboard) {\n offCtx.fillStyle = artboardBackgroundColor;\n offCtx.fillRect(artboard.x, artboard.y, artboard.width, artboard.height);\n }\n\n // Render affected elements to offscreen\n for (const element of affectedElements) {\n renderElementFn(offCtx, element);\n }\n\n // Render non-compositing stroke BEFORE fill cutout so the fill compositing\n // also punches through the stroke, leaving only its outer edge visible.\n // Without this, the stroke renders ON TOP of the fill compositing holes,\n // covering them with the stroke's inner half.\n if (compositingElement.knockoutParts.fill && !compositingElement.knockoutParts.stroke && compositingElement.stroke?.enabled) {\n offCtx.save();\n renderElementStroke(offCtx, compositingElement);\n offCtx.restore();\n }\n\n // Apply compositing operation\n offCtx.save();\n offCtx.globalCompositeOperation = compositeOp;\n\n if (compositingElement.knockoutParts.fill) {\n renderElementFill(offCtx, compositingElement, renderElementFn);\n }\n\n if (compositingElement.knockoutParts.stroke) {\n renderElementStroke(offCtx, compositingElement);\n }\n\n offCtx.restore();\n\n // Render non-compositing fill AFTER stroke cutout so it sits on top\n if (!compositingElement.knockoutParts.fill) {\n offCtx.save();\n renderElementFill(offCtx, compositingElement, renderElementFn);\n offCtx.restore();\n }\n\n // Composite offscreen to main canvas\n const logicalWidth = canvas.width / dpr;\n const logicalHeight = canvas.height / dpr;\n ctx.drawImage(offscreen as unknown as CanvasImageSource, 0, 0, logicalWidth, logicalHeight);\n\n // Restore context state\n ctx.restore();\n\n // Verify transform was restored correctly\n const afterRestore = ctx.getTransform();\n if (\n Math.abs(afterRestore.a - savedTransform.a) > 0.001 ||\n Math.abs(afterRestore.d - savedTransform.d) > 0.001 ||\n Math.abs(afterRestore.e - savedTransform.e) > 0.001 ||\n Math.abs(afterRestore.f - savedTransform.f) > 0.001\n ) {\n // Force restore if needed\n ctx.setTransform(\n savedTransform.a,\n savedTransform.b,\n savedTransform.c,\n savedTransform.d,\n savedTransform.e,\n savedTransform.f\n );\n }\n}\n\n/**\n * Render element with knockout compositing (destination-out)\n * Convenience wrapper — backward-compatible entry point\n */\nexport function renderWithKnockout(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n knockoutElement: AnyElementConfig,\n allElements: AnyElementConfig[],\n renderElementFn: (\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig\n ) => void,\n artboardBackgroundColor?: string,\n artboard?: { x: number; y: number; width: number; height: number }\n): void {\n renderWithCompositing(ctx, knockoutElement, allElements, renderElementFn, artboardBackgroundColor, artboard, 'destination-out');\n}\n\n/**\n * Render element with clip compositing (destination-in)\n * Keeps only content within the element shape\n */\nexport function renderWithClip(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n clipElement: AnyElementConfig,\n allElements: AnyElementConfig[],\n renderElementFn: (\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig\n ) => void,\n artboardBackgroundColor?: string,\n artboard?: { x: number; y: number; width: number; height: number }\n): void {\n renderWithCompositing(ctx, clipElement, allElements, renderElementFn, artboardBackgroundColor, artboard, 'destination-in');\n}\n\n/**\n * Determine which elements are affected by knockout based on scope\n */\nfunction getAffectedElements(\n knockoutElement: AnyElementConfig,\n scope: KnockoutScope,\n allElements: AnyElementConfig[]\n): AnyElementConfig[] {\n if (scope === 'artboard') {\n // Knockout affects ALL elements below this one in z-order\n return getAllElementsBelow(knockoutElement, allElements);\n } else {\n // scope === 'group': Knockout affects only group siblings\n return getGroupSiblings(knockoutElement, allElements);\n }\n}\n\n/**\n * Get all elements below knockout element in z-order\n * Used for 'artboard' scope\n */\nfunction getAllElementsBelow(knockoutElement: AnyElementConfig, allElements: AnyElementConfig[]): AnyElementConfig[] {\n const knockoutIndex = allElements.findIndex((el) => el.id === knockoutElement.id);\n if (knockoutIndex === -1) return [];\n\n // Return all elements that come before this one in the array (rendered below)\n return allElements.slice(0, knockoutIndex);\n}\n\n/**\n * Get sibling elements within the same group\n * Used for 'group' scope\n */\nfunction getGroupSiblings(knockoutElement: AnyElementConfig, allElements: AnyElementConfig[]): AnyElementConfig[] {\n // Find the parent group of the knockout element\n const parentGroup = findParentGroup(knockoutElement, allElements);\n\n if (!parentGroup) {\n // Element is not in a group, fall back to artboard scope behavior\n return getAllElementsBelow(knockoutElement, allElements);\n }\n\n // Get children of the parent group\n if (parentGroup.transformType !== 'group' || !parentGroup.children) {\n return [];\n }\n\n // Find the knockout element's index within the group\n const knockoutIndex = parentGroup.children.findIndex((child) => child.id === knockoutElement.id);\n\n if (knockoutIndex === -1) return [];\n\n // Return all siblings that come before this element (rendered below)\n return parentGroup.children.slice(0, knockoutIndex);\n}\n\n/**\n * Find parent group of an element\n * Recursively searches through group hierarchy\n */\nfunction findParentGroup(element: AnyElementConfig, allElements: AnyElementConfig[]): AnyElementConfig | null {\n for (const candidate of allElements) {\n if (candidate.transformType === 'group' && candidate.children) {\n // Check if element is a direct child\n if (candidate.children.some((child) => child.id === element.id)) {\n return candidate;\n }\n\n // Check nested groups recursively\n const nestedParent = findParentGroup(element, candidate.children);\n if (nestedParent) {\n return nestedParent;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Render element fill (for knockout)\n * This renders ONLY the fill using the centralized renderer\n */\nfunction renderElementFill(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig,\n _renderFn: (ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, element: AnyElementConfig) => void\n): void {\n // Use centralized renderer in fill-only mode with knockout context\n // This now supports text, images, and shapes\n renderElement(ctx, element, {\n mode: 'fill',\n renderingContext: { isKnockout: true },\n });\n}\n\n/**\n * Render element stroke (for knockout)\n */\nfunction renderElementStroke(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig\n): void {\n if (!element.stroke?.enabled) return;\n\n // Use centralized renderer in stroke-only mode with knockout context\n // This now supports text, images, and shapes\n renderElement(ctx, element, {\n mode: 'stroke',\n renderingContext: { isKnockout: true },\n });\n}\n\n/**\n * Render non-compositing parts of element\n */\nfunction renderNonCompositingParts(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig,\n renderFn: (ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, element: AnyElementConfig) => void\n): void {\n const knockoutParts = element.knockoutParts;\n if (!knockoutParts) {\n renderFn(ctx, element);\n return;\n }\n\n // Render fill if not knocked out\n if (!knockoutParts.fill) {\n ctx.save();\n renderElementFill(ctx, element, renderFn);\n ctx.restore();\n }\n\n // Render stroke if not knocked out\n if (!knockoutParts.stroke && element.stroke?.enabled) {\n ctx.save();\n renderElementStroke(ctx, element);\n ctx.restore();\n }\n}\n\n/**\n * Create offscreen canvas for compositing\n */\nfunction createOffscreenCanvas(width: number, height: number): HTMLCanvasElement | OffscreenCanvas {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n } else if (typeof document !== 'undefined') {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n throw new Error('No canvas context available');\n}\n","/**\n * Mask utility functions\n * Helper functions for mask creation and manipulation\n */\n\nimport type { MaskDefinition, MaskType, AnyElementConfig } from '../types/index.js';\n\n/**\n * Create a new mask definition\n */\nexport function createMask(\n type: MaskType,\n maskElement: AnyElementConfig,\n options: Partial<Omit<MaskDefinition, 'id' | 'type' | 'maskElement'>> = {}\n): MaskDefinition {\n return {\n id: `mask-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n type,\n maskElement,\n inverted: options.inverted || false,\n feather: options.feather || 0,\n opacity: options.opacity !== undefined ? options.opacity : 1.0,\n blendMode: options.blendMode || 'normal',\n };\n}\n\n/**\n * Create a clip mask from text\n */\nexport function createTextClipMask(\n text: string,\n fontSize: number = 100,\n fontFamily: string = 'Anton',\n options: Partial<Omit<MaskDefinition, 'id' | 'type' | 'maskElement'>> = {}\n): MaskDefinition {\n return createMask(\n 'clip',\n {\n transformType: 'custom',\n text,\n fontSize,\n fontFamily,\n x: 0,\n y: 0,\n rotation: 0,\n color: '#000000', // Color doesn't matter for clip masks\n },\n options\n );\n}\n\n/**\n * Create a clip mask from an image.\n * Opaque pixels in the image define the visible area; transparent pixels clip.\n */\nexport function createImageClipMask(\n imageUrl: string,\n width: number = 500,\n height: number = 500,\n options: Partial<Omit<MaskDefinition, 'id' | 'type' | 'maskElement'>> = {}\n): MaskDefinition {\n return createMask(\n 'clip',\n {\n transformType: 'image',\n imageUrl,\n x: 0,\n y: 0,\n rotation: 0,\n transformData: {\n type: 'image',\n width,\n height,\n cropX: 0,\n cropY: 0,\n cropWidth: 1,\n cropHeight: 1,\n flipHorizontal: false,\n flipVertical: false,\n borderRadius: 0,\n },\n },\n options\n );\n}\n\n/**\n * Create an alpha mask from an image.\n * The image's alpha channel controls element visibility.\n */\nexport function createImageAlphaMask(\n imageUrl: string,\n width: number = 500,\n height: number = 500,\n options: Partial<Omit<MaskDefinition, 'id' | 'type' | 'maskElement'>> = {}\n): MaskDefinition {\n return createMask(\n 'alpha',\n {\n transformType: 'image',\n imageUrl,\n x: 0,\n y: 0,\n rotation: 0,\n transformData: {\n type: 'image',\n width,\n height,\n cropX: 0,\n cropY: 0,\n cropWidth: 1,\n cropHeight: 1,\n flipHorizontal: false,\n flipVertical: false,\n borderRadius: 0,\n },\n },\n options\n );\n}\n\n/**\n * Create a luma mask from an image.\n * Bright pixels = visible, dark pixels = hidden.\n */\nexport function createImageLumaMask(\n imageUrl: string,\n width: number = 500,\n height: number = 500,\n options: Partial<Omit<MaskDefinition, 'id' | 'type' | 'maskElement'>> = {}\n): MaskDefinition {\n return createMask(\n 'luma',\n {\n transformType: 'image',\n imageUrl,\n x: 0,\n y: 0,\n rotation: 0,\n transformData: {\n type: 'image',\n width,\n height,\n cropX: 0,\n cropY: 0,\n cropWidth: 1,\n cropHeight: 1,\n flipHorizontal: false,\n flipVertical: false,\n borderRadius: 0,\n },\n },\n options\n );\n}\n\n/**\n * Create a distress mask from image/texture\n */\nexport function createDistressMask(\n textureUrl: string,\n opacity: number = 0.6,\n options: Partial<Omit<MaskDefinition, 'id' | 'type' | 'maskElement'>> = {}\n): MaskDefinition {\n return createMask(\n 'distress',\n {\n transformType: 'image',\n imageUrl: textureUrl,\n x: 0,\n y: 0,\n rotation: 0,\n transformData: {\n type: 'image',\n width: 500,\n height: 500,\n cropX: 0,\n cropY: 0,\n cropWidth: 1,\n cropHeight: 1,\n flipHorizontal: false,\n flipVertical: false,\n borderRadius: 0,\n },\n },\n { ...options, opacity }\n );\n}\n\n/**\n * Calculate relative position for mask element\n * Converts world coordinates to relative coordinates\n */\nexport function calculateRelativePosition(\n parentX: number,\n parentY: number,\n maskWorldX: number,\n maskWorldY: number\n): { x: number; y: number } {\n return {\n x: maskWorldX - parentX,\n y: maskWorldY - parentY,\n };\n}\n\n/**\n * Calculate world position for mask element\n * Converts relative coordinates to world coordinates\n */\nexport function calculateWorldPosition(\n parentX: number,\n parentY: number,\n maskRelativeX: number,\n maskRelativeY: number\n): { x: number; y: number } {\n return {\n x: parentX + maskRelativeX,\n y: parentY + maskRelativeY,\n };\n}\n\n/**\n * Validate mask definition\n */\nexport function isValidMask(mask: MaskDefinition): boolean {\n if (!mask.id || !mask.type) return false;\n if (!mask.maskElement) return false;\n if (mask.opacity !== undefined && (mask.opacity < 0 || mask.opacity > 1)) return false;\n if (mask.feather !== undefined && mask.feather < 0) return false;\n return true;\n}\n\n/**\n * Compute mask dimensions using object-contain scaling.\n *\n * The mask maintains its natural aspect ratio and scales to fit entirely\n * within the parent element's bounding box, plus an optional oversize bleed.\n * This prevents shape masks (star, heart, etc.) from stretching when\n * applied to non-square images, and ensures the full mask shape is visible\n * (no clipping of star points, heart bumps, etc.).\n */\nexport function computeMaskCoverDimensions(\n parentW: number,\n parentH: number,\n maskNaturalW: number,\n maskNaturalH: number,\n oversize: number = 0\n): { width: number; height: number } {\n if (maskNaturalW <= 0 || maskNaturalH <= 0 || parentW <= 0 || parentH <= 0) {\n return { width: parentW + oversize, height: parentH + oversize };\n }\n\n const maskAspect = maskNaturalW / maskNaturalH;\n const parentAspect = parentW / parentH;\n\n let fitW: number;\n let fitH: number;\n\n if (parentAspect > maskAspect) {\n // Parent is wider — constrain by height so mask fits vertically\n fitH = parentH;\n fitW = parentH * maskAspect;\n } else {\n // Parent is taller — constrain by width so mask fits horizontally\n fitW = parentW;\n fitH = parentW / maskAspect;\n }\n\n return {\n width: fitW + oversize,\n height: fitH + oversize,\n };\n}\n\n/**\n * Clone a mask definition\n */\nexport function cloneMask(mask: MaskDefinition): MaskDefinition {\n return {\n ...mask,\n id: `mask-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n maskElement: { ...mask.maskElement },\n };\n}\n\n","/**\n * Built-in mask image presets — procedurally generated SVG shapes\n *\n * Each preset renders an SVG path to a canvas to produce a data URL.\n * The data URL is stored as `imageUrl` and registered with ImageCache\n * so MaskRenderer can find them. A 64x64 thumbnail is also generated.\n */\n\nimport { ImageCache } from '../core/ImageCache.js';\n\n/** Thumbnail size for UI grid */\nconst THUMB_SIZE = 64;\n\n/** Full mask size */\nconst MASK_SIZE = 512;\n\nexport interface MaskImagePreset {\n id: string;\n name: string;\n description: string;\n /** Synthetic key — also used as imageUrl for masks */\n imageUrl: string;\n /** Data URL thumbnail (populated by ensureMaskPresetsReady) */\n thumbnailUrl: string;\n category: 'geometric' | 'organic';\n /** SVG path draw function */\n draw: (ctx: CanvasRenderingContext2D, size: number) => void;\n}\n\n// ── Shape draw functions ────────────────────────────────────────────────────\n\nfunction drawCircle(ctx: CanvasRenderingContext2D, size: number) {\n ctx.beginPath();\n ctx.arc(size / 2, size / 2, size * 0.45, 0, Math.PI * 2);\n ctx.fill();\n}\n\nfunction drawStar(ctx: CanvasRenderingContext2D, size: number) {\n const cx = size / 2, cy = size / 2;\n const outerR = size * 0.45, innerR = outerR * 0.4;\n const points = 5;\n ctx.beginPath();\n for (let i = 0; i < points * 2; i++) {\n const angle = -Math.PI / 2 + (Math.PI / points) * i;\n const r = i % 2 === 0 ? outerR : innerR;\n const x = cx + Math.cos(angle) * r;\n const y = cy + Math.sin(angle) * r;\n if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);\n }\n ctx.closePath();\n ctx.fill();\n}\n\nfunction drawHeart(ctx: CanvasRenderingContext2D, size: number) {\n const cx = size / 2, s = size * 0.42;\n ctx.beginPath();\n ctx.moveTo(cx, size * 0.82);\n ctx.bezierCurveTo(cx - s * 1.1, size * 0.6, cx - s * 1.3, size * 0.2, cx, size * 0.35);\n ctx.bezierCurveTo(cx + s * 1.3, size * 0.2, cx + s * 1.1, size * 0.6, cx, size * 0.82);\n ctx.closePath();\n ctx.fill();\n}\n\nfunction drawDiamond(ctx: CanvasRenderingContext2D, size: number) {\n const cx = size / 2, cy = size / 2;\n const rx = size * 0.4, ry = size * 0.48;\n ctx.beginPath();\n ctx.moveTo(cx, cy - ry);\n ctx.lineTo(cx + rx, cy);\n ctx.lineTo(cx, cy + ry);\n ctx.lineTo(cx - rx, cy);\n ctx.closePath();\n ctx.fill();\n}\n\nfunction drawHexagon(ctx: CanvasRenderingContext2D, size: number) {\n const cx = size / 2, cy = size / 2, r = size * 0.44;\n ctx.beginPath();\n for (let i = 0; i < 6; i++) {\n const angle = -Math.PI / 2 + (Math.PI / 3) * i;\n const x = cx + Math.cos(angle) * r;\n const y = cy + Math.sin(angle) * r;\n if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);\n }\n ctx.closePath();\n ctx.fill();\n}\n\nfunction drawShield(ctx: CanvasRenderingContext2D, size: number) {\n const cx = size / 2, w = size * 0.4, top = size * 0.12;\n ctx.beginPath();\n ctx.moveTo(cx, top);\n ctx.lineTo(cx + w, size * 0.25);\n ctx.lineTo(cx + w, size * 0.55);\n ctx.quadraticCurveTo(cx + w * 0.3, size * 0.8, cx, size * 0.9);\n ctx.quadraticCurveTo(cx - w * 0.3, size * 0.8, cx - w, size * 0.55);\n ctx.lineTo(cx - w, size * 0.25);\n ctx.closePath();\n ctx.fill();\n}\n\nfunction drawSplatter(ctx: CanvasRenderingContext2D, size: number) {\n // Pseudo-random splatter using deterministic seed\n const cx = size / 2, cy = size / 2;\n let seed = 42;\n const rand = () => { seed = (seed * 16807 + 0) % 2147483647; return seed / 2147483647; };\n\n // Main blob\n ctx.beginPath();\n ctx.arc(cx, cy, size * 0.28, 0, Math.PI * 2);\n ctx.fill();\n\n // Splatter droplets\n for (let i = 0; i < 30; i++) {\n const angle = rand() * Math.PI * 2;\n const dist = size * 0.15 + rand() * size * 0.3;\n const r = size * 0.02 + rand() * size * 0.06;\n ctx.beginPath();\n ctx.arc(cx + Math.cos(angle) * dist, cy + Math.sin(angle) * dist, r, 0, Math.PI * 2);\n ctx.fill();\n }\n}\n\nfunction drawTornEdge(ctx: CanvasRenderingContext2D, size: number) {\n let seed = 123;\n const rand = () => { seed = (seed * 16807 + 0) % 2147483647; return seed / 2147483647; };\n\n const margin = size * 0.08;\n const steps = 40;\n ctx.beginPath();\n ctx.moveTo(margin, margin);\n\n // Top edge (jagged)\n for (let i = 1; i <= steps; i++) {\n const x = margin + (size - 2 * margin) * (i / steps);\n const y = margin + (rand() - 0.5) * size * 0.08;\n ctx.lineTo(x, y);\n }\n // Right edge\n for (let i = 1; i <= steps; i++) {\n const x = size - margin + (rand() - 0.5) * size * 0.08;\n const y = margin + (size - 2 * margin) * (i / steps);\n ctx.lineTo(x, y);\n }\n // Bottom edge\n for (let i = steps; i >= 0; i--) {\n const x = margin + (size - 2 * margin) * (i / steps);\n const y = size - margin + (rand() - 0.5) * size * 0.08;\n ctx.lineTo(x, y);\n }\n // Left edge\n for (let i = steps; i >= 0; i--) {\n const x = margin + (rand() - 0.5) * size * 0.08;\n const y = margin + (size - 2 * margin) * (i / steps);\n ctx.lineTo(x, y);\n }\n ctx.closePath();\n ctx.fill();\n}\n\nfunction drawPaintStroke(ctx: CanvasRenderingContext2D, size: number) {\n let seed = 77;\n const rand = () => { seed = (seed * 16807 + 0) % 2147483647; return seed / 2147483647; };\n\n const y0 = size * 0.25, y1 = size * 0.75;\n const margin = size * 0.1;\n\n ctx.beginPath();\n ctx.moveTo(margin, y0 + rand() * size * 0.05);\n // Top contour\n for (let i = 1; i <= 10; i++) {\n const x = margin + (size - 2 * margin) * (i / 10);\n const y = y0 + (rand() - 0.5) * size * 0.1;\n ctx.lineTo(x, y);\n }\n // Bottom contour (backwards)\n for (let i = 10; i >= 0; i--) {\n const x = margin + (size - 2 * margin) * (i / 10);\n const y = y1 + (rand() - 0.5) * size * 0.1;\n ctx.lineTo(x, y);\n }\n ctx.closePath();\n ctx.fill();\n}\n\nfunction drawCloud(ctx: CanvasRenderingContext2D, size: number) {\n const cx = size / 2, cy = size * 0.55;\n // Main body\n ctx.beginPath();\n ctx.arc(cx, cy, size * 0.2, 0, Math.PI * 2);\n ctx.fill();\n // Left bump\n ctx.beginPath();\n ctx.arc(cx - size * 0.18, cy + size * 0.02, size * 0.15, 0, Math.PI * 2);\n ctx.fill();\n // Right bump\n ctx.beginPath();\n ctx.arc(cx + size * 0.18, cy + size * 0.02, size * 0.16, 0, Math.PI * 2);\n ctx.fill();\n // Top bump\n ctx.beginPath();\n ctx.arc(cx - size * 0.06, cy - size * 0.14, size * 0.14, 0, Math.PI * 2);\n ctx.fill();\n ctx.beginPath();\n ctx.arc(cx + size * 0.1, cy - size * 0.12, size * 0.12, 0, Math.PI * 2);\n ctx.fill();\n}\n\n// ── Presets array ───────────────────────────────────────────────────────────\n\nexport const MASK_IMAGE_PRESETS: MaskImagePreset[] = [\n // Geometric\n { id: 'circle', name: 'Circle', description: 'Perfect circle', imageUrl: 'builtin-mask:circle', thumbnailUrl: '', category: 'geometric', draw: drawCircle },\n { id: 'star', name: 'Star', description: '5-pointed star', imageUrl: 'builtin-mask:star', thumbnailUrl: '', category: 'geometric', draw: drawStar },\n { id: 'heart', name: 'Heart', description: 'Heart shape', imageUrl: 'builtin-mask:heart', thumbnailUrl: '', category: 'geometric', draw: drawHeart },\n { id: 'diamond', name: 'Diamond', description: 'Diamond/rhombus', imageUrl: 'builtin-mask:diamond', thumbnailUrl: '', category: 'geometric', draw: drawDiamond },\n { id: 'hexagon', name: 'Hexagon', description: 'Regular hexagon', imageUrl: 'builtin-mask:hexagon', thumbnailUrl: '', category: 'geometric', draw: drawHexagon },\n { id: 'shield', name: 'Shield', description: 'Shield/crest shape', imageUrl: 'builtin-mask:shield', thumbnailUrl: '', category: 'geometric', draw: drawShield },\n // Organic\n { id: 'splatter', name: 'Splatter', description: 'Ink splatter', imageUrl: 'builtin-mask:splatter', thumbnailUrl: '', category: 'organic', draw: drawSplatter },\n { id: 'torn-edge', name: 'Torn Edge', description: 'Rough torn paper edge', imageUrl: 'builtin-mask:torn-edge', thumbnailUrl: '', category: 'organic', draw: drawTornEdge },\n { id: 'paint-stroke', name: 'Paint Stroke', description: 'Horizontal brush stroke', imageUrl: 'builtin-mask:paint-stroke', thumbnailUrl: '', category: 'organic', draw: drawPaintStroke },\n { id: 'cloud', name: 'Cloud', description: 'Soft cloud shape', imageUrl: 'builtin-mask:cloud', thumbnailUrl: '', category: 'organic', draw: drawCloud },\n];\n\n// ── Lazy initialization ─────────────────────────────────────────────────────\n\nlet initialized = false;\n\n/**\n * Create a DOM canvas for toDataURL (returns null in worker/SSR contexts).\n */\nfunction createDOMCanvas(width: number, height: number): HTMLCanvasElement | null {\n if (typeof document === 'undefined') return null;\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\n/**\n * Generate all mask preset images, register in ImageCache, populate thumbnails.\n * Safe to call during render — idempotent and synchronous.\n * Skips silently during SSR (no document), but will run on client.\n */\nexport function ensureMaskPresetsReady(): void {\n // Skip during SSR but don't set initialized — allow client to run\n if (typeof document === 'undefined') return;\n if (initialized) return;\n initialized = true;\n\n const cache = ImageCache.getInstance();\n\n for (const preset of MASK_IMAGE_PRESETS) {\n // Generate full-size mask\n const maskCanvas = createDOMCanvas(MASK_SIZE, MASK_SIZE);\n if (!maskCanvas) continue;\n const maskCtx = maskCanvas.getContext('2d');\n if (!maskCtx) continue;\n\n maskCtx.fillStyle = 'white';\n preset.draw(maskCtx, MASK_SIZE);\n\n // Convert to data URL and preload via ImageCache\n const dataUrl = maskCanvas.toDataURL('image/png');\n\n // Register with ImageCache: acquire with the synthetic key, then load\n const img = cache.acquire(preset.imageUrl);\n img.crossOrigin = 'anonymous';\n img.src = dataUrl;\n // Don't release — keep alive for mask rendering\n\n // Generate 64x64 thumbnail\n const thumbCanvas = createDOMCanvas(THUMB_SIZE, THUMB_SIZE);\n if (thumbCanvas) {\n const thumbCtx = thumbCanvas.getContext('2d');\n if (thumbCtx) {\n // Dark background, white shape\n thumbCtx.fillStyle = '#1a1a2e';\n thumbCtx.fillRect(0, 0, THUMB_SIZE, THUMB_SIZE);\n thumbCtx.fillStyle = 'white';\n preset.draw(thumbCtx, THUMB_SIZE);\n preset.thumbnailUrl = thumbCanvas.toDataURL('image/png');\n }\n }\n }\n}\n\n/**\n * Get a mask preset by ID.\n */\nexport function getMaskPreset(id: string): MaskImagePreset | undefined {\n return MASK_IMAGE_PRESETS.find((p) => p.id === id);\n}\n\n// ── Worker-compatible bitmap generation ─────────────────────────────────────\n\n/**\n * Generate an ImageBitmap for a builtin mask preset.\n * Works in Web Worker contexts (uses OffscreenCanvas, no DOM).\n * Returns null if the preset ID is not found or OffscreenCanvas is unavailable.\n */\nexport function generateMaskBitmap(builtinUrl: string): ImageBitmap | null {\n if (!builtinUrl.startsWith('builtin-mask:')) return null;\n if (typeof OffscreenCanvas === 'undefined') return null;\n\n const id = builtinUrl.replace('builtin-mask:', '');\n const preset = MASK_IMAGE_PRESETS.find((p) => p.id === id);\n if (!preset) return null;\n\n const canvas = new OffscreenCanvas(MASK_SIZE, MASK_SIZE);\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n\n ctx.fillStyle = 'white';\n preset.draw(ctx as unknown as CanvasRenderingContext2D, MASK_SIZE);\n\n return canvas.transferToImageBitmap();\n}\n","/**\n * MaskRenderer - Core mask rendering system\n *\n * Supports 4 mask types:\n * - clip: Hard edge clipping (text, shape)\n * - alpha: Transparency/alpha channel masking\n * - luma: Luminosity-based masking\n * - distress: Texture/grunge masking (HIGH PRIORITY for t-shirt design)\n */\n\nimport type { MaskDefinition, AnyElementConfig, ImageElementConfig, ArtboardImageMask } from '../types/index.js';\nimport { renderElement } from './ElementRenderUtils.js';\nimport { ImageCache } from '../core/ImageCache.js';\nimport { computeMaskCoverDimensions } from './mask-utils.js';\nimport { ensureMaskPresetsReady } from '../effects/mask-presets.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst logger = createLogger('MaskRenderer');\n\n// Mask cache for performance optimization\nconst maskCache = new Map<string, HTMLCanvasElement | OffscreenCanvas>();\n\n// ---------------------------------------------------------------------------\n// Worker Mask Bitmap Registry\n// ---------------------------------------------------------------------------\n// In worker context (no DOM/ImageCache), mask image bitmaps must be\n// pre-loaded and registered here before rendering. The export worker\n// populates this registry before calling renderWithMasks.\n\nconst workerMaskBitmaps = new Map<string, ImageBitmap>();\n\n/**\n * Register a pre-loaded ImageBitmap for a mask image URL.\n * Call from the export worker after fetching mask images.\n */\nexport function registerMaskBitmap(imageUrl: string, bitmap: ImageBitmap): void {\n workerMaskBitmaps.set(imageUrl, bitmap);\n}\n\n/**\n * Clear all registered mask bitmaps (call after export completes).\n */\nexport function clearMaskBitmaps(): void {\n workerMaskBitmaps.clear();\n}\n\n/**\n * Clear mask cache for an element (call when element or masks change)\n */\nexport function invalidateMaskCache(elementId: string): void {\n const keysToDelete: string[] = [];\n maskCache.forEach((_, key) => {\n if (key.startsWith(elementId)) {\n keysToDelete.push(key);\n }\n });\n keysToDelete.forEach((key) => maskCache.delete(key));\n}\n\n/**\n * Clear entire mask cache\n */\nexport function clearMaskCache(): void {\n maskCache.clear();\n}\n\n/**\n * Render element with masks applied\n * This is the main entry point for masked rendering\n */\nexport function renderWithMasks(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n element: AnyElementConfig,\n renderFn: (ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D) => void\n): void {\n\n if (!element.masks || element.masks.length === 0) {\n // No masks, render normally\n renderFn(ctx);\n return;\n }\n\n // Create offscreen canvas for element\n const canvas = ctx.canvas;\n const offscreen = createOffscreenCanvas(canvas.width, canvas.height);\n const offCtx = offscreen.getContext('2d');\n if (!offCtx) {\n logger.error('[renderWithMasks] Failed to get offscreen context');\n return;\n }\n\n\n // Copy transform from main canvas to offscreen canvas (DPR scaling, etc.)\n const transform = ctx.getTransform();\n offCtx.setTransform(transform);\n\n // Render element to offscreen canvas\n renderFn(offCtx);\n\n // Apply each mask in order\n for (const mask of element.masks) {\n applyMask(offCtx, mask, element);\n }\n\n // Composite result back to main canvas\n // Reset transform to identity so we draw at device pixel 0,0\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.drawImage(offscreen as unknown as CanvasImageSource, 0, 0);\n ctx.restore();\n}\n\n/**\n * Apply a single mask to the rendered content\n */\nfunction applyMask(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n mask: MaskDefinition,\n parentElement: AnyElementConfig\n): void {\n switch (mask.type) {\n case 'clip':\n applyClipMask(ctx, mask, parentElement);\n break;\n case 'alpha':\n applyAlphaMask(ctx, mask, parentElement);\n break;\n case 'luma':\n applyLumaMask(ctx, mask, parentElement);\n break;\n case 'distress':\n applyDistressMask(ctx, mask, parentElement);\n break;\n }\n}\n\n/**\n * Apply clip mask (hard edge)\n * Uses destination-in compositing to clip content\n */\nfunction applyClipMask(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n mask: MaskDefinition,\n parentElement: AnyElementConfig\n): void {\n ctx.save();\n ctx.globalCompositeOperation = mask.inverted ? 'destination-out' : 'destination-in';\n\n // Apply mask opacity if specified\n if (mask.opacity !== undefined) {\n ctx.globalAlpha = mask.opacity;\n }\n\n // Render mask element (positioned relative to parent)\n renderMaskElement(ctx, mask.maskElement, parentElement);\n\n ctx.restore();\n}\n\n/**\n * Apply alpha mask (transparency-based)\n * Similar to clip mask but with alpha channel\n */\nfunction applyAlphaMask(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n mask: MaskDefinition,\n parentElement: AnyElementConfig\n): void {\n ctx.save();\n ctx.globalCompositeOperation = mask.inverted ? 'destination-out' : 'destination-in';\n\n // Apply mask opacity\n if (mask.opacity !== undefined) {\n ctx.globalAlpha = mask.opacity;\n }\n\n // Render mask element\n renderMaskElement(ctx, mask.maskElement, parentElement);\n\n // Apply feathering (blur) if specified\n if (mask.feather && mask.feather > 0) {\n applyFeathering(ctx, mask.feather);\n }\n\n ctx.restore();\n}\n\n/**\n * Apply luma mask (luminosity-based)\n * Converts mask to grayscale and uses brightness for opacity\n */\nfunction applyLumaMask(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n mask: MaskDefinition,\n parentElement: AnyElementConfig\n): void {\n // Create offscreen canvas for mask\n const maskCanvas = createOffscreenCanvas(ctx.canvas.width, ctx.canvas.height);\n const maskCtx = maskCanvas.getContext('2d');\n if (!maskCtx) return;\n\n // Render mask element to offscreen\n renderMaskElement(maskCtx, mask.maskElement, parentElement);\n\n // Get image data and convert to luminosity\n const imageData = maskCtx.getImageData(0, 0, maskCanvas.width, maskCanvas.height);\n const data = imageData.data;\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n // Calculate luminosity (perceived brightness)\n const luma = 0.299 * r + 0.587 * g + 0.114 * b;\n\n // Use luminosity as alpha\n data[i + 3] = mask.inverted ? 255 - luma : luma;\n }\n\n maskCtx.putImageData(imageData, 0, 0);\n\n // Apply mask with opacity\n ctx.save();\n ctx.globalCompositeOperation = 'destination-in';\n if (mask.opacity !== undefined) {\n ctx.globalAlpha = mask.opacity;\n }\n ctx.drawImage(maskCanvas as unknown as CanvasImageSource, 0, 0);\n ctx.restore();\n}\n\n/**\n * Apply distress mask (texture-based grunge effect)\n * HIGH PRIORITY for t-shirt design\n */\nfunction applyDistressMask(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n mask: MaskDefinition,\n parentElement: AnyElementConfig\n): void {\n // Distress masks work similar to alpha masks but with texture\n ctx.save();\n ctx.globalCompositeOperation = mask.inverted ? 'destination-in' : 'destination-out';\n\n // Apply mask opacity (strength of distress effect)\n if (mask.opacity !== undefined) {\n ctx.globalAlpha = mask.opacity;\n }\n\n // Render distress texture/pattern\n renderMaskElement(ctx, mask.maskElement, parentElement);\n\n // Apply feathering for softer distress edges\n if (mask.feather && mask.feather > 0) {\n applyFeathering(ctx, mask.feather);\n }\n\n ctx.restore();\n}\n\n/**\n * Render mask element positioned relative to parent.\n *\n * For image-type mask elements, loads the image via ImageCache so it\n * renders actual pixels (not a gray placeholder). This is the key\n * enabler for image-based clip/alpha/luma masks.\n */\nfunction renderMaskElement(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n maskElement: AnyElementConfig,\n parentElement: AnyElementConfig\n): void {\n // Position mask relative to parent element\n const parentX = parentElement.x || 0;\n const parentY = parentElement.y || 0;\n const maskX = maskElement.x || 0;\n const maskY = maskElement.y || 0;\n\n // Create a copy of the mask element with absolute positioning\n // and inherited parent transform (rotation + scale).\n const absoluteMaskElement: AnyElementConfig = {\n ...maskElement,\n x: parentX + maskX,\n y: parentY + maskY,\n // Inherit parent rotation so mask rotates with the element\n rotation: (maskElement.rotation || 0) + (parentElement.rotation || 0),\n };\n\n // Scale mask to match parent dimensions so the mask covers the full element.\n // The mask is rendered 4px larger (2px per side) to prevent anti-aliased\n // edge outlines via destination-in compositing.\n //\n // For image-type masks with a different aspect ratio than the parent,\n // we use object-contain scaling: the mask shape is drawn at its natural\n // proportions centered within the parent-sized area. The transparent\n // padding around the centered shape ensures destination-in clips the\n // image outside the shape.\n const MASK_OVERSIZE = 4;\n const parentTd = (parentElement as ImageElementConfig).transformData;\n const parentAny = parentElement as unknown as Record<string, unknown>;\n const parentW = parentTd?.width || (parentAny.width as number) || 0;\n const parentH = parentTd?.height || (parentAny.height as number) || 0;\n const maskTd = (maskElement as ImageElementConfig).transformData;\n if (parentW && parentH && maskTd) {\n (absoluteMaskElement as ImageElementConfig).transformData = {\n ...maskTd,\n width: parentW + MASK_OVERSIZE,\n height: parentH + MASK_OVERSIZE,\n };\n }\n\n // For image mask elements, resolve the loaded image so renderElement\n // draws real pixels instead of a gray placeholder.\n let loadedImage: HTMLImageElement | undefined;\n let loadedBitmap: ImageBitmap | undefined;\n if (maskElement.transformType === 'image') {\n const imageConfig = maskElement as ImageElementConfig;\n if (imageConfig.imageUrl) {\n if (typeof document !== 'undefined') {\n // Main thread: use ImageCache. For `builtin-mask:*` URLs the\n // ImageCache only holds the rendered shape after\n // `ensureMaskPresetsReady()` has populated it. The mask-picker\n // panel calls that on mount, but a design loaded with masks\n // already attached (e.g. opening an existing design) never\n // triggers the panel — without this lazy init, the mask\n // resolves to an empty cache entry and `renderElement` falls\n // back to a placeholder rectangle, defeating the mask. The\n // export worker generates these bitmaps procedurally via\n // `preloadMaskImages`; this is the main-thread equivalent.\n if (imageConfig.imageUrl.startsWith('builtin-mask:')) {\n ensureMaskPresetsReady();\n }\n const cache = ImageCache.getInstance();\n const img = cache.acquire(imageConfig.imageUrl);\n if (img.complete && img.naturalWidth > 0) {\n loadedImage = img;\n }\n cache.release(imageConfig.imageUrl);\n } else {\n // Worker context: check the pre-loaded mask bitmap registry\n loadedBitmap = workerMaskBitmaps.get(imageConfig.imageUrl);\n }\n }\n }\n\n // Use the (potentially scaled) dimensions from absoluteMaskElement\n const resolvedTd = (absoluteMaskElement as ImageElementConfig).transformData;\n\n // Check if we need object-contain scaling for this mask image.\n // When the mask's natural aspect ratio differs from the parent's,\n // we draw the mask image centered at its natural proportions within\n // the parent-sized area, with transparent padding around it.\n const maskNaturalW = maskTd?.width || 0;\n const maskNaturalH = maskTd?.height || 0;\n const needsContainScaling = maskNaturalW > 0 && maskNaturalH > 0 && parentW > 0 && parentH > 0\n && Math.abs((maskNaturalW / maskNaturalH) - (parentW / parentH)) > 0.001;\n\n if (loadedBitmap) {\n // Worker path: draw the ImageBitmap directly as the mask\n ctx.save();\n const w = resolvedTd?.width || loadedBitmap.width;\n const h = resolvedTd?.height || loadedBitmap.height;\n ctx.translate(absoluteMaskElement.x || 0, absoluteMaskElement.y || 0);\n ctx.rotate((-(absoluteMaskElement.rotation || 0) * Math.PI) / 180);\n if (needsContainScaling) {\n // Object-contain: draw mask at proportional size, centered\n const contain = computeMaskCoverDimensions(\n w, h, maskNaturalW, maskNaturalH, 0\n );\n ctx.drawImage(loadedBitmap, -contain.width / 2, -contain.height / 2, contain.width, contain.height);\n } else {\n ctx.drawImage(loadedBitmap, -w / 2, -h / 2, w, h);\n }\n ctx.restore();\n } else if (needsContainScaling && loadedImage) {\n // Main thread path with contain scaling: draw the mask image manually\n // at its natural proportions centered within the parent-sized area.\n const w = resolvedTd?.width || parentW;\n const h = resolvedTd?.height || parentH;\n const contain = computeMaskCoverDimensions(\n w, h, maskNaturalW, maskNaturalH, 0\n );\n ctx.save();\n ctx.translate(absoluteMaskElement.x || 0, absoluteMaskElement.y || 0);\n ctx.rotate((-(absoluteMaskElement.rotation || 0) * Math.PI) / 180);\n ctx.drawImage(loadedImage, -contain.width / 2, -contain.height / 2, contain.width, contain.height);\n ctx.restore();\n } else {\n // Main thread path (or fallback): use renderElement with loadedImage\n renderElement(ctx, absoluteMaskElement, { mode: 'both', loadedImage });\n }\n}\n\n/**\n * Apply feathering (blur) to mask edges\n * Only works in regular CanvasRenderingContext2D (not OffscreenCanvas in workers)\n */\nfunction applyFeathering(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n featherRadius: number\n): void {\n // Feathering via CSS filter only works in main thread canvas context\n if ('filter' in ctx) {\n (ctx as CanvasRenderingContext2D).filter = `blur(${featherRadius}px)`;\n }\n}\n\n/**\n * Create offscreen canvas for mask rendering\n */\nfunction createOffscreenCanvas(width: number, height: number): HTMLCanvasElement | OffscreenCanvas {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n } else if (typeof document !== 'undefined') {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n throw new Error('No canvas context available');\n}\n\n/**\n * Apply artboard-level image mask.\n *\n * Same algorithm as applyArtboardDistressTexture in DistressTextureRenderer.ts:\n * only masks element pixels — artboard background stays solid.\n *\n * Algorithm:\n * 1. Copy the artboard region to an offscreen canvas\n * 2. Load mask image from ImageCache\n * 3. Apply composite op based on maskType + inverted\n * 4. Clear + redraw background + draw masked result\n */\nexport function applyArtboardImageMask(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n config: ArtboardImageMask,\n artboard: { x: number; y: number; width: number; height: number },\n artboardBackgroundColor?: string\n): void {\n if (!config.enabled || !config.imageUrl || config.opacity <= 0) return;\n\n // Load the mask image from ImageCache\n const cache = ImageCache.getInstance();\n const img = cache.acquire(config.imageUrl);\n if (!img.complete || img.naturalWidth === 0) {\n cache.release(config.imageUrl);\n return; // Still loading — will render next frame\n }\n\n const { x, y, width, height } = artboard;\n\n // Get the current transform to handle DPR + zoom correctly\n const transform = ctx.getTransform();\n\n // Calculate the pixel-space bounds of the artboard\n const pixelX = transform.a * x + transform.e;\n const pixelY = transform.d * y + transform.f;\n const pixelWidth = transform.a * width;\n const pixelHeight = transform.d * height;\n\n const offWidth = Math.ceil(pixelWidth);\n const offHeight = Math.ceil(pixelHeight);\n if (offWidth <= 0 || offHeight <= 0) {\n cache.release(config.imageUrl);\n return;\n }\n\n const offCanvas = createOffscreenCanvas(offWidth, offHeight);\n const offCtx = offCanvas.getContext('2d') as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n if (!offCtx) {\n cache.release(config.imageUrl);\n return;\n }\n\n // Copy the artboard region from the main canvas\n offCtx.drawImage(\n ctx.canvas,\n pixelX, pixelY, pixelWidth, pixelHeight,\n 0, 0, offWidth, offHeight\n );\n\n // Determine composite operation\n let compositeOp: GlobalCompositeOperation;\n if (config.maskType === 'luma') {\n // Luma needs pixel-level processing; handled below\n compositeOp = 'destination-in';\n } else {\n // clip and alpha both use destination-in/destination-out\n compositeOp = config.inverted ? 'destination-out' : 'destination-in';\n }\n\n if (config.maskType === 'luma') {\n // Luma: convert mask to grayscale alpha, then composite\n const lumaCanvas = createOffscreenCanvas(offWidth, offHeight);\n const lumaCtx = lumaCanvas.getContext('2d') as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n if (lumaCtx) {\n lumaCtx.drawImage(img, 0, 0, offWidth, offHeight);\n const imageData = lumaCtx.getImageData(0, 0, offWidth, offHeight);\n const data = imageData.data;\n for (let i = 0; i < data.length; i += 4) {\n const luma = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2];\n data[i + 3] = config.inverted ? 255 - luma : luma;\n }\n lumaCtx.putImageData(imageData, 0, 0);\n\n offCtx.globalCompositeOperation = 'destination-in';\n offCtx.globalAlpha = config.opacity / 100;\n offCtx.drawImage(lumaCanvas as unknown as CanvasImageSource, 0, 0);\n }\n } else {\n offCtx.globalCompositeOperation = compositeOp;\n offCtx.globalAlpha = config.opacity / 100;\n offCtx.drawImage(img, 0, 0, offWidth, offHeight);\n }\n\n offCtx.globalCompositeOperation = 'source-over';\n offCtx.globalAlpha = 1;\n\n // Clear the artboard region on main canvas\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(pixelX, pixelY, pixelWidth, pixelHeight);\n\n // Redraw the artboard background so mask only affects elements\n if (artboardBackgroundColor) {\n ctx.fillStyle = artboardBackgroundColor;\n ctx.fillRect(pixelX, pixelY, pixelWidth, pixelHeight);\n }\n\n // Draw masked result on top\n ctx.drawImage(offCanvas, pixelX, pixelY);\n ctx.restore();\n\n cache.release(config.imageUrl);\n}\n","/**\n * DistressGenerator - Procedural distress texture generation\n * HIGH PRIORITY for t-shirt design\n *\n * Generates vintage/grunge effects:\n * - Worn: Perlin noise + edge wear\n * - Cracked: Crack/fracture patterns\n * - Grunge: Heavy texture overlay\n * - Retro: Halftone + fade effects\n */\n\nimport type { DistressEffect } from '../types/index.js';\n\n/**\n * Simple Perlin noise implementation\n * Used for organic distress patterns\n */\nclass SimplexNoise {\n private perm: number[];\n\n constructor(seed: number = Math.random()) {\n // Generate permutation table based on seed\n this.perm = [];\n for (let i = 0; i < 256; i++) {\n this.perm[i] = i;\n }\n\n // Shuffle using seed\n const random = this.seededRandom(seed);\n for (let i = 255; i > 0; i--) {\n const j = Math.floor(random() * (i + 1));\n [this.perm[i], this.perm[j]] = [this.perm[j], this.perm[i]];\n }\n\n // Extend permutation table\n for (let i = 0; i < 256; i++) {\n this.perm[256 + i] = this.perm[i];\n }\n }\n\n private seededRandom(seed: number): () => number {\n let x = Math.sin(seed++) * 10000;\n return () => {\n x = Math.sin(seed++) * 10000;\n return x - Math.floor(x);\n };\n }\n\n private fade(t: number): number {\n return t * t * t * (t * (t * 6 - 15) + 10);\n }\n\n private lerp(t: number, a: number, b: number): number {\n return a + t * (b - a);\n }\n\n private grad(hash: number, x: number, y: number): number {\n const h = hash & 15;\n const u = h < 8 ? x : y;\n const v = h < 4 ? y : h === 12 || h === 14 ? x : 0;\n return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);\n }\n\n noise(x: number, y: number): number {\n const X = Math.floor(x) & 255;\n const Y = Math.floor(y) & 255;\n\n x -= Math.floor(x);\n y -= Math.floor(y);\n\n const u = this.fade(x);\n const v = this.fade(y);\n\n const a = this.perm[X] + Y;\n const b = this.perm[X + 1] + Y;\n\n return this.lerp(\n v,\n this.lerp(u, this.grad(this.perm[a], x, y), this.grad(this.perm[b], x - 1, y)),\n this.lerp(u, this.grad(this.perm[a + 1], x, y - 1), this.grad(this.perm[b + 1], x - 1, y - 1))\n );\n }\n}\n\n/**\n * Generate worn/vintage distress effect\n * Uses Perlin noise for organic edge wear\n */\nexport function generateWornEffect(\n width: number,\n height: number,\n intensity: number,\n seed: number = Date.now()\n): ImageData {\n const canvas = createCanvas(width, height);\n const ctx = canvas.getContext('2d')!;\n const imageData = ctx.createImageData(width, height);\n const data = imageData.data;\n\n const noise = new SimplexNoise(seed);\n const scale = 0.02; // Noise scale\n const threshold = 1 - intensity / 100; // Higher intensity = more distress\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * 4;\n\n // Generate multi-octave noise for natural look\n let value = 0;\n value += noise.noise(x * scale, y * scale) * 0.5;\n value += noise.noise(x * scale * 2, y * scale * 2) * 0.25;\n value += noise.noise(x * scale * 4, y * scale * 4) * 0.125;\n\n // Normalize to 0-1\n value = (value + 1) / 2;\n\n // Edge wear (more distress at edges)\n const edgeX = Math.min(x / width, (width - x) / width) * 2;\n const edgeY = Math.min(y / height, (height - y) / height) * 2;\n const edgeFactor = Math.min(edgeX, edgeY);\n value *= 0.7 + edgeFactor * 0.3;\n\n // Apply threshold\n const alpha = value > threshold ? 255 : 0;\n\n data[idx] = 255; // R\n data[idx + 1] = 255; // G\n data[idx + 2] = 255; // B\n data[idx + 3] = alpha; // A\n }\n }\n\n return imageData;\n}\n\n/**\n * Generate cracked/fractured distress effect\n * Creates crack patterns using branching algorithm\n */\nexport function generateCrackedEffect(\n width: number,\n height: number,\n intensity: number,\n seed: number = Date.now()\n): ImageData {\n const canvas = createCanvas(width, height);\n const ctx = canvas.getContext('2d')!;\n\n // Clear to transparent\n ctx.clearRect(0, 0, width, height);\n\n // Set up crack drawing\n ctx.strokeStyle = '#000000';\n ctx.lineWidth = 1 + intensity / 50; // Thicker cracks with higher intensity\n ctx.lineCap = 'round';\n\n const random = seededRandom(seed);\n const numCracks = Math.floor((intensity / 100) * 30 + 5); // 5-35 cracks\n\n // Generate multiple crack paths\n for (let i = 0; i < numCracks; i++) {\n const startX = random() * width;\n const startY = random() * height;\n\n drawCrackBranch(ctx, startX, startY, random() * Math.PI * 2, 50 + random() * 100, random, 0);\n }\n\n return ctx.getImageData(0, 0, width, height);\n}\n\n/**\n * Recursively draw crack branch\n */\nfunction drawCrackBranch(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n x: number,\n y: number,\n angle: number,\n length: number,\n random: () => number,\n depth: number\n): void {\n if (depth > 3 || length < 10) return;\n\n const endX = x + Math.cos(angle) * length;\n const endY = y + Math.sin(angle) * length;\n\n ctx.beginPath();\n ctx.moveTo(x, y);\n ctx.lineTo(endX, endY);\n ctx.stroke();\n\n // Random branching\n if (random() > 0.5) {\n const branchAngle = angle + ((random() - 0.5) * Math.PI) / 2;\n drawCrackBranch(ctx, endX, endY, branchAngle, length * 0.6, random, depth + 1);\n }\n\n if (random() > 0.7) {\n const branchAngle = angle - ((random() - 0.5) * Math.PI) / 2;\n drawCrackBranch(ctx, endX, endY, branchAngle, length * 0.6, random, depth + 1);\n }\n}\n\n/**\n * Generate grunge/heavy texture effect\n * Dense noise pattern for heavy distress\n */\nexport function generateGrungeEffect(\n width: number,\n height: number,\n intensity: number,\n seed: number = Date.now()\n): ImageData {\n const canvas = createCanvas(width, height);\n const ctx = canvas.getContext('2d')!;\n const imageData = ctx.createImageData(width, height);\n const data = imageData.data;\n\n const random = seededRandom(seed);\n const density = (intensity / 100) * 0.5; // 0-50% density\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * 4;\n\n // Random splatters\n const value = random();\n const alpha = value < density ? 255 : 0;\n\n data[idx] = 0; // R (black)\n data[idx + 1] = 0; // G\n data[idx + 2] = 0; // B\n data[idx + 3] = alpha; // A\n }\n }\n\n return imageData;\n}\n\n/**\n * Generate retro/halftone distress effect\n * Dot pattern with fade\n */\nexport function generateRetroEffect(\n width: number,\n height: number,\n intensity: number,\n seed: number = Date.now()\n): ImageData {\n const canvas = createCanvas(width, height);\n const ctx = canvas.getContext('2d')!;\n ctx.fillStyle = '#000000';\n\n const random = seededRandom(seed);\n const dotSize = 4 + (intensity / 100) * 6; // 4-10px dots\n const spacing = dotSize * 2;\n\n // Draw halftone dots with random intensity\n for (let y = 0; y < height; y += spacing) {\n for (let x = 0; x < width; x += spacing) {\n if (random() < intensity / 100) {\n const size = dotSize * (0.5 + random() * 0.5);\n ctx.beginPath();\n ctx.arc(x, y, size / 2, 0, Math.PI * 2);\n ctx.fill();\n }\n }\n }\n\n return ctx.getImageData(0, 0, width, height);\n}\n\n/**\n * Apply distress effect to existing canvas\n * Composites distress onto rendered content\n */\nexport function applyDistressEffect(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n distress: DistressEffect\n): void {\n if (!distress.enabled) return;\n\n const width = ctx.canvas.width;\n const height = ctx.canvas.height;\n const seed = distress.seed || Date.now();\n\n let distressData: ImageData;\n\n // Generate distress pattern based on style\n switch (distress.style) {\n case 'worn':\n distressData = generateWornEffect(width, height, distress.intensity, seed);\n break;\n case 'cracked':\n distressData = generateCrackedEffect(width, height, distress.intensity, seed);\n break;\n case 'grunge':\n distressData = generateGrungeEffect(width, height, distress.intensity, seed);\n break;\n case 'retro':\n distressData = generateRetroEffect(width, height, distress.intensity, seed);\n break;\n default:\n return;\n }\n\n // Create temporary canvas for distress\n const tempCanvas = createCanvas(width, height);\n const tempCtx = tempCanvas.getContext('2d')!;\n tempCtx.putImageData(distressData, 0, 0);\n\n // Apply distress using destination-out to remove pixels\n ctx.save();\n ctx.globalCompositeOperation = 'destination-out';\n ctx.globalAlpha = distress.intensity / 100;\n ctx.drawImage(tempCanvas, 0, 0);\n ctx.restore();\n}\n\n/**\n * Create canvas (works in both main thread and worker)\n */\nfunction createCanvas(width: number, height: number): HTMLCanvasElement | OffscreenCanvas {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n } else if (typeof document !== 'undefined') {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n throw new Error('No canvas context available');\n}\n\n/**\n * Seeded random number generator\n */\nfunction seededRandom(seed: number): () => number {\n let x = Math.sin(seed++) * 10000;\n return () => {\n x = Math.sin(seed++) * 10000;\n return x - Math.floor(x);\n };\n}\n","/**\n * Built-in distress texture presets — procedurally generated\n *\n * Each preset uses generators from DistressGenerator.ts to create\n * textures at runtime. No external JPG files needed.\n *\n * Alpha mask convention: RGB=255 (white), A=opacity of knockout.\n * Dark/opaque pixels knock out design pixels, transparent preserves them.\n */\n\nimport {\n generateWornEffect,\n generateCrackedEffect,\n generateGrungeEffect,\n generateRetroEffect,\n} from './DistressGenerator.js';\nimport { registerAlphaMask } from './DistressTextureCache.js';\n\n/** Fixed seed so textures look the same across sessions */\nconst BUILTIN_SEED = 42;\n\n/** Full texture size */\nconst TEX_SIZE = 512;\n\n/** Thumbnail size for UI grid */\nconst THUMB_SIZE = 64;\n\nexport interface DistressTexturePreset {\n id: string;\n name: string;\n /** Synthetic key used for cache lookup (e.g. \"builtin:grunge-heavy\") */\n textureUrl: string;\n /** Data URL thumbnail (populated by ensureBuiltinTexturesReady) */\n thumbnailUrl: string;\n /** Brief description of the texture style */\n description: string;\n /** Generator function for this preset's texture */\n generate: (w: number, h: number) => ImageData;\n}\n\n/**\n * Convert generator output to alpha mask format.\n * Generators may output black RGB with alpha (grunge, cracked, retro)\n * or white RGB with alpha (worn). This normalizes to white RGB + alpha.\n */\nfunction toAlphaMask(imageData: ImageData): ImageData {\n const data = imageData.data;\n for (let i = 0; i < data.length; i += 4) {\n data[i] = 255; // R\n data[i + 1] = 255; // G\n data[i + 2] = 255; // B\n // A stays as-is\n }\n return imageData;\n}\n\n/**\n * Layer two ImageData arrays together (OR their alpha channels).\n * Both must be the same dimensions.\n */\nfunction layerAlpha(a: ImageData, b: ImageData): ImageData {\n const data = a.data;\n const bData = b.data;\n for (let i = 0; i < data.length; i += 4) {\n // Combine: clamp(a + b) for alpha\n data[i] = 255;\n data[i + 1] = 255;\n data[i + 2] = 255;\n data[i + 3] = Math.min(255, data[i + 3] + bData[i + 3]);\n }\n return a;\n}\n\n/**\n * Built-in distress texture presets.\n */\nexport const DISTRESS_TEXTURE_PRESETS: DistressTexturePreset[] = [\n {\n id: 'grunge-heavy',\n name: 'Heavy Grunge',\n textureUrl: 'builtin:grunge-heavy',\n thumbnailUrl: '',\n description: 'Dense random splatters',\n generate: (w, h) => generateGrungeEffect(w, h, 80, BUILTIN_SEED),\n },\n {\n id: 'grunge-fine',\n name: 'Fine Grunge',\n textureUrl: 'builtin:grunge-fine',\n thumbnailUrl: '',\n description: 'Sparse fine grain',\n generate: (w, h) => generateGrungeEffect(w, h, 25, BUILTIN_SEED + 1),\n },\n {\n id: 'concrete',\n name: 'Concrete',\n textureUrl: 'builtin:concrete',\n thumbnailUrl: '',\n description: 'Rough surface via Perlin noise',\n generate: (w, h) => generateWornEffect(w, h, 55, BUILTIN_SEED + 2),\n },\n {\n id: 'paper',\n name: 'Old Paper',\n textureUrl: 'builtin:paper',\n thumbnailUrl: '',\n description: 'Subtle aging',\n generate: (w, h) => generateWornEffect(w, h, 20, BUILTIN_SEED + 3),\n },\n {\n id: 'rust',\n name: 'Rust',\n textureUrl: 'builtin:rust',\n thumbnailUrl: '',\n description: 'Noise + splatter combined',\n generate: (w, h) => {\n const worn = generateWornEffect(w, h, 45, BUILTIN_SEED + 4);\n const grunge = generateGrungeEffect(w, h, 35, BUILTIN_SEED + 5);\n return layerAlpha(toAlphaMask(worn), toAlphaMask(grunge));\n },\n },\n {\n id: 'scratches',\n name: 'Scratches',\n textureUrl: 'builtin:scratches',\n thumbnailUrl: '',\n description: 'Branching crack lines',\n generate: (w, h) => generateCrackedEffect(w, h, 55, BUILTIN_SEED + 6),\n },\n {\n id: 'halftone',\n name: 'Halftone',\n textureUrl: 'builtin:halftone',\n thumbnailUrl: '',\n description: 'Dot grid pattern',\n generate: (w, h) => generateRetroEffect(w, h, 55, BUILTIN_SEED + 7),\n },\n {\n id: 'spray',\n name: 'Spray Paint',\n textureUrl: 'builtin:spray',\n thumbnailUrl: '',\n description: 'Medium random splatter',\n generate: (w, h) => generateGrungeEffect(w, h, 55, BUILTIN_SEED + 8),\n },\n];\n\n/**\n * Get a texture preset by ID\n */\nexport function getDistressTexturePreset(id: string): DistressTexturePreset | undefined {\n return DISTRESS_TEXTURE_PRESETS.find((p) => p.id === id);\n}\n\n// ---------------------------------------------------------------------------\n// Lazy initialization\n// ---------------------------------------------------------------------------\n\nlet initialized = false;\n\n/**\n * Create a canvas (works in both main thread and worker).\n */\nfunction createCanvas(width: number, height: number): HTMLCanvasElement | OffscreenCanvas {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\n/**\n * Create an HTMLCanvasElement (required for toDataURL).\n * Returns null in worker contexts where document is unavailable.\n */\nfunction createDOMCanvas(width: number, height: number): HTMLCanvasElement | null {\n if (typeof document === 'undefined') return null;\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\n/**\n * Generate a data URL thumbnail from ImageData.\n * Must use HTMLCanvasElement (not OffscreenCanvas) for toDataURL support.\n */\nfunction generateThumbnailDataUrl(imageData: ImageData): string {\n // Convert alpha-mask texture into a grayscale thumbnail:\n // High alpha (texture present) → dark pixels, low alpha → white pixels.\n // This matches how tools like Kittl display texture previews.\n\n // First, scale the full-size texture down to thumbnail size\n const fullCanvas = createDOMCanvas(imageData.width, imageData.height);\n if (!fullCanvas) return '';\n const fullCtx = fullCanvas.getContext('2d');\n if (!fullCtx) return '';\n fullCtx.putImageData(imageData, 0, 0);\n\n const canvas = createDOMCanvas(THUMB_SIZE, THUMB_SIZE);\n if (!canvas) return '';\n const ctx = canvas.getContext('2d');\n if (!ctx) return '';\n\n // Draw scaled-down texture to get the alpha values at thumbnail resolution\n ctx.drawImage(fullCanvas, 0, 0, imageData.width, imageData.height, 0, 0, THUMB_SIZE, THUMB_SIZE);\n\n // Read back pixel data and convert alpha → grayscale\n const thumbData = ctx.getImageData(0, 0, THUMB_SIZE, THUMB_SIZE);\n const pixels = thumbData.data;\n for (let i = 0; i < pixels.length; i += 4) {\n // alpha 0 → white (255), alpha 255 → dark gray (~60)\n const a = pixels[i + 3]!;\n const gray = 255 - Math.round((a / 255) * 195);\n pixels[i] = gray; // R\n pixels[i + 1] = gray; // G\n pixels[i + 2] = gray; // B\n pixels[i + 3] = 255; // Fully opaque\n }\n ctx.putImageData(thumbData, 0, 0);\n\n return canvas.toDataURL('image/png');\n}\n\n/**\n * Lazily generate all built-in textures, register them in the cache,\n * and populate thumbnail data URLs. No-ops on subsequent calls.\n */\nexport function ensureBuiltinTexturesReady(): void {\n if (initialized) return;\n initialized = true;\n\n for (const preset of DISTRESS_TEXTURE_PRESETS) {\n // Generate the full-size texture\n const imageData = preset.generate(TEX_SIZE, TEX_SIZE);\n\n // Convert to alpha mask format (white RGB, keep alpha)\n toAlphaMask(imageData);\n\n // Put into a canvas for the cache\n const maskCanvas = createCanvas(TEX_SIZE, TEX_SIZE);\n const maskCtx = maskCanvas.getContext('2d') as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n if (maskCtx) {\n maskCtx.putImageData(imageData, 0, 0);\n registerAlphaMask(preset.textureUrl, maskCanvas, TEX_SIZE, TEX_SIZE);\n }\n\n // Generate thumbnail data URL (only works in browser context, not worker)\n if (typeof document !== 'undefined') {\n preset.thumbnailUrl = generateThumbnailDataUrl(imageData);\n }\n }\n}\n","/**\n * DistressTextureCache - Loads grayscale JPEG textures and converts them to alpha masks.\n *\n * Dark pixels in the texture → high alpha (will knock out design pixels)\n * Light pixels in the texture → low alpha (will preserve design pixels)\n *\n * Shared between artboard-level and per-element distress texture rendering.\n * Works with both HTMLCanvasElement (preview) and OffscreenCanvas (export worker).\n */\n\n// Circular import: `distress-textures.ts` imports `registerAlphaMask` from\n// here. ES module circularity is fine because we only call this function from\n// inside `getAlphaMask`, not at module init time.\nimport { ensureBuiltinTexturesReady } from './distress-textures.js';\n\ntype CanvasLike = HTMLCanvasElement | OffscreenCanvas;\ntype ContextLike = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\ninterface CacheEntry {\n alphaMask: CanvasLike;\n width: number;\n height: number;\n}\n\n/** URLs currently being loaded (prevents duplicate fetches) */\nconst loadingUrls = new Set<string>();\n\n/** Cached alpha masks keyed by texture URL */\nconst cache = new Map<string, CacheEntry>();\n\n/** Callbacks waiting for a URL to finish loading */\nconst pendingCallbacks = new Map<string, Array<() => void>>();\n\n/**\n * Create an offscreen canvas, preferring OffscreenCanvas when available\n * (required for Web Worker export context).\n */\nfunction createCanvas(width: number, height: number): CanvasLike {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\nfunction getContext(canvas: CanvasLike): ContextLike | null {\n return canvas.getContext('2d') as ContextLike | null;\n}\n\n/**\n * Convert a loaded image's grayscale luminance to an alpha channel.\n * The resulting canvas has:\n * - RGB = white (255,255,255) everywhere\n * - Alpha = inverted luminance (dark source pixels → high alpha → strong knockout)\n *\n * Luminance formula: 0.299R + 0.587G + 0.114B (matches MaskRenderer.applyLumaMask)\n */\nfunction convertToAlphaMask(source: ImageBitmap | HTMLImageElement): CacheEntry {\n const { width, height } = source;\n\n // Draw source image to get pixel data\n const tempCanvas = createCanvas(width, height);\n const tempCtx = getContext(tempCanvas);\n if (!tempCtx) throw new Error('Failed to get 2d context for temp canvas');\n\n tempCtx.drawImage(source, 0, 0);\n const imageData = tempCtx.getImageData(0, 0, width, height);\n const data = imageData.data;\n\n // Convert: luminance → alpha (inverted: dark = high alpha = more knockout)\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n // Standard luminance\n const luma = 0.299 * r + 0.587 * g + 0.114 * b;\n\n // Invert: dark source pixels → high alpha (strong knockout)\n const alpha = 255 - luma;\n\n // Set pixel to white with computed alpha\n data[i] = 255; // R\n data[i + 1] = 255; // G\n data[i + 2] = 255; // B\n data[i + 3] = alpha;\n }\n\n // Write to the alpha mask canvas\n const maskCanvas = createCanvas(width, height);\n const maskCtx = getContext(maskCanvas);\n if (!maskCtx) throw new Error('Failed to get 2d context for mask canvas');\n\n maskCtx.putImageData(imageData, 0, 0);\n\n return { alphaMask: maskCanvas, width, height };\n}\n\n/**\n * Get a cached alpha mask for the given texture URL.\n * Returns the cached canvas synchronously if available, or null if still loading.\n * Automatically starts loading if the URL hasn't been requested before.\n */\nexport function getAlphaMask(url: string): CacheEntry | null {\n // Return cached immediately\n const cached = cache.get(url);\n if (cached) return cached;\n\n // CRITICAL: `builtin:*` URLs are synthetic keys for procedurally-generated\n // textures, NOT real network resources. The distress-picker panel calls\n // `ensureBuiltinTexturesReady()` on mount to populate the cache, but a\n // design loaded with a `builtin:` distress texture already attached (no\n // panel ever opened) leaves the cache empty. Without this lazy init we'd\n // fall through to `loadTexture(url)` → `img.src = \"builtin:grunge-heavy\"`\n // → CORS-blocked browser fetch → `onerror` clears `loadingUrls` → next\n // render frame retries the same failed fetch. The result is a CORS-error\n // spam loop that pegs the editor at single-digit FPS and makes every\n // export wait ~20s for the render loop to settle. Match the same fix\n // shape as `MaskRenderer` lazy-calling `ensureMaskPresetsReady()` for\n // `builtin-mask:*` URLs (canvas/CLAUDE.md gotcha #26).\n if (url.startsWith('builtin:')) {\n ensureBuiltinTexturesReady();\n const post = cache.get(url);\n if (post) return post;\n // If `ensureBuiltinTexturesReady` couldn't populate (e.g. unknown\n // preset name), don't try a network load — there's nothing at that URL.\n return null;\n }\n\n // Already loading — just wait\n if (loadingUrls.has(url)) return null;\n\n // Start loading\n loadingUrls.add(url);\n loadTexture(url);\n\n return null;\n}\n\n/**\n * Get a cached alpha mask synchronously (no auto-loading).\n * Returns null if not cached.\n */\nexport function getAlphaMaskSync(url: string): CacheEntry | null {\n return cache.get(url) ?? null;\n}\n\n/**\n * Preload a texture URL so it's ready when needed.\n * Returns a promise that resolves when the texture is cached.\n */\nexport function preloadTexture(url: string): Promise<void> {\n if (cache.has(url)) return Promise.resolve();\n\n return new Promise<void>((resolve) => {\n if (cache.has(url)) {\n resolve();\n return;\n }\n\n // Register callback\n const callbacks = pendingCallbacks.get(url) || [];\n callbacks.push(resolve);\n pendingCallbacks.set(url, callbacks);\n\n if (!loadingUrls.has(url)) {\n loadingUrls.add(url);\n loadTexture(url);\n }\n });\n}\n\n/**\n * Register an already-loaded ImageBitmap as a distress texture (for worker export).\n */\nexport function registerBitmap(url: string, bitmap: ImageBitmap): void {\n if (cache.has(url)) return;\n const entry = convertToAlphaMask(bitmap);\n cache.set(url, entry);\n notifyPending(url);\n}\n\n/**\n * Register a pre-built alpha mask directly (no luminance conversion).\n * Used by procedural generators that already output white RGB + alpha format.\n */\nexport function registerAlphaMask(key: string, canvas: CanvasLike, width: number, height: number): void {\n if (cache.has(key)) return;\n cache.set(key, { alphaMask: canvas, width, height });\n notifyPending(key);\n}\n\n/**\n * Clear the entire cache (e.g., on project reset).\n */\nexport function clearDistressTextureCache(): void {\n cache.clear();\n loadingUrls.clear();\n pendingCallbacks.clear();\n}\n\n/**\n * Remove a specific URL from the cache.\n */\nexport function invalidateTexture(url: string): void {\n cache.delete(url);\n loadingUrls.delete(url);\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction notifyPending(url: string): void {\n const callbacks = pendingCallbacks.get(url);\n if (callbacks) {\n callbacks.forEach((cb) => cb());\n pendingCallbacks.delete(url);\n }\n}\n\nfunction loadTexture(url: string): void {\n // Use Image element in browser context\n if (typeof document !== 'undefined') {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n const entry = convertToAlphaMask(img);\n cache.set(url, entry);\n loadingUrls.delete(url);\n notifyPending(url);\n };\n img.onerror = () => {\n loadingUrls.delete(url);\n notifyPending(url);\n };\n img.src = url;\n } else {\n // Worker context — use fetch + createImageBitmap\n fetch(url)\n .then((res) => res.blob())\n .then((blob) => createImageBitmap(blob))\n .then((bitmap) => {\n const entry = convertToAlphaMask(bitmap);\n cache.set(url, entry);\n loadingUrls.delete(url);\n notifyPending(url);\n })\n .catch(() => {\n loadingUrls.delete(url);\n notifyPending(url);\n });\n }\n}\n","/**\n * DistressTextureRenderer - Applies image-based distress textures via compositing.\n *\n * Uses grayscale JPEG textures interpreted as alpha masks to knock out\n * design pixels, creating authentic wear/grunge effects.\n *\n * Two scopes:\n * - Artboard-level: Applied after ALL elements render, before UI layers\n * - Per-element: Applied to individual elements within the rendering pipeline\n *\n * Compositing: draws the alpha mask with `destination-out` on an offscreen canvas\n * (same pattern as knockout in CompositingRenderer.ts).\n */\n\nimport type { ArtboardDistressTexture, DistressEffect } from '../types/index.js';\nimport { getAlphaMask } from '../effects/DistressTextureCache.js';\n\ntype CanvasLike = HTMLCanvasElement | OffscreenCanvas;\ntype ContextLike = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\nfunction createOffscreenCanvas(width: number, height: number): CanvasLike {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\n/**\n * Apply artboard-level distress texture.\n *\n * Only knocks out element pixels — the artboard background stays solid.\n *\n * Algorithm:\n * 1. Copy the current artboard region (background + elements) to an offscreen canvas\n * 2. Draw the alpha mask with `destination-out` to knock holes in everything\n * 3. Clear the artboard region on the main canvas\n * 4. Redraw the artboard background color (fills the holes that were in the bg)\n * 5. Draw the distressed result on top (element holes reveal the fresh background)\n */\nexport function applyArtboardDistressTexture(\n ctx: ContextLike,\n config: ArtboardDistressTexture,\n artboard: { x: number; y: number; width: number; height: number },\n artboardBackgroundColor?: string\n): void {\n if (!config.enabled || !config.textureUrl || config.intensity <= 0) return;\n\n const mask = getAlphaMask(config.textureUrl);\n if (!mask) return; // Still loading — will render next frame\n\n const { x, y, width, height } = artboard;\n\n // Get the current transform to handle DPR + zoom correctly\n const transform = ctx.getTransform();\n\n // Calculate the pixel-space bounds of the artboard\n const pixelX = transform.a * x + transform.e;\n const pixelY = transform.d * y + transform.f;\n const pixelWidth = transform.a * width;\n const pixelHeight = transform.d * height;\n\n // Create offscreen canvas at pixel dimensions\n const offWidth = Math.ceil(pixelWidth);\n const offHeight = Math.ceil(pixelHeight);\n if (offWidth <= 0 || offHeight <= 0) return;\n\n const offCanvas = createOffscreenCanvas(offWidth, offHeight);\n const offCtx = offCanvas.getContext('2d') as ContextLike;\n if (!offCtx) return;\n\n // Copy the artboard region from the main canvas\n offCtx.drawImage(\n ctx.canvas,\n pixelX, pixelY, pixelWidth, pixelHeight,\n 0, 0, offWidth, offHeight\n );\n\n // Apply distress via direct pixel manipulation (deterministic nearest-neighbor).\n const artMaskCtx = mask.alphaMask.getContext('2d') as ContextLike | null;\n if (artMaskCtx) {\n const artIntensity = config.intensity / 100;\n const mData = artMaskCtx.getImageData(0, 0, mask.width, mask.height).data;\n const mW = mask.width;\n const mH = mask.height;\n const content = offCtx.getImageData(0, 0, offWidth, offHeight);\n const cData = content.data;\n\n for (let y = 0; y < offHeight; y++) {\n const my = Math.floor((y / offHeight) * mH);\n for (let x = 0; x < offWidth; x++) {\n const mx = Math.floor((x / offWidth) * mW);\n const maskAlpha = mData[(my * mW + mx) * 4 + 3] / 255;\n const ci = (y * offWidth + x) * 4;\n cData[ci + 3] = Math.round(cData[ci + 3] * (1 - maskAlpha * artIntensity));\n }\n }\n offCtx.putImageData(content, 0, 0);\n } else {\n offCtx.globalCompositeOperation = 'destination-out';\n offCtx.globalAlpha = config.intensity / 100;\n offCtx.drawImage(mask.alphaMask, 0, 0, offWidth, offHeight);\n offCtx.globalCompositeOperation = 'source-over';\n }\n offCtx.globalAlpha = 1;\n\n // Clear the artboard region on main canvas\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(pixelX, pixelY, pixelWidth, pixelHeight);\n\n // Redraw the artboard background so distress only affects elements, not the bg\n if (artboardBackgroundColor) {\n ctx.fillStyle = artboardBackgroundColor;\n ctx.fillRect(pixelX, pixelY, pixelWidth, pixelHeight);\n }\n\n // Draw distressed result on top — holes in elements reveal the fresh background\n ctx.drawImage(offCanvas, pixelX, pixelY);\n ctx.restore();\n}\n\n/**\n * Apply per-element distress texture using `destination-out` compositing.\n *\n * Called within the element rendering pipeline when an element has\n * `distressEffect.style === 'custom'` and a `textureUrl`.\n *\n * Works by:\n * 1. Creating an offscreen canvas\n * 2. Rendering the element content via the provided renderFn\n * 3. Drawing the alpha mask with `destination-out` + intensity\n * 4. Drawing the composited result back to the main canvas\n */\nexport function applyElementDistressTexture(\n ctx: ContextLike,\n distress: DistressEffect,\n elementBounds: { x: number; y: number; width: number; height: number },\n renderFn: (offCtx: ContextLike) => void\n): void {\n if (!distress.enabled || distress.style !== 'custom' || !distress.textureUrl) return;\n\n const mask = getAlphaMask(distress.textureUrl);\n if (!mask) {\n // Still loading — render without distress for now\n renderFn(ctx);\n return;\n }\n\n const intensity = distress.textureOpacity ?? (distress.intensity / 100);\n\n // Get the current transform\n const transform = ctx.getTransform();\n\n // Expand bounds to account for rotation and stroke. The provided bounding box\n // is the axis-aligned extent of the *unrotated* content. When the element is\n // rotated, the rendered pixels extend further. The worst case for a rectangle\n // rotated by any angle is the diagonal, so we pad by the difference between\n // the diagonal and the axis-aligned extent, plus extra for strokes.\n const diagonal = Math.sqrt(elementBounds.width ** 2 + elementBounds.height ** 2);\n const extraW = (diagonal - elementBounds.width) / 2;\n const extraH = (diagonal - elementBounds.height) / 2;\n // Add generous stroke padding (elements may have thick strokes)\n const strokePad = 20;\n const padX = extraW + strokePad;\n const padY = extraH + strokePad;\n\n const paddedBounds = {\n x: elementBounds.x - padX,\n y: elementBounds.y - padY,\n width: elementBounds.width + padX * 2,\n height: elementBounds.height + padY * 2,\n };\n\n // Calculate pixel-space bounds (accounting for transform)\n const pixelX = transform.a * paddedBounds.x + transform.e;\n const pixelY = transform.d * paddedBounds.y + transform.f;\n const pixelWidth = transform.a * paddedBounds.width;\n const pixelHeight = transform.d * paddedBounds.height;\n\n const offWidth = Math.ceil(pixelWidth);\n const offHeight = Math.ceil(pixelHeight);\n if (offWidth <= 0 || offHeight <= 0) {\n renderFn(ctx);\n return;\n }\n\n const offCanvas = createOffscreenCanvas(offWidth, offHeight);\n const offCtx = offCanvas.getContext('2d') as ContextLike;\n if (!offCtx) {\n renderFn(ctx);\n return;\n }\n\n // Replicate the main canvas transform, shifted so the padded bounding box\n // top-left maps to (0, 0) in the offscreen canvas. This ensures the render\n // callback (which applies element-relative transforms like translate/rotate)\n // produces pixel-identical output regardless of pan/zoom on the main canvas.\n offCtx.setTransform(\n transform.a, transform.b,\n transform.c, transform.d,\n transform.e - pixelX,\n transform.f - pixelY,\n );\n\n // Render element content into offscreen\n renderFn(offCtx);\n\n // Apply distress via direct pixel manipulation (nearest-neighbor sampling).\n // This is fully deterministic — avoids drawImage scaling interpolation\n // which produces different results across canvas contexts.\n offCtx.setTransform(1, 0, 0, 1, 0, 0);\n const maskCtx = mask.alphaMask.getContext('2d') as ContextLike | null;\n if (maskCtx) {\n const mData = maskCtx.getImageData(0, 0, mask.width, mask.height).data;\n const mW = mask.width;\n const mH = mask.height;\n const content = offCtx.getImageData(0, 0, offWidth, offHeight);\n const cData = content.data;\n\n for (let y = 0; y < offHeight; y++) {\n const my = Math.floor((y / offHeight) * mH);\n for (let x = 0; x < offWidth; x++) {\n const mx = Math.floor((x / offWidth) * mW);\n const maskAlpha = mData[(my * mW + mx) * 4 + 3] / 255;\n const ci = (y * offWidth + x) * 4;\n cData[ci + 3] = Math.round(cData[ci + 3] * (1 - maskAlpha * intensity));\n }\n }\n offCtx.putImageData(content, 0, 0);\n } else {\n // Fallback: use drawImage compositing (may have sub-pixel variance)\n offCtx.globalCompositeOperation = 'destination-out';\n offCtx.globalAlpha = intensity;\n offCtx.drawImage(mask.alphaMask, 0, 0, offWidth, offHeight);\n offCtx.globalCompositeOperation = 'source-over';\n offCtx.globalAlpha = 1;\n }\n\n // Draw composited result back to main canvas\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.drawImage(offCanvas, pixelX, pixelY);\n ctx.restore();\n}\n","/**\n * ElementFactory - Type-safe element creation and deserialization\n * Critical for database persistence and undo/redo functionality\n */\n\nimport type { AnyElementConfig, TransformType } from '../types';\nimport type { BaseElement } from './BaseElement';\nimport { TextElement } from './TextElement';\nimport { CustomTransform } from '../transforms/CustomTransform';\nimport { CircleTransform } from '../transforms/CircleTransform';\nimport { LeanTransform } from '../transforms/LeanTransform';\nimport { ArchTransform } from '../transforms/ArchTransform';\nimport { AscendTransform } from '../transforms/AscendTransform';\nimport { WaveTransform } from '../transforms/WaveTransform';\nimport { FlagTransform } from '../transforms/FlagTransform';\nimport { ImageElement } from './ImageElement';\nimport { GroupElement } from './GroupElement';\nimport { ShapeElement } from './ShapeElement';\nimport { PathElement } from './PathElement';\n\n/**\n * ElementFactory provides type-safe element creation from JSON configurations\n *\n * Benefits:\n * - Type-safe deserialization from database\n * - Exhaustive compile-time checking (TypeScript ensures all cases are covered)\n * - Single source of truth for element construction\n * - Safe undo/redo operations\n *\n * Usage:\n * ```typescript\n * // From database\n * const config = JSON.parse(dbRecord);\n * const element = ElementFactory.createFromJSON(config);\n *\n * // For undo/redo\n * const cloned = ElementFactory.createFromJSON(element.toJSON());\n * ```\n */\nexport class ElementFactory {\n /**\n * Create an element instance from a JSON configuration\n * TypeScript ensures all transform types are handled\n *\n * @param config - Element configuration object\n * @returns BaseElement instance (TextElement, ImageElement, GroupElement, ShapeElement, or PathElement)\n * @throws Error if transform type is unknown\n */\n static createFromJSON(config: AnyElementConfig): BaseElement {\n const { transformType } = config;\n\n switch (transformType) {\n case 'custom':\n return new CustomTransform(config);\n\n case 'distort':\n throw new Error('DistortTransform is not yet implemented');\n\n case 'circle':\n return new CircleTransform(config);\n\n case 'lean':\n return new LeanTransform(config);\n\n case 'arch':\n return new ArchTransform(config);\n\n case 'ascend':\n return new AscendTransform(config);\n\n case 'wave':\n return new WaveTransform(config);\n\n case 'flag':\n return new FlagTransform(config);\n\n case 'image':\n return new ImageElement(config);\n\n case 'group': {\n // Recursively create children as actual instances\n // Cast is safe because createFromJSON returns concrete element types that are all valid children\n const children = (config.children || []).map((childConfig) =>\n ElementFactory.createFromJSON(childConfig) as Parameters<GroupElement['addChild']>[0]\n );\n // Create group with the full config (base props like opacity, blendMode,\n // stroke, masks, name, visible, locked must survive save→load), but with\n // children stripped — they're added below as factory-built instances.\n const { children: _childConfigs, ...groupConfig } = config;\n const group = new GroupElement(groupConfig);\n children.forEach((child) => group.addChild(child));\n return group;\n }\n\n case 'shape':\n return new ShapeElement(config);\n\n case 'path':\n return new PathElement(config);\n\n default:\n // TypeScript ensures this is unreachable if all cases are covered\n // If you get an error here, you forgot to handle a transform type!\n const exhaustiveCheck: never = transformType;\n throw new Error(`Unknown transform type: ${exhaustiveCheck}`);\n }\n }\n\n /**\n * Create multiple elements from an array of JSON configurations\n * Useful for bulk deserialization (e.g., loading a document from DB)\n *\n * @param configs - Array of element configurations\n * @returns Array of BaseElement instances\n */\n static createManyFromJSON(configs: AnyElementConfig[]): BaseElement[] {\n return configs.map((config) => this.createFromJSON(config));\n }\n\n /**\n * Type guard to check if an object is a valid TextElement instance\n * Useful for runtime validation\n *\n * @param obj - Object to check\n * @returns true if obj is a TextElement\n */\n static isTextElement(obj: unknown): obj is TextElement {\n const o = obj as Record<string, unknown>;\n return (\n !!obj &&\n typeof obj === 'object' &&\n typeof o.id === 'string' &&\n typeof o.transformType === 'string' &&\n typeof o.getBoundingBox === 'function' &&\n typeof o.getVisualBoundingBox === 'function' &&\n typeof o.hitTest === 'function' &&\n typeof o.render === 'function' &&\n typeof o.toJSON === 'function' &&\n typeof o.clone === 'function'\n );\n }\n\n /**\n * Validate an element configuration object\n * Returns true if the config has all required properties\n *\n * @param config - Configuration to validate\n * @returns true if valid\n */\n static isValidConfig(config: unknown): config is AnyElementConfig {\n const c = config as Record<string, unknown>;\n return (\n !!config &&\n typeof config === 'object' &&\n typeof c.transformType === 'string' &&\n (c.id === undefined || typeof c.id === 'string')\n );\n }\n\n /**\n * Create a default element of a given type\n * Useful for UI \"Add Element\" buttons\n *\n * @param transformType - Type of transform to create\n * @returns Default element configuration\n */\n static createDefaultConfig(transformType: TransformType): AnyElementConfig {\n const baseConfig = {\n id: `${transformType}-${Date.now()}`,\n x: window.innerWidth / 2,\n y: window.innerHeight / 2,\n rotation: 0,\n };\n\n switch (transformType) {\n case 'custom':\n return {\n ...baseConfig,\n transformType: 'custom',\n text: 'Custom Text',\n transformData: {\n type: 'custom',\n controlPoints: [],\n },\n };\n\n case 'distort':\n return {\n ...baseConfig,\n transformType: 'distort',\n text: 'Distorted Text',\n transformData: {\n type: 'distort',\n },\n };\n\n case 'circle':\n return {\n ...baseConfig,\n transformType: 'circle',\n text: 'Circular Text',\n transformData: {\n type: 'circle',\n radius: 100,\n scale: 1,\n reverse: false,\n },\n };\n\n case 'lean':\n return {\n ...baseConfig,\n transformType: 'lean',\n text: 'Leaning Text',\n transformData: {\n type: 'lean',\n leanAmount: 0,\n },\n };\n\n case 'arch':\n return {\n ...baseConfig,\n transformType: 'arch',\n text: 'Arched Text',\n transformData: {\n type: 'arch',\n archHeight: 0.5,\n },\n };\n\n case 'ascend':\n return {\n ...baseConfig,\n transformType: 'ascend',\n text: 'Ascending Text',\n transformData: {\n type: 'ascend',\n ascendAngle: -15,\n },\n };\n\n case 'wave':\n return {\n ...baseConfig,\n transformType: 'wave',\n text: 'Wavy Text',\n transformData: {\n type: 'wave',\n amplitude: 0.5,\n frequency: 2,\n },\n };\n\n case 'flag':\n return {\n ...baseConfig,\n transformType: 'flag',\n text: 'Flag Text',\n transformData: {\n type: 'flag',\n amplitude: 0.5,\n frequency: 2,\n },\n };\n\n case 'image':\n return {\n ...baseConfig,\n transformType: 'image',\n imageUrl: '',\n transformData: {\n type: 'image',\n width: 200,\n height: 200,\n cropX: 0,\n cropY: 0,\n cropWidth: 1,\n cropHeight: 1,\n flipHorizontal: false,\n flipVertical: false,\n borderRadius: 0,\n },\n };\n\n case 'group':\n return {\n ...baseConfig,\n transformType: 'group',\n children: [],\n transformData: {\n type: 'group',\n },\n };\n\n case 'shape':\n return {\n ...baseConfig,\n transformType: 'shape',\n transformData: {\n type: 'shape',\n shapeType: 'rectangle',\n width: 200,\n height: 200,\n borderRadius: 0,\n fillColor: '#3b82f6',\n fillOpacity: 1,\n },\n };\n\n case 'path':\n return {\n ...baseConfig,\n transformType: 'path',\n transformData: {\n type: 'path',\n points: [],\n closed: false,\n width: 200,\n height: 200,\n fillEnabled: false,\n fillColor: '#3b82f6',\n fillOpacity: 1,\n strokeEnabled: true,\n strokeColor: '#000000',\n strokeWidth: 2,\n },\n };\n\n case 'artboard':\n throw new Error('Artboards cannot be created via ElementFactory');\n\n default:\n const exhaustiveCheck: never = transformType;\n throw new Error(`Unknown transform type: ${exhaustiveCheck}`);\n }\n }\n\n /**\n * Clone an element by serializing and deserializing\n * Ensures a deep copy with proper class instance\n *\n * @param element - Element to clone\n * @returns Cloned element instance\n */\n static clone(element: BaseElement): BaseElement {\n const json = element.toJSON();\n // Note: toJSON() returns 'type' but we need 'transformType' for createFromJSON\n // Cast through 'any' to handle this mismatch temporarily\n return this.createFromJSON(json as unknown as AnyElementConfig);\n }\n}\n","/**\n * ImportManager - Handles importing workspace from JSON and images\n */\n\nimport { ElementFactory } from '../core/ElementFactory.js';\nimport { ArtboardElement } from '../core/ArtboardElement.js';\nimport type { CanvasDocument } from './ExportManager.js';\nimport type { TextElement } from '../core/TextElement.js';\nimport type { ImageElement } from '../core/ImageElement.js';\nimport type { GroupElement } from '../core/GroupElement.js';\nimport { createLogger } from './logger.js';\n\nconst logger = createLogger('ImportManager');\n\n/** V1 document format (pre-artboard) */\ninterface V1CanvasDocument {\n metadata: { version: string };\n canvas?: { width?: number; height?: number; backgroundColor?: string };\n elements?: Record<string, unknown>[];\n}\n\nexport interface ImportResult {\n success: boolean;\n artboards?: ArtboardElement[];\n elements?: (TextElement | ImageElement | GroupElement)[];\n activeArtboardId?: string | null;\n error?: string;\n}\n\nexport interface ImageImportResult {\n success: boolean;\n dataUrl?: string;\n filename?: string;\n width?: number;\n height?: number;\n error?: string;\n}\n\nexport class ImportManager {\n private static readonly SUPPORTED_VERSIONS = ['1.0.0', '2.0.0'];\n\n /**\n * Import workspace from JSON file\n */\n static async importFromJSON(file: File): Promise<ImportResult> {\n try {\n // Read file as text\n const text = await this.readFileAsText(file);\n\n // Parse JSON\n const document: CanvasDocument = JSON.parse(text);\n\n // Validate structure\n this.validateDocument(document);\n\n // Check version compatibility\n if (!this.SUPPORTED_VERSIONS.includes(document.metadata.version)) {\n throw new Error(\n `Unsupported version: ${document.metadata.version}. ` +\n `Supported versions: ${this.SUPPORTED_VERSIONS.join(', ')}`\n );\n }\n\n // Handle version 1.0.0 (no artboards) - migrate to artboards\n if (document.metadata.version === '1.0.0') {\n return this.migrateV1Document(document as unknown as V1CanvasDocument);\n }\n\n // Deserialize artboards and elements\n const artboards: ArtboardElement[] = [];\n const allElements: (TextElement | ImageElement | GroupElement)[] = [];\n\n document.artboards.forEach((artboardData) => {\n // Create artboard\n const artboard = ArtboardElement.fromJSON({\n id: artboardData.id,\n name: artboardData.name,\n x: artboardData.x,\n y: artboardData.y,\n width: artboardData.width,\n height: artboardData.height,\n backgroundColor: artboardData.backgroundColor,\n elementIds: artboardData.elements.map((e) => e.id || ''),\n });\n\n // Deserialize elements for this artboard\n const elements = artboardData.elements\n .map((elementConfig) => {\n try {\n return ElementFactory.createFromJSON(elementConfig);\n } catch (error) {\n logger.error('Failed to create element:', elementConfig, error);\n return null;\n }\n })\n .filter((element) => element !== null) as (TextElement | ImageElement | GroupElement)[];\n\n artboards.push(artboard);\n allElements.push(...elements);\n });\n\n // PERFORMANCE: Wait for all images to load in parallel before returning\n await this.preloadAllImages(allElements);\n\n return {\n success: true,\n artboards,\n elements: allElements,\n activeArtboardId: document.activeArtboardId,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Migrate v1 document (no artboards) to v2 (with artboards)\n */\n private static async migrateV1Document(document: V1CanvasDocument): Promise<ImportResult> {\n try {\n // V1 format: { metadata, canvas, elements }\n const elements = document.elements || [];\n\n // Create a default artboard containing all elements\n const artboard = new ArtboardElement({\n id: 'artboard-migrated',\n name: 'Artboard 1',\n x: 0,\n y: 0,\n width: document.canvas?.width || 1920,\n height: document.canvas?.height || 1080,\n backgroundColor: document.canvas?.backgroundColor || '#ffffff',\n });\n\n // Deserialize elements\n const deserializedElements = elements\n .map((elementConfig: Record<string, unknown>) => {\n try {\n return ElementFactory.createFromJSON(elementConfig as unknown as import('../types/index.js').AnyElementConfig);\n } catch (error) {\n logger.error('Failed to create element:', elementConfig, error);\n return null;\n }\n })\n .filter((element): element is TextElement | ImageElement | GroupElement => element !== null);\n\n // Add all element IDs to artboard\n deserializedElements.forEach((element) => {\n artboard.addElementId(element.id);\n });\n\n // PERFORMANCE: Wait for all images to load in parallel before returning\n await this.preloadAllImages(deserializedElements);\n\n return {\n success: true,\n artboards: [artboard],\n elements: deserializedElements,\n activeArtboardId: artboard.id,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Migration failed',\n };\n }\n }\n\n /**\n * Import image file\n */\n static async importImage(file: File): Promise<ImageImportResult> {\n try {\n // Validate file type\n if (!file.type.startsWith('image/')) {\n throw new Error('File is not an image');\n }\n\n // Check file size (max 10MB)\n const maxSize = 10 * 1024 * 1024; // 10MB\n if (file.size > maxSize) {\n throw new Error('Image file is too large (max 10MB)');\n }\n\n // Read as data URL\n const dataUrl = await this.readFileAsDataURL(file);\n\n // Get image dimensions\n const { width, height } = await this.getImageDimensions(dataUrl);\n\n return {\n success: true,\n dataUrl,\n filename: file.name,\n width,\n height,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Validate document structure\n */\n private static validateDocument(document: unknown): asserts document is CanvasDocument {\n if (!document || typeof document !== 'object') {\n throw new Error('Invalid document');\n }\n const doc = document as Record<string, unknown>;\n if (!doc.metadata) {\n throw new Error('Missing metadata');\n }\n if (!(doc.metadata as Record<string, unknown>).version) {\n throw new Error('Missing version in metadata');\n }\n if (!doc.artboards && !doc.elements) {\n throw new Error('Missing artboards or elements array');\n }\n if (doc.artboards && !Array.isArray(doc.artboards)) {\n throw new Error('Invalid artboards array');\n }\n }\n\n /**\n * Read file as text\n */\n private static readFileAsText(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => resolve(e.target?.result as string);\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsText(file);\n });\n }\n\n /**\n * Read file as data URL\n */\n private static readFileAsDataURL(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => resolve(e.target?.result as string);\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsDataURL(file);\n });\n }\n\n /**\n * Get image dimensions from data URL\n */\n private static getImageDimensions(dataUrl: string): Promise<{ width: number; height: number }> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n resolve({ width: img.width, height: img.height });\n };\n img.onerror = () => reject(new Error('Failed to load image'));\n img.src = dataUrl;\n });\n }\n\n /**\n * Validate imported data before applying to state\n */\n static validateImportedData(\n artboards: ArtboardElement[],\n elements: (TextElement | ImageElement | GroupElement)[]\n ): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Check for duplicate artboard IDs\n const artboardIds = new Set();\n artboards.forEach((artboard) => {\n if (artboardIds.has(artboard.id)) {\n errors.push(`Duplicate artboard ID: ${artboard.id}`);\n }\n artboardIds.add(artboard.id);\n });\n\n // Check for duplicate element IDs\n const elementIds = new Set();\n elements.forEach((element) => {\n if (elementIds.has(element.id)) {\n errors.push(`Duplicate element ID: ${element.id}`);\n }\n elementIds.add(element.id);\n });\n\n // Validate element-to-artboard references\n artboards.forEach((artboard) => {\n artboard.getElementIds().forEach((elementId: string) => {\n if (!elementIds.has(elementId)) {\n errors.push(`Artboard \"${artboard.name}\" references missing element: ${elementId}`);\n }\n });\n });\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Get import summary (for UI display before confirming)\n */\n static getImportSummary(\n artboards: ArtboardElement[],\n elements: (TextElement | ImageElement | GroupElement)[]\n ): {\n artboardCount: number;\n elementCount: number;\n artboardNames: string[];\n warnings: string[];\n } {\n const validation = this.validateImportedData(artboards, elements);\n\n return {\n artboardCount: artboards.length,\n elementCount: elements.length,\n artboardNames: artboards.map((a) => a.name),\n warnings: validation.errors,\n };\n }\n\n /**\n * Preload all images in parallel for fast artboard switching\n * Recursively finds all ImageElements (including those in groups)\n */\n private static async preloadAllImages(elements: (TextElement | ImageElement | GroupElement)[]): Promise<void> {\n const imageElements: ImageElement[] = [];\n\n // Recursively find all image elements\n const findImages = (el: TextElement | ImageElement | GroupElement) => {\n if (el.transformType === 'image') {\n imageElements.push(el as ImageElement);\n } else if (el.transformType === 'group' && 'children' in el) {\n (el as GroupElement).children.forEach((child) => findImages(child as TextElement | ImageElement | GroupElement));\n }\n };\n\n elements.forEach(findImages);\n\n // Wait for all images to load in parallel\n const loadPromises = imageElements.map((img: ImageElement) => {\n return new Promise<void>((resolve) => {\n if (img.imageLoaded) {\n resolve();\n } else if (img.imageElement) {\n // Image is currently loading\n const imgEl = img.imageElement;\n const onLoad = () => {\n imgEl.removeEventListener('load', onLoad);\n imgEl.removeEventListener('error', onError);\n resolve();\n };\n const onError = () => {\n imgEl.removeEventListener('load', onLoad);\n imgEl.removeEventListener('error', onError);\n resolve(); // Resolve even on error to not block other images\n };\n imgEl.addEventListener('load', onLoad);\n imgEl.addEventListener('error', onError);\n } else {\n resolve();\n }\n });\n });\n\n await Promise.all(loadPromises);\n }\n}\n\nexport default ImportManager;\n","/**\n * Element Serializer - Converts elements to worker-compatible format\n * Handles ImageBitmap registration with the worker for efficient caching.\n *\n * ARCHITECTURE (Worker-Based Caching):\n * The ImageBitmap cache lives in the web worker, not the main thread.\n * This reduces main thread memory by ~50% for image-heavy canvases.\n *\n * Flow:\n * 1. First export: Create ImageBitmap, transfer to worker, worker caches it\n * 2. Later exports: Send only JSON with cache keys, worker looks up cached bitmaps\n *\n * The main thread only tracks WHICH bitmaps have been registered (via registeredBitmapKeys).\n * Actual bitmap memory lives in the worker.\n */\n\nimport type { ArtboardElement } from '../core/ArtboardElement.js';\nimport type { BaseElement } from '../core/BaseElement.js';\nimport { ImageElement } from '../core/ImageElement.js';\nimport { ImageCache } from '../core/ImageCache.js';\nimport type { AnyElementConfig, ImageTransformData, ArtboardDistressTexture, ArtboardImageMask } from '../types/index.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst logger = createLogger('element-serializer');\n\n// ============================================================================\n// Worker Bitmap Registration Tracking\n// ============================================================================\n\n/**\n * Default maximum dimension for image capping (in pixels)\n * Images larger than this on any dimension will be scaled down while preserving aspect ratio.\n * This prevents memory issues with very large images (e.g., 6000x6000 = 144MB per bitmap).\n */\nexport const DEFAULT_MAX_BITMAP_DIMENSION = 4000;\n\n/**\n * Track which bitmap cache keys have been registered with the worker.\n * This is just a Set of keys - the actual bitmaps live in the worker.\n */\nconst registeredBitmapKeys = new Set<string>();\n\n/**\n * Get cache key for an image element\n * Uses element ID and image src to create a unique key\n * Format: \"{elementId}:{srcHash}\"\n */\nexport function getImageCacheKey(elementId: string, imageSrc: string | undefined): string {\n // Use a hash of the src to keep keys manageable\n const srcHash = imageSrc ? hashString(imageSrc) : 'no-src';\n return `${elementId}:${srcHash}`;\n}\n\n/**\n * Simple string hash for cache keys\n */\nfunction hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return hash.toString(36);\n}\n\n/**\n * Clear all registered bitmap keys.\n * Call this when the worker cache is cleared (e.g., on editor exit).\n * The actual bitmap cleanup happens in the worker via 'clear-all-bitmaps' message.\n */\nexport function clearRegisteredBitmapKeys(): void {\n registeredBitmapKeys.clear();\n}\n\n/**\n * Remove a specific element's registration tracking.\n * Call this when an element is removed or its image source changes.\n * The actual bitmap cleanup happens in the worker via 'clear-bitmap' message.\n */\nexport function unregisterElementBitmaps(elementId: string): void {\n // Find and remove any registration entries for this element\n for (const key of registeredBitmapKeys) {\n if (key.startsWith(`${elementId}:`)) {\n registeredBitmapKeys.delete(key);\n }\n }\n}\n\n/**\n * Mark a bitmap as registered with the worker\n */\nexport function markBitmapRegistered(cacheKey: string): void {\n registeredBitmapKeys.add(cacheKey);\n}\n\n/**\n * Check if a bitmap is already registered with the worker\n */\nexport function isBitmapRegistered(cacheKey: string): boolean {\n return registeredBitmapKeys.has(cacheKey);\n}\n\n// ============================================================================\n// Dimension Capping\n// ============================================================================\n\n/**\n * Create an ImageBitmap with dimension capping.\n * If the source image exceeds maxDimension on any side, it will be scaled down\n * while preserving aspect ratio.\n *\n * @param source - HTMLImageElement to create bitmap from\n * @param maxDimension - Maximum allowed dimension (default: 4000px)\n * @returns Promise<ImageBitmap> - The (potentially scaled) ImageBitmap\n */\nexport async function createCappedImageBitmap(\n source: HTMLImageElement,\n maxDimension: number = DEFAULT_MAX_BITMAP_DIMENSION\n): Promise<ImageBitmap> {\n const { naturalWidth, naturalHeight } = source;\n\n // If within limits, create bitmap at full resolution\n if (naturalWidth <= maxDimension && naturalHeight <= maxDimension) {\n return createImageBitmap(source);\n }\n\n // Scale down maintaining aspect ratio\n const scale = maxDimension / Math.max(naturalWidth, naturalHeight);\n const targetWidth = Math.round(naturalWidth * scale);\n const targetHeight = Math.round(naturalHeight * scale);\n\n return createImageBitmap(source, {\n resizeWidth: targetWidth,\n resizeHeight: targetHeight,\n resizeQuality: 'high',\n });\n}\n\n// ============================================================================\n// Legacy API Compatibility\n// ============================================================================\n\n// Callback to clear worker cache - set by WorkerExportManager\nlet workerCacheClearCallback: (() => void) | null = null;\nlet workerElementClearCallback: ((elementId: string) => void) | null = null;\n\n/**\n * Register callbacks for worker cache clearing.\n * Called by WorkerExportManager to enable legacy API to clear worker cache.\n * @internal\n */\nexport function registerWorkerCacheCallbacks(\n clearAll: () => void,\n clearElement: (elementId: string) => void\n): void {\n workerCacheClearCallback = clearAll;\n workerElementClearCallback = clearElement;\n}\n\n/**\n * Unregister callbacks (e.g., when worker terminates).\n * @internal\n */\nexport function unregisterWorkerCacheCallbacks(): void {\n workerCacheClearCallback = null;\n workerElementClearCallback = null;\n}\n\n/**\n * Clear all ImageBitmap caches.\n * This clears both the main thread tracking AND the worker cache (if available).\n * Call this when exiting editor mode to free memory.\n */\nexport function clearImageBitmapCache(): void {\n // Clear main thread tracking\n clearRegisteredBitmapKeys();\n\n // Also clear worker cache if callback is registered\n if (workerCacheClearCallback) {\n workerCacheClearCallback();\n }\n}\n\n/**\n * Remove a specific element's cached bitmaps.\n * This clears both the main thread tracking AND the worker cache (if available).\n * Call this when an element is removed or its image source changes.\n */\nexport function removeFromImageBitmapCache(elementId: string): void {\n // Clear main thread tracking\n unregisterElementBitmaps(elementId);\n\n // Also clear worker cache if callback is registered\n if (workerElementClearCallback) {\n workerElementClearCallback(elementId);\n }\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Serialized artboard data for export\n */\nexport interface SerializedArtboardData {\n id: string;\n name: string;\n width: number;\n height: number;\n backgroundColor: string;\n exportBackground: boolean;\n x: number;\n y: number;\n distressTexture?: ArtboardDistressTexture;\n imageMask?: ArtboardImageMask;\n}\n\n/**\n * Serialized export data sent to worker\n * Note: Images reference worker cache via bitmapCacheKey, not transferred inline\n */\nexport interface SerializedExportData {\n version: string;\n artboard: SerializedArtboardData;\n elements: AnyElementConfig[]; // Serialized element data\n fonts: string[]; // List of fonts used\n}\n\n/**\n * A new bitmap that needs to be registered with the worker\n */\nexport interface NewBitmapRegistration {\n cacheKey: string;\n bitmap: ImageBitmap;\n}\n\n/**\n * Result from serializeForWorkerExport\n */\nexport interface SerializationResult {\n /** Serialized data to send to worker for export */\n data: SerializedExportData;\n /** New bitmaps that need to be registered with worker before export */\n newBitmaps: NewBitmapRegistration[];\n}\n\nexport interface SerializedImageElement {\n id: string;\n type: 'image';\n x: number;\n y: number;\n width: number;\n height: number;\n rotation: number;\n /** Cache key for worker bitmap lookup in format \"{elementId}:{srcHash}\" */\n bitmapCacheKey: string;\n cropX?: number;\n cropY?: number;\n cropWidth?: number;\n cropHeight?: number;\n flipHorizontal?: boolean;\n flipVertical?: boolean;\n borderRadius?: number;\n opacity?: number;\n}\n\n// ============================================================================\n// Serialization Functions\n// ============================================================================\n\n/**\n * Recursively collect fonts from an element and its children.\n * Also checks rich text spans for per-character font families.\n */\nfunction collectFonts(elementJson: AnyElementConfig | Record<string, unknown>, fonts: Set<string>): void {\n // Collect font from this element\n const json = elementJson as Record<string, unknown>;\n if (typeof json.fontFamily === 'string') {\n fonts.add(json.fontFamily);\n }\n\n // Collect fonts from rich text spans (per-character font families)\n if (json.richText && typeof json.richText === 'object') {\n const richText = json.richText as Record<string, unknown>;\n if (richText.spans && Array.isArray(richText.spans)) {\n for (const span of richText.spans) {\n const spanObj = span as Record<string, unknown>;\n if (spanObj.style && typeof spanObj.style === 'object') {\n const style = spanObj.style as Record<string, unknown>;\n if (typeof style.fontFamily === 'string') {\n fonts.add(style.fontFamily);\n }\n }\n }\n }\n }\n\n // Recursively collect fonts from children (groups)\n if (json.children && Array.isArray(json.children)) {\n for (const child of json.children) {\n collectFonts(child as AnyElementConfig, fonts);\n }\n }\n\n // Recursively collect fonts from mask elements\n if (elementJson.masks && Array.isArray(elementJson.masks)) {\n for (const mask of elementJson.masks) {\n if (mask.maskElement) {\n collectFonts(mask.maskElement, fonts);\n }\n }\n }\n}\n\n/**\n * Resolve builtin-mask: URLs in mask elements to data URLs.\n * The ImageCache on the main thread has the generated data URLs for\n * builtin mask presets; replace the synthetic keys so the export worker\n * can fetch them via standard data: URLs.\n */\nfunction resolveMaskImageUrls(masks: unknown[]): unknown[] {\n if (typeof document === 'undefined') return masks; // Skip in worker/SSR\n const cache = ImageCache.getInstance();\n return masks.map((mask: any) => {\n if (!mask?.maskElement || mask.maskElement.transformType !== 'image') return mask;\n const imageUrl = mask.maskElement.imageUrl;\n if (!imageUrl || !imageUrl.startsWith('builtin-mask:')) return mask;\n\n // Resolve the synthetic URL to the actual data URL from ImageCache\n const img = cache.get(imageUrl);\n if (img?.src && img.src.startsWith('data:')) {\n return {\n ...mask,\n maskElement: {\n ...mask.maskElement,\n imageUrl: img.src, // Replace with data URL\n },\n };\n }\n return mask;\n });\n}\n\n/**\n * Serialize artboard and elements for worker export.\n *\n * ARCHITECTURE:\n * - Images are identified by bitmapCacheKey (format: \"{elementId}:{srcHash}\")\n * - If a bitmap is not yet registered with the worker, it's included in newBitmaps\n * - Caller should register newBitmaps with worker before sending export request\n * - Worker looks up bitmaps from its cache by bitmapCacheKey\n *\n * @param artboard - The artboard to export\n * @param elements - All elements in the canvas\n * @param maxBitmapDimension - Optional max dimension for image capping (default: 4000px)\n * @returns SerializationResult with serialized data and any new bitmaps to register\n */\nexport async function serializeForWorkerExport(\n artboard: ArtboardElement,\n elements: BaseElement[],\n maxBitmapDimension: number = DEFAULT_MAX_BITMAP_DIMENSION\n): Promise<SerializationResult> {\n // Filter elements that belong to this artboard\n const artboardElements = elements.filter((el) => artboard.hasElementId(el.id));\n\n const serializedElements: AnyElementConfig[] = [];\n const newBitmaps: NewBitmapRegistration[] = [];\n const fonts = new Set<string>();\n\n // Process each element\n for (const element of artboardElements) {\n // toJSON returns BaseElementConfig; cast to Record for flexible property access\n const json = element.toJSON();\n\n // Collect fonts from text elements (recursively for groups and masks)\n collectFonts(json as unknown as AnyElementConfig, fonts);\n\n // Handle image elements\n if (element instanceof ImageElement && !element.imageElement) {\n // Image hasn't loaded yet — skip it rather than serializing without a bitmap\n logger.warn(`[element-serializer] Skipping image ${element.id}: image not loaded (state: ${element.imageLoadState})`);\n continue;\n }\n if (element instanceof ImageElement && element.imageElement) {\n try {\n const cacheKey = getImageCacheKey(element.id, element.imageUrl);\n const isCached = isBitmapRegistered(cacheKey);\n // Check if bitmap is already registered with worker\n if (!isCached) {\n // Create new bitmap with dimension capping\n const bitmap = await createCappedImageBitmap(element.imageElement, maxBitmapDimension);\n\n // Add to new bitmaps list for registration\n newBitmaps.push({ cacheKey, bitmap });\n\n // Mark as registered (will be confirmed after worker receives it)\n markBitmapRegistered(cacheKey);\n }\n\n // Note: ImageElement stores dimensions in transformData\n const td = (element.transformData || {}) as ImageTransformData;\n const hasMasks = json.masks && (json.masks as unknown[]).length > 0;\n\n // For masked images, use the full frame dimensions — the mask handles\n // clipping, not the crop rectangle. For unmasked images, use visible\n // (cropped) dimensions so the worker draws at the correct on-screen size.\n const visibleWidth = hasMasks ? td.width : td.width * (td.cropWidth ?? 1);\n const visibleHeight = hasMasks ? td.height : td.height * (td.cropHeight ?? 1);\n\n const imageData: SerializedImageElement = {\n id: element.id,\n type: 'image',\n x: element.x,\n y: element.y,\n width: visibleWidth,\n height: visibleHeight,\n rotation: element.rotation || 0,\n bitmapCacheKey: cacheKey,\n };\n\n // Only include crop if it's actually cropped (not the full image)\n // and the element does NOT have masks (masks handle clipping instead).\n // transformData stores crop as fractions (0-1), but drawImage needs pixels\n // Default is cropX=0, cropY=0, cropWidth=1, cropHeight=1 (full image)\n const isCropped = !hasMasks && (td.cropX !== 0 || td.cropY !== 0 || td.cropWidth !== 1 || td.cropHeight !== 1);\n if (isCropped) {\n // We need to get bitmap dimensions for pixel conversion\n // For new bitmaps, we can use the one we just created\n // For cached bitmaps, we need to rely on the original image dimensions\n // Note: The worker will have the actual bitmap dimensions\n const bitmapWidth = element.imageElement.naturalWidth;\n const bitmapHeight = element.imageElement.naturalHeight;\n\n // Apply dimension capping to crop calculations\n let scale = 1;\n if (bitmapWidth > maxBitmapDimension || bitmapHeight > maxBitmapDimension) {\n scale = maxBitmapDimension / Math.max(bitmapWidth, bitmapHeight);\n }\n\n imageData.cropX = td.cropX * bitmapWidth * scale;\n imageData.cropY = td.cropY * bitmapHeight * scale;\n imageData.cropWidth = td.cropWidth * bitmapWidth * scale;\n imageData.cropHeight = td.cropHeight * bitmapHeight * scale;\n }\n\n // Flip and border radius\n if (td.flipHorizontal) imageData.flipHorizontal = td.flipHorizontal;\n if (td.flipVertical) imageData.flipVertical = td.flipVertical;\n if (td.borderRadius) imageData.borderRadius = td.borderRadius;\n if (element.opacity !== undefined) imageData.opacity = element.opacity;\n\n // Include effect properties so the worker can apply distress, masks, and knockout\n // to image elements (same as text elements get via toJSON() spread).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- extending typed image data with dynamic effect properties for worker\n const serializedImage: Record<string, unknown> = imageData as any;\n if (element.distressEffect) serializedImage.distressEffect = { ...element.distressEffect };\n if (json.masks && (json.masks as unknown[]).length > 0) serializedImage.masks = resolveMaskImageUrls(json.masks as unknown[]);\n if (json.blendMode) serializedImage.blendMode = json.blendMode;\n if (json.knockoutParts) serializedImage.knockoutParts = json.knockoutParts;\n\n // Include bounding box for distress/mask positioning in the worker\n if ('getVisualBoundingBox' in element && typeof element.getVisualBoundingBox === 'function') {\n serializedImage._boundingBox = element.getVisualBoundingBox();\n } else if ('getBoundingBox' in element && typeof element.getBoundingBox === 'function') {\n serializedImage._boundingBox = element.getBoundingBox();\n }\n\n serializedElements.push(serializedImage as unknown as AnyElementConfig);\n } catch (error) {\n logger.error(`[element-serializer] Failed to create ImageBitmap for ${json.id}:`, error);\n // Skip this image element\n }\n } else {\n // Text, group, or other elements - serialize with type mapping\n // The worker expects 'type' but toJSON() produces 'transformType'\n const serialized: Record<string, unknown> = {\n ...json,\n type: json.transformType, // Map transformType to type for worker compatibility\n };\n\n // Resolve builtin-mask: URLs in masks to data URLs for the worker\n if (serialized.masks && Array.isArray(serialized.masks) && serialized.masks.length > 0) {\n serialized.masks = resolveMaskImageUrls(serialized.masks);\n }\n\n // Include bounding box for distress/mask rendering in the worker\n // The worker can't call getBoundingBox() so we pre-compute it.\n // Use getVisualBoundingBox() which returns actual rendered pixel extent,\n // not the math bounding box used for resize handles. Transforms like\n // arch/circle/wave extend text well beyond the math bounds.\n if ('getVisualBoundingBox' in element && typeof element.getVisualBoundingBox === 'function') {\n serialized._boundingBox = element.getVisualBoundingBox();\n } else if ('getBoundingBox' in element && typeof element.getBoundingBox === 'function') {\n serialized._boundingBox = element.getBoundingBox();\n }\n\n serializedElements.push(serialized as unknown as AnyElementConfig);\n }\n }\n\n const fontsList = Array.from(fonts);\n\n return {\n data: {\n version: '1.0.0',\n artboard: {\n id: artboard.id,\n name: artboard.name,\n width: artboard.width,\n height: artboard.height,\n backgroundColor: artboard.backgroundColor,\n exportBackground: artboard.exportBackground,\n x: artboard.x,\n y: artboard.y,\n ...(artboard.distressTexture && { distressTexture: { ...artboard.distressTexture } }),\n ...(artboard.imageMask && { imageMask: { ...artboard.imageMask } }),\n },\n elements: serializedElements,\n fonts: fontsList,\n },\n newBitmaps,\n };\n}\n","// AUTO-GENERATED by scripts/bundle-worker.js. Do not edit.\nexport default \"\\\"use strict\\\";\\n(() => {\\n var __create = Object.create;\\n var __defProp = Object.defineProperty;\\n var __getOwnPropDesc = Object.getOwnPropertyDescriptor;\\n var __getOwnPropNames = Object.getOwnPropertyNames;\\n var __getProtoOf = Object.getPrototypeOf;\\n var __hasOwnProp = Object.prototype.hasOwnProperty;\\n var __esm = (fn, res) => function __init() {\\n return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;\\n };\\n var __commonJS = (cb, mod) => function __require() {\\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\\n };\\n var __export = (target, all) => {\\n for (var name in all)\\n __defProp(target, name, { get: all[name], enumerable: true });\\n };\\n var __copyProps = (to, from, except, desc) => {\\n if (from && typeof from === \\\"object\\\" || typeof from === \\\"function\\\") {\\n for (let key of __getOwnPropNames(from))\\n if (!__hasOwnProp.call(to, key) && key !== except)\\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\\n }\\n return to;\\n };\\n var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\\n // If the importer is in node compatibility mode or this is not an ESM\\n // file that has been converted to a CommonJS file using a Babel-\\n // compatible transform (i.e. \\\"__esModule\\\" has not been set), then set\\n // \\\"default\\\" to the CommonJS \\\"module.exports\\\" for node compatibility.\\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \\\"default\\\", { value: mod, enumerable: true }) : target,\\n mod\\n ));\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/DecodeStream.js\\n var ENCODING_MAPPING, DecodeStream;\\n var init_DecodeStream = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/DecodeStream.js\\\"() {\\n ENCODING_MAPPING = {\\n utf16le: \\\"utf-16le\\\",\\n ucs2: \\\"utf-16le\\\",\\n utf16be: \\\"utf-16be\\\"\\n };\\n DecodeStream = class {\\n constructor(buffer) {\\n this.buffer = buffer;\\n this.view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\\n this.pos = 0;\\n this.length = this.buffer.length;\\n }\\n readString(length, encoding = \\\"ascii\\\") {\\n encoding = ENCODING_MAPPING[encoding] || encoding;\\n let buf = this.readBuffer(length);\\n try {\\n let decoder = new TextDecoder(encoding);\\n return decoder.decode(buf);\\n } catch (err) {\\n return buf;\\n }\\n }\\n readBuffer(length) {\\n return this.buffer.slice(this.pos, this.pos += length);\\n }\\n readUInt24BE() {\\n return (this.readUInt16BE() << 8) + this.readUInt8();\\n }\\n readUInt24LE() {\\n return this.readUInt16LE() + (this.readUInt8() << 16);\\n }\\n readInt24BE() {\\n return (this.readInt16BE() << 8) + this.readUInt8();\\n }\\n readInt24LE() {\\n return this.readUInt16LE() + (this.readInt8() << 16);\\n }\\n };\\n DecodeStream.TYPES = {\\n UInt8: 1,\\n UInt16: 2,\\n UInt24: 3,\\n UInt32: 4,\\n Int8: 1,\\n Int16: 2,\\n Int24: 3,\\n Int32: 4,\\n Float: 4,\\n Double: 8\\n };\\n for (let key of Object.getOwnPropertyNames(DataView.prototype)) {\\n if (key.slice(0, 3) === \\\"get\\\") {\\n let type = key.slice(3).replace(\\\"Ui\\\", \\\"UI\\\");\\n if (type === \\\"Float32\\\") {\\n type = \\\"Float\\\";\\n } else if (type === \\\"Float64\\\") {\\n type = \\\"Double\\\";\\n }\\n let bytes = DecodeStream.TYPES[type];\\n DecodeStream.prototype[\\\"read\\\" + type + (bytes === 1 ? \\\"\\\" : \\\"BE\\\")] = function() {\\n const ret = this.view[key](this.pos, false);\\n this.pos += bytes;\\n return ret;\\n };\\n if (bytes !== 1) {\\n DecodeStream.prototype[\\\"read\\\" + type + \\\"LE\\\"] = function() {\\n const ret = this.view[key](this.pos, true);\\n this.pos += bytes;\\n return ret;\\n };\\n }\\n }\\n }\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/EncodeStream.js\\n function stringToUtf16(string, swap) {\\n let buf = new Uint16Array(string.length);\\n for (let i = 0; i < string.length; i++) {\\n let code = string.charCodeAt(i);\\n if (swap) {\\n code = code >> 8 | (code & 255) << 8;\\n }\\n buf[i] = code;\\n }\\n return new Uint8Array(buf.buffer);\\n }\\n function stringToAscii(string) {\\n let buf = new Uint8Array(string.length);\\n for (let i = 0; i < string.length; i++) {\\n buf[i] = string.charCodeAt(i);\\n }\\n return buf;\\n }\\n var textEncoder, isBigEndian, EncodeStream;\\n var init_EncodeStream = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/EncodeStream.js\\\"() {\\n init_DecodeStream();\\n textEncoder = new TextEncoder();\\n isBigEndian = new Uint8Array(new Uint16Array([4660]).buffer)[0] == 18;\\n EncodeStream = class {\\n constructor(buffer) {\\n this.buffer = buffer;\\n this.view = new DataView(this.buffer.buffer, this.buffer.byteOffset, this.buffer.byteLength);\\n this.pos = 0;\\n }\\n writeBuffer(buffer) {\\n this.buffer.set(buffer, this.pos);\\n this.pos += buffer.length;\\n }\\n writeString(string, encoding = \\\"ascii\\\") {\\n let buf;\\n switch (encoding) {\\n case \\\"utf16le\\\":\\n case \\\"utf16-le\\\":\\n case \\\"ucs2\\\":\\n buf = stringToUtf16(string, isBigEndian);\\n break;\\n case \\\"utf16be\\\":\\n case \\\"utf16-be\\\":\\n buf = stringToUtf16(string, !isBigEndian);\\n break;\\n case \\\"utf8\\\":\\n buf = textEncoder.encode(string);\\n break;\\n case \\\"ascii\\\":\\n buf = stringToAscii(string);\\n break;\\n default:\\n throw new Error(`Unsupported encoding: ${encoding}`);\\n }\\n this.writeBuffer(buf);\\n }\\n writeUInt24BE(val) {\\n this.buffer[this.pos++] = val >>> 16 & 255;\\n this.buffer[this.pos++] = val >>> 8 & 255;\\n this.buffer[this.pos++] = val & 255;\\n }\\n writeUInt24LE(val) {\\n this.buffer[this.pos++] = val & 255;\\n this.buffer[this.pos++] = val >>> 8 & 255;\\n this.buffer[this.pos++] = val >>> 16 & 255;\\n }\\n writeInt24BE(val) {\\n if (val >= 0) {\\n this.writeUInt24BE(val);\\n } else {\\n this.writeUInt24BE(val + 16777215 + 1);\\n }\\n }\\n writeInt24LE(val) {\\n if (val >= 0) {\\n this.writeUInt24LE(val);\\n } else {\\n this.writeUInt24LE(val + 16777215 + 1);\\n }\\n }\\n fill(val, length) {\\n if (length < this.buffer.length) {\\n this.buffer.fill(val, this.pos, this.pos + length);\\n this.pos += length;\\n } else {\\n const buf = new Uint8Array(length);\\n buf.fill(val);\\n this.writeBuffer(buf);\\n }\\n }\\n };\\n for (let key of Object.getOwnPropertyNames(DataView.prototype)) {\\n if (key.slice(0, 3) === \\\"set\\\") {\\n let type = key.slice(3).replace(\\\"Ui\\\", \\\"UI\\\");\\n if (type === \\\"Float32\\\") {\\n type = \\\"Float\\\";\\n } else if (type === \\\"Float64\\\") {\\n type = \\\"Double\\\";\\n }\\n let bytes = DecodeStream.TYPES[type];\\n EncodeStream.prototype[\\\"write\\\" + type + (bytes === 1 ? \\\"\\\" : \\\"BE\\\")] = function(value) {\\n this.view[key](this.pos, value, false);\\n this.pos += bytes;\\n };\\n if (bytes !== 1) {\\n EncodeStream.prototype[\\\"write\\\" + type + \\\"LE\\\"] = function(value) {\\n this.view[key](this.pos, value, true);\\n this.pos += bytes;\\n };\\n }\\n }\\n }\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Base.js\\n var Base;\\n var init_Base = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Base.js\\\"() {\\n init_DecodeStream();\\n init_EncodeStream();\\n Base = class {\\n fromBuffer(buffer) {\\n let stream = new DecodeStream(buffer);\\n return this.decode(stream);\\n }\\n toBuffer(value) {\\n let size = this.size(value);\\n let buffer = new Uint8Array(size);\\n let stream = new EncodeStream(buffer);\\n this.encode(stream, value);\\n return buffer;\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Number.js\\n var NumberT, uint8, uint16be, uint16, uint16le, uint24be, uint24, uint24le, uint32be, uint32, uint32le, int8, int16be, int16, int16le, int24be, int24le, int32be, int32, int32le, floatbe, floatle, doublebe, doublele, Fixed, fixed16be, fixed16, fixed16le, fixed32be, fixed32, fixed32le;\\n var init_Number = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Number.js\\\"() {\\n init_DecodeStream();\\n init_Base();\\n NumberT = class extends Base {\\n constructor(type, endian = \\\"BE\\\") {\\n super();\\n this.type = type;\\n this.endian = endian;\\n this.fn = this.type;\\n if (this.type[this.type.length - 1] !== \\\"8\\\") {\\n this.fn += this.endian;\\n }\\n }\\n size() {\\n return DecodeStream.TYPES[this.type];\\n }\\n decode(stream) {\\n return stream[`read${this.fn}`]();\\n }\\n encode(stream, val) {\\n return stream[`write${this.fn}`](val);\\n }\\n };\\n uint8 = new NumberT(\\\"UInt8\\\");\\n uint16be = new NumberT(\\\"UInt16\\\", \\\"BE\\\");\\n uint16 = uint16be;\\n uint16le = new NumberT(\\\"UInt16\\\", \\\"LE\\\");\\n uint24be = new NumberT(\\\"UInt24\\\", \\\"BE\\\");\\n uint24 = uint24be;\\n uint24le = new NumberT(\\\"UInt24\\\", \\\"LE\\\");\\n uint32be = new NumberT(\\\"UInt32\\\", \\\"BE\\\");\\n uint32 = uint32be;\\n uint32le = new NumberT(\\\"UInt32\\\", \\\"LE\\\");\\n int8 = new NumberT(\\\"Int8\\\");\\n int16be = new NumberT(\\\"Int16\\\", \\\"BE\\\");\\n int16 = int16be;\\n int16le = new NumberT(\\\"Int16\\\", \\\"LE\\\");\\n int24be = new NumberT(\\\"Int24\\\", \\\"BE\\\");\\n int24le = new NumberT(\\\"Int24\\\", \\\"LE\\\");\\n int32be = new NumberT(\\\"Int32\\\", \\\"BE\\\");\\n int32 = int32be;\\n int32le = new NumberT(\\\"Int32\\\", \\\"LE\\\");\\n floatbe = new NumberT(\\\"Float\\\", \\\"BE\\\");\\n floatle = new NumberT(\\\"Float\\\", \\\"LE\\\");\\n doublebe = new NumberT(\\\"Double\\\", \\\"BE\\\");\\n doublele = new NumberT(\\\"Double\\\", \\\"LE\\\");\\n Fixed = class extends NumberT {\\n constructor(size, endian, fracBits = size >> 1) {\\n super(`Int${size}`, endian);\\n this._point = 1 << fracBits;\\n }\\n decode(stream) {\\n return super.decode(stream) / this._point;\\n }\\n encode(stream, val) {\\n return super.encode(stream, val * this._point | 0);\\n }\\n };\\n fixed16be = new Fixed(16, \\\"BE\\\");\\n fixed16 = fixed16be;\\n fixed16le = new Fixed(16, \\\"LE\\\");\\n fixed32be = new Fixed(32, \\\"BE\\\");\\n fixed32 = fixed32be;\\n fixed32le = new Fixed(32, \\\"LE\\\");\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/utils.js\\n function resolveLength(length, stream, parent) {\\n let res;\\n if (typeof length === \\\"number\\\") {\\n res = length;\\n } else if (typeof length === \\\"function\\\") {\\n res = length.call(parent, parent);\\n } else if (parent && typeof length === \\\"string\\\") {\\n res = parent[length];\\n } else if (stream && length instanceof NumberT) {\\n res = length.decode(stream);\\n }\\n if (isNaN(res)) {\\n throw new Error(\\\"Not a fixed size\\\");\\n }\\n return res;\\n }\\n var PropertyDescriptor;\\n var init_utils = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/utils.js\\\"() {\\n init_Number();\\n PropertyDescriptor = class {\\n constructor(opts = {}) {\\n this.enumerable = true;\\n this.configurable = true;\\n for (let key in opts) {\\n const val = opts[key];\\n this[key] = val;\\n }\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Array.js\\n var ArrayT;\\n var init_Array = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Array.js\\\"() {\\n init_Base();\\n init_Number();\\n init_utils();\\n ArrayT = class extends Base {\\n constructor(type, length, lengthType = \\\"count\\\") {\\n super();\\n this.type = type;\\n this.length = length;\\n this.lengthType = lengthType;\\n }\\n decode(stream, parent) {\\n let length;\\n const { pos } = stream;\\n const res = [];\\n let ctx = parent;\\n if (this.length != null) {\\n length = resolveLength(this.length, stream, parent);\\n }\\n if (this.length instanceof NumberT) {\\n Object.defineProperties(res, {\\n parent: { value: parent },\\n _startOffset: { value: pos },\\n _currentOffset: { value: 0, writable: true },\\n _length: { value: length }\\n });\\n ctx = res;\\n }\\n if (length == null || this.lengthType === \\\"bytes\\\") {\\n const target = length != null ? stream.pos + length : (parent != null ? parent._length : void 0) ? parent._startOffset + parent._length : stream.length;\\n while (stream.pos < target) {\\n res.push(this.type.decode(stream, ctx));\\n }\\n } else {\\n for (let i = 0, end = length; i < end; i++) {\\n res.push(this.type.decode(stream, ctx));\\n }\\n }\\n return res;\\n }\\n size(array, ctx, includePointers = true) {\\n if (!array) {\\n return this.type.size(null, ctx) * resolveLength(this.length, null, ctx);\\n }\\n let size = 0;\\n if (this.length instanceof NumberT) {\\n size += this.length.size();\\n ctx = { parent: ctx, pointerSize: 0 };\\n }\\n for (let item of array) {\\n size += this.type.size(item, ctx);\\n }\\n if (ctx && includePointers && this.length instanceof NumberT) {\\n size += ctx.pointerSize;\\n }\\n return size;\\n }\\n encode(stream, array, parent) {\\n let ctx = parent;\\n if (this.length instanceof NumberT) {\\n ctx = {\\n pointers: [],\\n startOffset: stream.pos,\\n parent\\n };\\n ctx.pointerOffset = stream.pos + this.size(array, ctx, false);\\n this.length.encode(stream, array.length);\\n }\\n for (let item of array) {\\n this.type.encode(stream, item, ctx);\\n }\\n if (this.length instanceof NumberT) {\\n let i = 0;\\n while (i < ctx.pointers.length) {\\n const ptr = ctx.pointers[i++];\\n ptr.type.encode(stream, ptr.val, ptr.parent);\\n }\\n }\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/LazyArray.js\\n var LazyArray, LazyArrayValue;\\n var init_LazyArray = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/LazyArray.js\\\"() {\\n init_Array();\\n init_Number();\\n init_utils();\\n LazyArray = class extends ArrayT {\\n decode(stream, parent) {\\n const { pos } = stream;\\n const length = resolveLength(this.length, stream, parent);\\n if (this.length instanceof NumberT) {\\n parent = {\\n parent,\\n _startOffset: pos,\\n _currentOffset: 0,\\n _length: length\\n };\\n }\\n const res = new LazyArrayValue(this.type, length, stream, parent);\\n stream.pos += length * this.type.size(null, parent);\\n return res;\\n }\\n size(val, ctx) {\\n if (val instanceof LazyArrayValue) {\\n val = val.toArray();\\n }\\n return super.size(val, ctx);\\n }\\n encode(stream, val, ctx) {\\n if (val instanceof LazyArrayValue) {\\n val = val.toArray();\\n }\\n return super.encode(stream, val, ctx);\\n }\\n };\\n LazyArrayValue = class {\\n constructor(type, length, stream, ctx) {\\n this.type = type;\\n this.length = length;\\n this.stream = stream;\\n this.ctx = ctx;\\n this.base = this.stream.pos;\\n this.items = [];\\n }\\n get(index) {\\n if (index < 0 || index >= this.length) {\\n return void 0;\\n }\\n if (this.items[index] == null) {\\n const { pos } = this.stream;\\n this.stream.pos = this.base + this.type.size(null, this.ctx) * index;\\n this.items[index] = this.type.decode(this.stream, this.ctx);\\n this.stream.pos = pos;\\n }\\n return this.items[index];\\n }\\n toArray() {\\n const result = [];\\n for (let i = 0, end = this.length; i < end; i++) {\\n result.push(this.get(i));\\n }\\n return result;\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Bitfield.js\\n var Bitfield;\\n var init_Bitfield = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Bitfield.js\\\"() {\\n init_Base();\\n Bitfield = class extends Base {\\n constructor(type, flags = []) {\\n super();\\n this.type = type;\\n this.flags = flags;\\n }\\n decode(stream) {\\n const val = this.type.decode(stream);\\n const res = {};\\n for (let i = 0; i < this.flags.length; i++) {\\n const flag = this.flags[i];\\n if (flag != null) {\\n res[flag] = !!(val & 1 << i);\\n }\\n }\\n return res;\\n }\\n size() {\\n return this.type.size();\\n }\\n encode(stream, keys) {\\n let val = 0;\\n for (let i = 0; i < this.flags.length; i++) {\\n const flag = this.flags[i];\\n if (flag != null) {\\n if (keys[flag]) {\\n val |= 1 << i;\\n }\\n }\\n }\\n return this.type.encode(stream, val);\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Boolean.js\\n var init_Boolean = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Boolean.js\\\"() {\\n init_Base();\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Buffer.js\\n var BufferT;\\n var init_Buffer = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Buffer.js\\\"() {\\n init_Base();\\n init_Number();\\n init_utils();\\n BufferT = class extends Base {\\n constructor(length) {\\n super();\\n this.length = length;\\n }\\n decode(stream, parent) {\\n const length = resolveLength(this.length, stream, parent);\\n return stream.readBuffer(length);\\n }\\n size(val, parent) {\\n if (!val) {\\n return resolveLength(this.length, null, parent);\\n }\\n let len = val.length;\\n if (this.length instanceof NumberT) {\\n len += this.length.size();\\n }\\n return len;\\n }\\n encode(stream, buf, parent) {\\n if (this.length instanceof NumberT) {\\n this.length.encode(stream, buf.length);\\n }\\n return stream.writeBuffer(buf);\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Enum.js\\n var init_Enum = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Enum.js\\\"() {\\n init_Base();\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Optional.js\\n var Optional;\\n var init_Optional = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Optional.js\\\"() {\\n init_Base();\\n Optional = class extends Base {\\n constructor(type, condition = true) {\\n super();\\n this.type = type;\\n this.condition = condition;\\n }\\n decode(stream, parent) {\\n let { condition } = this;\\n if (typeof condition === \\\"function\\\") {\\n condition = condition.call(parent, parent);\\n }\\n if (condition) {\\n return this.type.decode(stream, parent);\\n }\\n }\\n size(val, parent) {\\n let { condition } = this;\\n if (typeof condition === \\\"function\\\") {\\n condition = condition.call(parent, parent);\\n }\\n if (condition) {\\n return this.type.size(val, parent);\\n } else {\\n return 0;\\n }\\n }\\n encode(stream, val, parent) {\\n let { condition } = this;\\n if (typeof condition === \\\"function\\\") {\\n condition = condition.call(parent, parent);\\n }\\n if (condition) {\\n return this.type.encode(stream, val, parent);\\n }\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Reserved.js\\n var Reserved;\\n var init_Reserved = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Reserved.js\\\"() {\\n init_Base();\\n init_utils();\\n Reserved = class extends Base {\\n constructor(type, count = 1) {\\n super();\\n this.type = type;\\n this.count = count;\\n }\\n decode(stream, parent) {\\n stream.pos += this.size(null, parent);\\n return void 0;\\n }\\n size(data, parent) {\\n const count = resolveLength(this.count, null, parent);\\n return this.type.size() * count;\\n }\\n encode(stream, val, parent) {\\n return stream.fill(0, this.size(val, parent));\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/String.js\\n function encodingWidth(encoding) {\\n switch (encoding) {\\n case \\\"ascii\\\":\\n case \\\"utf8\\\":\\n return 1;\\n case \\\"utf16le\\\":\\n case \\\"utf16-le\\\":\\n case \\\"utf-16be\\\":\\n case \\\"utf-16le\\\":\\n case \\\"utf16be\\\":\\n case \\\"utf16-be\\\":\\n case \\\"ucs2\\\":\\n return 2;\\n default:\\n return 1;\\n }\\n }\\n function byteLength(string, encoding) {\\n switch (encoding) {\\n case \\\"ascii\\\":\\n return string.length;\\n case \\\"utf8\\\":\\n let len = 0;\\n for (let i = 0; i < string.length; i++) {\\n let c = string.charCodeAt(i);\\n if (c >= 55296 && c <= 56319 && i < string.length - 1) {\\n let c2 = string.charCodeAt(++i);\\n if ((c2 & 64512) === 56320) {\\n c = ((c & 1023) << 10) + (c2 & 1023) + 65536;\\n } else {\\n i--;\\n }\\n }\\n if ((c & 4294967168) === 0) {\\n len++;\\n } else if ((c & 4294965248) === 0) {\\n len += 2;\\n } else if ((c & 4294901760) === 0) {\\n len += 3;\\n } else if ((c & 4292870144) === 0) {\\n len += 4;\\n }\\n }\\n return len;\\n case \\\"utf16le\\\":\\n case \\\"utf16-le\\\":\\n case \\\"utf16be\\\":\\n case \\\"utf16-be\\\":\\n case \\\"ucs2\\\":\\n return string.length * 2;\\n default:\\n throw new Error(\\\"Unknown encoding \\\" + encoding);\\n }\\n }\\n var StringT;\\n var init_String = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/String.js\\\"() {\\n init_Base();\\n init_Number();\\n init_utils();\\n StringT = class extends Base {\\n constructor(length, encoding = \\\"ascii\\\") {\\n super();\\n this.length = length;\\n this.encoding = encoding;\\n }\\n decode(stream, parent) {\\n let length, pos;\\n let { encoding } = this;\\n if (typeof encoding === \\\"function\\\") {\\n encoding = encoding.call(parent, parent) || \\\"ascii\\\";\\n }\\n let width = encodingWidth(encoding);\\n if (this.length != null) {\\n length = resolveLength(this.length, stream, parent);\\n } else {\\n let buffer;\\n ({ buffer, length, pos } = stream);\\n while (pos < length - width + 1 && (buffer[pos] !== 0 || width === 2 && buffer[pos + 1] !== 0)) {\\n pos += width;\\n }\\n length = pos - stream.pos;\\n }\\n const string = stream.readString(length, encoding);\\n if (this.length == null && stream.pos < stream.length) {\\n stream.pos += width;\\n }\\n return string;\\n }\\n size(val, parent) {\\n if (val === void 0 || val === null) {\\n return resolveLength(this.length, null, parent);\\n }\\n let { encoding } = this;\\n if (typeof encoding === \\\"function\\\") {\\n encoding = encoding.call(parent != null ? parent.val : void 0, parent != null ? parent.val : void 0) || \\\"ascii\\\";\\n }\\n if (encoding === \\\"utf16be\\\") {\\n encoding = \\\"utf16le\\\";\\n }\\n let size = byteLength(val, encoding);\\n if (this.length instanceof NumberT) {\\n size += this.length.size();\\n }\\n if (this.length == null) {\\n size += encodingWidth(encoding);\\n }\\n return size;\\n }\\n encode(stream, val, parent) {\\n let { encoding } = this;\\n if (typeof encoding === \\\"function\\\") {\\n encoding = encoding.call(parent != null ? parent.val : void 0, parent != null ? parent.val : void 0) || \\\"ascii\\\";\\n }\\n if (this.length instanceof NumberT) {\\n this.length.encode(stream, byteLength(val, encoding));\\n }\\n stream.writeString(val, encoding);\\n if (this.length == null) {\\n return encodingWidth(encoding) == 2 ? stream.writeUInt16LE(0) : stream.writeUInt8(0);\\n }\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Struct.js\\n var Struct;\\n var init_Struct = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Struct.js\\\"() {\\n init_Base();\\n init_utils();\\n Struct = class extends Base {\\n constructor(fields = {}) {\\n super();\\n this.fields = fields;\\n }\\n decode(stream, parent, length = 0) {\\n const res = this._setup(stream, parent, length);\\n this._parseFields(stream, res, this.fields);\\n if (this.process != null) {\\n this.process.call(res, stream);\\n }\\n return res;\\n }\\n _setup(stream, parent, length) {\\n const res = {};\\n Object.defineProperties(res, {\\n parent: { value: parent },\\n _startOffset: { value: stream.pos },\\n _currentOffset: { value: 0, writable: true },\\n _length: { value: length }\\n });\\n return res;\\n }\\n _parseFields(stream, res, fields) {\\n for (let key in fields) {\\n var val;\\n const type = fields[key];\\n if (typeof type === \\\"function\\\") {\\n val = type.call(res, res);\\n } else {\\n val = type.decode(stream, res);\\n }\\n if (val !== void 0) {\\n if (val instanceof PropertyDescriptor) {\\n Object.defineProperty(res, key, val);\\n } else {\\n res[key] = val;\\n }\\n }\\n res._currentOffset = stream.pos - res._startOffset;\\n }\\n }\\n size(val, parent, includePointers = true) {\\n if (val == null) {\\n val = {};\\n }\\n const ctx = {\\n parent,\\n val,\\n pointerSize: 0\\n };\\n if (this.preEncode != null) {\\n this.preEncode.call(val);\\n }\\n let size = 0;\\n for (let key in this.fields) {\\n const type = this.fields[key];\\n if (type.size != null) {\\n size += type.size(val[key], ctx);\\n }\\n }\\n if (includePointers) {\\n size += ctx.pointerSize;\\n }\\n return size;\\n }\\n encode(stream, val, parent) {\\n let type;\\n if (this.preEncode != null) {\\n this.preEncode.call(val, stream);\\n }\\n const ctx = {\\n pointers: [],\\n startOffset: stream.pos,\\n parent,\\n val,\\n pointerSize: 0\\n };\\n ctx.pointerOffset = stream.pos + this.size(val, ctx, false);\\n for (let key in this.fields) {\\n type = this.fields[key];\\n if (type.encode != null) {\\n type.encode(stream, val[key], ctx);\\n }\\n }\\n let i = 0;\\n while (i < ctx.pointers.length) {\\n const ptr = ctx.pointers[i++];\\n ptr.type.encode(stream, ptr.val, ptr.parent);\\n }\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/VersionedStruct.js\\n var getPath, VersionedStruct;\\n var init_VersionedStruct = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/VersionedStruct.js\\\"() {\\n init_Struct();\\n getPath = (object, pathArray) => {\\n return pathArray.reduce((prevObj, key) => prevObj && prevObj[key], object);\\n };\\n VersionedStruct = class _VersionedStruct extends Struct {\\n constructor(type, versions = {}) {\\n super();\\n this.type = type;\\n this.versions = versions;\\n if (typeof type === \\\"string\\\") {\\n this.versionPath = type.split(\\\".\\\");\\n }\\n }\\n decode(stream, parent, length = 0) {\\n const res = this._setup(stream, parent, length);\\n if (typeof this.type === \\\"string\\\") {\\n res.version = getPath(parent, this.versionPath);\\n } else {\\n res.version = this.type.decode(stream);\\n }\\n if (this.versions.header) {\\n this._parseFields(stream, res, this.versions.header);\\n }\\n const fields = this.versions[res.version];\\n if (fields == null) {\\n throw new Error(`Unknown version ${res.version}`);\\n }\\n if (fields instanceof _VersionedStruct) {\\n return fields.decode(stream, parent);\\n }\\n this._parseFields(stream, res, fields);\\n if (this.process != null) {\\n this.process.call(res, stream);\\n }\\n return res;\\n }\\n size(val, parent, includePointers = true) {\\n let key, type;\\n if (!val) {\\n throw new Error(\\\"Not a fixed size\\\");\\n }\\n if (this.preEncode != null) {\\n this.preEncode.call(val);\\n }\\n const ctx = {\\n parent,\\n val,\\n pointerSize: 0\\n };\\n let size = 0;\\n if (typeof this.type !== \\\"string\\\") {\\n size += this.type.size(val.version, ctx);\\n }\\n if (this.versions.header) {\\n for (key in this.versions.header) {\\n type = this.versions.header[key];\\n if (type.size != null) {\\n size += type.size(val[key], ctx);\\n }\\n }\\n }\\n const fields = this.versions[val.version];\\n if (fields == null) {\\n throw new Error(`Unknown version ${val.version}`);\\n }\\n for (key in fields) {\\n type = fields[key];\\n if (type.size != null) {\\n size += type.size(val[key], ctx);\\n }\\n }\\n if (includePointers) {\\n size += ctx.pointerSize;\\n }\\n return size;\\n }\\n encode(stream, val, parent) {\\n let key, type;\\n if (this.preEncode != null) {\\n this.preEncode.call(val, stream);\\n }\\n const ctx = {\\n pointers: [],\\n startOffset: stream.pos,\\n parent,\\n val,\\n pointerSize: 0\\n };\\n ctx.pointerOffset = stream.pos + this.size(val, ctx, false);\\n if (typeof this.type !== \\\"string\\\") {\\n this.type.encode(stream, val.version);\\n }\\n if (this.versions.header) {\\n for (key in this.versions.header) {\\n type = this.versions.header[key];\\n if (type.encode != null) {\\n type.encode(stream, val[key], ctx);\\n }\\n }\\n }\\n const fields = this.versions[val.version];\\n for (key in fields) {\\n type = fields[key];\\n if (type.encode != null) {\\n type.encode(stream, val[key], ctx);\\n }\\n }\\n let i = 0;\\n while (i < ctx.pointers.length) {\\n const ptr = ctx.pointers[i++];\\n ptr.type.encode(stream, ptr.val, ptr.parent);\\n }\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Pointer.js\\n var Pointer, VoidPointer;\\n var init_Pointer = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/src/Pointer.js\\\"() {\\n init_utils();\\n init_Base();\\n Pointer = class extends Base {\\n constructor(offsetType, type, options = {}) {\\n super();\\n this.offsetType = offsetType;\\n this.type = type;\\n this.options = options;\\n if (this.type === \\\"void\\\") {\\n this.type = null;\\n }\\n if (this.options.type == null) {\\n this.options.type = \\\"local\\\";\\n }\\n if (this.options.allowNull == null) {\\n this.options.allowNull = true;\\n }\\n if (this.options.nullValue == null) {\\n this.options.nullValue = 0;\\n }\\n if (this.options.lazy == null) {\\n this.options.lazy = false;\\n }\\n if (this.options.relativeTo) {\\n if (typeof this.options.relativeTo !== \\\"function\\\") {\\n throw new Error(\\\"relativeTo option must be a function\\\");\\n }\\n this.relativeToGetter = options.relativeTo;\\n }\\n }\\n decode(stream, ctx) {\\n const offset = this.offsetType.decode(stream, ctx);\\n if (offset === this.options.nullValue && this.options.allowNull) {\\n return null;\\n }\\n let relative;\\n switch (this.options.type) {\\n case \\\"local\\\":\\n relative = ctx._startOffset;\\n break;\\n case \\\"immediate\\\":\\n relative = stream.pos - this.offsetType.size();\\n break;\\n case \\\"parent\\\":\\n relative = ctx.parent._startOffset;\\n break;\\n default:\\n var c = ctx;\\n while (c.parent) {\\n c = c.parent;\\n }\\n relative = c._startOffset || 0;\\n }\\n if (this.options.relativeTo) {\\n relative += this.relativeToGetter(ctx);\\n }\\n const ptr = offset + relative;\\n if (this.type != null) {\\n let val = null;\\n const decodeValue = () => {\\n if (val != null) {\\n return val;\\n }\\n const { pos } = stream;\\n stream.pos = ptr;\\n val = this.type.decode(stream, ctx);\\n stream.pos = pos;\\n return val;\\n };\\n if (this.options.lazy) {\\n return new PropertyDescriptor({\\n get: decodeValue\\n });\\n }\\n return decodeValue();\\n } else {\\n return ptr;\\n }\\n }\\n size(val, ctx) {\\n const parent = ctx;\\n switch (this.options.type) {\\n case \\\"local\\\":\\n case \\\"immediate\\\":\\n break;\\n case \\\"parent\\\":\\n ctx = ctx.parent;\\n break;\\n default:\\n while (ctx.parent) {\\n ctx = ctx.parent;\\n }\\n }\\n let { type } = this;\\n if (type == null) {\\n if (!(val instanceof VoidPointer)) {\\n throw new Error(\\\"Must be a VoidPointer\\\");\\n }\\n ({ type } = val);\\n val = val.value;\\n }\\n if (val && ctx) {\\n let size = type.size(val, parent);\\n ctx.pointerSize += size;\\n }\\n return this.offsetType.size();\\n }\\n encode(stream, val, ctx) {\\n let relative;\\n const parent = ctx;\\n if (val == null) {\\n this.offsetType.encode(stream, this.options.nullValue);\\n return;\\n }\\n switch (this.options.type) {\\n case \\\"local\\\":\\n relative = ctx.startOffset;\\n break;\\n case \\\"immediate\\\":\\n relative = stream.pos + this.offsetType.size(val, parent);\\n break;\\n case \\\"parent\\\":\\n ctx = ctx.parent;\\n relative = ctx.startOffset;\\n break;\\n default:\\n relative = 0;\\n while (ctx.parent) {\\n ctx = ctx.parent;\\n }\\n }\\n if (this.options.relativeTo) {\\n relative += this.relativeToGetter(parent.val);\\n }\\n this.offsetType.encode(stream, ctx.pointerOffset - relative);\\n let { type } = this;\\n if (type == null) {\\n if (!(val instanceof VoidPointer)) {\\n throw new Error(\\\"Must be a VoidPointer\\\");\\n }\\n ({ type } = val);\\n val = val.value;\\n }\\n ctx.pointers.push({\\n type,\\n val,\\n parent\\n });\\n return ctx.pointerOffset += type.size(val, parent);\\n }\\n };\\n VoidPointer = class {\\n constructor(type, value) {\\n this.type = type;\\n this.value = value;\\n }\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/index.js\\n var init_restructure = __esm({\\n \\\"../../node_modules/.pnpm/restructure@3.0.2/node_modules/restructure/index.js\\\"() {\\n init_EncodeStream();\\n init_DecodeStream();\\n init_Array();\\n init_LazyArray();\\n init_Bitfield();\\n init_Boolean();\\n init_Buffer();\\n init_Enum();\\n init_Optional();\\n init_Reserved();\\n init_String();\\n init_Struct();\\n init_VersionedStruct();\\n init_utils();\\n init_Number();\\n init_Pointer();\\n }\\n });\\n\\n // ../../node_modules/.pnpm/@swc+helpers@0.5.21/node_modules/@swc/helpers/esm/_define_property.js\\n function _define_property(obj, key, value) {\\n if (key in obj) {\\n Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true });\\n } else obj[key] = value;\\n return obj;\\n }\\n var init_define_property = __esm({\\n \\\"../../node_modules/.pnpm/@swc+helpers@0.5.21/node_modules/@swc/helpers/esm/_define_property.js\\\"() {\\n }\\n });\\n\\n // ../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib/tslib.es6.mjs\\n function __decorate(decorators, target, key, desc) {\\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\\n if (typeof Reflect === \\\"object\\\" && typeof Reflect.decorate === \\\"function\\\") r = Reflect.decorate(decorators, target, key, desc);\\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\\n return c > 3 && r && Object.defineProperty(target, key, r), r;\\n }\\n var init_tslib_es6 = __esm({\\n \\\"../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib/tslib.es6.mjs\\\"() {\\n }\\n });\\n\\n // ../../node_modules/.pnpm/@swc+helpers@0.5.21/node_modules/@swc/helpers/esm/_ts_decorate.js\\n var init_ts_decorate = __esm({\\n \\\"../../node_modules/.pnpm/@swc+helpers@0.5.21/node_modules/@swc/helpers/esm/_ts_decorate.js\\\"() {\\n init_tslib_es6();\\n }\\n });\\n\\n // ../../node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js\\n var require_fast_deep_equal = __commonJS({\\n \\\"../../node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js\\\"(exports, module) {\\n \\\"use strict\\\";\\n module.exports = function equal(a, b) {\\n if (a === b) return true;\\n if (a && b && typeof a == \\\"object\\\" && typeof b == \\\"object\\\") {\\n if (a.constructor !== b.constructor) return false;\\n var length, i, keys;\\n if (Array.isArray(a)) {\\n length = a.length;\\n if (length != b.length) return false;\\n for (i = length; i-- !== 0; )\\n if (!equal(a[i], b[i])) return false;\\n return true;\\n }\\n if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;\\n if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();\\n if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();\\n keys = Object.keys(a);\\n length = keys.length;\\n if (length !== Object.keys(b).length) return false;\\n for (i = length; i-- !== 0; )\\n if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;\\n for (i = length; i-- !== 0; ) {\\n var key = keys[i];\\n if (!equal(a[key], b[key])) return false;\\n }\\n return true;\\n }\\n return a !== a && b !== b;\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js\\n var require_base64_js = __commonJS({\\n \\\"../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js\\\"(exports) {\\n \\\"use strict\\\";\\n exports.byteLength = byteLength2;\\n exports.toByteArray = toByteArray;\\n exports.fromByteArray = fromByteArray;\\n var lookup = [];\\n var revLookup = [];\\n var Arr = typeof Uint8Array !== \\\"undefined\\\" ? Uint8Array : Array;\\n var code = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n for (i = 0, len = code.length; i < len; ++i) {\\n lookup[i] = code[i];\\n revLookup[code.charCodeAt(i)] = i;\\n }\\n var i;\\n var len;\\n revLookup[\\\"-\\\".charCodeAt(0)] = 62;\\n revLookup[\\\"_\\\".charCodeAt(0)] = 63;\\n function getLens(b64) {\\n var len2 = b64.length;\\n if (len2 % 4 > 0) {\\n throw new Error(\\\"Invalid string. Length must be a multiple of 4\\\");\\n }\\n var validLen = b64.indexOf(\\\"=\\\");\\n if (validLen === -1) validLen = len2;\\n var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4;\\n return [validLen, placeHoldersLen];\\n }\\n function byteLength2(b64) {\\n var lens = getLens(b64);\\n var validLen = lens[0];\\n var placeHoldersLen = lens[1];\\n return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;\\n }\\n function _byteLength(b64, validLen, placeHoldersLen) {\\n return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;\\n }\\n function toByteArray(b64) {\\n var tmp;\\n var lens = getLens(b64);\\n var validLen = lens[0];\\n var placeHoldersLen = lens[1];\\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));\\n var curByte = 0;\\n var len2 = placeHoldersLen > 0 ? validLen - 4 : validLen;\\n var i2;\\n for (i2 = 0; i2 < len2; i2 += 4) {\\n tmp = revLookup[b64.charCodeAt(i2)] << 18 | revLookup[b64.charCodeAt(i2 + 1)] << 12 | revLookup[b64.charCodeAt(i2 + 2)] << 6 | revLookup[b64.charCodeAt(i2 + 3)];\\n arr[curByte++] = tmp >> 16 & 255;\\n arr[curByte++] = tmp >> 8 & 255;\\n arr[curByte++] = tmp & 255;\\n }\\n if (placeHoldersLen === 2) {\\n tmp = revLookup[b64.charCodeAt(i2)] << 2 | revLookup[b64.charCodeAt(i2 + 1)] >> 4;\\n arr[curByte++] = tmp & 255;\\n }\\n if (placeHoldersLen === 1) {\\n tmp = revLookup[b64.charCodeAt(i2)] << 10 | revLookup[b64.charCodeAt(i2 + 1)] << 4 | revLookup[b64.charCodeAt(i2 + 2)] >> 2;\\n arr[curByte++] = tmp >> 8 & 255;\\n arr[curByte++] = tmp & 255;\\n }\\n return arr;\\n }\\n function tripletToBase64(num) {\\n return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];\\n }\\n function encodeChunk(uint82, start, end) {\\n var tmp;\\n var output = [];\\n for (var i2 = start; i2 < end; i2 += 3) {\\n tmp = (uint82[i2] << 16 & 16711680) + (uint82[i2 + 1] << 8 & 65280) + (uint82[i2 + 2] & 255);\\n output.push(tripletToBase64(tmp));\\n }\\n return output.join(\\\"\\\");\\n }\\n function fromByteArray(uint82) {\\n var tmp;\\n var len2 = uint82.length;\\n var extraBytes = len2 % 3;\\n var parts = [];\\n var maxChunkLength = 16383;\\n for (var i2 = 0, len22 = len2 - extraBytes; i2 < len22; i2 += maxChunkLength) {\\n parts.push(encodeChunk(uint82, i2, i2 + maxChunkLength > len22 ? len22 : i2 + maxChunkLength));\\n }\\n if (extraBytes === 1) {\\n tmp = uint82[len2 - 1];\\n parts.push(\\n lookup[tmp >> 2] + lookup[tmp << 4 & 63] + \\\"==\\\"\\n );\\n } else if (extraBytes === 2) {\\n tmp = (uint82[len2 - 2] << 8) + uint82[len2 - 1];\\n parts.push(\\n lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + \\\"=\\\"\\n );\\n }\\n return parts.join(\\\"\\\");\\n }\\n }\\n });\\n\\n // ../../node_modules/.pnpm/tiny-inflate@1.0.3/node_modules/tiny-inflate/index.js\\n var require_tiny_inflate = __commonJS({\\n \\\"../../node_modules/.pnpm/tiny-inflate@1.0.3/node_modules/tiny-inflate/index.js\\\"(exports, module) {\\n var TINF_OK = 0;\\n var TINF_DATA_ERROR = -3;\\n function Tree() {\\n this.table = new Uint16Array(16);\\n this.trans = new Uint16Array(288);\\n }\\n function Data(source, dest) {\\n this.source = source;\\n this.sourceIndex = 0;\\n this.tag = 0;\\n this.bitcount = 0;\\n this.dest = dest;\\n this.destLen = 0;\\n this.ltree = new Tree();\\n this.dtree = new Tree();\\n }\\n var sltree = new Tree();\\n var sdtree = new Tree();\\n var length_bits = new Uint8Array(30);\\n var length_base = new Uint16Array(30);\\n var dist_bits = new Uint8Array(30);\\n var dist_base = new Uint16Array(30);\\n var clcidx = new Uint8Array([\\n 16,\\n 17,\\n 18,\\n 0,\\n 8,\\n 7,\\n 9,\\n 6,\\n 10,\\n 5,\\n 11,\\n 4,\\n 12,\\n 3,\\n 13,\\n 2,\\n 14,\\n 1,\\n 15\\n ]);\\n var code_tree = new Tree();\\n var lengths = new Uint8Array(288 + 32);\\n function tinf_build_bits_base(bits, base, delta, first) {\\n var i, sum;\\n for (i = 0; i < delta; ++i) bits[i] = 0;\\n for (i = 0; i < 30 - delta; ++i) bits[i + delta] = i / delta | 0;\\n for (sum = first, i = 0; i < 30; ++i) {\\n base[i] = sum;\\n sum += 1 << bits[i];\\n }\\n }\\n function tinf_build_fixed_trees(lt, dt) {\\n var i;\\n for (i = 0; i < 7; ++i) lt.table[i] = 0;\\n lt.table[7] = 24;\\n lt.table[8] = 152;\\n lt.table[9] = 112;\\n for (i = 0; i < 24; ++i) lt.trans[i] = 256 + i;\\n for (i = 0; i < 144; ++i) lt.trans[24 + i] = i;\\n for (i = 0; i < 8; ++i) lt.trans[24 + 144 + i] = 280 + i;\\n for (i = 0; i < 112; ++i) lt.trans[24 + 144 + 8 + i] = 144 + i;\\n for (i = 0; i < 5; ++i) dt.table[i] = 0;\\n dt.table[5] = 32;\\n for (i = 0; i < 32; ++i) dt.trans[i] = i;\\n }\\n var offs = new Uint16Array(16);\\n function tinf_build_tree(t, lengths2, off, num) {\\n var i, sum;\\n for (i = 0; i < 16; ++i) t.table[i] = 0;\\n for (i = 0; i < num; ++i) t.table[lengths2[off + i]]++;\\n t.table[0] = 0;\\n for (sum = 0, i = 0; i < 16; ++i) {\\n offs[i] = sum;\\n sum += t.table[i];\\n }\\n for (i = 0; i < num; ++i) {\\n if (lengths2[off + i]) t.trans[offs[lengths2[off + i]]++] = i;\\n }\\n }\\n function tinf_getbit(d) {\\n if (!d.bitcount--) {\\n d.tag = d.source[d.sourceIndex++];\\n d.bitcount = 7;\\n }\\n var bit = d.tag & 1;\\n d.tag >>>= 1;\\n return bit;\\n }\\n function tinf_read_bits(d, num, base) {\\n if (!num)\\n return base;\\n while (d.bitcount < 24) {\\n d.tag |= d.source[d.sourceIndex++] << d.bitcount;\\n d.bitcount += 8;\\n }\\n var val = d.tag & 65535 >>> 16 - num;\\n d.tag >>>= num;\\n d.bitcount -= num;\\n return val + base;\\n }\\n function tinf_decode_symbol(d, t) {\\n while (d.bitcount < 24) {\\n d.tag |= d.source[d.sourceIndex++] << d.bitcount;\\n d.bitcount += 8;\\n }\\n var sum = 0, cur = 0, len = 0;\\n var tag = d.tag;\\n do {\\n cur = 2 * cur + (tag & 1);\\n tag >>>= 1;\\n ++len;\\n sum += t.table[len];\\n cur -= t.table[len];\\n } while (cur >= 0);\\n d.tag = tag;\\n d.bitcount -= len;\\n return t.trans[sum + cur];\\n }\\n function tinf_decode_trees(d, lt, dt) {\\n var hlit, hdist, hclen;\\n var i, num, length;\\n hlit = tinf_read_bits(d, 5, 257);\\n hdist = tinf_read_bits(d, 5, 1);\\n hclen = tinf_read_bits(d, 4, 4);\\n for (i = 0; i < 19; ++i) lengths[i] = 0;\\n for (i = 0; i < hclen; ++i) {\\n var clen = tinf_read_bits(d, 3, 0);\\n lengths[clcidx[i]] = clen;\\n }\\n tinf_build_tree(code_tree, lengths, 0, 19);\\n for (num = 0; num < hlit + hdist; ) {\\n var sym = tinf_decode_symbol(d, code_tree);\\n switch (sym) {\\n case 16:\\n var prev = lengths[num - 1];\\n for (length = tinf_read_bits(d, 2, 3); length; --length) {\\n lengths[num++] = prev;\\n }\\n break;\\n case 17:\\n for (length = tinf_read_bits(d, 3, 3); length; --length) {\\n lengths[num++] = 0;\\n }\\n break;\\n case 18:\\n for (length = tinf_read_bits(d, 7, 11); length; --length) {\\n lengths[num++] = 0;\\n }\\n break;\\n default:\\n lengths[num++] = sym;\\n break;\\n }\\n }\\n tinf_build_tree(lt, lengths, 0, hlit);\\n tinf_build_tree(dt, lengths, hlit, hdist);\\n }\\n function tinf_inflate_block_data(d, lt, dt) {\\n while (1) {\\n var sym = tinf_decode_symbol(d, lt);\\n if (sym === 256) {\\n return TINF_OK;\\n }\\n if (sym < 256) {\\n d.dest[d.destLen++] = sym;\\n } else {\\n var length, dist, offs2;\\n var i;\\n sym -= 257;\\n length = tinf_read_bits(d, length_bits[sym], length_base[sym]);\\n dist = tinf_decode_symbol(d, dt);\\n offs2 = d.destLen - tinf_read_bits(d, dist_bits[dist], dist_base[dist]);\\n for (i = offs2; i < offs2 + length; ++i) {\\n d.dest[d.destLen++] = d.dest[i];\\n }\\n }\\n }\\n }\\n function tinf_inflate_uncompressed_block(d) {\\n var length, invlength;\\n var i;\\n while (d.bitcount > 8) {\\n d.sourceIndex--;\\n d.bitcount -= 8;\\n }\\n length = d.source[d.sourceIndex + 1];\\n length = 256 * length + d.source[d.sourceIndex];\\n invlength = d.source[d.sourceIndex + 3];\\n invlength = 256 * invlength + d.source[d.sourceIndex + 2];\\n if (length !== (~invlength & 65535))\\n return TINF_DATA_ERROR;\\n d.sourceIndex += 4;\\n for (i = length; i; --i)\\n d.dest[d.destLen++] = d.source[d.sourceIndex++];\\n d.bitcount = 0;\\n return TINF_OK;\\n }\\n function tinf_uncompress(source, dest) {\\n var d = new Data(source, dest);\\n var bfinal, btype, res;\\n do {\\n bfinal = tinf_getbit(d);\\n btype = tinf_read_bits(d, 2, 0);\\n switch (btype) {\\n case 0:\\n res = tinf_inflate_uncompressed_block(d);\\n break;\\n case 1:\\n res = tinf_inflate_block_data(d, sltree, sdtree);\\n break;\\n case 2:\\n tinf_decode_trees(d, d.ltree, d.dtree);\\n res = tinf_inflate_block_data(d, d.ltree, d.dtree);\\n break;\\n default:\\n res = TINF_DATA_ERROR;\\n }\\n if (res !== TINF_OK)\\n throw new Error(\\\"Data error\\\");\\n } while (!bfinal);\\n if (d.destLen < d.dest.length) {\\n if (typeof d.dest.slice === \\\"function\\\")\\n return d.dest.slice(0, d.destLen);\\n else\\n return d.dest.subarray(0, d.destLen);\\n }\\n return d.dest;\\n }\\n tinf_build_fixed_trees(sltree, sdtree);\\n tinf_build_bits_base(length_bits, length_base, 4, 3);\\n tinf_build_bits_base(dist_bits, dist_base, 2, 1);\\n length_bits[28] = 0;\\n length_base[28] = 258;\\n module.exports = tinf_uncompress;\\n }\\n });\\n\\n // ../../node_modules/.pnpm/unicode-trie@2.0.0/node_modules/unicode-trie/swap.js\\n var require_swap = __commonJS({\\n \\\"../../node_modules/.pnpm/unicode-trie@2.0.0/node_modules/unicode-trie/swap.js\\\"(exports, module) {\\n var isBigEndian2 = new Uint8Array(new Uint32Array([305419896]).buffer)[0] === 18;\\n var swap = (b, n, m) => {\\n let i = b[n];\\n b[n] = b[m];\\n b[m] = i;\\n };\\n var swap32 = (array) => {\\n const len = array.length;\\n for (let i = 0; i < len; i += 4) {\\n swap(array, i, i + 3);\\n swap(array, i + 1, i + 2);\\n }\\n };\\n var swap32LE = (array) => {\\n if (isBigEndian2) {\\n swap32(array);\\n }\\n };\\n module.exports = {\\n swap32LE\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/unicode-trie@2.0.0/node_modules/unicode-trie/index.js\\n var require_unicode_trie = __commonJS({\\n \\\"../../node_modules/.pnpm/unicode-trie@2.0.0/node_modules/unicode-trie/index.js\\\"(exports, module) {\\n var inflate = require_tiny_inflate();\\n var { swap32LE } = require_swap();\\n var SHIFT_1 = 6 + 5;\\n var SHIFT_2 = 5;\\n var SHIFT_1_2 = SHIFT_1 - SHIFT_2;\\n var OMITTED_BMP_INDEX_1_LENGTH = 65536 >> SHIFT_1;\\n var INDEX_2_BLOCK_LENGTH = 1 << SHIFT_1_2;\\n var INDEX_2_MASK = INDEX_2_BLOCK_LENGTH - 1;\\n var INDEX_SHIFT = 2;\\n var DATA_BLOCK_LENGTH = 1 << SHIFT_2;\\n var DATA_MASK = DATA_BLOCK_LENGTH - 1;\\n var LSCP_INDEX_2_OFFSET = 65536 >> SHIFT_2;\\n var LSCP_INDEX_2_LENGTH = 1024 >> SHIFT_2;\\n var INDEX_2_BMP_LENGTH = LSCP_INDEX_2_OFFSET + LSCP_INDEX_2_LENGTH;\\n var UTF8_2B_INDEX_2_OFFSET = INDEX_2_BMP_LENGTH;\\n var UTF8_2B_INDEX_2_LENGTH = 2048 >> 6;\\n var INDEX_1_OFFSET = UTF8_2B_INDEX_2_OFFSET + UTF8_2B_INDEX_2_LENGTH;\\n var DATA_GRANULARITY = 1 << INDEX_SHIFT;\\n var UnicodeTrie = class {\\n constructor(data) {\\n const isBuffer = typeof data.readUInt32BE === \\\"function\\\" && typeof data.slice === \\\"function\\\";\\n if (isBuffer || data instanceof Uint8Array) {\\n let uncompressedLength;\\n if (isBuffer) {\\n this.highStart = data.readUInt32LE(0);\\n this.errorValue = data.readUInt32LE(4);\\n uncompressedLength = data.readUInt32LE(8);\\n data = data.slice(12);\\n } else {\\n const view = new DataView(data.buffer);\\n this.highStart = view.getUint32(0, true);\\n this.errorValue = view.getUint32(4, true);\\n uncompressedLength = view.getUint32(8, true);\\n data = data.subarray(12);\\n }\\n data = inflate(data, new Uint8Array(uncompressedLength));\\n data = inflate(data, new Uint8Array(uncompressedLength));\\n swap32LE(data);\\n this.data = new Uint32Array(data.buffer);\\n } else {\\n ({ data: this.data, highStart: this.highStart, errorValue: this.errorValue } = data);\\n }\\n }\\n get(codePoint) {\\n let index;\\n if (codePoint < 0 || codePoint > 1114111) {\\n return this.errorValue;\\n }\\n if (codePoint < 55296 || codePoint > 56319 && codePoint <= 65535) {\\n index = (this.data[codePoint >> SHIFT_2] << INDEX_SHIFT) + (codePoint & DATA_MASK);\\n return this.data[index];\\n }\\n if (codePoint <= 65535) {\\n index = (this.data[LSCP_INDEX_2_OFFSET + (codePoint - 55296 >> SHIFT_2)] << INDEX_SHIFT) + (codePoint & DATA_MASK);\\n return this.data[index];\\n }\\n if (codePoint < this.highStart) {\\n index = this.data[INDEX_1_OFFSET - OMITTED_BMP_INDEX_1_LENGTH + (codePoint >> SHIFT_1)];\\n index = this.data[index + (codePoint >> SHIFT_2 & INDEX_2_MASK)];\\n index = (index << INDEX_SHIFT) + (codePoint & DATA_MASK);\\n return this.data[index];\\n }\\n return this.data[this.data.length - DATA_GRANULARITY];\\n }\\n };\\n module.exports = UnicodeTrie;\\n }\\n });\\n\\n // ../../node_modules/.pnpm/unicode-properties@1.4.1/node_modules/unicode-properties/dist/module.mjs\\n function $parcel$interopDefault(a) {\\n return a && a.__esModule ? a.default : a;\\n }\\n function $747425b437e121da$export$410364bbb673ddbc(codePoint) {\\n const val = $747425b437e121da$var$trie.get(codePoint);\\n return (0, /* @__PURE__ */ $parcel$interopDefault($f4087201da764553$exports)).categories[val >> $747425b437e121da$var$CATEGORY_SHIFT & $747425b437e121da$var$CATEGORY_MASK];\\n }\\n function $747425b437e121da$export$c03b919c6651ed55(codePoint) {\\n const val = $747425b437e121da$var$trie.get(codePoint);\\n return (0, /* @__PURE__ */ $parcel$interopDefault($f4087201da764553$exports)).combiningClasses[val >> $747425b437e121da$var$COMBINING_SHIFT & $747425b437e121da$var$COMBINING_MASK];\\n }\\n function $747425b437e121da$export$941569448d136665(codePoint) {\\n const val = $747425b437e121da$var$trie.get(codePoint);\\n return (0, /* @__PURE__ */ $parcel$interopDefault($f4087201da764553$exports)).scripts[val >> $747425b437e121da$var$SCRIPT_SHIFT & $747425b437e121da$var$SCRIPT_MASK];\\n }\\n function $747425b437e121da$export$727d9dbc4fbb948f(codePoint) {\\n return $747425b437e121da$export$410364bbb673ddbc(codePoint) === \\\"Nd\\\";\\n }\\n function $747425b437e121da$export$e33ad6871e762338(codePoint) {\\n const category = $747425b437e121da$export$410364bbb673ddbc(codePoint);\\n return category === \\\"Mn\\\" || category === \\\"Me\\\" || category === \\\"Mc\\\";\\n }\\n var import_base64_js, import_unicode_trie, $f4087201da764553$exports, $747425b437e121da$var$trie, $747425b437e121da$var$log2, $747425b437e121da$var$bits, $747425b437e121da$var$CATEGORY_BITS, $747425b437e121da$var$COMBINING_BITS, $747425b437e121da$var$SCRIPT_BITS, $747425b437e121da$var$EAW_BITS, $747425b437e121da$var$NUMBER_BITS, $747425b437e121da$var$CATEGORY_SHIFT, $747425b437e121da$var$COMBINING_SHIFT, $747425b437e121da$var$SCRIPT_SHIFT, $747425b437e121da$var$CATEGORY_MASK, $747425b437e121da$var$COMBINING_MASK, $747425b437e121da$var$SCRIPT_MASK, $747425b437e121da$var$EAW_MASK, $747425b437e121da$var$NUMBER_MASK;\\n var init_module = __esm({\\n \\\"../../node_modules/.pnpm/unicode-properties@1.4.1/node_modules/unicode-properties/dist/module.mjs\\\"() {\\n import_base64_js = __toESM(require_base64_js(), 1);\\n import_unicode_trie = __toESM(require_unicode_trie(), 1);\\n $f4087201da764553$exports = {};\\n $f4087201da764553$exports = JSON.parse('{\\\"categories\\\":[\\\"Cc\\\",\\\"Zs\\\",\\\"Po\\\",\\\"Sc\\\",\\\"Ps\\\",\\\"Pe\\\",\\\"Sm\\\",\\\"Pd\\\",\\\"Nd\\\",\\\"Lu\\\",\\\"Sk\\\",\\\"Pc\\\",\\\"Ll\\\",\\\"So\\\",\\\"Lo\\\",\\\"Pi\\\",\\\"Cf\\\",\\\"No\\\",\\\"Pf\\\",\\\"Lt\\\",\\\"Lm\\\",\\\"Mn\\\",\\\"Me\\\",\\\"Mc\\\",\\\"Nl\\\",\\\"Zl\\\",\\\"Zp\\\",\\\"Cs\\\",\\\"Co\\\"],\\\"combiningClasses\\\":[\\\"Not_Reordered\\\",\\\"Above\\\",\\\"Above_Right\\\",\\\"Below\\\",\\\"Attached_Above_Right\\\",\\\"Attached_Below\\\",\\\"Overlay\\\",\\\"Iota_Subscript\\\",\\\"Double_Below\\\",\\\"Double_Above\\\",\\\"Below_Right\\\",\\\"Above_Left\\\",\\\"CCC10\\\",\\\"CCC11\\\",\\\"CCC12\\\",\\\"CCC13\\\",\\\"CCC14\\\",\\\"CCC15\\\",\\\"CCC16\\\",\\\"CCC17\\\",\\\"CCC18\\\",\\\"CCC19\\\",\\\"CCC20\\\",\\\"CCC21\\\",\\\"CCC22\\\",\\\"CCC23\\\",\\\"CCC24\\\",\\\"CCC25\\\",\\\"CCC30\\\",\\\"CCC31\\\",\\\"CCC32\\\",\\\"CCC27\\\",\\\"CCC28\\\",\\\"CCC29\\\",\\\"CCC33\\\",\\\"CCC34\\\",\\\"CCC35\\\",\\\"CCC36\\\",\\\"Nukta\\\",\\\"Virama\\\",\\\"CCC84\\\",\\\"CCC91\\\",\\\"CCC103\\\",\\\"CCC107\\\",\\\"CCC118\\\",\\\"CCC122\\\",\\\"CCC129\\\",\\\"CCC130\\\",\\\"CCC132\\\",\\\"Attached_Above\\\",\\\"Below_Left\\\",\\\"Left\\\",\\\"Kana_Voicing\\\",\\\"CCC26\\\",\\\"Right\\\"],\\\"scripts\\\":[\\\"Common\\\",\\\"Latin\\\",\\\"Bopomofo\\\",\\\"Inherited\\\",\\\"Greek\\\",\\\"Coptic\\\",\\\"Cyrillic\\\",\\\"Armenian\\\",\\\"Hebrew\\\",\\\"Arabic\\\",\\\"Syriac\\\",\\\"Thaana\\\",\\\"Nko\\\",\\\"Samaritan\\\",\\\"Mandaic\\\",\\\"Devanagari\\\",\\\"Bengali\\\",\\\"Gurmukhi\\\",\\\"Gujarati\\\",\\\"Oriya\\\",\\\"Tamil\\\",\\\"Telugu\\\",\\\"Kannada\\\",\\\"Malayalam\\\",\\\"Sinhala\\\",\\\"Thai\\\",\\\"Lao\\\",\\\"Tibetan\\\",\\\"Myanmar\\\",\\\"Georgian\\\",\\\"Hangul\\\",\\\"Ethiopic\\\",\\\"Cherokee\\\",\\\"Canadian_Aboriginal\\\",\\\"Ogham\\\",\\\"Runic\\\",\\\"Tagalog\\\",\\\"Hanunoo\\\",\\\"Buhid\\\",\\\"Tagbanwa\\\",\\\"Khmer\\\",\\\"Mongolian\\\",\\\"Limbu\\\",\\\"Tai_Le\\\",\\\"New_Tai_Lue\\\",\\\"Buginese\\\",\\\"Tai_Tham\\\",\\\"Balinese\\\",\\\"Sundanese\\\",\\\"Batak\\\",\\\"Lepcha\\\",\\\"Ol_Chiki\\\",\\\"Braille\\\",\\\"Glagolitic\\\",\\\"Tifinagh\\\",\\\"Han\\\",\\\"Hiragana\\\",\\\"Katakana\\\",\\\"Yi\\\",\\\"Lisu\\\",\\\"Vai\\\",\\\"Bamum\\\",\\\"Syloti_Nagri\\\",\\\"Phags_Pa\\\",\\\"Saurashtra\\\",\\\"Kayah_Li\\\",\\\"Rejang\\\",\\\"Javanese\\\",\\\"Cham\\\",\\\"Tai_Viet\\\",\\\"Meetei_Mayek\\\",\\\"null\\\",\\\"Linear_B\\\",\\\"Lycian\\\",\\\"Carian\\\",\\\"Old_Italic\\\",\\\"Gothic\\\",\\\"Old_Permic\\\",\\\"Ugaritic\\\",\\\"Old_Persian\\\",\\\"Deseret\\\",\\\"Shavian\\\",\\\"Osmanya\\\",\\\"Osage\\\",\\\"Elbasan\\\",\\\"Caucasian_Albanian\\\",\\\"Linear_A\\\",\\\"Cypriot\\\",\\\"Imperial_Aramaic\\\",\\\"Palmyrene\\\",\\\"Nabataean\\\",\\\"Hatran\\\",\\\"Phoenician\\\",\\\"Lydian\\\",\\\"Meroitic_Hieroglyphs\\\",\\\"Meroitic_Cursive\\\",\\\"Kharoshthi\\\",\\\"Old_South_Arabian\\\",\\\"Old_North_Arabian\\\",\\\"Manichaean\\\",\\\"Avestan\\\",\\\"Inscriptional_Parthian\\\",\\\"Inscriptional_Pahlavi\\\",\\\"Psalter_Pahlavi\\\",\\\"Old_Turkic\\\",\\\"Old_Hungarian\\\",\\\"Hanifi_Rohingya\\\",\\\"Old_Sogdian\\\",\\\"Sogdian\\\",\\\"Elymaic\\\",\\\"Brahmi\\\",\\\"Kaithi\\\",\\\"Sora_Sompeng\\\",\\\"Chakma\\\",\\\"Mahajani\\\",\\\"Sharada\\\",\\\"Khojki\\\",\\\"Multani\\\",\\\"Khudawadi\\\",\\\"Grantha\\\",\\\"Newa\\\",\\\"Tirhuta\\\",\\\"Siddham\\\",\\\"Modi\\\",\\\"Takri\\\",\\\"Ahom\\\",\\\"Dogra\\\",\\\"Warang_Citi\\\",\\\"Nandinagari\\\",\\\"Zanabazar_Square\\\",\\\"Soyombo\\\",\\\"Pau_Cin_Hau\\\",\\\"Bhaiksuki\\\",\\\"Marchen\\\",\\\"Masaram_Gondi\\\",\\\"Gunjala_Gondi\\\",\\\"Makasar\\\",\\\"Cuneiform\\\",\\\"Egyptian_Hieroglyphs\\\",\\\"Anatolian_Hieroglyphs\\\",\\\"Mro\\\",\\\"Bassa_Vah\\\",\\\"Pahawh_Hmong\\\",\\\"Medefaidrin\\\",\\\"Miao\\\",\\\"Tangut\\\",\\\"Nushu\\\",\\\"Duployan\\\",\\\"SignWriting\\\",\\\"Nyiakeng_Puachue_Hmong\\\",\\\"Wancho\\\",\\\"Mende_Kikakui\\\",\\\"Adlam\\\"],\\\"eaw\\\":[\\\"N\\\",\\\"Na\\\",\\\"A\\\",\\\"W\\\",\\\"H\\\",\\\"F\\\"]}');\\n $747425b437e121da$var$trie = new (0, import_unicode_trie.default)((0, import_base64_js.default).toByteArray(\\\"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\\\"));\\n $747425b437e121da$var$log2 = Math.log2 || ((n) => Math.log(n) / Math.LN2);\\n $747425b437e121da$var$bits = (n) => $747425b437e121da$var$log2(n) + 1 | 0;\\n $747425b437e121da$var$CATEGORY_BITS = $747425b437e121da$var$bits((0, /* @__PURE__ */ $parcel$interopDefault($f4087201da764553$exports)).categories.length - 1);\\n $747425b437e121da$var$COMBINING_BITS = $747425b437e121da$var$bits((0, /* @__PURE__ */ $parcel$interopDefault($f4087201da764553$exports)).combiningClasses.length - 1);\\n $747425b437e121da$var$SCRIPT_BITS = $747425b437e121da$var$bits((0, /* @__PURE__ */ $parcel$interopDefault($f4087201da764553$exports)).scripts.length - 1);\\n $747425b437e121da$var$EAW_BITS = $747425b437e121da$var$bits((0, /* @__PURE__ */ $parcel$interopDefault($f4087201da764553$exports)).eaw.length - 1);\\n $747425b437e121da$var$NUMBER_BITS = 10;\\n $747425b437e121da$var$CATEGORY_SHIFT = $747425b437e121da$var$COMBINING_BITS + $747425b437e121da$var$SCRIPT_BITS + $747425b437e121da$var$EAW_BITS + $747425b437e121da$var$NUMBER_BITS;\\n $747425b437e121da$var$COMBINING_SHIFT = $747425b437e121da$var$SCRIPT_BITS + $747425b437e121da$var$EAW_BITS + $747425b437e121da$var$NUMBER_BITS;\\n $747425b437e121da$var$SCRIPT_SHIFT = $747425b437e121da$var$EAW_BITS + $747425b437e121da$var$NUMBER_BITS;\\n $747425b437e121da$var$CATEGORY_MASK = (1 << $747425b437e121da$var$CATEGORY_BITS) - 1;\\n $747425b437e121da$var$COMBINING_MASK = (1 << $747425b437e121da$var$COMBINING_BITS) - 1;\\n $747425b437e121da$var$SCRIPT_MASK = (1 << $747425b437e121da$var$SCRIPT_BITS) - 1;\\n $747425b437e121da$var$EAW_MASK = (1 << $747425b437e121da$var$EAW_BITS) - 1;\\n $747425b437e121da$var$NUMBER_MASK = (1 << $747425b437e121da$var$NUMBER_BITS) - 1;\\n }\\n });\\n\\n // ../../node_modules/.pnpm/dfa@1.2.0/node_modules/dfa/index.js\\n var require_dfa = __commonJS({\\n \\\"../../node_modules/.pnpm/dfa@1.2.0/node_modules/dfa/index.js\\\"(exports, module) {\\n \\\"use strict\\\";\\n var INITIAL_STATE = 1;\\n var FAIL_STATE = 0;\\n var StateMachine = class {\\n constructor(dfa) {\\n this.stateTable = dfa.stateTable;\\n this.accepting = dfa.accepting;\\n this.tags = dfa.tags;\\n }\\n /**\\n * Returns an iterable object that yields pattern matches over the input sequence.\\n * Matches are of the form [startIndex, endIndex, tags].\\n */\\n match(str) {\\n var self2 = this;\\n return {\\n *[Symbol.iterator]() {\\n var state = INITIAL_STATE;\\n var startRun = null;\\n var lastAccepting = null;\\n var lastState = null;\\n for (var p = 0; p < str.length; p++) {\\n var c = str[p];\\n lastState = state;\\n state = self2.stateTable[state][c];\\n if (state === FAIL_STATE) {\\n if (startRun != null && lastAccepting != null && lastAccepting >= startRun) {\\n yield [startRun, lastAccepting, self2.tags[lastState]];\\n }\\n state = self2.stateTable[INITIAL_STATE][c];\\n startRun = null;\\n }\\n if (state !== FAIL_STATE && startRun == null) {\\n startRun = p;\\n }\\n if (self2.accepting[state]) {\\n lastAccepting = p;\\n }\\n if (state === FAIL_STATE) {\\n state = INITIAL_STATE;\\n }\\n }\\n if (startRun != null && lastAccepting != null && lastAccepting >= startRun) {\\n yield [startRun, lastAccepting, self2.tags[state]];\\n }\\n }\\n };\\n }\\n /**\\n * For each match over the input sequence, action functions matching\\n * the tag definitions in the input pattern are called with the startIndex,\\n * endIndex, and sub-match sequence.\\n */\\n apply(str, actions) {\\n for (var [start, end, tags] of this.match(str)) {\\n for (var tag of tags) {\\n if (typeof actions[tag] === \\\"function\\\") {\\n actions[tag](start, end, str.slice(start, end + 1));\\n }\\n }\\n }\\n }\\n };\\n module.exports = StateMachine;\\n }\\n });\\n\\n // ../../node_modules/.pnpm/clone@2.1.2/node_modules/clone/clone.js\\n var require_clone = __commonJS({\\n \\\"../../node_modules/.pnpm/clone@2.1.2/node_modules/clone/clone.js\\\"(exports, module) {\\n var clone = function() {\\n \\\"use strict\\\";\\n function _instanceof(obj, type) {\\n return type != null && obj instanceof type;\\n }\\n var nativeMap;\\n try {\\n nativeMap = Map;\\n } catch (_) {\\n nativeMap = function() {\\n };\\n }\\n var nativeSet;\\n try {\\n nativeSet = Set;\\n } catch (_) {\\n nativeSet = function() {\\n };\\n }\\n var nativePromise;\\n try {\\n nativePromise = Promise;\\n } catch (_) {\\n nativePromise = function() {\\n };\\n }\\n function clone2(parent, circular, depth, prototype, includeNonEnumerable) {\\n if (typeof circular === \\\"object\\\") {\\n depth = circular.depth;\\n prototype = circular.prototype;\\n includeNonEnumerable = circular.includeNonEnumerable;\\n circular = circular.circular;\\n }\\n var allParents = [];\\n var allChildren = [];\\n var useBuffer = typeof Buffer != \\\"undefined\\\";\\n if (typeof circular == \\\"undefined\\\")\\n circular = true;\\n if (typeof depth == \\\"undefined\\\")\\n depth = Infinity;\\n function _clone(parent2, depth2) {\\n if (parent2 === null)\\n return null;\\n if (depth2 === 0)\\n return parent2;\\n var child;\\n var proto;\\n if (typeof parent2 != \\\"object\\\") {\\n return parent2;\\n }\\n if (_instanceof(parent2, nativeMap)) {\\n child = new nativeMap();\\n } else if (_instanceof(parent2, nativeSet)) {\\n child = new nativeSet();\\n } else if (_instanceof(parent2, nativePromise)) {\\n child = new nativePromise(function(resolve, reject) {\\n parent2.then(function(value) {\\n resolve(_clone(value, depth2 - 1));\\n }, function(err) {\\n reject(_clone(err, depth2 - 1));\\n });\\n });\\n } else if (clone2.__isArray(parent2)) {\\n child = [];\\n } else if (clone2.__isRegExp(parent2)) {\\n child = new RegExp(parent2.source, __getRegExpFlags(parent2));\\n if (parent2.lastIndex) child.lastIndex = parent2.lastIndex;\\n } else if (clone2.__isDate(parent2)) {\\n child = new Date(parent2.getTime());\\n } else if (useBuffer && Buffer.isBuffer(parent2)) {\\n if (Buffer.allocUnsafe) {\\n child = Buffer.allocUnsafe(parent2.length);\\n } else {\\n child = new Buffer(parent2.length);\\n }\\n parent2.copy(child);\\n return child;\\n } else if (_instanceof(parent2, Error)) {\\n child = Object.create(parent2);\\n } else {\\n if (typeof prototype == \\\"undefined\\\") {\\n proto = Object.getPrototypeOf(parent2);\\n child = Object.create(proto);\\n } else {\\n child = Object.create(prototype);\\n proto = prototype;\\n }\\n }\\n if (circular) {\\n var index = allParents.indexOf(parent2);\\n if (index != -1) {\\n return allChildren[index];\\n }\\n allParents.push(parent2);\\n allChildren.push(child);\\n }\\n if (_instanceof(parent2, nativeMap)) {\\n parent2.forEach(function(value, key) {\\n var keyChild = _clone(key, depth2 - 1);\\n var valueChild = _clone(value, depth2 - 1);\\n child.set(keyChild, valueChild);\\n });\\n }\\n if (_instanceof(parent2, nativeSet)) {\\n parent2.forEach(function(value) {\\n var entryChild = _clone(value, depth2 - 1);\\n child.add(entryChild);\\n });\\n }\\n for (var i in parent2) {\\n var attrs;\\n if (proto) {\\n attrs = Object.getOwnPropertyDescriptor(proto, i);\\n }\\n if (attrs && attrs.set == null) {\\n continue;\\n }\\n child[i] = _clone(parent2[i], depth2 - 1);\\n }\\n if (Object.getOwnPropertySymbols) {\\n var symbols = Object.getOwnPropertySymbols(parent2);\\n for (var i = 0; i < symbols.length; i++) {\\n var symbol = symbols[i];\\n var descriptor = Object.getOwnPropertyDescriptor(parent2, symbol);\\n if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {\\n continue;\\n }\\n child[symbol] = _clone(parent2[symbol], depth2 - 1);\\n if (!descriptor.enumerable) {\\n Object.defineProperty(child, symbol, {\\n enumerable: false\\n });\\n }\\n }\\n }\\n if (includeNonEnumerable) {\\n var allPropertyNames = Object.getOwnPropertyNames(parent2);\\n for (var i = 0; i < allPropertyNames.length; i++) {\\n var propertyName = allPropertyNames[i];\\n var descriptor = Object.getOwnPropertyDescriptor(parent2, propertyName);\\n if (descriptor && descriptor.enumerable) {\\n continue;\\n }\\n child[propertyName] = _clone(parent2[propertyName], depth2 - 1);\\n Object.defineProperty(child, propertyName, {\\n enumerable: false\\n });\\n }\\n }\\n return child;\\n }\\n return _clone(parent, depth);\\n }\\n clone2.clonePrototype = function clonePrototype(parent) {\\n if (parent === null)\\n return null;\\n var c = function() {\\n };\\n c.prototype = parent;\\n return new c();\\n };\\n function __objToStr(o) {\\n return Object.prototype.toString.call(o);\\n }\\n clone2.__objToStr = __objToStr;\\n function __isDate(o) {\\n return typeof o === \\\"object\\\" && __objToStr(o) === \\\"[object Date]\\\";\\n }\\n clone2.__isDate = __isDate;\\n function __isArray(o) {\\n return typeof o === \\\"object\\\" && __objToStr(o) === \\\"[object Array]\\\";\\n }\\n clone2.__isArray = __isArray;\\n function __isRegExp(o) {\\n return typeof o === \\\"object\\\" && __objToStr(o) === \\\"[object RegExp]\\\";\\n }\\n clone2.__isRegExp = __isRegExp;\\n function __getRegExpFlags(re) {\\n var flags = \\\"\\\";\\n if (re.global) flags += \\\"g\\\";\\n if (re.ignoreCase) flags += \\\"i\\\";\\n if (re.multiline) flags += \\\"m\\\";\\n return flags;\\n }\\n clone2.__getRegExpFlags = __getRegExpFlags;\\n return clone2;\\n }();\\n if (typeof module === \\\"object\\\" && module.exports) {\\n module.exports = clone;\\n }\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/streams.js\\n var require_streams = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/streams.js\\\"(exports) {\\n function BrotliInput(buffer) {\\n this.buffer = buffer;\\n this.pos = 0;\\n }\\n BrotliInput.prototype.read = function(buf, i, count) {\\n if (this.pos + count > this.buffer.length) {\\n count = this.buffer.length - this.pos;\\n }\\n for (var p = 0; p < count; p++)\\n buf[i + p] = this.buffer[this.pos + p];\\n this.pos += count;\\n return count;\\n };\\n exports.BrotliInput = BrotliInput;\\n function BrotliOutput(buf) {\\n this.buffer = buf;\\n this.pos = 0;\\n }\\n BrotliOutput.prototype.write = function(buf, count) {\\n if (this.pos + count > this.buffer.length)\\n throw new Error(\\\"Output buffer is not large enough\\\");\\n this.buffer.set(buf.subarray(0, count), this.pos);\\n this.pos += count;\\n return count;\\n };\\n exports.BrotliOutput = BrotliOutput;\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/bit_reader.js\\n var require_bit_reader = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/bit_reader.js\\\"(exports, module) {\\n var BROTLI_READ_SIZE = 4096;\\n var BROTLI_IBUF_SIZE = 2 * BROTLI_READ_SIZE + 32;\\n var BROTLI_IBUF_MASK = 2 * BROTLI_READ_SIZE - 1;\\n var kBitMask = new Uint32Array([\\n 0,\\n 1,\\n 3,\\n 7,\\n 15,\\n 31,\\n 63,\\n 127,\\n 255,\\n 511,\\n 1023,\\n 2047,\\n 4095,\\n 8191,\\n 16383,\\n 32767,\\n 65535,\\n 131071,\\n 262143,\\n 524287,\\n 1048575,\\n 2097151,\\n 4194303,\\n 8388607,\\n 16777215\\n ]);\\n function BrotliBitReader(input) {\\n this.buf_ = new Uint8Array(BROTLI_IBUF_SIZE);\\n this.input_ = input;\\n this.reset();\\n }\\n BrotliBitReader.READ_SIZE = BROTLI_READ_SIZE;\\n BrotliBitReader.IBUF_MASK = BROTLI_IBUF_MASK;\\n BrotliBitReader.prototype.reset = function() {\\n this.buf_ptr_ = 0;\\n this.val_ = 0;\\n this.pos_ = 0;\\n this.bit_pos_ = 0;\\n this.bit_end_pos_ = 0;\\n this.eos_ = 0;\\n this.readMoreInput();\\n for (var i = 0; i < 4; i++) {\\n this.val_ |= this.buf_[this.pos_] << 8 * i;\\n ++this.pos_;\\n }\\n return this.bit_end_pos_ > 0;\\n };\\n BrotliBitReader.prototype.readMoreInput = function() {\\n if (this.bit_end_pos_ > 256) {\\n return;\\n } else if (this.eos_) {\\n if (this.bit_pos_ > this.bit_end_pos_)\\n throw new Error(\\\"Unexpected end of input \\\" + this.bit_pos_ + \\\" \\\" + this.bit_end_pos_);\\n } else {\\n var dst = this.buf_ptr_;\\n var bytes_read = this.input_.read(this.buf_, dst, BROTLI_READ_SIZE);\\n if (bytes_read < 0) {\\n throw new Error(\\\"Unexpected end of input\\\");\\n }\\n if (bytes_read < BROTLI_READ_SIZE) {\\n this.eos_ = 1;\\n for (var p = 0; p < 32; p++)\\n this.buf_[dst + bytes_read + p] = 0;\\n }\\n if (dst === 0) {\\n for (var p = 0; p < 32; p++)\\n this.buf_[(BROTLI_READ_SIZE << 1) + p] = this.buf_[p];\\n this.buf_ptr_ = BROTLI_READ_SIZE;\\n } else {\\n this.buf_ptr_ = 0;\\n }\\n this.bit_end_pos_ += bytes_read << 3;\\n }\\n };\\n BrotliBitReader.prototype.fillBitWindow = function() {\\n while (this.bit_pos_ >= 8) {\\n this.val_ >>>= 8;\\n this.val_ |= this.buf_[this.pos_ & BROTLI_IBUF_MASK] << 24;\\n ++this.pos_;\\n this.bit_pos_ = this.bit_pos_ - 8 >>> 0;\\n this.bit_end_pos_ = this.bit_end_pos_ - 8 >>> 0;\\n }\\n };\\n BrotliBitReader.prototype.readBits = function(n_bits) {\\n if (32 - this.bit_pos_ < n_bits) {\\n this.fillBitWindow();\\n }\\n var val = this.val_ >>> this.bit_pos_ & kBitMask[n_bits];\\n this.bit_pos_ += n_bits;\\n return val;\\n };\\n module.exports = BrotliBitReader;\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/dictionary.bin.js\\n var require_dictionary_bin = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/dictionary.bin.js\\\"(exports, module) {\\n module.exports = \\\"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\\\";\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/dictionary-browser.js\\n var require_dictionary_browser = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/dictionary-browser.js\\\"(exports) {\\n var base64 = require_base64_js();\\n exports.init = function() {\\n var BrotliDecompressBuffer = require_decode().BrotliDecompressBuffer;\\n var compressed = base64.toByteArray(require_dictionary_bin());\\n return BrotliDecompressBuffer(compressed);\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/dictionary.js\\n var require_dictionary = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/dictionary.js\\\"(exports) {\\n var data = require_dictionary_browser();\\n exports.init = function() {\\n exports.dictionary = data.init();\\n };\\n exports.offsetsByLength = new Uint32Array([\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 4096,\\n 9216,\\n 21504,\\n 35840,\\n 44032,\\n 53248,\\n 63488,\\n 74752,\\n 87040,\\n 93696,\\n 100864,\\n 104704,\\n 106752,\\n 108928,\\n 113536,\\n 115968,\\n 118528,\\n 119872,\\n 121280,\\n 122016\\n ]);\\n exports.sizeBitsByLength = new Uint8Array([\\n 0,\\n 0,\\n 0,\\n 0,\\n 10,\\n 10,\\n 11,\\n 11,\\n 10,\\n 10,\\n 10,\\n 10,\\n 10,\\n 9,\\n 9,\\n 8,\\n 7,\\n 7,\\n 8,\\n 7,\\n 7,\\n 6,\\n 6,\\n 5,\\n 5\\n ]);\\n exports.minDictionaryWordLength = 4;\\n exports.maxDictionaryWordLength = 24;\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/huffman.js\\n var require_huffman = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/huffman.js\\\"(exports) {\\n function HuffmanCode(bits, value) {\\n this.bits = bits;\\n this.value = value;\\n }\\n exports.HuffmanCode = HuffmanCode;\\n var MAX_LENGTH = 15;\\n function GetNextKey(key, len) {\\n var step = 1 << len - 1;\\n while (key & step) {\\n step >>= 1;\\n }\\n return (key & step - 1) + step;\\n }\\n function ReplicateValue(table, i, step, end, code) {\\n do {\\n end -= step;\\n table[i + end] = new HuffmanCode(code.bits, code.value);\\n } while (end > 0);\\n }\\n function NextTableBitSize(count, len, root_bits) {\\n var left = 1 << len - root_bits;\\n while (len < MAX_LENGTH) {\\n left -= count[len];\\n if (left <= 0) break;\\n ++len;\\n left <<= 1;\\n }\\n return len - root_bits;\\n }\\n exports.BrotliBuildHuffmanTable = function(root_table, table, root_bits, code_lengths, code_lengths_size) {\\n var start_table = table;\\n var code;\\n var len;\\n var symbol;\\n var key;\\n var step;\\n var low;\\n var mask;\\n var table_bits;\\n var table_size;\\n var total_size;\\n var sorted;\\n var count = new Int32Array(MAX_LENGTH + 1);\\n var offset = new Int32Array(MAX_LENGTH + 1);\\n sorted = new Int32Array(code_lengths_size);\\n for (symbol = 0; symbol < code_lengths_size; symbol++) {\\n count[code_lengths[symbol]]++;\\n }\\n offset[1] = 0;\\n for (len = 1; len < MAX_LENGTH; len++) {\\n offset[len + 1] = offset[len] + count[len];\\n }\\n for (symbol = 0; symbol < code_lengths_size; symbol++) {\\n if (code_lengths[symbol] !== 0) {\\n sorted[offset[code_lengths[symbol]]++] = symbol;\\n }\\n }\\n table_bits = root_bits;\\n table_size = 1 << table_bits;\\n total_size = table_size;\\n if (offset[MAX_LENGTH] === 1) {\\n for (key = 0; key < total_size; ++key) {\\n root_table[table + key] = new HuffmanCode(0, sorted[0] & 65535);\\n }\\n return total_size;\\n }\\n key = 0;\\n symbol = 0;\\n for (len = 1, step = 2; len <= root_bits; ++len, step <<= 1) {\\n for (; count[len] > 0; --count[len]) {\\n code = new HuffmanCode(len & 255, sorted[symbol++] & 65535);\\n ReplicateValue(root_table, table + key, step, table_size, code);\\n key = GetNextKey(key, len);\\n }\\n }\\n mask = total_size - 1;\\n low = -1;\\n for (len = root_bits + 1, step = 2; len <= MAX_LENGTH; ++len, step <<= 1) {\\n for (; count[len] > 0; --count[len]) {\\n if ((key & mask) !== low) {\\n table += table_size;\\n table_bits = NextTableBitSize(count, len, root_bits);\\n table_size = 1 << table_bits;\\n total_size += table_size;\\n low = key & mask;\\n root_table[start_table + low] = new HuffmanCode(table_bits + root_bits & 255, table - start_table - low & 65535);\\n }\\n code = new HuffmanCode(len - root_bits & 255, sorted[symbol++] & 65535);\\n ReplicateValue(root_table, table + (key >> root_bits), step, table_size, code);\\n key = GetNextKey(key, len);\\n }\\n }\\n return total_size;\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/context.js\\n var require_context = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/context.js\\\"(exports) {\\n exports.lookup = new Uint8Array([\\n /* CONTEXT_UTF8, last byte. */\\n /* ASCII range. */\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 4,\\n 4,\\n 0,\\n 0,\\n 4,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 8,\\n 12,\\n 16,\\n 12,\\n 12,\\n 20,\\n 12,\\n 16,\\n 24,\\n 28,\\n 12,\\n 12,\\n 32,\\n 12,\\n 36,\\n 12,\\n 44,\\n 44,\\n 44,\\n 44,\\n 44,\\n 44,\\n 44,\\n 44,\\n 44,\\n 44,\\n 32,\\n 32,\\n 24,\\n 40,\\n 28,\\n 12,\\n 12,\\n 48,\\n 52,\\n 52,\\n 52,\\n 48,\\n 52,\\n 52,\\n 52,\\n 48,\\n 52,\\n 52,\\n 52,\\n 52,\\n 52,\\n 48,\\n 52,\\n 52,\\n 52,\\n 52,\\n 52,\\n 48,\\n 52,\\n 52,\\n 52,\\n 52,\\n 52,\\n 24,\\n 12,\\n 28,\\n 12,\\n 12,\\n 12,\\n 56,\\n 60,\\n 60,\\n 60,\\n 56,\\n 60,\\n 60,\\n 60,\\n 56,\\n 60,\\n 60,\\n 60,\\n 60,\\n 60,\\n 56,\\n 60,\\n 60,\\n 60,\\n 60,\\n 60,\\n 56,\\n 60,\\n 60,\\n 60,\\n 60,\\n 60,\\n 24,\\n 12,\\n 28,\\n 12,\\n 0,\\n /* UTF8 continuation byte range. */\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n 0,\\n 1,\\n /* UTF8 lead byte range. */\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n 2,\\n 3,\\n /* CONTEXT_UTF8 second last byte. */\\n /* ASCII range. */\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 1,\\n 1,\\n 1,\\n 1,\\n 0,\\n /* UTF8 continuation byte range. */\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n /* UTF8 lead byte range. */\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n /* CONTEXT_SIGNED, second last byte. */\\n 0,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 1,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 4,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 5,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 6,\\n 7,\\n /* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */\\n 0,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 8,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 16,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 24,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 32,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 40,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 48,\\n 56,\\n /* CONTEXT_LSB6, last byte. */\\n 0,\\n 1,\\n 2,\\n 3,\\n 4,\\n 5,\\n 6,\\n 7,\\n 8,\\n 9,\\n 10,\\n 11,\\n 12,\\n 13,\\n 14,\\n 15,\\n 16,\\n 17,\\n 18,\\n 19,\\n 20,\\n 21,\\n 22,\\n 23,\\n 24,\\n 25,\\n 26,\\n 27,\\n 28,\\n 29,\\n 30,\\n 31,\\n 32,\\n 33,\\n 34,\\n 35,\\n 36,\\n 37,\\n 38,\\n 39,\\n 40,\\n 41,\\n 42,\\n 43,\\n 44,\\n 45,\\n 46,\\n 47,\\n 48,\\n 49,\\n 50,\\n 51,\\n 52,\\n 53,\\n 54,\\n 55,\\n 56,\\n 57,\\n 58,\\n 59,\\n 60,\\n 61,\\n 62,\\n 63,\\n 0,\\n 1,\\n 2,\\n 3,\\n 4,\\n 5,\\n 6,\\n 7,\\n 8,\\n 9,\\n 10,\\n 11,\\n 12,\\n 13,\\n 14,\\n 15,\\n 16,\\n 17,\\n 18,\\n 19,\\n 20,\\n 21,\\n 22,\\n 23,\\n 24,\\n 25,\\n 26,\\n 27,\\n 28,\\n 29,\\n 30,\\n 31,\\n 32,\\n 33,\\n 34,\\n 35,\\n 36,\\n 37,\\n 38,\\n 39,\\n 40,\\n 41,\\n 42,\\n 43,\\n 44,\\n 45,\\n 46,\\n 47,\\n 48,\\n 49,\\n 50,\\n 51,\\n 52,\\n 53,\\n 54,\\n 55,\\n 56,\\n 57,\\n 58,\\n 59,\\n 60,\\n 61,\\n 62,\\n 63,\\n 0,\\n 1,\\n 2,\\n 3,\\n 4,\\n 5,\\n 6,\\n 7,\\n 8,\\n 9,\\n 10,\\n 11,\\n 12,\\n 13,\\n 14,\\n 15,\\n 16,\\n 17,\\n 18,\\n 19,\\n 20,\\n 21,\\n 22,\\n 23,\\n 24,\\n 25,\\n 26,\\n 27,\\n 28,\\n 29,\\n 30,\\n 31,\\n 32,\\n 33,\\n 34,\\n 35,\\n 36,\\n 37,\\n 38,\\n 39,\\n 40,\\n 41,\\n 42,\\n 43,\\n 44,\\n 45,\\n 46,\\n 47,\\n 48,\\n 49,\\n 50,\\n 51,\\n 52,\\n 53,\\n 54,\\n 55,\\n 56,\\n 57,\\n 58,\\n 59,\\n 60,\\n 61,\\n 62,\\n 63,\\n 0,\\n 1,\\n 2,\\n 3,\\n 4,\\n 5,\\n 6,\\n 7,\\n 8,\\n 9,\\n 10,\\n 11,\\n 12,\\n 13,\\n 14,\\n 15,\\n 16,\\n 17,\\n 18,\\n 19,\\n 20,\\n 21,\\n 22,\\n 23,\\n 24,\\n 25,\\n 26,\\n 27,\\n 28,\\n 29,\\n 30,\\n 31,\\n 32,\\n 33,\\n 34,\\n 35,\\n 36,\\n 37,\\n 38,\\n 39,\\n 40,\\n 41,\\n 42,\\n 43,\\n 44,\\n 45,\\n 46,\\n 47,\\n 48,\\n 49,\\n 50,\\n 51,\\n 52,\\n 53,\\n 54,\\n 55,\\n 56,\\n 57,\\n 58,\\n 59,\\n 60,\\n 61,\\n 62,\\n 63,\\n /* CONTEXT_MSB6, last byte. */\\n 0,\\n 0,\\n 0,\\n 0,\\n 1,\\n 1,\\n 1,\\n 1,\\n 2,\\n 2,\\n 2,\\n 2,\\n 3,\\n 3,\\n 3,\\n 3,\\n 4,\\n 4,\\n 4,\\n 4,\\n 5,\\n 5,\\n 5,\\n 5,\\n 6,\\n 6,\\n 6,\\n 6,\\n 7,\\n 7,\\n 7,\\n 7,\\n 8,\\n 8,\\n 8,\\n 8,\\n 9,\\n 9,\\n 9,\\n 9,\\n 10,\\n 10,\\n 10,\\n 10,\\n 11,\\n 11,\\n 11,\\n 11,\\n 12,\\n 12,\\n 12,\\n 12,\\n 13,\\n 13,\\n 13,\\n 13,\\n 14,\\n 14,\\n 14,\\n 14,\\n 15,\\n 15,\\n 15,\\n 15,\\n 16,\\n 16,\\n 16,\\n 16,\\n 17,\\n 17,\\n 17,\\n 17,\\n 18,\\n 18,\\n 18,\\n 18,\\n 19,\\n 19,\\n 19,\\n 19,\\n 20,\\n 20,\\n 20,\\n 20,\\n 21,\\n 21,\\n 21,\\n 21,\\n 22,\\n 22,\\n 22,\\n 22,\\n 23,\\n 23,\\n 23,\\n 23,\\n 24,\\n 24,\\n 24,\\n 24,\\n 25,\\n 25,\\n 25,\\n 25,\\n 26,\\n 26,\\n 26,\\n 26,\\n 27,\\n 27,\\n 27,\\n 27,\\n 28,\\n 28,\\n 28,\\n 28,\\n 29,\\n 29,\\n 29,\\n 29,\\n 30,\\n 30,\\n 30,\\n 30,\\n 31,\\n 31,\\n 31,\\n 31,\\n 32,\\n 32,\\n 32,\\n 32,\\n 33,\\n 33,\\n 33,\\n 33,\\n 34,\\n 34,\\n 34,\\n 34,\\n 35,\\n 35,\\n 35,\\n 35,\\n 36,\\n 36,\\n 36,\\n 36,\\n 37,\\n 37,\\n 37,\\n 37,\\n 38,\\n 38,\\n 38,\\n 38,\\n 39,\\n 39,\\n 39,\\n 39,\\n 40,\\n 40,\\n 40,\\n 40,\\n 41,\\n 41,\\n 41,\\n 41,\\n 42,\\n 42,\\n 42,\\n 42,\\n 43,\\n 43,\\n 43,\\n 43,\\n 44,\\n 44,\\n 44,\\n 44,\\n 45,\\n 45,\\n 45,\\n 45,\\n 46,\\n 46,\\n 46,\\n 46,\\n 47,\\n 47,\\n 47,\\n 47,\\n 48,\\n 48,\\n 48,\\n 48,\\n 49,\\n 49,\\n 49,\\n 49,\\n 50,\\n 50,\\n 50,\\n 50,\\n 51,\\n 51,\\n 51,\\n 51,\\n 52,\\n 52,\\n 52,\\n 52,\\n 53,\\n 53,\\n 53,\\n 53,\\n 54,\\n 54,\\n 54,\\n 54,\\n 55,\\n 55,\\n 55,\\n 55,\\n 56,\\n 56,\\n 56,\\n 56,\\n 57,\\n 57,\\n 57,\\n 57,\\n 58,\\n 58,\\n 58,\\n 58,\\n 59,\\n 59,\\n 59,\\n 59,\\n 60,\\n 60,\\n 60,\\n 60,\\n 61,\\n 61,\\n 61,\\n 61,\\n 62,\\n 62,\\n 62,\\n 62,\\n 63,\\n 63,\\n 63,\\n 63,\\n /* CONTEXT_{M,L}SB6, second last byte, */\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0,\\n 0\\n ]);\\n exports.lookupOffsets = new Uint16Array([\\n /* CONTEXT_LSB6 */\\n 1024,\\n 1536,\\n /* CONTEXT_MSB6 */\\n 1280,\\n 1536,\\n /* CONTEXT_UTF8 */\\n 0,\\n 256,\\n /* CONTEXT_SIGNED */\\n 768,\\n 512\\n ]);\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/prefix.js\\n var require_prefix = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/prefix.js\\\"(exports) {\\n function PrefixCodeRange(offset, nbits) {\\n this.offset = offset;\\n this.nbits = nbits;\\n }\\n exports.kBlockLengthPrefixCode = [\\n new PrefixCodeRange(1, 2),\\n new PrefixCodeRange(5, 2),\\n new PrefixCodeRange(9, 2),\\n new PrefixCodeRange(13, 2),\\n new PrefixCodeRange(17, 3),\\n new PrefixCodeRange(25, 3),\\n new PrefixCodeRange(33, 3),\\n new PrefixCodeRange(41, 3),\\n new PrefixCodeRange(49, 4),\\n new PrefixCodeRange(65, 4),\\n new PrefixCodeRange(81, 4),\\n new PrefixCodeRange(97, 4),\\n new PrefixCodeRange(113, 5),\\n new PrefixCodeRange(145, 5),\\n new PrefixCodeRange(177, 5),\\n new PrefixCodeRange(209, 5),\\n new PrefixCodeRange(241, 6),\\n new PrefixCodeRange(305, 6),\\n new PrefixCodeRange(369, 7),\\n new PrefixCodeRange(497, 8),\\n new PrefixCodeRange(753, 9),\\n new PrefixCodeRange(1265, 10),\\n new PrefixCodeRange(2289, 11),\\n new PrefixCodeRange(4337, 12),\\n new PrefixCodeRange(8433, 13),\\n new PrefixCodeRange(16625, 24)\\n ];\\n exports.kInsertLengthPrefixCode = [\\n new PrefixCodeRange(0, 0),\\n new PrefixCodeRange(1, 0),\\n new PrefixCodeRange(2, 0),\\n new PrefixCodeRange(3, 0),\\n new PrefixCodeRange(4, 0),\\n new PrefixCodeRange(5, 0),\\n new PrefixCodeRange(6, 1),\\n new PrefixCodeRange(8, 1),\\n new PrefixCodeRange(10, 2),\\n new PrefixCodeRange(14, 2),\\n new PrefixCodeRange(18, 3),\\n new PrefixCodeRange(26, 3),\\n new PrefixCodeRange(34, 4),\\n new PrefixCodeRange(50, 4),\\n new PrefixCodeRange(66, 5),\\n new PrefixCodeRange(98, 5),\\n new PrefixCodeRange(130, 6),\\n new PrefixCodeRange(194, 7),\\n new PrefixCodeRange(322, 8),\\n new PrefixCodeRange(578, 9),\\n new PrefixCodeRange(1090, 10),\\n new PrefixCodeRange(2114, 12),\\n new PrefixCodeRange(6210, 14),\\n new PrefixCodeRange(22594, 24)\\n ];\\n exports.kCopyLengthPrefixCode = [\\n new PrefixCodeRange(2, 0),\\n new PrefixCodeRange(3, 0),\\n new PrefixCodeRange(4, 0),\\n new PrefixCodeRange(5, 0),\\n new PrefixCodeRange(6, 0),\\n new PrefixCodeRange(7, 0),\\n new PrefixCodeRange(8, 0),\\n new PrefixCodeRange(9, 0),\\n new PrefixCodeRange(10, 1),\\n new PrefixCodeRange(12, 1),\\n new PrefixCodeRange(14, 2),\\n new PrefixCodeRange(18, 2),\\n new PrefixCodeRange(22, 3),\\n new PrefixCodeRange(30, 3),\\n new PrefixCodeRange(38, 4),\\n new PrefixCodeRange(54, 4),\\n new PrefixCodeRange(70, 5),\\n new PrefixCodeRange(102, 5),\\n new PrefixCodeRange(134, 6),\\n new PrefixCodeRange(198, 7),\\n new PrefixCodeRange(326, 8),\\n new PrefixCodeRange(582, 9),\\n new PrefixCodeRange(1094, 10),\\n new PrefixCodeRange(2118, 24)\\n ];\\n exports.kInsertRangeLut = [\\n 0,\\n 0,\\n 8,\\n 8,\\n 0,\\n 16,\\n 8,\\n 16,\\n 16\\n ];\\n exports.kCopyRangeLut = [\\n 0,\\n 8,\\n 0,\\n 8,\\n 16,\\n 0,\\n 16,\\n 8,\\n 16\\n ];\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/transform.js\\n var require_transform = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/transform.js\\\"(exports) {\\n var BrotliDictionary = require_dictionary();\\n var kIdentity = 0;\\n var kOmitLast1 = 1;\\n var kOmitLast2 = 2;\\n var kOmitLast3 = 3;\\n var kOmitLast4 = 4;\\n var kOmitLast5 = 5;\\n var kOmitLast6 = 6;\\n var kOmitLast7 = 7;\\n var kOmitLast8 = 8;\\n var kOmitLast9 = 9;\\n var kUppercaseFirst = 10;\\n var kUppercaseAll = 11;\\n var kOmitFirst1 = 12;\\n var kOmitFirst2 = 13;\\n var kOmitFirst3 = 14;\\n var kOmitFirst4 = 15;\\n var kOmitFirst5 = 16;\\n var kOmitFirst6 = 17;\\n var kOmitFirst7 = 18;\\n var kOmitFirst9 = 20;\\n function Transform(prefix, transform, suffix) {\\n this.prefix = new Uint8Array(prefix.length);\\n this.transform = transform;\\n this.suffix = new Uint8Array(suffix.length);\\n for (var i = 0; i < prefix.length; i++)\\n this.prefix[i] = prefix.charCodeAt(i);\\n for (var i = 0; i < suffix.length; i++)\\n this.suffix[i] = suffix.charCodeAt(i);\\n }\\n var kTransforms = [\\n new Transform(\\\"\\\", kIdentity, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" \\\"),\\n new Transform(\\\" \\\", kIdentity, \\\" \\\"),\\n new Transform(\\\"\\\", kOmitFirst1, \\\"\\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, \\\" \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" the \\\"),\\n new Transform(\\\" \\\", kIdentity, \\\"\\\"),\\n new Transform(\\\"s \\\", kIdentity, \\\" \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" of \\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" and \\\"),\\n new Transform(\\\"\\\", kOmitFirst2, \\\"\\\"),\\n new Transform(\\\"\\\", kOmitLast1, \\\"\\\"),\\n new Transform(\\\", \\\", kIdentity, \\\" \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\", \\\"),\\n new Transform(\\\" \\\", kUppercaseFirst, \\\" \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" in \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" to \\\"),\\n new Transform(\\\"e \\\", kIdentity, \\\" \\\"),\\n new Transform(\\\"\\\", kIdentity, '\\\"'),\\n new Transform(\\\"\\\", kIdentity, \\\".\\\"),\\n new Transform(\\\"\\\", kIdentity, '\\\">'),\\n new Transform(\\\"\\\", kIdentity, \\\"\\\\n\\\"),\\n new Transform(\\\"\\\", kOmitLast3, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"]\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" for \\\"),\\n new Transform(\\\"\\\", kOmitFirst3, \\\"\\\"),\\n new Transform(\\\"\\\", kOmitLast2, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" a \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" that \\\"),\\n new Transform(\\\" \\\", kUppercaseFirst, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\". \\\"),\\n new Transform(\\\".\\\", kIdentity, \\\"\\\"),\\n new Transform(\\\" \\\", kIdentity, \\\", \\\"),\\n new Transform(\\\"\\\", kOmitFirst4, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" with \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"'\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" from \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" by \\\"),\\n new Transform(\\\"\\\", kOmitFirst5, \\\"\\\"),\\n new Transform(\\\"\\\", kOmitFirst6, \\\"\\\"),\\n new Transform(\\\" the \\\", kIdentity, \\\"\\\"),\\n new Transform(\\\"\\\", kOmitLast4, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\". The \\\"),\\n new Transform(\\\"\\\", kUppercaseAll, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" on \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" as \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" is \\\"),\\n new Transform(\\\"\\\", kOmitLast7, \\\"\\\"),\\n new Transform(\\\"\\\", kOmitLast1, \\\"ing \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"\\\\n\\t\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\":\\\"),\\n new Transform(\\\" \\\", kIdentity, \\\". \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"ed \\\"),\\n new Transform(\\\"\\\", kOmitFirst9, \\\"\\\"),\\n new Transform(\\\"\\\", kOmitFirst7, \\\"\\\"),\\n new Transform(\\\"\\\", kOmitLast6, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"(\\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, \\\", \\\"),\\n new Transform(\\\"\\\", kOmitLast8, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" at \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"ly \\\"),\\n new Transform(\\\" the \\\", kIdentity, \\\" of \\\"),\\n new Transform(\\\"\\\", kOmitLast5, \\\"\\\"),\\n new Transform(\\\"\\\", kOmitLast9, \\\"\\\"),\\n new Transform(\\\" \\\", kUppercaseFirst, \\\", \\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, '\\\"'),\\n new Transform(\\\".\\\", kIdentity, \\\"(\\\"),\\n new Transform(\\\"\\\", kUppercaseAll, \\\" \\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, '\\\">'),\\n new Transform(\\\"\\\", kIdentity, '=\\\"'),\\n new Transform(\\\" \\\", kIdentity, \\\".\\\"),\\n new Transform(\\\".com/\\\", kIdentity, \\\"\\\"),\\n new Transform(\\\" the \\\", kIdentity, \\\" of the \\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, \\\"'\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\". This \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\",\\\"),\\n new Transform(\\\".\\\", kIdentity, \\\" \\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, \\\"(\\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, \\\".\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\" not \\\"),\\n new Transform(\\\" \\\", kIdentity, '=\\\"'),\\n new Transform(\\\"\\\", kIdentity, \\\"er \\\"),\\n new Transform(\\\" \\\", kUppercaseAll, \\\" \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"al \\\"),\\n new Transform(\\\" \\\", kUppercaseAll, \\\"\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"='\\\"),\\n new Transform(\\\"\\\", kUppercaseAll, '\\\"'),\\n new Transform(\\\"\\\", kUppercaseFirst, \\\". \\\"),\\n new Transform(\\\" \\\", kIdentity, \\\"(\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"ful \\\"),\\n new Transform(\\\" \\\", kUppercaseFirst, \\\". \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"ive \\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"less \\\"),\\n new Transform(\\\"\\\", kUppercaseAll, \\\"'\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"est \\\"),\\n new Transform(\\\" \\\", kUppercaseFirst, \\\".\\\"),\\n new Transform(\\\"\\\", kUppercaseAll, '\\\">'),\\n new Transform(\\\" \\\", kIdentity, \\\"='\\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, \\\",\\\"),\\n new Transform(\\\"\\\", kIdentity, \\\"ize \\\"),\\n new Transform(\\\"\\\", kUppercaseAll, \\\".\\\"),\\n new Transform(\\\"\\\\xC2\\\\xA0\\\", kIdentity, \\\"\\\"),\\n new Transform(\\\" \\\", kIdentity, \\\",\\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, '=\\\"'),\\n new Transform(\\\"\\\", kUppercaseAll, '=\\\"'),\\n new Transform(\\\"\\\", kIdentity, \\\"ous \\\"),\\n new Transform(\\\"\\\", kUppercaseAll, \\\", \\\"),\\n new Transform(\\\"\\\", kUppercaseFirst, \\\"='\\\"),\\n new Transform(\\\" \\\", kUppercaseFirst, \\\",\\\"),\\n new Transform(\\\" \\\", kUppercaseAll, '=\\\"'),\\n new Transform(\\\" \\\", kUppercaseAll, \\\", \\\"),\\n new Transform(\\\"\\\", kUppercaseAll, \\\",\\\"),\\n new Transform(\\\"\\\", kUppercaseAll, \\\"(\\\"),\\n new Transform(\\\"\\\", kUppercaseAll, \\\". \\\"),\\n new Transform(\\\" \\\", kUppercaseAll, \\\".\\\"),\\n new Transform(\\\"\\\", kUppercaseAll, \\\"='\\\"),\\n new Transform(\\\" \\\", kUppercaseAll, \\\". \\\"),\\n new Transform(\\\" \\\", kUppercaseFirst, '=\\\"'),\\n new Transform(\\\" \\\", kUppercaseAll, \\\"='\\\"),\\n new Transform(\\\" \\\", kUppercaseFirst, \\\"='\\\")\\n ];\\n exports.kTransforms = kTransforms;\\n exports.kNumTransforms = kTransforms.length;\\n function ToUpperCase(p, i) {\\n if (p[i] < 192) {\\n if (p[i] >= 97 && p[i] <= 122) {\\n p[i] ^= 32;\\n }\\n return 1;\\n }\\n if (p[i] < 224) {\\n p[i + 1] ^= 32;\\n return 2;\\n }\\n p[i + 2] ^= 5;\\n return 3;\\n }\\n exports.transformDictionaryWord = function(dst, idx, word, len, transform) {\\n var prefix = kTransforms[transform].prefix;\\n var suffix = kTransforms[transform].suffix;\\n var t = kTransforms[transform].transform;\\n var skip = t < kOmitFirst1 ? 0 : t - (kOmitFirst1 - 1);\\n var i = 0;\\n var start_idx = idx;\\n var uppercase;\\n if (skip > len) {\\n skip = len;\\n }\\n var prefix_pos = 0;\\n while (prefix_pos < prefix.length) {\\n dst[idx++] = prefix[prefix_pos++];\\n }\\n word += skip;\\n len -= skip;\\n if (t <= kOmitLast9) {\\n len -= t;\\n }\\n for (i = 0; i < len; i++) {\\n dst[idx++] = BrotliDictionary.dictionary[word + i];\\n }\\n uppercase = idx - len;\\n if (t === kUppercaseFirst) {\\n ToUpperCase(dst, uppercase);\\n } else if (t === kUppercaseAll) {\\n while (len > 0) {\\n var step = ToUpperCase(dst, uppercase);\\n uppercase += step;\\n len -= step;\\n }\\n }\\n var suffix_pos = 0;\\n while (suffix_pos < suffix.length) {\\n dst[idx++] = suffix[suffix_pos++];\\n }\\n return idx - start_idx;\\n };\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/decode.js\\n var require_decode = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/dec/decode.js\\\"(exports) {\\n var BrotliInput = require_streams().BrotliInput;\\n var BrotliOutput = require_streams().BrotliOutput;\\n var BrotliBitReader = require_bit_reader();\\n var BrotliDictionary = require_dictionary();\\n var HuffmanCode = require_huffman().HuffmanCode;\\n var BrotliBuildHuffmanTable = require_huffman().BrotliBuildHuffmanTable;\\n var Context = require_context();\\n var Prefix = require_prefix();\\n var Transform = require_transform();\\n var kDefaultCodeLength = 8;\\n var kCodeLengthRepeatCode = 16;\\n var kNumLiteralCodes = 256;\\n var kNumInsertAndCopyCodes = 704;\\n var kNumBlockLengthCodes = 26;\\n var kLiteralContextBits = 6;\\n var kDistanceContextBits = 2;\\n var HUFFMAN_TABLE_BITS = 8;\\n var HUFFMAN_TABLE_MASK = 255;\\n var HUFFMAN_MAX_TABLE_SIZE = 1080;\\n var CODE_LENGTH_CODES = 18;\\n var kCodeLengthCodeOrder = new Uint8Array([\\n 1,\\n 2,\\n 3,\\n 4,\\n 0,\\n 5,\\n 17,\\n 6,\\n 16,\\n 7,\\n 8,\\n 9,\\n 10,\\n 11,\\n 12,\\n 13,\\n 14,\\n 15\\n ]);\\n var NUM_DISTANCE_SHORT_CODES = 16;\\n var kDistanceShortCodeIndexOffset = new Uint8Array([\\n 3,\\n 2,\\n 1,\\n 0,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 3,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2,\\n 2\\n ]);\\n var kDistanceShortCodeValueOffset = new Int8Array([\\n 0,\\n 0,\\n 0,\\n 0,\\n -1,\\n 1,\\n -2,\\n 2,\\n -3,\\n 3,\\n -1,\\n 1,\\n -2,\\n 2,\\n -3,\\n 3\\n ]);\\n var kMaxHuffmanTableSize = new Uint16Array([\\n 256,\\n 402,\\n 436,\\n 468,\\n 500,\\n 534,\\n 566,\\n 598,\\n 630,\\n 662,\\n 694,\\n 726,\\n 758,\\n 790,\\n 822,\\n 854,\\n 886,\\n 920,\\n 952,\\n 984,\\n 1016,\\n 1048,\\n 1080\\n ]);\\n function DecodeWindowBits(br) {\\n var n;\\n if (br.readBits(1) === 0) {\\n return 16;\\n }\\n n = br.readBits(3);\\n if (n > 0) {\\n return 17 + n;\\n }\\n n = br.readBits(3);\\n if (n > 0) {\\n return 8 + n;\\n }\\n return 17;\\n }\\n function DecodeVarLenUint8(br) {\\n if (br.readBits(1)) {\\n var nbits = br.readBits(3);\\n if (nbits === 0) {\\n return 1;\\n } else {\\n return br.readBits(nbits) + (1 << nbits);\\n }\\n }\\n return 0;\\n }\\n function MetaBlockLength() {\\n this.meta_block_length = 0;\\n this.input_end = 0;\\n this.is_uncompressed = 0;\\n this.is_metadata = false;\\n }\\n function DecodeMetaBlockLength(br) {\\n var out = new MetaBlockLength();\\n var size_nibbles;\\n var size_bytes;\\n var i;\\n out.input_end = br.readBits(1);\\n if (out.input_end && br.readBits(1)) {\\n return out;\\n }\\n size_nibbles = br.readBits(2) + 4;\\n if (size_nibbles === 7) {\\n out.is_metadata = true;\\n if (br.readBits(1) !== 0)\\n throw new Error(\\\"Invalid reserved bit\\\");\\n size_bytes = br.readBits(2);\\n if (size_bytes === 0)\\n return out;\\n for (i = 0; i < size_bytes; i++) {\\n var next_byte = br.readBits(8);\\n if (i + 1 === size_bytes && size_bytes > 1 && next_byte === 0)\\n throw new Error(\\\"Invalid size byte\\\");\\n out.meta_block_length |= next_byte << i * 8;\\n }\\n } else {\\n for (i = 0; i < size_nibbles; ++i) {\\n var next_nibble = br.readBits(4);\\n if (i + 1 === size_nibbles && size_nibbles > 4 && next_nibble === 0)\\n throw new Error(\\\"Invalid size nibble\\\");\\n out.meta_block_length |= next_nibble << i * 4;\\n }\\n }\\n ++out.meta_block_length;\\n if (!out.input_end && !out.is_metadata) {\\n out.is_uncompressed = br.readBits(1);\\n }\\n return out;\\n }\\n function ReadSymbol(table, index, br) {\\n var start_index = index;\\n var nbits;\\n br.fillBitWindow();\\n index += br.val_ >>> br.bit_pos_ & HUFFMAN_TABLE_MASK;\\n nbits = table[index].bits - HUFFMAN_TABLE_BITS;\\n if (nbits > 0) {\\n br.bit_pos_ += HUFFMAN_TABLE_BITS;\\n index += table[index].value;\\n index += br.val_ >>> br.bit_pos_ & (1 << nbits) - 1;\\n }\\n br.bit_pos_ += table[index].bits;\\n return table[index].value;\\n }\\n function ReadHuffmanCodeLengths(code_length_code_lengths, num_symbols, code_lengths, br) {\\n var symbol = 0;\\n var prev_code_len = kDefaultCodeLength;\\n var repeat = 0;\\n var repeat_code_len = 0;\\n var space = 32768;\\n var table = [];\\n for (var i = 0; i < 32; i++)\\n table.push(new HuffmanCode(0, 0));\\n BrotliBuildHuffmanTable(table, 0, 5, code_length_code_lengths, CODE_LENGTH_CODES);\\n while (symbol < num_symbols && space > 0) {\\n var p = 0;\\n var code_len;\\n br.readMoreInput();\\n br.fillBitWindow();\\n p += br.val_ >>> br.bit_pos_ & 31;\\n br.bit_pos_ += table[p].bits;\\n code_len = table[p].value & 255;\\n if (code_len < kCodeLengthRepeatCode) {\\n repeat = 0;\\n code_lengths[symbol++] = code_len;\\n if (code_len !== 0) {\\n prev_code_len = code_len;\\n space -= 32768 >> code_len;\\n }\\n } else {\\n var extra_bits = code_len - 14;\\n var old_repeat;\\n var repeat_delta;\\n var new_len = 0;\\n if (code_len === kCodeLengthRepeatCode) {\\n new_len = prev_code_len;\\n }\\n if (repeat_code_len !== new_len) {\\n repeat = 0;\\n repeat_code_len = new_len;\\n }\\n old_repeat = repeat;\\n if (repeat > 0) {\\n repeat -= 2;\\n repeat <<= extra_bits;\\n }\\n repeat += br.readBits(extra_bits) + 3;\\n repeat_delta = repeat - old_repeat;\\n if (symbol + repeat_delta > num_symbols) {\\n throw new Error(\\\"[ReadHuffmanCodeLengths] symbol + repeat_delta > num_symbols\\\");\\n }\\n for (var x = 0; x < repeat_delta; x++)\\n code_lengths[symbol + x] = repeat_code_len;\\n symbol += repeat_delta;\\n if (repeat_code_len !== 0) {\\n space -= repeat_delta << 15 - repeat_code_len;\\n }\\n }\\n }\\n if (space !== 0) {\\n throw new Error(\\\"[ReadHuffmanCodeLengths] space = \\\" + space);\\n }\\n for (; symbol < num_symbols; symbol++)\\n code_lengths[symbol] = 0;\\n }\\n function ReadHuffmanCode(alphabet_size, tables, table, br) {\\n var table_size = 0;\\n var simple_code_or_skip;\\n var code_lengths = new Uint8Array(alphabet_size);\\n br.readMoreInput();\\n simple_code_or_skip = br.readBits(2);\\n if (simple_code_or_skip === 1) {\\n var i;\\n var max_bits_counter = alphabet_size - 1;\\n var max_bits = 0;\\n var symbols = new Int32Array(4);\\n var num_symbols = br.readBits(2) + 1;\\n while (max_bits_counter) {\\n max_bits_counter >>= 1;\\n ++max_bits;\\n }\\n for (i = 0; i < num_symbols; ++i) {\\n symbols[i] = br.readBits(max_bits) % alphabet_size;\\n code_lengths[symbols[i]] = 2;\\n }\\n code_lengths[symbols[0]] = 1;\\n switch (num_symbols) {\\n case 1:\\n break;\\n case 3:\\n if (symbols[0] === symbols[1] || symbols[0] === symbols[2] || symbols[1] === symbols[2]) {\\n throw new Error(\\\"[ReadHuffmanCode] invalid symbols\\\");\\n }\\n break;\\n case 2:\\n if (symbols[0] === symbols[1]) {\\n throw new Error(\\\"[ReadHuffmanCode] invalid symbols\\\");\\n }\\n code_lengths[symbols[1]] = 1;\\n break;\\n case 4:\\n if (symbols[0] === symbols[1] || symbols[0] === symbols[2] || symbols[0] === symbols[3] || symbols[1] === symbols[2] || symbols[1] === symbols[3] || symbols[2] === symbols[3]) {\\n throw new Error(\\\"[ReadHuffmanCode] invalid symbols\\\");\\n }\\n if (br.readBits(1)) {\\n code_lengths[symbols[2]] = 3;\\n code_lengths[symbols[3]] = 3;\\n } else {\\n code_lengths[symbols[0]] = 2;\\n }\\n break;\\n }\\n } else {\\n var i;\\n var code_length_code_lengths = new Uint8Array(CODE_LENGTH_CODES);\\n var space = 32;\\n var num_codes = 0;\\n var huff = [\\n new HuffmanCode(2, 0),\\n new HuffmanCode(2, 4),\\n new HuffmanCode(2, 3),\\n new HuffmanCode(3, 2),\\n new HuffmanCode(2, 0),\\n new HuffmanCode(2, 4),\\n new HuffmanCode(2, 3),\\n new HuffmanCode(4, 1),\\n new HuffmanCode(2, 0),\\n new HuffmanCode(2, 4),\\n new HuffmanCode(2, 3),\\n new HuffmanCode(3, 2),\\n new HuffmanCode(2, 0),\\n new HuffmanCode(2, 4),\\n new HuffmanCode(2, 3),\\n new HuffmanCode(4, 5)\\n ];\\n for (i = simple_code_or_skip; i < CODE_LENGTH_CODES && space > 0; ++i) {\\n var code_len_idx = kCodeLengthCodeOrder[i];\\n var p = 0;\\n var v;\\n br.fillBitWindow();\\n p += br.val_ >>> br.bit_pos_ & 15;\\n br.bit_pos_ += huff[p].bits;\\n v = huff[p].value;\\n code_length_code_lengths[code_len_idx] = v;\\n if (v !== 0) {\\n space -= 32 >> v;\\n ++num_codes;\\n }\\n }\\n if (!(num_codes === 1 || space === 0))\\n throw new Error(\\\"[ReadHuffmanCode] invalid num_codes or space\\\");\\n ReadHuffmanCodeLengths(code_length_code_lengths, alphabet_size, code_lengths, br);\\n }\\n table_size = BrotliBuildHuffmanTable(tables, table, HUFFMAN_TABLE_BITS, code_lengths, alphabet_size);\\n if (table_size === 0) {\\n throw new Error(\\\"[ReadHuffmanCode] BuildHuffmanTable failed: \\\");\\n }\\n return table_size;\\n }\\n function ReadBlockLength(table, index, br) {\\n var code;\\n var nbits;\\n code = ReadSymbol(table, index, br);\\n nbits = Prefix.kBlockLengthPrefixCode[code].nbits;\\n return Prefix.kBlockLengthPrefixCode[code].offset + br.readBits(nbits);\\n }\\n function TranslateShortCodes(code, ringbuffer, index) {\\n var val;\\n if (code < NUM_DISTANCE_SHORT_CODES) {\\n index += kDistanceShortCodeIndexOffset[code];\\n index &= 3;\\n val = ringbuffer[index] + kDistanceShortCodeValueOffset[code];\\n } else {\\n val = code - NUM_DISTANCE_SHORT_CODES + 1;\\n }\\n return val;\\n }\\n function MoveToFront(v, index) {\\n var value = v[index];\\n var i = index;\\n for (; i; --i) v[i] = v[i - 1];\\n v[0] = value;\\n }\\n function InverseMoveToFrontTransform(v, v_len) {\\n var mtf = new Uint8Array(256);\\n var i;\\n for (i = 0; i < 256; ++i) {\\n mtf[i] = i;\\n }\\n for (i = 0; i < v_len; ++i) {\\n var index = v[i];\\n v[i] = mtf[index];\\n if (index) MoveToFront(mtf, index);\\n }\\n }\\n function HuffmanTreeGroup(alphabet_size, num_htrees) {\\n this.alphabet_size = alphabet_size;\\n this.num_htrees = num_htrees;\\n this.codes = new Array(num_htrees + num_htrees * kMaxHuffmanTableSize[alphabet_size + 31 >>> 5]);\\n this.htrees = new Uint32Array(num_htrees);\\n }\\n HuffmanTreeGroup.prototype.decode = function(br) {\\n var i;\\n var table_size;\\n var next = 0;\\n for (i = 0; i < this.num_htrees; ++i) {\\n this.htrees[i] = next;\\n table_size = ReadHuffmanCode(this.alphabet_size, this.codes, next, br);\\n next += table_size;\\n }\\n };\\n function DecodeContextMap(context_map_size, br) {\\n var out = { num_htrees: null, context_map: null };\\n var use_rle_for_zeros;\\n var max_run_length_prefix = 0;\\n var table;\\n var i;\\n br.readMoreInput();\\n var num_htrees = out.num_htrees = DecodeVarLenUint8(br) + 1;\\n var context_map = out.context_map = new Uint8Array(context_map_size);\\n if (num_htrees <= 1) {\\n return out;\\n }\\n use_rle_for_zeros = br.readBits(1);\\n if (use_rle_for_zeros) {\\n max_run_length_prefix = br.readBits(4) + 1;\\n }\\n table = [];\\n for (i = 0; i < HUFFMAN_MAX_TABLE_SIZE; i++) {\\n table[i] = new HuffmanCode(0, 0);\\n }\\n ReadHuffmanCode(num_htrees + max_run_length_prefix, table, 0, br);\\n for (i = 0; i < context_map_size; ) {\\n var code;\\n br.readMoreInput();\\n code = ReadSymbol(table, 0, br);\\n if (code === 0) {\\n context_map[i] = 0;\\n ++i;\\n } else if (code <= max_run_length_prefix) {\\n var reps = 1 + (1 << code) + br.readBits(code);\\n while (--reps) {\\n if (i >= context_map_size) {\\n throw new Error(\\\"[DecodeContextMap] i >= context_map_size\\\");\\n }\\n context_map[i] = 0;\\n ++i;\\n }\\n } else {\\n context_map[i] = code - max_run_length_prefix;\\n ++i;\\n }\\n }\\n if (br.readBits(1)) {\\n InverseMoveToFrontTransform(context_map, context_map_size);\\n }\\n return out;\\n }\\n function DecodeBlockType(max_block_type, trees, tree_type, block_types, ringbuffers, indexes, br) {\\n var ringbuffer = tree_type * 2;\\n var index = tree_type;\\n var type_code = ReadSymbol(trees, tree_type * HUFFMAN_MAX_TABLE_SIZE, br);\\n var block_type;\\n if (type_code === 0) {\\n block_type = ringbuffers[ringbuffer + (indexes[index] & 1)];\\n } else if (type_code === 1) {\\n block_type = ringbuffers[ringbuffer + (indexes[index] - 1 & 1)] + 1;\\n } else {\\n block_type = type_code - 2;\\n }\\n if (block_type >= max_block_type) {\\n block_type -= max_block_type;\\n }\\n block_types[tree_type] = block_type;\\n ringbuffers[ringbuffer + (indexes[index] & 1)] = block_type;\\n ++indexes[index];\\n }\\n function CopyUncompressedBlockToOutput(output, len, pos, ringbuffer, ringbuffer_mask, br) {\\n var rb_size = ringbuffer_mask + 1;\\n var rb_pos = pos & ringbuffer_mask;\\n var br_pos = br.pos_ & BrotliBitReader.IBUF_MASK;\\n var nbytes;\\n if (len < 8 || br.bit_pos_ + (len << 3) < br.bit_end_pos_) {\\n while (len-- > 0) {\\n br.readMoreInput();\\n ringbuffer[rb_pos++] = br.readBits(8);\\n if (rb_pos === rb_size) {\\n output.write(ringbuffer, rb_size);\\n rb_pos = 0;\\n }\\n }\\n return;\\n }\\n if (br.bit_end_pos_ < 32) {\\n throw new Error(\\\"[CopyUncompressedBlockToOutput] br.bit_end_pos_ < 32\\\");\\n }\\n while (br.bit_pos_ < 32) {\\n ringbuffer[rb_pos] = br.val_ >>> br.bit_pos_;\\n br.bit_pos_ += 8;\\n ++rb_pos;\\n --len;\\n }\\n nbytes = br.bit_end_pos_ - br.bit_pos_ >> 3;\\n if (br_pos + nbytes > BrotliBitReader.IBUF_MASK) {\\n var tail = BrotliBitReader.IBUF_MASK + 1 - br_pos;\\n for (var x = 0; x < tail; x++)\\n ringbuffer[rb_pos + x] = br.buf_[br_pos + x];\\n nbytes -= tail;\\n rb_pos += tail;\\n len -= tail;\\n br_pos = 0;\\n }\\n for (var x = 0; x < nbytes; x++)\\n ringbuffer[rb_pos + x] = br.buf_[br_pos + x];\\n rb_pos += nbytes;\\n len -= nbytes;\\n if (rb_pos >= rb_size) {\\n output.write(ringbuffer, rb_size);\\n rb_pos -= rb_size;\\n for (var x = 0; x < rb_pos; x++)\\n ringbuffer[x] = ringbuffer[rb_size + x];\\n }\\n while (rb_pos + len >= rb_size) {\\n nbytes = rb_size - rb_pos;\\n if (br.input_.read(ringbuffer, rb_pos, nbytes) < nbytes) {\\n throw new Error(\\\"[CopyUncompressedBlockToOutput] not enough bytes\\\");\\n }\\n output.write(ringbuffer, rb_size);\\n len -= nbytes;\\n rb_pos = 0;\\n }\\n if (br.input_.read(ringbuffer, rb_pos, len) < len) {\\n throw new Error(\\\"[CopyUncompressedBlockToOutput] not enough bytes\\\");\\n }\\n br.reset();\\n }\\n function JumpToByteBoundary(br) {\\n var new_bit_pos = br.bit_pos_ + 7 & ~7;\\n var pad_bits = br.readBits(new_bit_pos - br.bit_pos_);\\n return pad_bits == 0;\\n }\\n function BrotliDecompressedSize(buffer) {\\n var input = new BrotliInput(buffer);\\n var br = new BrotliBitReader(input);\\n DecodeWindowBits(br);\\n var out = DecodeMetaBlockLength(br);\\n return out.meta_block_length;\\n }\\n exports.BrotliDecompressedSize = BrotliDecompressedSize;\\n function BrotliDecompressBuffer(buffer, output_size) {\\n var input = new BrotliInput(buffer);\\n if (output_size == null) {\\n output_size = BrotliDecompressedSize(buffer);\\n }\\n var output_buffer = new Uint8Array(output_size);\\n var output = new BrotliOutput(output_buffer);\\n BrotliDecompress(input, output);\\n if (output.pos < output.buffer.length) {\\n output.buffer = output.buffer.subarray(0, output.pos);\\n }\\n return output.buffer;\\n }\\n exports.BrotliDecompressBuffer = BrotliDecompressBuffer;\\n function BrotliDecompress(input, output) {\\n var i;\\n var pos = 0;\\n var input_end = 0;\\n var window_bits = 0;\\n var max_backward_distance;\\n var max_distance = 0;\\n var ringbuffer_size;\\n var ringbuffer_mask;\\n var ringbuffer;\\n var ringbuffer_end;\\n var dist_rb = [16, 15, 11, 4];\\n var dist_rb_idx = 0;\\n var prev_byte1 = 0;\\n var prev_byte2 = 0;\\n var hgroup = [new HuffmanTreeGroup(0, 0), new HuffmanTreeGroup(0, 0), new HuffmanTreeGroup(0, 0)];\\n var block_type_trees;\\n var block_len_trees;\\n var br;\\n var kRingBufferWriteAheadSlack = 128 + BrotliBitReader.READ_SIZE;\\n br = new BrotliBitReader(input);\\n window_bits = DecodeWindowBits(br);\\n max_backward_distance = (1 << window_bits) - 16;\\n ringbuffer_size = 1 << window_bits;\\n ringbuffer_mask = ringbuffer_size - 1;\\n ringbuffer = new Uint8Array(ringbuffer_size + kRingBufferWriteAheadSlack + BrotliDictionary.maxDictionaryWordLength);\\n ringbuffer_end = ringbuffer_size;\\n block_type_trees = [];\\n block_len_trees = [];\\n for (var x = 0; x < 3 * HUFFMAN_MAX_TABLE_SIZE; x++) {\\n block_type_trees[x] = new HuffmanCode(0, 0);\\n block_len_trees[x] = new HuffmanCode(0, 0);\\n }\\n while (!input_end) {\\n var meta_block_remaining_len = 0;\\n var is_uncompressed;\\n var block_length = [1 << 28, 1 << 28, 1 << 28];\\n var block_type = [0];\\n var num_block_types = [1, 1, 1];\\n var block_type_rb = [0, 1, 0, 1, 0, 1];\\n var block_type_rb_index = [0];\\n var distance_postfix_bits;\\n var num_direct_distance_codes;\\n var distance_postfix_mask;\\n var num_distance_codes;\\n var context_map = null;\\n var context_modes = null;\\n var num_literal_htrees;\\n var dist_context_map = null;\\n var num_dist_htrees;\\n var context_offset = 0;\\n var context_map_slice = null;\\n var literal_htree_index = 0;\\n var dist_context_offset = 0;\\n var dist_context_map_slice = null;\\n var dist_htree_index = 0;\\n var context_lookup_offset1 = 0;\\n var context_lookup_offset2 = 0;\\n var context_mode;\\n var htree_command;\\n for (i = 0; i < 3; ++i) {\\n hgroup[i].codes = null;\\n hgroup[i].htrees = null;\\n }\\n br.readMoreInput();\\n var _out = DecodeMetaBlockLength(br);\\n meta_block_remaining_len = _out.meta_block_length;\\n if (pos + meta_block_remaining_len > output.buffer.length) {\\n var tmp = new Uint8Array(pos + meta_block_remaining_len);\\n tmp.set(output.buffer);\\n output.buffer = tmp;\\n }\\n input_end = _out.input_end;\\n is_uncompressed = _out.is_uncompressed;\\n if (_out.is_metadata) {\\n JumpToByteBoundary(br);\\n for (; meta_block_remaining_len > 0; --meta_block_remaining_len) {\\n br.readMoreInput();\\n br.readBits(8);\\n }\\n continue;\\n }\\n if (meta_block_remaining_len === 0) {\\n continue;\\n }\\n if (is_uncompressed) {\\n br.bit_pos_ = br.bit_pos_ + 7 & ~7;\\n CopyUncompressedBlockToOutput(\\n output,\\n meta_block_remaining_len,\\n pos,\\n ringbuffer,\\n ringbuffer_mask,\\n br\\n );\\n pos += meta_block_remaining_len;\\n continue;\\n }\\n for (i = 0; i < 3; ++i) {\\n num_block_types[i] = DecodeVarLenUint8(br) + 1;\\n if (num_block_types[i] >= 2) {\\n ReadHuffmanCode(num_block_types[i] + 2, block_type_trees, i * HUFFMAN_MAX_TABLE_SIZE, br);\\n ReadHuffmanCode(kNumBlockLengthCodes, block_len_trees, i * HUFFMAN_MAX_TABLE_SIZE, br);\\n block_length[i] = ReadBlockLength(block_len_trees, i * HUFFMAN_MAX_TABLE_SIZE, br);\\n block_type_rb_index[i] = 1;\\n }\\n }\\n br.readMoreInput();\\n distance_postfix_bits = br.readBits(2);\\n num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES + (br.readBits(4) << distance_postfix_bits);\\n distance_postfix_mask = (1 << distance_postfix_bits) - 1;\\n num_distance_codes = num_direct_distance_codes + (48 << distance_postfix_bits);\\n context_modes = new Uint8Array(num_block_types[0]);\\n for (i = 0; i < num_block_types[0]; ++i) {\\n br.readMoreInput();\\n context_modes[i] = br.readBits(2) << 1;\\n }\\n var _o1 = DecodeContextMap(num_block_types[0] << kLiteralContextBits, br);\\n num_literal_htrees = _o1.num_htrees;\\n context_map = _o1.context_map;\\n var _o2 = DecodeContextMap(num_block_types[2] << kDistanceContextBits, br);\\n num_dist_htrees = _o2.num_htrees;\\n dist_context_map = _o2.context_map;\\n hgroup[0] = new HuffmanTreeGroup(kNumLiteralCodes, num_literal_htrees);\\n hgroup[1] = new HuffmanTreeGroup(kNumInsertAndCopyCodes, num_block_types[1]);\\n hgroup[2] = new HuffmanTreeGroup(num_distance_codes, num_dist_htrees);\\n for (i = 0; i < 3; ++i) {\\n hgroup[i].decode(br);\\n }\\n context_map_slice = 0;\\n dist_context_map_slice = 0;\\n context_mode = context_modes[block_type[0]];\\n context_lookup_offset1 = Context.lookupOffsets[context_mode];\\n context_lookup_offset2 = Context.lookupOffsets[context_mode + 1];\\n htree_command = hgroup[1].htrees[0];\\n while (meta_block_remaining_len > 0) {\\n var cmd_code;\\n var range_idx;\\n var insert_code;\\n var copy_code;\\n var insert_length;\\n var copy_length;\\n var distance_code;\\n var distance;\\n var context;\\n var j;\\n var copy_dst;\\n br.readMoreInput();\\n if (block_length[1] === 0) {\\n DecodeBlockType(\\n num_block_types[1],\\n block_type_trees,\\n 1,\\n block_type,\\n block_type_rb,\\n block_type_rb_index,\\n br\\n );\\n block_length[1] = ReadBlockLength(block_len_trees, HUFFMAN_MAX_TABLE_SIZE, br);\\n htree_command = hgroup[1].htrees[block_type[1]];\\n }\\n --block_length[1];\\n cmd_code = ReadSymbol(hgroup[1].codes, htree_command, br);\\n range_idx = cmd_code >> 6;\\n if (range_idx >= 2) {\\n range_idx -= 2;\\n distance_code = -1;\\n } else {\\n distance_code = 0;\\n }\\n insert_code = Prefix.kInsertRangeLut[range_idx] + (cmd_code >> 3 & 7);\\n copy_code = Prefix.kCopyRangeLut[range_idx] + (cmd_code & 7);\\n insert_length = Prefix.kInsertLengthPrefixCode[insert_code].offset + br.readBits(Prefix.kInsertLengthPrefixCode[insert_code].nbits);\\n copy_length = Prefix.kCopyLengthPrefixCode[copy_code].offset + br.readBits(Prefix.kCopyLengthPrefixCode[copy_code].nbits);\\n prev_byte1 = ringbuffer[pos - 1 & ringbuffer_mask];\\n prev_byte2 = ringbuffer[pos - 2 & ringbuffer_mask];\\n for (j = 0; j < insert_length; ++j) {\\n br.readMoreInput();\\n if (block_length[0] === 0) {\\n DecodeBlockType(\\n num_block_types[0],\\n block_type_trees,\\n 0,\\n block_type,\\n block_type_rb,\\n block_type_rb_index,\\n br\\n );\\n block_length[0] = ReadBlockLength(block_len_trees, 0, br);\\n context_offset = block_type[0] << kLiteralContextBits;\\n context_map_slice = context_offset;\\n context_mode = context_modes[block_type[0]];\\n context_lookup_offset1 = Context.lookupOffsets[context_mode];\\n context_lookup_offset2 = Context.lookupOffsets[context_mode + 1];\\n }\\n context = Context.lookup[context_lookup_offset1 + prev_byte1] | Context.lookup[context_lookup_offset2 + prev_byte2];\\n literal_htree_index = context_map[context_map_slice + context];\\n --block_length[0];\\n prev_byte2 = prev_byte1;\\n prev_byte1 = ReadSymbol(hgroup[0].codes, hgroup[0].htrees[literal_htree_index], br);\\n ringbuffer[pos & ringbuffer_mask] = prev_byte1;\\n if ((pos & ringbuffer_mask) === ringbuffer_mask) {\\n output.write(ringbuffer, ringbuffer_size);\\n }\\n ++pos;\\n }\\n meta_block_remaining_len -= insert_length;\\n if (meta_block_remaining_len <= 0) break;\\n if (distance_code < 0) {\\n var context;\\n br.readMoreInput();\\n if (block_length[2] === 0) {\\n DecodeBlockType(\\n num_block_types[2],\\n block_type_trees,\\n 2,\\n block_type,\\n block_type_rb,\\n block_type_rb_index,\\n br\\n );\\n block_length[2] = ReadBlockLength(block_len_trees, 2 * HUFFMAN_MAX_TABLE_SIZE, br);\\n dist_context_offset = block_type[2] << kDistanceContextBits;\\n dist_context_map_slice = dist_context_offset;\\n }\\n --block_length[2];\\n context = (copy_length > 4 ? 3 : copy_length - 2) & 255;\\n dist_htree_index = dist_context_map[dist_context_map_slice + context];\\n distance_code = ReadSymbol(hgroup[2].codes, hgroup[2].htrees[dist_htree_index], br);\\n if (distance_code >= num_direct_distance_codes) {\\n var nbits;\\n var postfix;\\n var offset;\\n distance_code -= num_direct_distance_codes;\\n postfix = distance_code & distance_postfix_mask;\\n distance_code >>= distance_postfix_bits;\\n nbits = (distance_code >> 1) + 1;\\n offset = (2 + (distance_code & 1) << nbits) - 4;\\n distance_code = num_direct_distance_codes + (offset + br.readBits(nbits) << distance_postfix_bits) + postfix;\\n }\\n }\\n distance = TranslateShortCodes(distance_code, dist_rb, dist_rb_idx);\\n if (distance < 0) {\\n throw new Error(\\\"[BrotliDecompress] invalid distance\\\");\\n }\\n if (pos < max_backward_distance && max_distance !== max_backward_distance) {\\n max_distance = pos;\\n } else {\\n max_distance = max_backward_distance;\\n }\\n copy_dst = pos & ringbuffer_mask;\\n if (distance > max_distance) {\\n if (copy_length >= BrotliDictionary.minDictionaryWordLength && copy_length <= BrotliDictionary.maxDictionaryWordLength) {\\n var offset = BrotliDictionary.offsetsByLength[copy_length];\\n var word_id = distance - max_distance - 1;\\n var shift = BrotliDictionary.sizeBitsByLength[copy_length];\\n var mask = (1 << shift) - 1;\\n var word_idx = word_id & mask;\\n var transform_idx = word_id >> shift;\\n offset += word_idx * copy_length;\\n if (transform_idx < Transform.kNumTransforms) {\\n var len = Transform.transformDictionaryWord(ringbuffer, copy_dst, offset, copy_length, transform_idx);\\n copy_dst += len;\\n pos += len;\\n meta_block_remaining_len -= len;\\n if (copy_dst >= ringbuffer_end) {\\n output.write(ringbuffer, ringbuffer_size);\\n for (var _x = 0; _x < copy_dst - ringbuffer_end; _x++)\\n ringbuffer[_x] = ringbuffer[ringbuffer_end + _x];\\n }\\n } else {\\n throw new Error(\\\"Invalid backward reference. pos: \\\" + pos + \\\" distance: \\\" + distance + \\\" len: \\\" + copy_length + \\\" bytes left: \\\" + meta_block_remaining_len);\\n }\\n } else {\\n throw new Error(\\\"Invalid backward reference. pos: \\\" + pos + \\\" distance: \\\" + distance + \\\" len: \\\" + copy_length + \\\" bytes left: \\\" + meta_block_remaining_len);\\n }\\n } else {\\n if (distance_code > 0) {\\n dist_rb[dist_rb_idx & 3] = distance;\\n ++dist_rb_idx;\\n }\\n if (copy_length > meta_block_remaining_len) {\\n throw new Error(\\\"Invalid backward reference. pos: \\\" + pos + \\\" distance: \\\" + distance + \\\" len: \\\" + copy_length + \\\" bytes left: \\\" + meta_block_remaining_len);\\n }\\n for (j = 0; j < copy_length; ++j) {\\n ringbuffer[pos & ringbuffer_mask] = ringbuffer[pos - distance & ringbuffer_mask];\\n if ((pos & ringbuffer_mask) === ringbuffer_mask) {\\n output.write(ringbuffer, ringbuffer_size);\\n }\\n ++pos;\\n --meta_block_remaining_len;\\n }\\n }\\n prev_byte1 = ringbuffer[pos - 1 & ringbuffer_mask];\\n prev_byte2 = ringbuffer[pos - 2 & ringbuffer_mask];\\n }\\n pos &= 1073741823;\\n }\\n output.write(ringbuffer, pos & ringbuffer_mask);\\n }\\n exports.BrotliDecompress = BrotliDecompress;\\n BrotliDictionary.init();\\n }\\n });\\n\\n // ../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/decompress.js\\n var require_decompress = __commonJS({\\n \\\"../../node_modules/.pnpm/brotli@1.3.3/node_modules/brotli/decompress.js\\\"(exports, module) {\\n module.exports = require_decode().BrotliDecompressBuffer;\\n }\\n });\\n\\n // ../../node_modules/.pnpm/fontkit@2.0.4/node_modules/fontkit/dist/browser-module.mjs\\n var browser_module_exports = {};\\n __export(browser_module_exports, {\\n create: () => $d636bc798e7178db$export$185802fd694ee1f5,\\n defaultLanguage: () => $d636bc798e7178db$export$42940898df819940,\\n logErrors: () => $d636bc798e7178db$export$bd5c5d8b8dcafd78,\\n registerFormat: () => $d636bc798e7178db$export$36b2f24e97d43be,\\n setDefaultLanguage: () => $d636bc798e7178db$export$5157e7780d44cc36\\n });\\n function $parcel$export(e, n, v, s) {\\n Object.defineProperty(e, n, { get: v, set: s, enumerable: true, configurable: true });\\n }\\n function $parcel$interopDefault2(a) {\\n return a && a.__esModule ? a.default : a;\\n }\\n function $d636bc798e7178db$export$36b2f24e97d43be(format) {\\n $d636bc798e7178db$var$formats.push(format);\\n }\\n function $d636bc798e7178db$export$185802fd694ee1f5(buffer, postscriptName) {\\n for (let i = 0; i < $d636bc798e7178db$var$formats.length; i++) {\\n let format = $d636bc798e7178db$var$formats[i];\\n if (format.probe(buffer)) {\\n let font = new format(new (0, DecodeStream)(buffer));\\n if (postscriptName) return font.getFont(postscriptName);\\n return font;\\n }\\n }\\n throw new Error(\\\"Unknown font format\\\");\\n }\\n function $d636bc798e7178db$export$5157e7780d44cc36(lang = \\\"en\\\") {\\n $d636bc798e7178db$export$42940898df819940 = lang;\\n }\\n function $e71565f2ce09cb6b$export$69a3209f1a06c04d(target, key, descriptor) {\\n if (descriptor.get) {\\n let get = descriptor.get;\\n descriptor.get = function() {\\n let value = get.call(this);\\n Object.defineProperty(this, key, {\\n value\\n });\\n return value;\\n };\\n } else if (typeof descriptor.value === \\\"function\\\") {\\n let fn = descriptor.value;\\n return {\\n get() {\\n let cache2 = /* @__PURE__ */ new Map();\\n function memoized(...args) {\\n let key2 = args.length > 0 ? args[0] : \\\"value\\\";\\n if (cache2.has(key2)) return cache2.get(key2);\\n let result = fn.apply(this, args);\\n cache2.set(key2, result);\\n return result;\\n }\\n Object.defineProperty(this, key, {\\n value: memoized\\n });\\n return memoized;\\n }\\n };\\n }\\n }\\n function $e449ad78d50845fe$export$badc544e0651b6b1(platformID, encodingID, languageID = 0) {\\n if (platformID === 1 && $e449ad78d50845fe$export$479e671907f486d1[languageID]) return $e449ad78d50845fe$export$479e671907f486d1[languageID];\\n return $e449ad78d50845fe$export$6fef87b7618bdf0b[platformID][encodingID];\\n }\\n function $e449ad78d50845fe$export$1dceb3c14ed68bee(encoding) {\\n let cached = $e449ad78d50845fe$var$encodingCache.get(encoding);\\n if (cached) return cached;\\n let mapping = $e449ad78d50845fe$var$MAC_ENCODINGS[encoding];\\n if (mapping) {\\n let res = /* @__PURE__ */ new Map();\\n for (let i = 0; i < mapping.length; i++) res.set(mapping.charCodeAt(i), 128 + i);\\n $e449ad78d50845fe$var$encodingCache.set(encoding, res);\\n return res;\\n }\\n if ($e449ad78d50845fe$var$SINGLE_BYTE_ENCODINGS.has(encoding)) {\\n let decoder = new TextDecoder(encoding);\\n let mapping2 = new Uint8Array(128);\\n for (let i = 0; i < 128; i++) mapping2[i] = 128 + i;\\n let res = /* @__PURE__ */ new Map();\\n let s = decoder.decode(mapping2);\\n for (let i = 0; i < 128; i++) res.set(s.charCodeAt(i), 128 + i);\\n $e449ad78d50845fe$var$encodingCache.set(encoding, res);\\n return res;\\n }\\n }\\n function $7cbbe4e24ef3cb75$export$df0008c6ff2da22a(SubTable) {\\n let Lookup = new Struct({\\n lookupType: uint16,\\n flags: $7cbbe4e24ef3cb75$var$LookupFlags,\\n subTableCount: uint16,\\n subTables: new ArrayT(new Pointer(uint16, SubTable), \\\"subTableCount\\\"),\\n markFilteringSet: new Optional(uint16, (t) => t.flags.flags.useMarkFilteringSet)\\n });\\n return new LazyArray(new Pointer(uint16, Lookup), uint16);\\n }\\n function $6cb7dd5f47d82580$export$79f7d93d790934ba(entryData = {}, lookupType = uint16) {\\n let entry = Object.assign({\\n newState: uint16,\\n flags: uint16\\n }, entryData);\\n let Entry = new Struct(entry);\\n let StateArray = new $6cb7dd5f47d82580$export$c5af1eebc882e39a(new ArrayT(uint16, (t) => t.nClasses));\\n let StateHeader = new Struct({\\n nClasses: uint32,\\n classTable: new Pointer(uint32, new $6cb7dd5f47d82580$export$8351f8c2ae2f103c(lookupType)),\\n stateArray: new Pointer(uint32, StateArray),\\n entryTable: new Pointer(uint32, new $6cb7dd5f47d82580$export$c5af1eebc882e39a(Entry))\\n });\\n return StateHeader;\\n }\\n function $6cb7dd5f47d82580$export$105027425199cc51(entryData = {}, lookupType = uint16) {\\n let ClassLookupTable = new Struct({\\n version() {\\n return 8;\\n },\\n firstGlyph: uint16,\\n values: new ArrayT(uint8, uint16)\\n });\\n let entry = Object.assign({\\n newStateOffset: uint16,\\n // convert offset to stateArray index\\n newState: (t) => (t.newStateOffset - (t.parent.stateArray.base - t.parent._startOffset)) / t.parent.nClasses,\\n flags: uint16\\n }, entryData);\\n let Entry = new Struct(entry);\\n let StateArray = new $6cb7dd5f47d82580$export$c5af1eebc882e39a(new ArrayT(uint8, (t) => t.nClasses));\\n let StateHeader1 = new Struct({\\n nClasses: uint16,\\n classTable: new Pointer(uint16, ClassLookupTable),\\n stateArray: new Pointer(uint16, StateArray),\\n entryTable: new Pointer(uint16, new $6cb7dd5f47d82580$export$c5af1eebc882e39a(Entry))\\n });\\n return StateHeader1;\\n }\\n function $12727730ddfc8bfe$export$2e0ae67339d5f1ac(arr, cmp) {\\n let min = 0;\\n let max = arr.length - 1;\\n while (min <= max) {\\n let mid = min + max >> 1;\\n let res = cmp(arr[mid]);\\n if (res < 0) max = mid - 1;\\n else if (res > 0) min = mid + 1;\\n else return mid;\\n }\\n return -1;\\n }\\n function $12727730ddfc8bfe$export$d02631cccf789723(index, end) {\\n let range = [];\\n while (index < end) range.push(index++);\\n return range;\\n }\\n function $12727730ddfc8bfe$export$94fdf11bafc8de6b(base64) {\\n let bufferLength = base64.length * 0.75;\\n if (base64[base64.length - 1] === \\\"=\\\") {\\n bufferLength--;\\n if (base64[base64.length - 2] === \\\"=\\\") bufferLength--;\\n }\\n let bytes = new Uint8Array(bufferLength);\\n let p = 0;\\n for (let i = 0, len = base64.length; i < len; i += 4) {\\n let encoded1 = $12727730ddfc8bfe$var$LOOKUP[base64.charCodeAt(i)];\\n let encoded2 = $12727730ddfc8bfe$var$LOOKUP[base64.charCodeAt(i + 1)];\\n let encoded3 = $12727730ddfc8bfe$var$LOOKUP[base64.charCodeAt(i + 2)];\\n let encoded4 = $12727730ddfc8bfe$var$LOOKUP[base64.charCodeAt(i + 3)];\\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\\n }\\n return bytes;\\n }\\n function $130d1a642ebcd2b7$export$ce50e82f12a827a4(tag) {\\n return $130d1a642ebcd2b7$var$OPENTYPE_SCRIPTS[tag];\\n }\\n function $130d1a642ebcd2b7$export$e5cb25e204fb8450(string) {\\n let len = string.length;\\n let idx = 0;\\n while (idx < len) {\\n let code = string.charCodeAt(idx++);\\n if (55296 <= code && code <= 56319 && idx < len) {\\n let next = string.charCodeAt(idx);\\n if (56320 <= next && next <= 57343) {\\n idx++;\\n code = ((code & 1023) << 10) + (next & 1023) + 65536;\\n }\\n }\\n let script = (0, $747425b437e121da$export$941569448d136665)(code);\\n if (script !== \\\"Common\\\" && script !== \\\"Inherited\\\" && script !== \\\"Unknown\\\") return $130d1a642ebcd2b7$var$UNICODE_SCRIPTS[script];\\n }\\n return $130d1a642ebcd2b7$var$UNICODE_SCRIPTS.Unknown;\\n }\\n function $130d1a642ebcd2b7$export$16fab0757cfc223d(codePoints) {\\n for (let i = 0; i < codePoints.length; i++) {\\n let codePoint = codePoints[i];\\n let script = (0, $747425b437e121da$export$941569448d136665)(codePoint);\\n if (script !== \\\"Common\\\" && script !== \\\"Inherited\\\" && script !== \\\"Unknown\\\") return $130d1a642ebcd2b7$var$UNICODE_SCRIPTS[script];\\n }\\n return $130d1a642ebcd2b7$var$UNICODE_SCRIPTS.Unknown;\\n }\\n function $130d1a642ebcd2b7$export$9fddb9d0dd7d8a54(script) {\\n if ($130d1a642ebcd2b7$var$RTL[script]) return \\\"rtl\\\";\\n return \\\"ltr\\\";\\n }\\n function $3b6302b64eccc32c$export$b813f7d2a1677c16(features) {\\n let res = {};\\n for (let k in features) {\\n let r;\\n if (r = $3b6302b64eccc32c$var$OTMapping[k]) {\\n if (res[r[0]] == null) res[r[0]] = {};\\n res[r[0]][r[1]] = features[k];\\n }\\n }\\n return res;\\n }\\n function $3b6302b64eccc32c$var$mapFeatureStrings(f) {\\n let [type, setting] = f;\\n if (isNaN(type)) var typeCode = $3b6302b64eccc32c$var$features[type] && $3b6302b64eccc32c$var$features[type].code;\\n else var typeCode = type;\\n if (isNaN(setting)) var settingCode = $3b6302b64eccc32c$var$features[type] && $3b6302b64eccc32c$var$features[type][setting];\\n else var settingCode = setting;\\n return [\\n typeCode,\\n settingCode\\n ];\\n }\\n function $3b6302b64eccc32c$export$bd6df347a4f391c4(features) {\\n let res = {};\\n if (Array.isArray(features)) for (let k = 0; k < features.length; k++) {\\n let r;\\n let f = $3b6302b64eccc32c$var$mapFeatureStrings(features[k]);\\n if (r = $3b6302b64eccc32c$var$AATMapping[f[0]] && $3b6302b64eccc32c$var$AATMapping[f[0]][f[1]]) res[r] = true;\\n }\\n else if (typeof features === \\\"object\\\") for (let type in features) {\\n let feature = features[type];\\n for (let setting in feature) {\\n let r;\\n let f = $3b6302b64eccc32c$var$mapFeatureStrings([\\n type,\\n setting\\n ]);\\n if (feature[setting] && (r = $3b6302b64eccc32c$var$AATMapping[f[0]] && $3b6302b64eccc32c$var$AATMapping[f[0]][f[1]])) res[r] = true;\\n }\\n }\\n return Object.keys(res);\\n }\\n function $55f71433a605c87d$var$swap(glyphs, rangeA, rangeB, reverseA = false, reverseB = false) {\\n let end = glyphs.splice(rangeB[0] - (rangeB[1] - 1), rangeB[1]);\\n if (reverseB) end.reverse();\\n let start = glyphs.splice(rangeA[0], rangeA[1], ...end);\\n if (reverseA) start.reverse();\\n glyphs.splice(rangeB[0] - (rangeA[1] - 1), 0, ...start);\\n return glyphs;\\n }\\n function $55f71433a605c87d$var$reorderGlyphs(glyphs, verb, firstGlyph, lastGlyph) {\\n let length = lastGlyph - firstGlyph + 1;\\n switch (verb) {\\n case 0:\\n return glyphs;\\n case 1:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 1\\n ], [\\n lastGlyph,\\n 0\\n ]);\\n case 2:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 0\\n ], [\\n lastGlyph,\\n 1\\n ]);\\n case 3:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 1\\n ], [\\n lastGlyph,\\n 1\\n ]);\\n case 4:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 2\\n ], [\\n lastGlyph,\\n 0\\n ]);\\n case 5:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 2\\n ], [\\n lastGlyph,\\n 0\\n ], true, false);\\n case 6:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 0\\n ], [\\n lastGlyph,\\n 2\\n ]);\\n case 7:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 0\\n ], [\\n lastGlyph,\\n 2\\n ], false, true);\\n case 8:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 1\\n ], [\\n lastGlyph,\\n 2\\n ]);\\n case 9:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 1\\n ], [\\n lastGlyph,\\n 2\\n ], false, true);\\n case 10:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 2\\n ], [\\n lastGlyph,\\n 1\\n ]);\\n case 11:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 2\\n ], [\\n lastGlyph,\\n 1\\n ], true, false);\\n case 12:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 2\\n ], [\\n lastGlyph,\\n 2\\n ]);\\n case 13:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 2\\n ], [\\n lastGlyph,\\n 2\\n ], true, false);\\n case 14:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 2\\n ], [\\n lastGlyph,\\n 2\\n ], false, true);\\n case 15:\\n return $55f71433a605c87d$var$swap(glyphs, [\\n firstGlyph,\\n 2\\n ], [\\n lastGlyph,\\n 2\\n ], true, true);\\n default:\\n throw new Error(`Unknown verb: ${verb}`);\\n }\\n }\\n function $764eb544bbe1ccf0$var$getShapingClass(codePoint) {\\n let res = $764eb544bbe1ccf0$var$trie.get(codePoint);\\n if (res) return res - 1;\\n let category = (0, $747425b437e121da$export$410364bbb673ddbc)(codePoint);\\n if (category === \\\"Mn\\\" || category === \\\"Me\\\" || category === \\\"Cf\\\") return $764eb544bbe1ccf0$var$ShapingClasses.Transparent;\\n return $764eb544bbe1ccf0$var$ShapingClasses.Non_Joining;\\n }\\n function $e1c6bbc8cb416f8c$var$getType(code) {\\n if ($e1c6bbc8cb416f8c$var$isL(code)) return $e1c6bbc8cb416f8c$var$L;\\n if ($e1c6bbc8cb416f8c$var$isV(code)) return $e1c6bbc8cb416f8c$var$V;\\n if ($e1c6bbc8cb416f8c$var$isT(code)) return $e1c6bbc8cb416f8c$var$T;\\n if ($e1c6bbc8cb416f8c$var$isLV(code)) return $e1c6bbc8cb416f8c$var$LV;\\n if ($e1c6bbc8cb416f8c$var$isLVT(code)) return $e1c6bbc8cb416f8c$var$LVT;\\n if ($e1c6bbc8cb416f8c$var$isTone(code)) return $e1c6bbc8cb416f8c$var$M;\\n return $e1c6bbc8cb416f8c$var$X;\\n }\\n function $e1c6bbc8cb416f8c$var$getGlyph(font, code, features) {\\n return new (0, $10e7b257e1a9a756$export$2e2bcd8739ae039)(font, font.glyphForCodePoint(code).id, [\\n code\\n ], features);\\n }\\n function $e1c6bbc8cb416f8c$var$decompose(glyphs, i, font) {\\n let glyph = glyphs[i];\\n let code = glyph.codePoints[0];\\n let s = code - $e1c6bbc8cb416f8c$var$HANGUL_BASE;\\n let t = $e1c6bbc8cb416f8c$var$T_BASE + s % $e1c6bbc8cb416f8c$var$T_COUNT;\\n s = s / $e1c6bbc8cb416f8c$var$T_COUNT | 0;\\n let l = $e1c6bbc8cb416f8c$var$L_BASE + s / $e1c6bbc8cb416f8c$var$V_COUNT | 0;\\n let v = $e1c6bbc8cb416f8c$var$V_BASE + s % $e1c6bbc8cb416f8c$var$V_COUNT;\\n if (!font.hasGlyphForCodePoint(l) || !font.hasGlyphForCodePoint(v) || t !== $e1c6bbc8cb416f8c$var$T_BASE && !font.hasGlyphForCodePoint(t)) return i;\\n let ljmo = $e1c6bbc8cb416f8c$var$getGlyph(font, l, glyph.features);\\n ljmo.features.ljmo = true;\\n let vjmo = $e1c6bbc8cb416f8c$var$getGlyph(font, v, glyph.features);\\n vjmo.features.vjmo = true;\\n let insert = [\\n ljmo,\\n vjmo\\n ];\\n if (t > $e1c6bbc8cb416f8c$var$T_BASE) {\\n let tjmo = $e1c6bbc8cb416f8c$var$getGlyph(font, t, glyph.features);\\n tjmo.features.tjmo = true;\\n insert.push(tjmo);\\n }\\n glyphs.splice(i, 1, ...insert);\\n return i + insert.length - 1;\\n }\\n function $e1c6bbc8cb416f8c$var$compose(glyphs, i, font) {\\n let glyph = glyphs[i];\\n let code = glyphs[i].codePoints[0];\\n let type = $e1c6bbc8cb416f8c$var$getType(code);\\n let prev = glyphs[i - 1].codePoints[0];\\n let prevType = $e1c6bbc8cb416f8c$var$getType(prev);\\n let lv, ljmo, vjmo, tjmo;\\n if (prevType === $e1c6bbc8cb416f8c$var$LV && type === $e1c6bbc8cb416f8c$var$T) {\\n lv = prev;\\n tjmo = glyph;\\n } else {\\n if (type === $e1c6bbc8cb416f8c$var$V) {\\n ljmo = glyphs[i - 1];\\n vjmo = glyph;\\n } else {\\n ljmo = glyphs[i - 2];\\n vjmo = glyphs[i - 1];\\n tjmo = glyph;\\n }\\n let l = ljmo.codePoints[0];\\n let v = vjmo.codePoints[0];\\n if ($e1c6bbc8cb416f8c$var$isCombiningL(l) && $e1c6bbc8cb416f8c$var$isCombiningV(v)) lv = $e1c6bbc8cb416f8c$var$HANGUL_BASE + ((l - $e1c6bbc8cb416f8c$var$L_BASE) * $e1c6bbc8cb416f8c$var$V_COUNT + (v - $e1c6bbc8cb416f8c$var$V_BASE)) * $e1c6bbc8cb416f8c$var$T_COUNT;\\n }\\n let t = tjmo && tjmo.codePoints[0] || $e1c6bbc8cb416f8c$var$T_BASE;\\n if (lv != null && (t === $e1c6bbc8cb416f8c$var$T_BASE || $e1c6bbc8cb416f8c$var$isCombiningT(t))) {\\n let s = lv + (t - $e1c6bbc8cb416f8c$var$T_BASE);\\n if (font.hasGlyphForCodePoint(s)) {\\n let del = prevType === $e1c6bbc8cb416f8c$var$V ? 3 : 2;\\n glyphs.splice(i - del + 1, del, $e1c6bbc8cb416f8c$var$getGlyph(font, s, glyph.features));\\n return i - del + 1;\\n }\\n }\\n if (ljmo) ljmo.features.ljmo = true;\\n if (vjmo) vjmo.features.vjmo = true;\\n if (tjmo) tjmo.features.tjmo = true;\\n if (prevType === $e1c6bbc8cb416f8c$var$LV) {\\n $e1c6bbc8cb416f8c$var$decompose(glyphs, i - 1, font);\\n return i + 1;\\n }\\n return i;\\n }\\n function $e1c6bbc8cb416f8c$var$getLength(code) {\\n switch ($e1c6bbc8cb416f8c$var$getType(code)) {\\n case $e1c6bbc8cb416f8c$var$LV:\\n case $e1c6bbc8cb416f8c$var$LVT:\\n return 1;\\n case $e1c6bbc8cb416f8c$var$V:\\n return 2;\\n case $e1c6bbc8cb416f8c$var$T:\\n return 3;\\n }\\n }\\n function $e1c6bbc8cb416f8c$var$reorderToneMark(glyphs, i, font) {\\n let glyph = glyphs[i];\\n let code = glyphs[i].codePoints[0];\\n if (font.glyphForCodePoint(code).advanceWidth === 0) return;\\n let prev = glyphs[i - 1].codePoints[0];\\n let len = $e1c6bbc8cb416f8c$var$getLength(prev);\\n glyphs.splice(i, 1);\\n return glyphs.splice(i - len, 0, glyph);\\n }\\n function $e1c6bbc8cb416f8c$var$insertDottedCircle(glyphs, i, font) {\\n let glyph = glyphs[i];\\n let code = glyphs[i].codePoints[0];\\n if (font.hasGlyphForCodePoint($e1c6bbc8cb416f8c$var$DOTTED_CIRCLE)) {\\n let dottedCircle = $e1c6bbc8cb416f8c$var$getGlyph(font, $e1c6bbc8cb416f8c$var$DOTTED_CIRCLE, glyph.features);\\n let idx = font.glyphForCodePoint(code).advanceWidth === 0 ? i : i + 1;\\n glyphs.splice(idx, 0, dottedCircle);\\n i++;\\n }\\n return i;\\n }\\n function $7826f90f6f0cecc9$var$indicCategory(glyph) {\\n return $7826f90f6f0cecc9$var$trie.get(glyph.codePoints[0]) >> 8;\\n }\\n function $7826f90f6f0cecc9$var$indicPosition(glyph) {\\n return 1 << ($7826f90f6f0cecc9$var$trie.get(glyph.codePoints[0]) & 255);\\n }\\n function $7826f90f6f0cecc9$var$setupSyllables(font, glyphs) {\\n let syllable = 0;\\n let last = 0;\\n for (let [start, end, tags] of $7826f90f6f0cecc9$var$stateMachine.match(glyphs.map($7826f90f6f0cecc9$var$indicCategory))) {\\n if (start > last) {\\n ++syllable;\\n for (let i = last; i < start; i++) glyphs[i].shaperInfo = new $7826f90f6f0cecc9$var$IndicInfo((0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).X, (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).End, \\\"non_indic_cluster\\\", syllable);\\n }\\n ++syllable;\\n for (let i = start; i <= end; i++) glyphs[i].shaperInfo = new $7826f90f6f0cecc9$var$IndicInfo(1 << $7826f90f6f0cecc9$var$indicCategory(glyphs[i]), $7826f90f6f0cecc9$var$indicPosition(glyphs[i]), tags[0], syllable);\\n last = end + 1;\\n }\\n if (last < glyphs.length) {\\n ++syllable;\\n for (let i = last; i < glyphs.length; i++) glyphs[i].shaperInfo = new $7826f90f6f0cecc9$var$IndicInfo((0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).X, (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).End, \\\"non_indic_cluster\\\", syllable);\\n }\\n }\\n function $7826f90f6f0cecc9$var$isConsonant(glyph) {\\n return glyph.shaperInfo.category & (0, $90a9d3398ee54fe5$export$8519deaa7de2b07);\\n }\\n function $7826f90f6f0cecc9$var$isJoiner(glyph) {\\n return glyph.shaperInfo.category & (0, $90a9d3398ee54fe5$export$bbcd928767338e0d);\\n }\\n function $7826f90f6f0cecc9$var$isHalantOrCoeng(glyph) {\\n return glyph.shaperInfo.category & (0, $90a9d3398ee54fe5$export$ca9599b2a300afc);\\n }\\n function $7826f90f6f0cecc9$var$wouldSubstitute(glyphs, feature) {\\n for (let glyph of glyphs) glyph.features = {\\n [feature]: true\\n };\\n let GSUB = glyphs[0]._font._layoutEngine.engine.GSUBProcessor;\\n GSUB.applyFeatures([\\n feature\\n ], glyphs);\\n return glyphs.length === 1;\\n }\\n function $7826f90f6f0cecc9$var$consonantPosition(font, consonant, virama) {\\n let glyphs = [\\n virama,\\n consonant,\\n virama\\n ];\\n if ($7826f90f6f0cecc9$var$wouldSubstitute(glyphs.slice(0, 2), \\\"blwf\\\") || $7826f90f6f0cecc9$var$wouldSubstitute(glyphs.slice(1, 3), \\\"blwf\\\")) return (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Below_C;\\n else if ($7826f90f6f0cecc9$var$wouldSubstitute(glyphs.slice(0, 2), \\\"pstf\\\") || $7826f90f6f0cecc9$var$wouldSubstitute(glyphs.slice(1, 3), \\\"pstf\\\")) return (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Post_C;\\n else if ($7826f90f6f0cecc9$var$wouldSubstitute(glyphs.slice(0, 2), \\\"pref\\\") || $7826f90f6f0cecc9$var$wouldSubstitute(glyphs.slice(1, 3), \\\"pref\\\")) return (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Post_C;\\n return (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Base_C;\\n }\\n function $7826f90f6f0cecc9$var$initialReordering(font, glyphs, plan) {\\n let indicConfig = plan.indicConfig;\\n let features = font._layoutEngine.engine.GSUBProcessor.features;\\n let dottedCircle = font.glyphForCodePoint(9676).id;\\n let virama = font.glyphForCodePoint(indicConfig.virama).id;\\n if (virama) {\\n let info = new (0, $10e7b257e1a9a756$export$2e2bcd8739ae039)(font, virama, [\\n indicConfig.virama\\n ]);\\n for (let i = 0; i < glyphs.length; i++) if (glyphs[i].shaperInfo.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Base_C) glyphs[i].shaperInfo.position = $7826f90f6f0cecc9$var$consonantPosition(font, glyphs[i].copy(), info);\\n }\\n for (let start = 0, end = $7826f90f6f0cecc9$var$nextSyllable(glyphs, 0); start < glyphs.length; start = end, end = $7826f90f6f0cecc9$var$nextSyllable(glyphs, start)) {\\n let { category, syllableType } = glyphs[start].shaperInfo;\\n if (syllableType === \\\"symbol_cluster\\\" || syllableType === \\\"non_indic_cluster\\\") continue;\\n if (syllableType === \\\"broken_cluster\\\" && dottedCircle) {\\n let g = new (0, $10e7b257e1a9a756$export$2e2bcd8739ae039)(font, dottedCircle, [\\n 9676\\n ]);\\n g.shaperInfo = new $7826f90f6f0cecc9$var$IndicInfo(1 << $7826f90f6f0cecc9$var$indicCategory(g), $7826f90f6f0cecc9$var$indicPosition(g), glyphs[start].shaperInfo.syllableType, glyphs[start].shaperInfo.syllable);\\n let i = start;\\n while (i < end && glyphs[i].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).Repha) i++;\\n glyphs.splice(i++, 0, g);\\n end++;\\n }\\n let base = end;\\n let limit = start;\\n let hasReph = false;\\n if (indicConfig.rephPos !== (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Ra_To_Become_Reph && features.rphf && start + 3 <= end && (indicConfig.rephMode === \\\"Implicit\\\" && !$7826f90f6f0cecc9$var$isJoiner(glyphs[start + 2]) || indicConfig.rephMode === \\\"Explicit\\\" && glyphs[start + 2].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).ZWJ)) {\\n let g = [\\n glyphs[start].copy(),\\n glyphs[start + 1].copy(),\\n glyphs[start + 2].copy()\\n ];\\n if ($7826f90f6f0cecc9$var$wouldSubstitute(g.slice(0, 2), \\\"rphf\\\") || indicConfig.rephMode === \\\"Explicit\\\" && $7826f90f6f0cecc9$var$wouldSubstitute(g, \\\"rphf\\\")) {\\n limit += 2;\\n while (limit < end && $7826f90f6f0cecc9$var$isJoiner(glyphs[limit])) limit++;\\n base = start;\\n hasReph = true;\\n }\\n } else if (indicConfig.rephMode === \\\"Log_Repha\\\" && glyphs[start].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).Repha) {\\n limit++;\\n while (limit < end && $7826f90f6f0cecc9$var$isJoiner(glyphs[limit])) limit++;\\n base = start;\\n hasReph = true;\\n }\\n switch (indicConfig.basePos) {\\n case \\\"Last\\\": {\\n let i = end;\\n let seenBelow = false;\\n do {\\n let info = glyphs[--i].shaperInfo;\\n if ($7826f90f6f0cecc9$var$isConsonant(glyphs[i])) {\\n if (info.position !== (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Below_C && (info.position !== (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Post_C || seenBelow)) {\\n base = i;\\n break;\\n }\\n if (info.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Below_C) seenBelow = true;\\n base = i;\\n } else if (start < i && info.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).ZWJ && glyphs[i - 1].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).H) break;\\n } while (i > limit);\\n break;\\n }\\n case \\\"First\\\":\\n base = start;\\n for (let i = base + 1; i < end; i++) if ($7826f90f6f0cecc9$var$isConsonant(glyphs[i])) glyphs[i].shaperInfo.position = (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Below_C;\\n }\\n if (hasReph && base === start && limit - base <= 2) hasReph = false;\\n for (let i = start; i < base; i++) {\\n let info = glyphs[i].shaperInfo;\\n info.position = Math.min((0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Pre_C, info.position);\\n }\\n if (base < end) glyphs[base].shaperInfo.position = (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Base_C;\\n for (let i = base + 1; i < end; i++) if (glyphs[i].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).M) {\\n for (let j = i + 1; j < end; j++) if ($7826f90f6f0cecc9$var$isConsonant(glyphs[j])) {\\n glyphs[j].shaperInfo.position = (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Final_C;\\n break;\\n }\\n break;\\n }\\n if (hasReph) glyphs[start].shaperInfo.position = (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Ra_To_Become_Reph;\\n if (plan.isOldSpec) {\\n let disallowDoubleHalants = plan.unicodeScript !== \\\"Malayalam\\\";\\n for (let i = base + 1; i < end; i++) if (glyphs[i].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).H) {\\n let j;\\n for (j = end - 1; j > i; j--) {\\n if ($7826f90f6f0cecc9$var$isConsonant(glyphs[j]) || disallowDoubleHalants && glyphs[j].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).H) break;\\n }\\n if (glyphs[j].shaperInfo.category !== (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).H && j > i) {\\n let t = glyphs[i];\\n glyphs.splice(i, 0, ...glyphs.splice(i + 1, j - i));\\n glyphs[j] = t;\\n }\\n break;\\n }\\n }\\n let lastPos = (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Start;\\n for (let i = start; i < end; i++) {\\n let info = glyphs[i].shaperInfo;\\n if (info.category & ((0, $90a9d3398ee54fe5$export$bbcd928767338e0d) | (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).N | (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).RS | (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).CM | (0, $90a9d3398ee54fe5$export$ca9599b2a300afc) & info.category)) {\\n info.position = lastPos;\\n if (info.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).H && info.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Pre_M) {\\n for (let j = i; j > start; j--) if (glyphs[j - 1].shaperInfo.position !== (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Pre_M) {\\n info.position = glyphs[j - 1].shaperInfo.position;\\n break;\\n }\\n }\\n } else if (info.position !== (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).SMVD) lastPos = info.position;\\n }\\n let last = base;\\n for (let i = base + 1; i < end; i++) {\\n if ($7826f90f6f0cecc9$var$isConsonant(glyphs[i])) {\\n for (let j = last + 1; j < i; j++) if (glyphs[j].shaperInfo.position < (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).SMVD) glyphs[j].shaperInfo.position = glyphs[i].shaperInfo.position;\\n last = i;\\n } else if (glyphs[i].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).M) last = i;\\n }\\n let arr = glyphs.slice(start, end);\\n arr.sort((a, b) => a.shaperInfo.position - b.shaperInfo.position);\\n glyphs.splice(start, arr.length, ...arr);\\n for (let i = start; i < end; i++) if (glyphs[i].shaperInfo.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Base_C) {\\n base = i;\\n break;\\n }\\n for (let i = start; i < end && glyphs[i].shaperInfo.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Ra_To_Become_Reph; i++) glyphs[i].features.rphf = true;\\n let blwf = !plan.isOldSpec && indicConfig.blwfMode === \\\"Pre_And_Post\\\";\\n for (let i = start; i < base; i++) {\\n glyphs[i].features.half = true;\\n if (blwf) glyphs[i].features.blwf = true;\\n }\\n for (let i = base + 1; i < end; i++) {\\n glyphs[i].features.abvf = true;\\n glyphs[i].features.pstf = true;\\n glyphs[i].features.blwf = true;\\n }\\n if (plan.isOldSpec && plan.unicodeScript === \\\"Devanagari\\\") {\\n for (let i = start; i + 1 < base; i++) if (glyphs[i].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).Ra && glyphs[i + 1].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).H && (i + 1 === base || glyphs[i + 2].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).ZWJ)) {\\n glyphs[i].features.blwf = true;\\n glyphs[i + 1].features.blwf = true;\\n }\\n }\\n let prefLen = 2;\\n if (features.pref && base + prefLen < end)\\n for (let i = base + 1; i + prefLen - 1 < end; i++) {\\n let g = [\\n glyphs[i].copy(),\\n glyphs[i + 1].copy()\\n ];\\n if ($7826f90f6f0cecc9$var$wouldSubstitute(g, \\\"pref\\\")) {\\n for (let j = 0; j < prefLen; j++) glyphs[i++].features.pref = true;\\n if (features.cfar) for (; i < end; i++) glyphs[i].features.cfar = true;\\n break;\\n }\\n }\\n for (let i = start + 1; i < end; i++) if ($7826f90f6f0cecc9$var$isJoiner(glyphs[i])) {\\n let nonJoiner = glyphs[i].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).ZWNJ;\\n let j = i;\\n do {\\n j--;\\n if (nonJoiner) delete glyphs[j].features.half;\\n } while (j > start && !$7826f90f6f0cecc9$var$isConsonant(glyphs[j]));\\n }\\n }\\n }\\n function $7826f90f6f0cecc9$var$finalReordering(font, glyphs, plan) {\\n let indicConfig = plan.indicConfig;\\n let features = font._layoutEngine.engine.GSUBProcessor.features;\\n for (let start = 0, end = $7826f90f6f0cecc9$var$nextSyllable(glyphs, 0); start < glyphs.length; start = end, end = $7826f90f6f0cecc9$var$nextSyllable(glyphs, start)) {\\n let tryPref = !!features.pref;\\n let base = start;\\n for (; base < end; base++) if (glyphs[base].shaperInfo.position >= (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Base_C) {\\n if (tryPref && base + 1 < end) {\\n for (let i = base + 1; i < end; i++) if (glyphs[i].features.pref) {\\n if (!(glyphs[i].substituted && glyphs[i].isLigated && !glyphs[i].isMultiplied)) {\\n base = i;\\n while (base < end && $7826f90f6f0cecc9$var$isHalantOrCoeng(glyphs[base])) base++;\\n glyphs[base].shaperInfo.position = (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).BASE_C;\\n tryPref = false;\\n }\\n break;\\n }\\n }\\n if (plan.unicodeScript === \\\"Malayalam\\\") for (let i = base + 1; i < end; i++) {\\n while (i < end && $7826f90f6f0cecc9$var$isJoiner(glyphs[i])) i++;\\n if (i === end || !$7826f90f6f0cecc9$var$isHalantOrCoeng(glyphs[i])) break;\\n i++;\\n while (i < end && $7826f90f6f0cecc9$var$isJoiner(glyphs[i])) i++;\\n if (i < end && $7826f90f6f0cecc9$var$isConsonant(glyphs[i]) && glyphs[i].shaperInfo.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Below_C) {\\n base = i;\\n glyphs[base].shaperInfo.position = (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Base_C;\\n }\\n }\\n if (start < base && glyphs[base].shaperInfo.position > (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Base_C) base--;\\n break;\\n }\\n if (base === end && start < base && glyphs[base - 1].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).ZWJ) base--;\\n if (base < end) while (start < base && glyphs[base].shaperInfo.category & ((0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).N | (0, $90a9d3398ee54fe5$export$ca9599b2a300afc))) base--;\\n if (start + 1 < end && start < base) {\\n let newPos = base === end ? base - 2 : base - 1;\\n if (plan.unicodeScript !== \\\"Malayalam\\\" && plan.unicodeScript !== \\\"Tamil\\\") {\\n while (newPos > start && !(glyphs[newPos].shaperInfo.category & ((0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).M | (0, $90a9d3398ee54fe5$export$ca9599b2a300afc)))) newPos--;\\n if ($7826f90f6f0cecc9$var$isHalantOrCoeng(glyphs[newPos]) && glyphs[newPos].shaperInfo.position !== (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Pre_M) {\\n if (newPos + 1 < end && $7826f90f6f0cecc9$var$isJoiner(glyphs[newPos + 1])) newPos++;\\n } else newPos = start;\\n }\\n if (start < newPos && glyphs[newPos].shaperInfo.position !== (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Pre_M) {\\n for (let i = newPos; i > start; i--) if (glyphs[i - 1].shaperInfo.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Pre_M) {\\n let oldPos = i - 1;\\n if (oldPos < base && base <= newPos) base--;\\n let tmp = glyphs[oldPos];\\n glyphs.splice(oldPos, 0, ...glyphs.splice(oldPos + 1, newPos - oldPos));\\n glyphs[newPos] = tmp;\\n newPos--;\\n }\\n }\\n }\\n if (start + 1 < end && glyphs[start].shaperInfo.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Ra_To_Become_Reph && glyphs[start].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).Repha !== (glyphs[start].isLigated && !glyphs[start].isMultiplied)) {\\n let newRephPos;\\n let rephPos = indicConfig.rephPos;\\n let found = false;\\n if (rephPos !== (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).After_Post) {\\n newRephPos = start + 1;\\n while (newRephPos < base && !$7826f90f6f0cecc9$var$isHalantOrCoeng(glyphs[newRephPos])) newRephPos++;\\n if (newRephPos < base && $7826f90f6f0cecc9$var$isHalantOrCoeng(glyphs[newRephPos])) {\\n if (newRephPos + 1 < base && $7826f90f6f0cecc9$var$isJoiner(glyphs[newRephPos + 1])) newRephPos++;\\n found = true;\\n }\\n if (!found && rephPos === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).After_Main) {\\n newRephPos = base;\\n while (newRephPos + 1 < end && glyphs[newRephPos + 1].shaperInfo.position <= (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).After_Main) newRephPos++;\\n found = newRephPos < end;\\n }\\n if (!found && rephPos === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).After_Sub) {\\n newRephPos = base;\\n while (newRephPos + 1 < end && !(glyphs[newRephPos + 1].shaperInfo.position & ((0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Post_C | (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).After_Post | (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).SMVD))) newRephPos++;\\n found = newRephPos < end;\\n }\\n }\\n if (!found) {\\n newRephPos = start + 1;\\n while (newRephPos < base && !$7826f90f6f0cecc9$var$isHalantOrCoeng(glyphs[newRephPos])) newRephPos++;\\n if (newRephPos < base && $7826f90f6f0cecc9$var$isHalantOrCoeng(glyphs[newRephPos])) {\\n if (newRephPos + 1 < base && $7826f90f6f0cecc9$var$isJoiner(glyphs[newRephPos + 1])) newRephPos++;\\n found = true;\\n }\\n }\\n if (!found) {\\n newRephPos = end - 1;\\n while (newRephPos > start && glyphs[newRephPos].shaperInfo.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).SMVD) newRephPos--;\\n if ($7826f90f6f0cecc9$var$isHalantOrCoeng(glyphs[newRephPos])) {\\n for (let i = base + 1; i < newRephPos; i++) if (glyphs[i].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).M) newRephPos--;\\n }\\n }\\n let reph = glyphs[start];\\n glyphs.splice(start, 0, ...glyphs.splice(start + 1, newRephPos - start));\\n glyphs[newRephPos] = reph;\\n if (start < base && base <= newRephPos) base--;\\n }\\n if (tryPref && base + 1 < end) {\\n for (let i = base + 1; i < end; i++) if (glyphs[i].features.pref) {\\n if (glyphs[i].isLigated && !glyphs[i].isMultiplied) {\\n let newPos = base;\\n if (plan.unicodeScript !== \\\"Malayalam\\\" && plan.unicodeScript !== \\\"Tamil\\\") {\\n while (newPos > start && !(glyphs[newPos - 1].shaperInfo.category & ((0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).M | (0, $90a9d3398ee54fe5$export$ca9599b2a300afc)))) newPos--;\\n if (newPos > start && glyphs[newPos - 1].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).M) {\\n let oldPos2 = i;\\n for (let j = base + 1; j < oldPos2; j++) if (glyphs[j].shaperInfo.category === (0, $90a9d3398ee54fe5$export$a513ea61a7bee91c).M) {\\n newPos--;\\n break;\\n }\\n }\\n }\\n if (newPos > start && $7826f90f6f0cecc9$var$isHalantOrCoeng(glyphs[newPos - 1])) {\\n if (newPos < end && $7826f90f6f0cecc9$var$isJoiner(glyphs[newPos])) newPos++;\\n }\\n let oldPos = i;\\n let tmp = glyphs[oldPos];\\n glyphs.splice(newPos + 1, 0, ...glyphs.splice(newPos, oldPos - newPos));\\n glyphs[newPos] = tmp;\\n if (newPos <= base && base < oldPos) base++;\\n }\\n break;\\n }\\n }\\n if (glyphs[start].shaperInfo.position === (0, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0).Pre_M && (!start || !/Cf|Mn/.test((0, $747425b437e121da$export$410364bbb673ddbc)(glyphs[start - 1].codePoints[0])))) glyphs[start].features.init = true;\\n }\\n }\\n function $7826f90f6f0cecc9$var$nextSyllable(glyphs, start) {\\n if (start >= glyphs.length) return start;\\n let syllable = glyphs[start].shaperInfo.syllable;\\n while (++start < glyphs.length && glyphs[start].shaperInfo.syllable === syllable) ;\\n return start;\\n }\\n function $7ab494fe977143c6$var$useCategory(glyph) {\\n return $7ab494fe977143c6$var$trie.get(glyph.codePoints[0]);\\n }\\n function $7ab494fe977143c6$var$setupSyllables(font, glyphs) {\\n let syllable = 0;\\n for (let [start, end, tags] of $7ab494fe977143c6$var$stateMachine.match(glyphs.map($7ab494fe977143c6$var$useCategory))) {\\n ++syllable;\\n for (let i = start; i <= end; i++) glyphs[i].shaperInfo = new $7ab494fe977143c6$var$USEInfo($7ab494fe977143c6$var$categories[$7ab494fe977143c6$var$useCategory(glyphs[i])], tags[0], syllable);\\n let limit = glyphs[start].shaperInfo.category === \\\"R\\\" ? 1 : Math.min(3, end - start);\\n for (let i = start; i < start + limit; i++) glyphs[i].features.rphf = true;\\n }\\n }\\n function $7ab494fe977143c6$var$clearSubstitutionFlags(font, glyphs) {\\n for (let glyph of glyphs) glyph.substituted = false;\\n }\\n function $7ab494fe977143c6$var$recordRphf(font, glyphs) {\\n for (let glyph of glyphs) if (glyph.substituted && glyph.features.rphf)\\n glyph.shaperInfo.category = \\\"R\\\";\\n }\\n function $7ab494fe977143c6$var$recordPref(font, glyphs) {\\n for (let glyph of glyphs) if (glyph.substituted)\\n glyph.shaperInfo.category = \\\"VPre\\\";\\n }\\n function $7ab494fe977143c6$var$reorder(font, glyphs) {\\n let dottedCircle = font.glyphForCodePoint(9676).id;\\n for (let start = 0, end = $7ab494fe977143c6$var$nextSyllable(glyphs, 0); start < glyphs.length; start = end, end = $7ab494fe977143c6$var$nextSyllable(glyphs, start)) {\\n let i, j;\\n let info = glyphs[start].shaperInfo;\\n let type = info.syllableType;\\n if (type !== \\\"virama_terminated_cluster\\\" && type !== \\\"standard_cluster\\\" && type !== \\\"broken_cluster\\\") continue;\\n if (type === \\\"broken_cluster\\\" && dottedCircle) {\\n let g = new (0, $10e7b257e1a9a756$export$2e2bcd8739ae039)(font, dottedCircle, [\\n 9676\\n ]);\\n g.shaperInfo = info;\\n for (i = start; i < end && glyphs[i].shaperInfo.category === \\\"R\\\"; i++) ;\\n glyphs.splice(++i, 0, g);\\n end++;\\n }\\n if (info.category === \\\"R\\\" && end - start > 1)\\n for (i = start + 1; i < end; i++) {\\n info = glyphs[i].shaperInfo;\\n if ($7ab494fe977143c6$var$isBase(info) || $7ab494fe977143c6$var$isHalant(glyphs[i])) {\\n if ($7ab494fe977143c6$var$isHalant(glyphs[i])) i--;\\n glyphs.splice(start, 0, ...glyphs.splice(start + 1, i - start), glyphs[i]);\\n break;\\n }\\n }\\n for (i = start, j = end; i < end; i++) {\\n info = glyphs[i].shaperInfo;\\n if ($7ab494fe977143c6$var$isBase(info) || $7ab494fe977143c6$var$isHalant(glyphs[i]))\\n j = $7ab494fe977143c6$var$isHalant(glyphs[i]) ? i + 1 : i;\\n else if ((info.category === \\\"VPre\\\" || info.category === \\\"VMPre\\\") && j < i) glyphs.splice(j, 1, glyphs[i], ...glyphs.splice(j, i - j));\\n }\\n }\\n }\\n function $7ab494fe977143c6$var$nextSyllable(glyphs, start) {\\n if (start >= glyphs.length) return start;\\n let syllable = glyphs[start].shaperInfo.syllable;\\n while (++start < glyphs.length && glyphs[start].shaperInfo.syllable === syllable) ;\\n return start;\\n }\\n function $7ab494fe977143c6$var$isHalant(glyph) {\\n return glyph.shaperInfo.category === \\\"H\\\" && !glyph.isLigated;\\n }\\n function $7ab494fe977143c6$var$isBase(info) {\\n return info.category === \\\"B\\\" || info.category === \\\"GB\\\";\\n }\\n function $102b6fe50f1d50b4$export$7877a478dd30fd3d(script) {\\n if (!Array.isArray(script)) script = [\\n script\\n ];\\n for (let s of script) {\\n let shaper = $102b6fe50f1d50b4$var$SHAPERS[s];\\n if (shaper) return shaper;\\n }\\n return 0, $649970d87335b30f$export$2e2bcd8739ae039;\\n }\\n function $21ee218f84ac7f32$var$read255UInt16(stream) {\\n let code = stream.readUInt8();\\n if (code === $21ee218f84ac7f32$var$WORD_CODE) return stream.readUInt16BE();\\n if (code === $21ee218f84ac7f32$var$ONE_MORE_BYTE_CODE1) return stream.readUInt8() + $21ee218f84ac7f32$var$LOWEST_U_CODE;\\n if (code === $21ee218f84ac7f32$var$ONE_MORE_BYTE_CODE2) return stream.readUInt8() + $21ee218f84ac7f32$var$LOWEST_U_CODE * 2;\\n return code;\\n }\\n function $21ee218f84ac7f32$var$withSign(flag, baseval) {\\n return flag & 1 ? baseval : -baseval;\\n }\\n function $21ee218f84ac7f32$var$decodeTriplet(flags, glyphs, nPoints) {\\n let y;\\n let x = y = 0;\\n let res = [];\\n for (let i = 0; i < nPoints; i++) {\\n let dx = 0, dy = 0;\\n let flag = flags.readUInt8();\\n let onCurve = !(flag >> 7);\\n flag &= 127;\\n if (flag < 10) {\\n dx = 0;\\n dy = $21ee218f84ac7f32$var$withSign(flag, ((flag & 14) << 7) + glyphs.readUInt8());\\n } else if (flag < 20) {\\n dx = $21ee218f84ac7f32$var$withSign(flag, ((flag - 10 & 14) << 7) + glyphs.readUInt8());\\n dy = 0;\\n } else if (flag < 84) {\\n var b0 = flag - 20;\\n var b1 = glyphs.readUInt8();\\n dx = $21ee218f84ac7f32$var$withSign(flag, 1 + (b0 & 48) + (b1 >> 4));\\n dy = $21ee218f84ac7f32$var$withSign(flag >> 1, 1 + ((b0 & 12) << 2) + (b1 & 15));\\n } else if (flag < 120) {\\n var b0 = flag - 84;\\n dx = $21ee218f84ac7f32$var$withSign(flag, 1 + (b0 / 12 << 8) + glyphs.readUInt8());\\n dy = $21ee218f84ac7f32$var$withSign(flag >> 1, 1 + (b0 % 12 >> 2 << 8) + glyphs.readUInt8());\\n } else if (flag < 124) {\\n var b1 = glyphs.readUInt8();\\n let b2 = glyphs.readUInt8();\\n dx = $21ee218f84ac7f32$var$withSign(flag, (b1 << 4) + (b2 >> 4));\\n dy = $21ee218f84ac7f32$var$withSign(flag >> 1, ((b2 & 15) << 8) + glyphs.readUInt8());\\n } else {\\n dx = $21ee218f84ac7f32$var$withSign(flag, glyphs.readUInt16BE());\\n dy = $21ee218f84ac7f32$var$withSign(flag >> 1, glyphs.readUInt16BE());\\n }\\n x += dx;\\n y += dy;\\n res.push(new (0, $69aac16029968692$export$baf26146a414f24a)(onCurve, false, x, y));\\n }\\n return res;\\n }\\n var import_fast_deep_equal, import_unicode_trie2, import_dfa, import_clone, import_tiny_inflate, import_decompress, $d636bc798e7178db$exports, $d636bc798e7178db$export$bd5c5d8b8dcafd78, $d636bc798e7178db$var$formats, $d636bc798e7178db$export$42940898df819940, $26a62205ad06574e$var$SubHeader, $26a62205ad06574e$var$CmapGroup, $26a62205ad06574e$var$UnicodeValueRange, $26a62205ad06574e$var$UVSMapping, $26a62205ad06574e$var$DefaultUVS, $26a62205ad06574e$var$NonDefaultUVS, $26a62205ad06574e$var$VarSelectorRecord, $26a62205ad06574e$var$CmapSubtable, $26a62205ad06574e$var$CmapEntry, $26a62205ad06574e$export$2e2bcd8739ae039, $f2612a29f92ac062$export$2e2bcd8739ae039, $2c179dd593583073$export$2e2bcd8739ae039, $bdc9060542264b85$var$HmtxEntry, $bdc9060542264b85$export$2e2bcd8739ae039, $dbf51cb3d3fe409d$export$2e2bcd8739ae039, $e449ad78d50845fe$var$SINGLE_BYTE_ENCODINGS, $e449ad78d50845fe$var$MAC_ENCODINGS, $e449ad78d50845fe$var$encodingCache, $e449ad78d50845fe$export$6fef87b7618bdf0b, $e449ad78d50845fe$export$479e671907f486d1, $e449ad78d50845fe$export$2092376fd002e13, $2bcf221753ec8e32$var$NameRecord, $2bcf221753ec8e32$var$LangTagRecord, $2bcf221753ec8e32$var$NameTable, $2bcf221753ec8e32$export$2e2bcd8739ae039, $2bcf221753ec8e32$var$NAMES, $84b272aa31b70606$var$OS2, $84b272aa31b70606$var$versions, $84b272aa31b70606$export$2e2bcd8739ae039, $32d9e2eb9565d93c$export$2e2bcd8739ae039, $5202bd9d9ad8eaac$export$2e2bcd8739ae039, $5c0f37ca5ffb1850$export$2e2bcd8739ae039, $2b2b260902b1c57e$var$loca, $2b2b260902b1c57e$export$2e2bcd8739ae039, $7afb878c7bea4f66$export$2e2bcd8739ae039, $6c92b6371bce8bd9$export$2e2bcd8739ae039, $43e9821ef3717eec$export$2e2bcd8739ae039, $c2d28e92708f99da$var$FLOAT_EOF, $c2d28e92708f99da$var$FLOAT_LOOKUP, $c2d28e92708f99da$var$FLOAT_ENCODE_LOOKUP, $c2d28e92708f99da$export$2e2bcd8739ae039, $61aa549f16d58b9b$export$2e2bcd8739ae039, $0e34a43d05bde82c$export$2e2bcd8739ae039, $0e34a43d05bde82c$var$Ptr, $6d59db2e29cc77b3$var$CFFBlendOp, $6d59db2e29cc77b3$export$2e2bcd8739ae039, $229224aec43783c5$export$2e2bcd8739ae039, $bc0433d9b7e41f5f$export$dee0027060fa13bd, $bc0433d9b7e41f5f$export$4f58f497e14a53c3, $ef658f5c9a1488b2$export$c33b50336c234f16, $ef658f5c9a1488b2$export$3ed0f9e1fee8d489, $ef658f5c9a1488b2$export$dc28be11139d4120, $7cbbe4e24ef3cb75$var$LangSysTable, $7cbbe4e24ef3cb75$var$LangSysRecord, $7cbbe4e24ef3cb75$var$Script, $7cbbe4e24ef3cb75$var$ScriptRecord, $7cbbe4e24ef3cb75$export$3e15fc05ce864229, $7cbbe4e24ef3cb75$var$FeatureParams, $7cbbe4e24ef3cb75$export$6e91cf7616333d5, $7cbbe4e24ef3cb75$var$FeatureRecord, $7cbbe4e24ef3cb75$export$aa18130def4b6cb4, $7cbbe4e24ef3cb75$var$LookupFlags, $7cbbe4e24ef3cb75$var$RangeRecord, $7cbbe4e24ef3cb75$export$17608c3f81a6111, $7cbbe4e24ef3cb75$var$ClassRangeRecord, $7cbbe4e24ef3cb75$export$843d551fbbafef71, $7cbbe4e24ef3cb75$export$8215d14a63d9fb10, $7cbbe4e24ef3cb75$var$LookupRecord, $7cbbe4e24ef3cb75$var$Rule, $7cbbe4e24ef3cb75$var$RuleSet, $7cbbe4e24ef3cb75$var$ClassRule, $7cbbe4e24ef3cb75$var$ClassSet, $7cbbe4e24ef3cb75$export$841858b892ce1f4c, $7cbbe4e24ef3cb75$var$ChainRule, $7cbbe4e24ef3cb75$var$ChainRuleSet, $7cbbe4e24ef3cb75$export$5e6d09e6861162f6, $1a47b0c45c1c22fe$var$F2DOT14, $1a47b0c45c1c22fe$var$RegionAxisCoordinates, $1a47b0c45c1c22fe$var$VariationRegionList, $1a47b0c45c1c22fe$var$DeltaSet, $1a47b0c45c1c22fe$var$ItemVariationData, $1a47b0c45c1c22fe$export$fe1b122a2710f241, $1a47b0c45c1c22fe$var$ConditionTable, $1a47b0c45c1c22fe$var$ConditionSet, $1a47b0c45c1c22fe$var$FeatureTableSubstitutionRecord, $1a47b0c45c1c22fe$var$FeatureTableSubstitution, $1a47b0c45c1c22fe$var$FeatureVariationRecord, $1a47b0c45c1c22fe$export$441b70b7971dd419, $b84fd3dd9d8eddb2$var$PredefinedOp, $b84fd3dd9d8eddb2$var$CFFEncodingVersion, $b84fd3dd9d8eddb2$var$Range1, $b84fd3dd9d8eddb2$var$Range2, $b84fd3dd9d8eddb2$var$CFFCustomEncoding, $b84fd3dd9d8eddb2$var$CFFEncoding, $b84fd3dd9d8eddb2$var$RangeArray, $b84fd3dd9d8eddb2$var$CFFCustomCharset, $b84fd3dd9d8eddb2$var$CFFCharset, $b84fd3dd9d8eddb2$var$FDRange3, $b84fd3dd9d8eddb2$var$FDRange4, $b84fd3dd9d8eddb2$var$FDSelect, $b84fd3dd9d8eddb2$var$ptr, $b84fd3dd9d8eddb2$var$CFFPrivateOp, $b84fd3dd9d8eddb2$var$FontDict, $b84fd3dd9d8eddb2$var$CFFTopDict, $b84fd3dd9d8eddb2$var$VariationStore, $b84fd3dd9d8eddb2$var$CFF2TopDict, $b84fd3dd9d8eddb2$var$CFFTop, $b84fd3dd9d8eddb2$export$2e2bcd8739ae039, $822ac0d589e4e237$var$CFFFont, $822ac0d589e4e237$export$2e2bcd8739ae039, $2bbf2bc1ce37cd8f$var$VerticalOrigin, $2bbf2bc1ce37cd8f$export$2e2bcd8739ae039, $0941618dc22a946d$export$16b227cb15d716a0, $0941618dc22a946d$export$62c53e75f69bfe12, $0941618dc22a946d$var$EBDTComponent, $0941618dc22a946d$var$ByteAligned, $0941618dc22a946d$var$BitAligned, $0941618dc22a946d$export$f1f5ddeb20d14f, $9911c4c7201c13de$var$SBitLineMetrics, $9911c4c7201c13de$var$CodeOffsetPair, $9911c4c7201c13de$var$IndexSubtable, $9911c4c7201c13de$var$IndexSubtableArray, $9911c4c7201c13de$var$BitmapSizeTable, $9911c4c7201c13de$export$2e2bcd8739ae039, $abb847051efd51b1$var$ImageTable, $abb847051efd51b1$export$2e2bcd8739ae039, $eb629188f3dfefdd$var$LayerRecord, $eb629188f3dfefdd$var$BaseGlyphRecord, $eb629188f3dfefdd$export$2e2bcd8739ae039, $08734b8e7dc64587$var$ColorRecord, $08734b8e7dc64587$export$2e2bcd8739ae039, $497cef411d884e34$var$BaseCoord, $497cef411d884e34$var$BaseValues, $497cef411d884e34$var$FeatMinMaxRecord, $497cef411d884e34$var$MinMax, $497cef411d884e34$var$BaseLangSysRecord, $497cef411d884e34$var$BaseScript, $497cef411d884e34$var$BaseScriptRecord, $497cef411d884e34$var$BaseScriptList, $497cef411d884e34$var$BaseTagList, $497cef411d884e34$var$Axis, $497cef411d884e34$export$2e2bcd8739ae039, $cf5f33c63ef209e6$var$AttachPoint, $cf5f33c63ef209e6$var$AttachList, $cf5f33c63ef209e6$var$CaretValue, $cf5f33c63ef209e6$var$LigGlyph, $cf5f33c63ef209e6$var$LigCaretList, $cf5f33c63ef209e6$var$MarkGlyphSetsDef, $cf5f33c63ef209e6$export$2e2bcd8739ae039, $47e0e8ef515d9903$var$ValueFormat, $47e0e8ef515d9903$var$types, $47e0e8ef515d9903$var$ValueRecord, $47e0e8ef515d9903$var$PairValueRecord, $47e0e8ef515d9903$var$PairSet, $47e0e8ef515d9903$var$Class2Record, $47e0e8ef515d9903$var$Anchor, $47e0e8ef515d9903$var$EntryExitRecord, $47e0e8ef515d9903$var$MarkRecord, $47e0e8ef515d9903$var$MarkArray, $47e0e8ef515d9903$var$BaseRecord, $47e0e8ef515d9903$var$BaseArray, $47e0e8ef515d9903$var$ComponentRecord, $47e0e8ef515d9903$var$LigatureAttach, $47e0e8ef515d9903$var$LigatureArray, $47e0e8ef515d9903$export$73a8cfb19cd43a0f, $47e0e8ef515d9903$export$2e2bcd8739ae039, $d3f442064af66e06$var$Sequence, $d3f442064af66e06$var$AlternateSet, $d3f442064af66e06$var$Ligature, $d3f442064af66e06$var$LigatureSet, $d3f442064af66e06$var$GSUBLookup, $d3f442064af66e06$export$2e2bcd8739ae039, $71cfb3c4767fbd0c$var$JstfGSUBModList, $71cfb3c4767fbd0c$var$JstfPriority, $71cfb3c4767fbd0c$var$JstfLangSys, $71cfb3c4767fbd0c$var$JstfLangSysRecord, $71cfb3c4767fbd0c$var$JstfScript, $71cfb3c4767fbd0c$var$JstfScriptRecord, $71cfb3c4767fbd0c$export$2e2bcd8739ae039, $d059a6bd2d3b5b63$var$VariableSizeNumber, $d059a6bd2d3b5b63$var$MapDataEntry, $d059a6bd2d3b5b63$var$DeltaSetIndexMap, $d059a6bd2d3b5b63$export$2e2bcd8739ae039, $dceeca3e1977ce30$var$Signature, $dceeca3e1977ce30$var$SignatureBlock, $dceeca3e1977ce30$export$2e2bcd8739ae039, $8acd740a9435aad0$var$GaspRange, $8acd740a9435aad0$export$2e2bcd8739ae039, $b5f380243c34d6a0$var$DeviceRecord, $b5f380243c34d6a0$export$2e2bcd8739ae039, $ca2df1256966e313$var$KernPair, $ca2df1256966e313$var$ClassTable, $ca2df1256966e313$var$Kern2Array, $ca2df1256966e313$var$KernSubtable, $ca2df1256966e313$var$KernTable, $ca2df1256966e313$export$2e2bcd8739ae039, $7a9f92b0c46ebe33$export$2e2bcd8739ae039, $2b2ccc419d152631$export$2e2bcd8739ae039, $ca5b40b9bcda9c9b$var$Ratio, $ca5b40b9bcda9c9b$var$vTable, $ca5b40b9bcda9c9b$var$VdmxGroup, $ca5b40b9bcda9c9b$export$2e2bcd8739ae039, $69530a3c40755af0$export$2e2bcd8739ae039, $344073dd270f0e62$var$VmtxEntry, $344073dd270f0e62$export$2e2bcd8739ae039, $3793b781918cfced$var$shortFrac, $3793b781918cfced$var$Correspondence, $3793b781918cfced$var$Segment, $3793b781918cfced$export$2e2bcd8739ae039, $6cb7dd5f47d82580$var$UnboundedArrayAccessor, $6cb7dd5f47d82580$export$c5af1eebc882e39a, $6cb7dd5f47d82580$export$8351f8c2ae2f103c, $6a3746e8c708f5a3$var$BslnSubtable, $6a3746e8c708f5a3$export$2e2bcd8739ae039, $d0c76fac617b308a$var$Setting, $d0c76fac617b308a$var$FeatureName, $d0c76fac617b308a$export$2e2bcd8739ae039, $e83fd065f00fcd01$var$Axis, $e83fd065f00fcd01$var$Instance, $e83fd065f00fcd01$export$2e2bcd8739ae039, $dbe33c8d3a7f131c$var$shortFrac, $dbe33c8d3a7f131c$var$Offset, $dbe33c8d3a7f131c$var$gvar, $dbe33c8d3a7f131c$export$2e2bcd8739ae039, $05b01887df96c4ee$var$ClassTable, $05b01887df96c4ee$var$WidthDeltaRecord, $05b01887df96c4ee$var$WidthDeltaCluster, $05b01887df96c4ee$var$ActionData, $05b01887df96c4ee$var$Action, $05b01887df96c4ee$var$PostcompensationAction, $05b01887df96c4ee$var$PostCompensationTable, $05b01887df96c4ee$var$JustificationTable, $05b01887df96c4ee$export$2e2bcd8739ae039, $03ee6ebd54db1053$var$LigatureData, $03ee6ebd54db1053$var$ContextualData, $03ee6ebd54db1053$var$InsertionData, $03ee6ebd54db1053$var$SubstitutionTable, $03ee6ebd54db1053$var$SubtableData, $03ee6ebd54db1053$var$Subtable, $03ee6ebd54db1053$var$FeatureEntry, $03ee6ebd54db1053$var$MorxChain, $03ee6ebd54db1053$export$2e2bcd8739ae039, $b7492a80b0d1a056$var$OpticalBounds, $b7492a80b0d1a056$export$2e2bcd8739ae039, $c3395722bea751e2$var$tables, $c3395722bea751e2$export$2e2bcd8739ae039, $816c07a04b6dba87$var$TableEntry, $816c07a04b6dba87$var$Directory, $816c07a04b6dba87$export$2e2bcd8739ae039, $12727730ddfc8bfe$export$3d28c1996ced1f14, $12727730ddfc8bfe$var$CHARS, $12727730ddfc8bfe$var$LOOKUP, $f08dd41ef10b694c$export$2e2bcd8739ae039, $0bba3a9db57637f3$export$2e2bcd8739ae039, $0a4bdfeb6dfd6f5e$export$2e2bcd8739ae039, $f34600ab9d7f70d8$export$2e2bcd8739ae039, $130d1a642ebcd2b7$var$UNICODE_SCRIPTS, $130d1a642ebcd2b7$var$OPENTYPE_SCRIPTS, $130d1a642ebcd2b7$var$RTL, $be07b3e97a42687a$export$2e2bcd8739ae039, $1ac75d9a55b67f01$export$2e2bcd8739ae039, $3b6302b64eccc32c$var$features, $3b6302b64eccc32c$var$feature, $3b6302b64eccc32c$var$OTMapping, $3b6302b64eccc32c$var$AATMapping, $ff5ce077dae0f144$export$2e2bcd8739ae039, $50c7aac9316f2948$var$START_OF_TEXT_STATE, $50c7aac9316f2948$var$END_OF_TEXT_CLASS, $50c7aac9316f2948$var$OUT_OF_BOUNDS_CLASS, $50c7aac9316f2948$var$DELETED_GLYPH_CLASS, $50c7aac9316f2948$var$DONT_ADVANCE, $50c7aac9316f2948$export$2e2bcd8739ae039, $55f71433a605c87d$var$MARK_FIRST, $55f71433a605c87d$var$MARK_LAST, $55f71433a605c87d$var$VERB, $55f71433a605c87d$var$SET_MARK, $55f71433a605c87d$var$SET_COMPONENT, $55f71433a605c87d$var$PERFORM_ACTION, $55f71433a605c87d$var$LAST_MASK, $55f71433a605c87d$var$STORE_MASK, $55f71433a605c87d$var$OFFSET_MASK, $55f71433a605c87d$var$REVERSE_DIRECTION, $55f71433a605c87d$var$CURRENT_INSERT_BEFORE, $55f71433a605c87d$var$MARKED_INSERT_BEFORE, $55f71433a605c87d$var$CURRENT_INSERT_COUNT, $55f71433a605c87d$var$MARKED_INSERT_COUNT, $55f71433a605c87d$export$2e2bcd8739ae039, $ba6dd74203be8728$export$2e2bcd8739ae039, $94d7a73bd2edfc9a$export$2e2bcd8739ae039, $649970d87335b30f$var$VARIATION_FEATURES, $649970d87335b30f$var$COMMON_FEATURES, $649970d87335b30f$var$FRACTIONAL_FEATURES, $649970d87335b30f$var$HORIZONTAL_FEATURES, $649970d87335b30f$var$DIRECTIONAL_FEATURES, $649970d87335b30f$export$2e2bcd8739ae039, $764eb544bbe1ccf0$var$trie, $764eb544bbe1ccf0$var$FEATURES, $764eb544bbe1ccf0$var$ShapingClasses, $764eb544bbe1ccf0$var$ISOL, $764eb544bbe1ccf0$var$FINA, $764eb544bbe1ccf0$var$FIN2, $764eb544bbe1ccf0$var$FIN3, $764eb544bbe1ccf0$var$MEDI, $764eb544bbe1ccf0$var$MED2, $764eb544bbe1ccf0$var$INIT, $764eb544bbe1ccf0$var$NONE, $764eb544bbe1ccf0$var$STATE_TABLE, $764eb544bbe1ccf0$export$2e2bcd8739ae039, $85d408632270248b$export$2e2bcd8739ae039, $a83b9c36aaa94fd3$var$DEFAULT_SCRIPTS, $a83b9c36aaa94fd3$export$2e2bcd8739ae039, $10e7b257e1a9a756$export$2e2bcd8739ae039, $e1c6bbc8cb416f8c$export$2e2bcd8739ae039, $e1c6bbc8cb416f8c$var$HANGUL_BASE, $e1c6bbc8cb416f8c$var$HANGUL_END, $e1c6bbc8cb416f8c$var$HANGUL_COUNT, $e1c6bbc8cb416f8c$var$L_BASE, $e1c6bbc8cb416f8c$var$V_BASE, $e1c6bbc8cb416f8c$var$T_BASE, $e1c6bbc8cb416f8c$var$L_COUNT, $e1c6bbc8cb416f8c$var$V_COUNT, $e1c6bbc8cb416f8c$var$T_COUNT, $e1c6bbc8cb416f8c$var$L_END, $e1c6bbc8cb416f8c$var$V_END, $e1c6bbc8cb416f8c$var$T_END, $e1c6bbc8cb416f8c$var$DOTTED_CIRCLE, $e1c6bbc8cb416f8c$var$isL, $e1c6bbc8cb416f8c$var$isV, $e1c6bbc8cb416f8c$var$isT, $e1c6bbc8cb416f8c$var$isTone, $e1c6bbc8cb416f8c$var$isLVT, $e1c6bbc8cb416f8c$var$isLV, $e1c6bbc8cb416f8c$var$isCombiningL, $e1c6bbc8cb416f8c$var$isCombiningV, $e1c6bbc8cb416f8c$var$isCombiningT, $e1c6bbc8cb416f8c$var$X, $e1c6bbc8cb416f8c$var$L, $e1c6bbc8cb416f8c$var$V, $e1c6bbc8cb416f8c$var$T, $e1c6bbc8cb416f8c$var$LV, $e1c6bbc8cb416f8c$var$LVT, $e1c6bbc8cb416f8c$var$M, $e1c6bbc8cb416f8c$var$NO_ACTION, $e1c6bbc8cb416f8c$var$DECOMPOSE, $e1c6bbc8cb416f8c$var$COMPOSE, $e1c6bbc8cb416f8c$var$TONE_MARK, $e1c6bbc8cb416f8c$var$INVALID, $e1c6bbc8cb416f8c$var$STATE_TABLE, $4b0735ca6c692ea5$exports, $aa333a9607471296$exports, $90a9d3398ee54fe5$export$a513ea61a7bee91c, $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0, $90a9d3398ee54fe5$export$8519deaa7de2b07, $90a9d3398ee54fe5$export$bbcd928767338e0d, $90a9d3398ee54fe5$export$ca9599b2a300afc, $90a9d3398ee54fe5$export$e99d119da76a0fc5, $90a9d3398ee54fe5$export$f647c9cfdd77d95a, $7826f90f6f0cecc9$var$decompositions, $7826f90f6f0cecc9$var$trie, $7826f90f6f0cecc9$var$stateMachine, $7826f90f6f0cecc9$export$2e2bcd8739ae039, $7826f90f6f0cecc9$var$IndicInfo, $7ab494fe977143c6$var$categories, $7ab494fe977143c6$var$decompositions, $7ab494fe977143c6$var$trie, $7ab494fe977143c6$var$stateMachine, $7ab494fe977143c6$export$2e2bcd8739ae039, $7ab494fe977143c6$var$USEInfo, $102b6fe50f1d50b4$var$SHAPERS, $0a876c45f1f7c41c$export$2e2bcd8739ae039, $c96c93587d49c14d$export$2e2bcd8739ae039, $a62492810de27e3d$export$2e2bcd8739ae039, $4c0a7fa5df7a9ab1$export$2e2bcd8739ae039, $f43aec954cdfdf21$var$SVG_COMMANDS, $f43aec954cdfdf21$export$2e2bcd8739ae039, $7713b9b7b438dff8$export$2e2bcd8739ae039, $f92906be28e61769$export$2e2bcd8739ae039, $69aac16029968692$var$GlyfHeader, $69aac16029968692$var$ON_CURVE, $69aac16029968692$var$X_SHORT_VECTOR, $69aac16029968692$var$Y_SHORT_VECTOR, $69aac16029968692$var$REPEAT, $69aac16029968692$var$SAME_X, $69aac16029968692$var$SAME_Y, $69aac16029968692$var$ARG_1_AND_2_ARE_WORDS, $69aac16029968692$var$WE_HAVE_A_SCALE, $69aac16029968692$var$MORE_COMPONENTS, $69aac16029968692$var$WE_HAVE_AN_X_AND_Y_SCALE, $69aac16029968692$var$WE_HAVE_A_TWO_BY_TWO, $69aac16029968692$var$WE_HAVE_INSTRUCTIONS, $69aac16029968692$export$baf26146a414f24a, $69aac16029968692$var$Component, $69aac16029968692$export$2e2bcd8739ae039, $62cc5109c6101893$export$2e2bcd8739ae039, $25d8f049c222084c$var$SBIXImage, $25d8f049c222084c$export$2e2bcd8739ae039, $0d411f0165859681$var$COLRLayer, $0d411f0165859681$export$2e2bcd8739ae039, $0bb840cac04e911b$var$TUPLES_SHARE_POINT_NUMBERS, $0bb840cac04e911b$var$TUPLE_COUNT_MASK, $0bb840cac04e911b$var$EMBEDDED_TUPLE_COORD, $0bb840cac04e911b$var$INTERMEDIATE_TUPLE, $0bb840cac04e911b$var$PRIVATE_POINT_NUMBERS, $0bb840cac04e911b$var$TUPLE_INDEX_MASK, $0bb840cac04e911b$var$POINTS_ARE_WORDS, $0bb840cac04e911b$var$POINT_RUN_COUNT_MASK, $0bb840cac04e911b$var$DELTAS_ARE_ZERO, $0bb840cac04e911b$var$DELTAS_ARE_WORDS, $0bb840cac04e911b$var$DELTA_RUN_COUNT_MASK, $0bb840cac04e911b$export$2e2bcd8739ae039, $5cc7476da92df375$var$resolved, $5cc7476da92df375$export$2e2bcd8739ae039, $807e58506be70005$var$ON_CURVE, $807e58506be70005$var$X_SHORT_VECTOR, $807e58506be70005$var$Y_SHORT_VECTOR, $807e58506be70005$var$REPEAT, $807e58506be70005$var$SAME_X, $807e58506be70005$var$SAME_Y, $807e58506be70005$var$Point, $807e58506be70005$var$Glyf, $807e58506be70005$export$2e2bcd8739ae039, $4abbb6a5dbdc441a$export$2e2bcd8739ae039, $001d739428a71d5a$export$2e2bcd8739ae039, $4c1709dee528ea76$export$2e2bcd8739ae039, $c1726355ecc5b889$var$WOFFDirectoryEntry, $c1726355ecc5b889$var$WOFFDirectory, $c1726355ecc5b889$export$2e2bcd8739ae039, $760785214b9fc52c$export$2e2bcd8739ae039, $8046190c9f1ad19e$export$2e2bcd8739ae039, $c28ec7bbb3b8de3a$var$Base128, $c28ec7bbb3b8de3a$var$knownTags, $c28ec7bbb3b8de3a$var$WOFF2DirectoryEntry, $c28ec7bbb3b8de3a$var$WOFF2Directory, $c28ec7bbb3b8de3a$export$2e2bcd8739ae039, $21ee218f84ac7f32$export$2e2bcd8739ae039, $21ee218f84ac7f32$var$Substream, $21ee218f84ac7f32$var$GlyfTable, $21ee218f84ac7f32$var$WORD_CODE, $21ee218f84ac7f32$var$ONE_MORE_BYTE_CODE2, $21ee218f84ac7f32$var$ONE_MORE_BYTE_CODE1, $21ee218f84ac7f32$var$LOWEST_U_CODE, $cd5853a56c68fec7$var$TTCHeader, $cd5853a56c68fec7$export$2e2bcd8739ae039, $05f49f930186144e$var$DFontName, $05f49f930186144e$var$DFontData, $05f49f930186144e$var$Ref, $05f49f930186144e$var$Type, $05f49f930186144e$var$TypeList, $05f49f930186144e$var$DFontMap, $05f49f930186144e$var$DFontHeader, $05f49f930186144e$export$2e2bcd8739ae039;\\n var init_browser_module = __esm({\\n \\\"../../node_modules/.pnpm/fontkit@2.0.4/node_modules/fontkit/dist/browser-module.mjs\\\"() {\\n init_restructure();\\n init_define_property();\\n init_ts_decorate();\\n import_fast_deep_equal = __toESM(require_fast_deep_equal(), 1);\\n init_module();\\n import_unicode_trie2 = __toESM(require_unicode_trie(), 1);\\n import_dfa = __toESM(require_dfa(), 1);\\n import_clone = __toESM(require_clone(), 1);\\n import_tiny_inflate = __toESM(require_tiny_inflate(), 1);\\n import_decompress = __toESM(require_decompress(), 1);\\n $d636bc798e7178db$exports = {};\\n $parcel$export($d636bc798e7178db$exports, \\\"logErrors\\\", () => $d636bc798e7178db$export$bd5c5d8b8dcafd78);\\n $parcel$export($d636bc798e7178db$exports, \\\"registerFormat\\\", () => $d636bc798e7178db$export$36b2f24e97d43be);\\n $parcel$export($d636bc798e7178db$exports, \\\"create\\\", () => $d636bc798e7178db$export$185802fd694ee1f5);\\n $parcel$export($d636bc798e7178db$exports, \\\"defaultLanguage\\\", () => $d636bc798e7178db$export$42940898df819940);\\n $parcel$export($d636bc798e7178db$exports, \\\"setDefaultLanguage\\\", () => $d636bc798e7178db$export$5157e7780d44cc36);\\n $d636bc798e7178db$export$bd5c5d8b8dcafd78 = false;\\n $d636bc798e7178db$var$formats = [];\\n $d636bc798e7178db$export$42940898df819940 = \\\"en\\\";\\n $26a62205ad06574e$var$SubHeader = new Struct({\\n firstCode: uint16,\\n entryCount: uint16,\\n idDelta: int16,\\n idRangeOffset: uint16\\n });\\n $26a62205ad06574e$var$CmapGroup = new Struct({\\n startCharCode: uint32,\\n endCharCode: uint32,\\n glyphID: uint32\\n });\\n $26a62205ad06574e$var$UnicodeValueRange = new Struct({\\n startUnicodeValue: uint24,\\n additionalCount: uint8\\n });\\n $26a62205ad06574e$var$UVSMapping = new Struct({\\n unicodeValue: uint24,\\n glyphID: uint16\\n });\\n $26a62205ad06574e$var$DefaultUVS = new ArrayT($26a62205ad06574e$var$UnicodeValueRange, uint32);\\n $26a62205ad06574e$var$NonDefaultUVS = new ArrayT($26a62205ad06574e$var$UVSMapping, uint32);\\n $26a62205ad06574e$var$VarSelectorRecord = new Struct({\\n varSelector: uint24,\\n defaultUVS: new Pointer(uint32, $26a62205ad06574e$var$DefaultUVS, {\\n type: \\\"parent\\\"\\n }),\\n nonDefaultUVS: new Pointer(uint32, $26a62205ad06574e$var$NonDefaultUVS, {\\n type: \\\"parent\\\"\\n })\\n });\\n $26a62205ad06574e$var$CmapSubtable = new VersionedStruct(uint16, {\\n 0: {\\n length: uint16,\\n language: uint16,\\n codeMap: new LazyArray(uint8, 256)\\n },\\n 2: {\\n length: uint16,\\n language: uint16,\\n subHeaderKeys: new ArrayT(uint16, 256),\\n subHeaderCount: (t) => Math.max.apply(Math, t.subHeaderKeys),\\n subHeaders: new LazyArray($26a62205ad06574e$var$SubHeader, \\\"subHeaderCount\\\"),\\n glyphIndexArray: new LazyArray(uint16, \\\"subHeaderCount\\\")\\n },\\n 4: {\\n length: uint16,\\n language: uint16,\\n segCountX2: uint16,\\n segCount: (t) => t.segCountX2 >> 1,\\n searchRange: uint16,\\n entrySelector: uint16,\\n rangeShift: uint16,\\n endCode: new LazyArray(uint16, \\\"segCount\\\"),\\n reservedPad: new Reserved(uint16),\\n startCode: new LazyArray(uint16, \\\"segCount\\\"),\\n idDelta: new LazyArray(int16, \\\"segCount\\\"),\\n idRangeOffset: new LazyArray(uint16, \\\"segCount\\\"),\\n glyphIndexArray: new LazyArray(uint16, (t) => (t.length - t._currentOffset) / 2)\\n },\\n 6: {\\n length: uint16,\\n language: uint16,\\n firstCode: uint16,\\n entryCount: uint16,\\n glyphIndices: new LazyArray(uint16, \\\"entryCount\\\")\\n },\\n 8: {\\n reserved: new Reserved(uint16),\\n length: uint32,\\n language: uint16,\\n is32: new LazyArray(uint8, 8192),\\n nGroups: uint32,\\n groups: new LazyArray($26a62205ad06574e$var$CmapGroup, \\\"nGroups\\\")\\n },\\n 10: {\\n reserved: new Reserved(uint16),\\n length: uint32,\\n language: uint32,\\n firstCode: uint32,\\n entryCount: uint32,\\n glyphIndices: new LazyArray(uint16, \\\"numChars\\\")\\n },\\n 12: {\\n reserved: new Reserved(uint16),\\n length: uint32,\\n language: uint32,\\n nGroups: uint32,\\n groups: new LazyArray($26a62205ad06574e$var$CmapGroup, \\\"nGroups\\\")\\n },\\n 13: {\\n reserved: new Reserved(uint16),\\n length: uint32,\\n language: uint32,\\n nGroups: uint32,\\n groups: new LazyArray($26a62205ad06574e$var$CmapGroup, \\\"nGroups\\\")\\n },\\n 14: {\\n length: uint32,\\n numRecords: uint32,\\n varSelectors: new LazyArray($26a62205ad06574e$var$VarSelectorRecord, \\\"numRecords\\\")\\n }\\n });\\n $26a62205ad06574e$var$CmapEntry = new Struct({\\n platformID: uint16,\\n encodingID: uint16,\\n table: new Pointer(uint32, $26a62205ad06574e$var$CmapSubtable, {\\n type: \\\"parent\\\",\\n lazy: true\\n })\\n });\\n $26a62205ad06574e$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n numSubtables: uint16,\\n tables: new ArrayT($26a62205ad06574e$var$CmapEntry, \\\"numSubtables\\\")\\n });\\n $f2612a29f92ac062$export$2e2bcd8739ae039 = new Struct({\\n version: int32,\\n revision: int32,\\n checkSumAdjustment: uint32,\\n magicNumber: uint32,\\n flags: uint16,\\n unitsPerEm: uint16,\\n created: new ArrayT(int32, 2),\\n modified: new ArrayT(int32, 2),\\n xMin: int16,\\n yMin: int16,\\n xMax: int16,\\n yMax: int16,\\n macStyle: new Bitfield(uint16, [\\n \\\"bold\\\",\\n \\\"italic\\\",\\n \\\"underline\\\",\\n \\\"outline\\\",\\n \\\"shadow\\\",\\n \\\"condensed\\\",\\n \\\"extended\\\"\\n ]),\\n lowestRecPPEM: uint16,\\n fontDirectionHint: int16,\\n indexToLocFormat: int16,\\n glyphDataFormat: int16\\n // 0 for current format\\n });\\n $2c179dd593583073$export$2e2bcd8739ae039 = new Struct({\\n version: int32,\\n ascent: int16,\\n descent: int16,\\n lineGap: int16,\\n advanceWidthMax: uint16,\\n minLeftSideBearing: int16,\\n minRightSideBearing: int16,\\n xMaxExtent: int16,\\n caretSlopeRise: int16,\\n caretSlopeRun: int16,\\n caretOffset: int16,\\n reserved: new Reserved(int16, 4),\\n metricDataFormat: int16,\\n numberOfMetrics: uint16\\n // Number of advance widths in 'hmtx' table\\n });\\n $bdc9060542264b85$var$HmtxEntry = new Struct({\\n advance: uint16,\\n bearing: int16\\n });\\n $bdc9060542264b85$export$2e2bcd8739ae039 = new Struct({\\n metrics: new LazyArray($bdc9060542264b85$var$HmtxEntry, (t) => t.parent.hhea.numberOfMetrics),\\n bearings: new LazyArray(int16, (t) => t.parent.maxp.numGlyphs - t.parent.hhea.numberOfMetrics)\\n });\\n $dbf51cb3d3fe409d$export$2e2bcd8739ae039 = new Struct({\\n version: int32,\\n numGlyphs: uint16,\\n maxPoints: uint16,\\n maxContours: uint16,\\n maxComponentPoints: uint16,\\n maxComponentContours: uint16,\\n maxZones: uint16,\\n maxTwilightPoints: uint16,\\n maxStorage: uint16,\\n maxFunctionDefs: uint16,\\n maxInstructionDefs: uint16,\\n maxStackElements: uint16,\\n maxSizeOfInstructions: uint16,\\n maxComponentElements: uint16,\\n maxComponentDepth: uint16\\n // Maximum levels of recursion; 1 for simple components\\n });\\n $e449ad78d50845fe$var$SINGLE_BYTE_ENCODINGS = /* @__PURE__ */ new Set([\\n \\\"x-mac-roman\\\",\\n \\\"x-mac-cyrillic\\\",\\n \\\"iso-8859-6\\\",\\n \\\"iso-8859-8\\\"\\n ]);\\n $e449ad78d50845fe$var$MAC_ENCODINGS = {\\n \\\"x-mac-croatian\\\": \\\"\\\\xC4\\\\xC5\\\\xC7\\\\xC9\\\\xD1\\\\xD6\\\\xDC\\\\xE1\\\\xE0\\\\xE2\\\\xE4\\\\xE3\\\\xE5\\\\xE7\\\\xE9\\\\xE8\\\\xEA\\\\xEB\\\\xED\\\\xEC\\\\xEE\\\\xEF\\\\xF1\\\\xF3\\\\xF2\\\\xF4\\\\xF6\\\\xF5\\\\xFA\\\\xF9\\\\xFB\\\\xFC\\\\u2020\\\\xB0\\\\xA2\\\\xA3\\\\xA7\\\\u2022\\\\xB6\\\\xDF\\\\xAE\\\\u0160\\\\u2122\\\\xB4\\\\xA8\\\\u2260\\\\u017D\\\\xD8\\\\u221E\\\\xB1\\\\u2264\\\\u2265\\\\u2206\\\\xB5\\\\u2202\\\\u2211\\\\u220F\\\\u0161\\\\u222B\\\\xAA\\\\xBA\\\\u03A9\\\\u017E\\\\xF8\\\\xBF\\\\xA1\\\\xAC\\\\u221A\\\\u0192\\\\u2248\\\\u0106\\\\xAB\\\\u010C\\\\u2026 \\\\xC0\\\\xC3\\\\xD5\\\\u0152\\\\u0153\\\\u0110\\\\u2014\\\\u201C\\\\u201D\\\\u2018\\\\u2019\\\\xF7\\\\u25CA\\\\uF8FF\\\\xA9\\\\u2044\\\\u20AC\\\\u2039\\\\u203A\\\\xC6\\\\xBB\\\\u2013\\\\xB7\\\\u201A\\\\u201E\\\\u2030\\\\xC2\\\\u0107\\\\xC1\\\\u010D\\\\xC8\\\\xCD\\\\xCE\\\\xCF\\\\xCC\\\\xD3\\\\xD4\\\\u0111\\\\xD2\\\\xDA\\\\xDB\\\\xD9\\\\u0131\\\\u02C6\\\\u02DC\\\\xAF\\\\u03C0\\\\xCB\\\\u02DA\\\\xB8\\\\xCA\\\\xE6\\\\u02C7\\\",\\n \\\"x-mac-gaelic\\\": \\\"\\\\xC4\\\\xC5\\\\xC7\\\\xC9\\\\xD1\\\\xD6\\\\xDC\\\\xE1\\\\xE0\\\\xE2\\\\xE4\\\\xE3\\\\xE5\\\\xE7\\\\xE9\\\\xE8\\\\xEA\\\\xEB\\\\xED\\\\xEC\\\\xEE\\\\xEF\\\\xF1\\\\xF3\\\\xF2\\\\xF4\\\\xF6\\\\xF5\\\\xFA\\\\xF9\\\\xFB\\\\xFC\\\\u2020\\\\xB0\\\\xA2\\\\xA3\\\\xA7\\\\u2022\\\\xB6\\\\xDF\\\\xAE\\\\xA9\\\\u2122\\\\xB4\\\\xA8\\\\u2260\\\\xC6\\\\xD8\\\\u1E02\\\\xB1\\\\u2264\\\\u2265\\\\u1E03\\\\u010A\\\\u010B\\\\u1E0A\\\\u1E0B\\\\u1E1E\\\\u1E1F\\\\u0120\\\\u0121\\\\u1E40\\\\xE6\\\\xF8\\\\u1E41\\\\u1E56\\\\u1E57\\\\u027C\\\\u0192\\\\u017F\\\\u1E60\\\\xAB\\\\xBB\\\\u2026 \\\\xC0\\\\xC3\\\\xD5\\\\u0152\\\\u0153\\\\u2013\\\\u2014\\\\u201C\\\\u201D\\\\u2018\\\\u2019\\\\u1E61\\\\u1E9B\\\\xFF\\\\u0178\\\\u1E6A\\\\u20AC\\\\u2039\\\\u203A\\\\u0176\\\\u0177\\\\u1E6B\\\\xB7\\\\u1EF2\\\\u1EF3\\\\u204A\\\\xC2\\\\xCA\\\\xC1\\\\xCB\\\\xC8\\\\xCD\\\\xCE\\\\xCF\\\\xCC\\\\xD3\\\\xD4\\\\u2663\\\\xD2\\\\xDA\\\\xDB\\\\xD9\\\\u0131\\\\xDD\\\\xFD\\\\u0174\\\\u0175\\\\u1E84\\\\u1E85\\\\u1E80\\\\u1E81\\\\u1E82\\\\u1E83\\\",\\n \\\"x-mac-greek\\\": \\\"\\\\xC4\\\\xB9\\\\xB2\\\\xC9\\\\xB3\\\\xD6\\\\xDC\\\\u0385\\\\xE0\\\\xE2\\\\xE4\\\\u0384\\\\xA8\\\\xE7\\\\xE9\\\\xE8\\\\xEA\\\\xEB\\\\xA3\\\\u2122\\\\xEE\\\\xEF\\\\u2022\\\\xBD\\\\u2030\\\\xF4\\\\xF6\\\\xA6\\\\u20AC\\\\xF9\\\\xFB\\\\xFC\\\\u2020\\\\u0393\\\\u0394\\\\u0398\\\\u039B\\\\u039E\\\\u03A0\\\\xDF\\\\xAE\\\\xA9\\\\u03A3\\\\u03AA\\\\xA7\\\\u2260\\\\xB0\\\\xB7\\\\u0391\\\\xB1\\\\u2264\\\\u2265\\\\xA5\\\\u0392\\\\u0395\\\\u0396\\\\u0397\\\\u0399\\\\u039A\\\\u039C\\\\u03A6\\\\u03AB\\\\u03A8\\\\u03A9\\\\u03AC\\\\u039D\\\\xAC\\\\u039F\\\\u03A1\\\\u2248\\\\u03A4\\\\xAB\\\\xBB\\\\u2026 \\\\u03A5\\\\u03A7\\\\u0386\\\\u0388\\\\u0153\\\\u2013\\\\u2015\\\\u201C\\\\u201D\\\\u2018\\\\u2019\\\\xF7\\\\u0389\\\\u038A\\\\u038C\\\\u038E\\\\u03AD\\\\u03AE\\\\u03AF\\\\u03CC\\\\u038F\\\\u03CD\\\\u03B1\\\\u03B2\\\\u03C8\\\\u03B4\\\\u03B5\\\\u03C6\\\\u03B3\\\\u03B7\\\\u03B9\\\\u03BE\\\\u03BA\\\\u03BB\\\\u03BC\\\\u03BD\\\\u03BF\\\\u03C0\\\\u03CE\\\\u03C1\\\\u03C3\\\\u03C4\\\\u03B8\\\\u03C9\\\\u03C2\\\\u03C7\\\\u03C5\\\\u03B6\\\\u03CA\\\\u03CB\\\\u0390\\\\u03B0\\\\xAD\\\",\\n \\\"x-mac-icelandic\\\": \\\"\\\\xC4\\\\xC5\\\\xC7\\\\xC9\\\\xD1\\\\xD6\\\\xDC\\\\xE1\\\\xE0\\\\xE2\\\\xE4\\\\xE3\\\\xE5\\\\xE7\\\\xE9\\\\xE8\\\\xEA\\\\xEB\\\\xED\\\\xEC\\\\xEE\\\\xEF\\\\xF1\\\\xF3\\\\xF2\\\\xF4\\\\xF6\\\\xF5\\\\xFA\\\\xF9\\\\xFB\\\\xFC\\\\xDD\\\\xB0\\\\xA2\\\\xA3\\\\xA7\\\\u2022\\\\xB6\\\\xDF\\\\xAE\\\\xA9\\\\u2122\\\\xB4\\\\xA8\\\\u2260\\\\xC6\\\\xD8\\\\u221E\\\\xB1\\\\u2264\\\\u2265\\\\xA5\\\\xB5\\\\u2202\\\\u2211\\\\u220F\\\\u03C0\\\\u222B\\\\xAA\\\\xBA\\\\u03A9\\\\xE6\\\\xF8\\\\xBF\\\\xA1\\\\xAC\\\\u221A\\\\u0192\\\\u2248\\\\u2206\\\\xAB\\\\xBB\\\\u2026 \\\\xC0\\\\xC3\\\\xD5\\\\u0152\\\\u0153\\\\u2013\\\\u2014\\\\u201C\\\\u201D\\\\u2018\\\\u2019\\\\xF7\\\\u25CA\\\\xFF\\\\u0178\\\\u2044\\\\u20AC\\\\xD0\\\\xF0\\\\xDE\\\\xFE\\\\xFD\\\\xB7\\\\u201A\\\\u201E\\\\u2030\\\\xC2\\\\xCA\\\\xC1\\\\xCB\\\\xC8\\\\xCD\\\\xCE\\\\xCF\\\\xCC\\\\xD3\\\\xD4\\\\uF8FF\\\\xD2\\\\xDA\\\\xDB\\\\xD9\\\\u0131\\\\u02C6\\\\u02DC\\\\xAF\\\\u02D8\\\\u02D9\\\\u02DA\\\\xB8\\\\u02DD\\\\u02DB\\\\u02C7\\\",\\n \\\"x-mac-inuit\\\": \\\"\\\\u1403\\\\u1404\\\\u1405\\\\u1406\\\\u140A\\\\u140B\\\\u1431\\\\u1432\\\\u1433\\\\u1434\\\\u1438\\\\u1439\\\\u1449\\\\u144E\\\\u144F\\\\u1450\\\\u1451\\\\u1455\\\\u1456\\\\u1466\\\\u146D\\\\u146E\\\\u146F\\\\u1470\\\\u1472\\\\u1473\\\\u1483\\\\u148B\\\\u148C\\\\u148D\\\\u148E\\\\u1490\\\\u1491\\\\xB0\\\\u14A1\\\\u14A5\\\\u14A6\\\\u2022\\\\xB6\\\\u14A7\\\\xAE\\\\xA9\\\\u2122\\\\u14A8\\\\u14AA\\\\u14AB\\\\u14BB\\\\u14C2\\\\u14C3\\\\u14C4\\\\u14C5\\\\u14C7\\\\u14C8\\\\u14D0\\\\u14EF\\\\u14F0\\\\u14F1\\\\u14F2\\\\u14F4\\\\u14F5\\\\u1505\\\\u14D5\\\\u14D6\\\\u14D7\\\\u14D8\\\\u14DA\\\\u14DB\\\\u14EA\\\\u1528\\\\u1529\\\\u152A\\\\u152B\\\\u152D\\\\u2026 \\\\u152E\\\\u153E\\\\u1555\\\\u1556\\\\u1557\\\\u2013\\\\u2014\\\\u201C\\\\u201D\\\\u2018\\\\u2019\\\\u1558\\\\u1559\\\\u155A\\\\u155D\\\\u1546\\\\u1547\\\\u1548\\\\u1549\\\\u154B\\\\u154C\\\\u1550\\\\u157F\\\\u1580\\\\u1581\\\\u1582\\\\u1583\\\\u1584\\\\u1585\\\\u158F\\\\u1590\\\\u1591\\\\u1592\\\\u1593\\\\u1594\\\\u1595\\\\u1671\\\\u1672\\\\u1673\\\\u1674\\\\u1675\\\\u1676\\\\u1596\\\\u15A0\\\\u15A1\\\\u15A2\\\\u15A3\\\\u15A4\\\\u15A5\\\\u15A6\\\\u157C\\\\u0141\\\\u0142\\\",\\n \\\"x-mac-ce\\\": \\\"\\\\xC4\\\\u0100\\\\u0101\\\\xC9\\\\u0104\\\\xD6\\\\xDC\\\\xE1\\\\u0105\\\\u010C\\\\xE4\\\\u010D\\\\u0106\\\\u0107\\\\xE9\\\\u0179\\\\u017A\\\\u010E\\\\xED\\\\u010F\\\\u0112\\\\u0113\\\\u0116\\\\xF3\\\\u0117\\\\xF4\\\\xF6\\\\xF5\\\\xFA\\\\u011A\\\\u011B\\\\xFC\\\\u2020\\\\xB0\\\\u0118\\\\xA3\\\\xA7\\\\u2022\\\\xB6\\\\xDF\\\\xAE\\\\xA9\\\\u2122\\\\u0119\\\\xA8\\\\u2260\\\\u0123\\\\u012E\\\\u012F\\\\u012A\\\\u2264\\\\u2265\\\\u012B\\\\u0136\\\\u2202\\\\u2211\\\\u0142\\\\u013B\\\\u013C\\\\u013D\\\\u013E\\\\u0139\\\\u013A\\\\u0145\\\\u0146\\\\u0143\\\\xAC\\\\u221A\\\\u0144\\\\u0147\\\\u2206\\\\xAB\\\\xBB\\\\u2026 \\\\u0148\\\\u0150\\\\xD5\\\\u0151\\\\u014C\\\\u2013\\\\u2014\\\\u201C\\\\u201D\\\\u2018\\\\u2019\\\\xF7\\\\u25CA\\\\u014D\\\\u0154\\\\u0155\\\\u0158\\\\u2039\\\\u203A\\\\u0159\\\\u0156\\\\u0157\\\\u0160\\\\u201A\\\\u201E\\\\u0161\\\\u015A\\\\u015B\\\\xC1\\\\u0164\\\\u0165\\\\xCD\\\\u017D\\\\u017E\\\\u016A\\\\xD3\\\\xD4\\\\u016B\\\\u016E\\\\xDA\\\\u016F\\\\u0170\\\\u0171\\\\u0172\\\\u0173\\\\xDD\\\\xFD\\\\u0137\\\\u017B\\\\u0141\\\\u017C\\\\u0122\\\\u02C7\\\",\\n \\\"x-mac-romanian\\\": \\\"\\\\xC4\\\\xC5\\\\xC7\\\\xC9\\\\xD1\\\\xD6\\\\xDC\\\\xE1\\\\xE0\\\\xE2\\\\xE4\\\\xE3\\\\xE5\\\\xE7\\\\xE9\\\\xE8\\\\xEA\\\\xEB\\\\xED\\\\xEC\\\\xEE\\\\xEF\\\\xF1\\\\xF3\\\\xF2\\\\xF4\\\\xF6\\\\xF5\\\\xFA\\\\xF9\\\\xFB\\\\xFC\\\\u2020\\\\xB0\\\\xA2\\\\xA3\\\\xA7\\\\u2022\\\\xB6\\\\xDF\\\\xAE\\\\xA9\\\\u2122\\\\xB4\\\\xA8\\\\u2260\\\\u0102\\\\u0218\\\\u221E\\\\xB1\\\\u2264\\\\u2265\\\\xA5\\\\xB5\\\\u2202\\\\u2211\\\\u220F\\\\u03C0\\\\u222B\\\\xAA\\\\xBA\\\\u03A9\\\\u0103\\\\u0219\\\\xBF\\\\xA1\\\\xAC\\\\u221A\\\\u0192\\\\u2248\\\\u2206\\\\xAB\\\\xBB\\\\u2026 \\\\xC0\\\\xC3\\\\xD5\\\\u0152\\\\u0153\\\\u2013\\\\u2014\\\\u201C\\\\u201D\\\\u2018\\\\u2019\\\\xF7\\\\u25CA\\\\xFF\\\\u0178\\\\u2044\\\\u20AC\\\\u2039\\\\u203A\\\\u021A\\\\u021B\\\\u2021\\\\xB7\\\\u201A\\\\u201E\\\\u2030\\\\xC2\\\\xCA\\\\xC1\\\\xCB\\\\xC8\\\\xCD\\\\xCE\\\\xCF\\\\xCC\\\\xD3\\\\xD4\\\\uF8FF\\\\xD2\\\\xDA\\\\xDB\\\\xD9\\\\u0131\\\\u02C6\\\\u02DC\\\\xAF\\\\u02D8\\\\u02D9\\\\u02DA\\\\xB8\\\\u02DD\\\\u02DB\\\\u02C7\\\",\\n \\\"x-mac-turkish\\\": \\\"\\\\xC4\\\\xC5\\\\xC7\\\\xC9\\\\xD1\\\\xD6\\\\xDC\\\\xE1\\\\xE0\\\\xE2\\\\xE4\\\\xE3\\\\xE5\\\\xE7\\\\xE9\\\\xE8\\\\xEA\\\\xEB\\\\xED\\\\xEC\\\\xEE\\\\xEF\\\\xF1\\\\xF3\\\\xF2\\\\xF4\\\\xF6\\\\xF5\\\\xFA\\\\xF9\\\\xFB\\\\xFC\\\\u2020\\\\xB0\\\\xA2\\\\xA3\\\\xA7\\\\u2022\\\\xB6\\\\xDF\\\\xAE\\\\xA9\\\\u2122\\\\xB4\\\\xA8\\\\u2260\\\\xC6\\\\xD8\\\\u221E\\\\xB1\\\\u2264\\\\u2265\\\\xA5\\\\xB5\\\\u2202\\\\u2211\\\\u220F\\\\u03C0\\\\u222B\\\\xAA\\\\xBA\\\\u03A9\\\\xE6\\\\xF8\\\\xBF\\\\xA1\\\\xAC\\\\u221A\\\\u0192\\\\u2248\\\\u2206\\\\xAB\\\\xBB\\\\u2026 \\\\xC0\\\\xC3\\\\xD5\\\\u0152\\\\u0153\\\\u2013\\\\u2014\\\\u201C\\\\u201D\\\\u2018\\\\u2019\\\\xF7\\\\u25CA\\\\xFF\\\\u0178\\\\u011E\\\\u011F\\\\u0130\\\\u0131\\\\u015E\\\\u015F\\\\u2021\\\\xB7\\\\u201A\\\\u201E\\\\u2030\\\\xC2\\\\xCA\\\\xC1\\\\xCB\\\\xC8\\\\xCD\\\\xCE\\\\xCF\\\\xCC\\\\xD3\\\\xD4\\\\uF8FF\\\\xD2\\\\xDA\\\\xDB\\\\xD9\\\\uF8A0\\\\u02C6\\\\u02DC\\\\xAF\\\\u02D8\\\\u02D9\\\\u02DA\\\\xB8\\\\u02DD\\\\u02DB\\\\u02C7\\\"\\n };\\n $e449ad78d50845fe$var$encodingCache = /* @__PURE__ */ new Map();\\n $e449ad78d50845fe$export$6fef87b7618bdf0b = [\\n // unicode\\n [\\n \\\"utf-16be\\\",\\n \\\"utf-16be\\\",\\n \\\"utf-16be\\\",\\n \\\"utf-16be\\\",\\n \\\"utf-16be\\\",\\n \\\"utf-16be\\\",\\n \\\"utf-16be\\\"\\n ],\\n // macintosh\\n // Mappings available at http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/\\n // 0\\tRoman 17\\tMalayalam\\n // 1\\tJapanese\\t 18\\tSinhalese\\n // 2\\tTraditional Chinese\\t 19\\tBurmese\\n // 3\\tKorean\\t 20\\tKhmer\\n // 4\\tArabic\\t 21\\tThai\\n // 5\\tHebrew\\t 22\\tLaotian\\n // 6\\tGreek\\t 23\\tGeorgian\\n // 7\\tRussian\\t 24\\tArmenian\\n // 8\\tRSymbol\\t 25\\tSimplified Chinese\\n // 9\\tDevanagari\\t 26\\tTibetan\\n // 10\\tGurmukhi\\t 27\\tMongolian\\n // 11\\tGujarati\\t 28\\tGeez\\n // 12\\tOriya\\t 29\\tSlavic\\n // 13\\tBengali\\t 30\\tVietnamese\\n // 14\\tTamil\\t 31\\tSindhi\\n // 15\\tTelugu\\t 32\\t(Uninterpreted)\\n // 16\\tKannada\\n [\\n \\\"x-mac-roman\\\",\\n \\\"shift-jis\\\",\\n \\\"big5\\\",\\n \\\"euc-kr\\\",\\n \\\"iso-8859-6\\\",\\n \\\"iso-8859-8\\\",\\n \\\"x-mac-greek\\\",\\n \\\"x-mac-cyrillic\\\",\\n \\\"x-mac-symbol\\\",\\n \\\"x-mac-devanagari\\\",\\n \\\"x-mac-gurmukhi\\\",\\n \\\"x-mac-gujarati\\\",\\n \\\"Oriya\\\",\\n \\\"Bengali\\\",\\n \\\"Tamil\\\",\\n \\\"Telugu\\\",\\n \\\"Kannada\\\",\\n \\\"Malayalam\\\",\\n \\\"Sinhalese\\\",\\n \\\"Burmese\\\",\\n \\\"Khmer\\\",\\n \\\"iso-8859-11\\\",\\n \\\"Laotian\\\",\\n \\\"Georgian\\\",\\n \\\"Armenian\\\",\\n \\\"gbk\\\",\\n \\\"Tibetan\\\",\\n \\\"Mongolian\\\",\\n \\\"Geez\\\",\\n \\\"x-mac-ce\\\",\\n \\\"Vietnamese\\\",\\n \\\"Sindhi\\\"\\n ],\\n // ISO (deprecated)\\n [\\n \\\"ascii\\\",\\n null,\\n \\\"iso-8859-1\\\"\\n ],\\n // windows\\n // Docs here: http://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx\\n [\\n \\\"symbol\\\",\\n \\\"utf-16be\\\",\\n \\\"shift-jis\\\",\\n \\\"gb18030\\\",\\n \\\"big5\\\",\\n \\\"euc-kr\\\",\\n \\\"johab\\\",\\n null,\\n null,\\n null,\\n \\\"utf-16be\\\"\\n ]\\n ];\\n $e449ad78d50845fe$export$479e671907f486d1 = {\\n 15: \\\"x-mac-icelandic\\\",\\n 17: \\\"x-mac-turkish\\\",\\n 18: \\\"x-mac-croatian\\\",\\n 24: \\\"x-mac-ce\\\",\\n 25: \\\"x-mac-ce\\\",\\n 26: \\\"x-mac-ce\\\",\\n 27: \\\"x-mac-ce\\\",\\n 28: \\\"x-mac-ce\\\",\\n 30: \\\"x-mac-icelandic\\\",\\n 37: \\\"x-mac-romanian\\\",\\n 38: \\\"x-mac-ce\\\",\\n 39: \\\"x-mac-ce\\\",\\n 40: \\\"x-mac-ce\\\",\\n 143: \\\"x-mac-inuit\\\",\\n 146: \\\"x-mac-gaelic\\\"\\n };\\n $e449ad78d50845fe$export$2092376fd002e13 = [\\n // unicode\\n [],\\n {\\n 0: \\\"en\\\",\\n 30: \\\"fo\\\",\\n 60: \\\"ks\\\",\\n 90: \\\"rw\\\",\\n 1: \\\"fr\\\",\\n 31: \\\"fa\\\",\\n 61: \\\"ku\\\",\\n 91: \\\"rn\\\",\\n 2: \\\"de\\\",\\n 32: \\\"ru\\\",\\n 62: \\\"sd\\\",\\n 92: \\\"ny\\\",\\n 3: \\\"it\\\",\\n 33: \\\"zh\\\",\\n 63: \\\"bo\\\",\\n 93: \\\"mg\\\",\\n 4: \\\"nl\\\",\\n 34: \\\"nl-BE\\\",\\n 64: \\\"ne\\\",\\n 94: \\\"eo\\\",\\n 5: \\\"sv\\\",\\n 35: \\\"ga\\\",\\n 65: \\\"sa\\\",\\n 128: \\\"cy\\\",\\n 6: \\\"es\\\",\\n 36: \\\"sq\\\",\\n 66: \\\"mr\\\",\\n 129: \\\"eu\\\",\\n 7: \\\"da\\\",\\n 37: \\\"ro\\\",\\n 67: \\\"bn\\\",\\n 130: \\\"ca\\\",\\n 8: \\\"pt\\\",\\n 38: \\\"cz\\\",\\n 68: \\\"as\\\",\\n 131: \\\"la\\\",\\n 9: \\\"no\\\",\\n 39: \\\"sk\\\",\\n 69: \\\"gu\\\",\\n 132: \\\"qu\\\",\\n 10: \\\"he\\\",\\n 40: \\\"si\\\",\\n 70: \\\"pa\\\",\\n 133: \\\"gn\\\",\\n 11: \\\"ja\\\",\\n 41: \\\"yi\\\",\\n 71: \\\"or\\\",\\n 134: \\\"ay\\\",\\n 12: \\\"ar\\\",\\n 42: \\\"sr\\\",\\n 72: \\\"ml\\\",\\n 135: \\\"tt\\\",\\n 13: \\\"fi\\\",\\n 43: \\\"mk\\\",\\n 73: \\\"kn\\\",\\n 136: \\\"ug\\\",\\n 14: \\\"el\\\",\\n 44: \\\"bg\\\",\\n 74: \\\"ta\\\",\\n 137: \\\"dz\\\",\\n 15: \\\"is\\\",\\n 45: \\\"uk\\\",\\n 75: \\\"te\\\",\\n 138: \\\"jv\\\",\\n 16: \\\"mt\\\",\\n 46: \\\"be\\\",\\n 76: \\\"si\\\",\\n 139: \\\"su\\\",\\n 17: \\\"tr\\\",\\n 47: \\\"uz\\\",\\n 77: \\\"my\\\",\\n 140: \\\"gl\\\",\\n 18: \\\"hr\\\",\\n 48: \\\"kk\\\",\\n 78: \\\"km\\\",\\n 141: \\\"af\\\",\\n 19: \\\"zh-Hant\\\",\\n 49: \\\"az-Cyrl\\\",\\n 79: \\\"lo\\\",\\n 142: \\\"br\\\",\\n 20: \\\"ur\\\",\\n 50: \\\"az-Arab\\\",\\n 80: \\\"vi\\\",\\n 143: \\\"iu\\\",\\n 21: \\\"hi\\\",\\n 51: \\\"hy\\\",\\n 81: \\\"id\\\",\\n 144: \\\"gd\\\",\\n 22: \\\"th\\\",\\n 52: \\\"ka\\\",\\n 82: \\\"tl\\\",\\n 145: \\\"gv\\\",\\n 23: \\\"ko\\\",\\n 53: \\\"mo\\\",\\n 83: \\\"ms\\\",\\n 146: \\\"ga\\\",\\n 24: \\\"lt\\\",\\n 54: \\\"ky\\\",\\n 84: \\\"ms-Arab\\\",\\n 147: \\\"to\\\",\\n 25: \\\"pl\\\",\\n 55: \\\"tg\\\",\\n 85: \\\"am\\\",\\n 148: \\\"el-polyton\\\",\\n 26: \\\"hu\\\",\\n 56: \\\"tk\\\",\\n 86: \\\"ti\\\",\\n 149: \\\"kl\\\",\\n 27: \\\"es\\\",\\n 57: \\\"mn-CN\\\",\\n 87: \\\"om\\\",\\n 150: \\\"az\\\",\\n 28: \\\"lv\\\",\\n 58: \\\"mn\\\",\\n 88: \\\"so\\\",\\n 151: \\\"nn\\\",\\n 29: \\\"se\\\",\\n 59: \\\"ps\\\",\\n 89: \\\"sw\\\"\\n },\\n // ISO (deprecated)\\n [],\\n {\\n 1078: \\\"af\\\",\\n 16393: \\\"en-IN\\\",\\n 1159: \\\"rw\\\",\\n 1074: \\\"tn\\\",\\n 1052: \\\"sq\\\",\\n 6153: \\\"en-IE\\\",\\n 1089: \\\"sw\\\",\\n 1115: \\\"si\\\",\\n 1156: \\\"gsw\\\",\\n 8201: \\\"en-JM\\\",\\n 1111: \\\"kok\\\",\\n 1051: \\\"sk\\\",\\n 1118: \\\"am\\\",\\n 17417: \\\"en-MY\\\",\\n 1042: \\\"ko\\\",\\n 1060: \\\"sl\\\",\\n 5121: \\\"ar-DZ\\\",\\n 5129: \\\"en-NZ\\\",\\n 1088: \\\"ky\\\",\\n 11274: \\\"es-AR\\\",\\n 15361: \\\"ar-BH\\\",\\n 13321: \\\"en-PH\\\",\\n 1108: \\\"lo\\\",\\n 16394: \\\"es-BO\\\",\\n 3073: \\\"ar\\\",\\n 18441: \\\"en-SG\\\",\\n 1062: \\\"lv\\\",\\n 13322: \\\"es-CL\\\",\\n 2049: \\\"ar-IQ\\\",\\n 7177: \\\"en-ZA\\\",\\n 1063: \\\"lt\\\",\\n 9226: \\\"es-CO\\\",\\n 11265: \\\"ar-JO\\\",\\n 11273: \\\"en-TT\\\",\\n 2094: \\\"dsb\\\",\\n 5130: \\\"es-CR\\\",\\n 13313: \\\"ar-KW\\\",\\n 2057: \\\"en-GB\\\",\\n 1134: \\\"lb\\\",\\n 7178: \\\"es-DO\\\",\\n 12289: \\\"ar-LB\\\",\\n 1033: \\\"en\\\",\\n 1071: \\\"mk\\\",\\n 12298: \\\"es-EC\\\",\\n 4097: \\\"ar-LY\\\",\\n 12297: \\\"en-ZW\\\",\\n 2110: \\\"ms-BN\\\",\\n 17418: \\\"es-SV\\\",\\n 6145: \\\"ary\\\",\\n 1061: \\\"et\\\",\\n 1086: \\\"ms\\\",\\n 4106: \\\"es-GT\\\",\\n 8193: \\\"ar-OM\\\",\\n 1080: \\\"fo\\\",\\n 1100: \\\"ml\\\",\\n 18442: \\\"es-HN\\\",\\n 16385: \\\"ar-QA\\\",\\n 1124: \\\"fil\\\",\\n 1082: \\\"mt\\\",\\n 2058: \\\"es-MX\\\",\\n 1025: \\\"ar-SA\\\",\\n 1035: \\\"fi\\\",\\n 1153: \\\"mi\\\",\\n 19466: \\\"es-NI\\\",\\n 10241: \\\"ar-SY\\\",\\n 2060: \\\"fr-BE\\\",\\n 1146: \\\"arn\\\",\\n 6154: \\\"es-PA\\\",\\n 7169: \\\"aeb\\\",\\n 3084: \\\"fr-CA\\\",\\n 1102: \\\"mr\\\",\\n 15370: \\\"es-PY\\\",\\n 14337: \\\"ar-AE\\\",\\n 1036: \\\"fr\\\",\\n 1148: \\\"moh\\\",\\n 10250: \\\"es-PE\\\",\\n 9217: \\\"ar-YE\\\",\\n 5132: \\\"fr-LU\\\",\\n 1104: \\\"mn\\\",\\n 20490: \\\"es-PR\\\",\\n 1067: \\\"hy\\\",\\n 6156: \\\"fr-MC\\\",\\n 2128: \\\"mn-CN\\\",\\n 3082: \\\"es\\\",\\n 1101: \\\"as\\\",\\n 4108: \\\"fr-CH\\\",\\n 1121: \\\"ne\\\",\\n 1034: \\\"es\\\",\\n 2092: \\\"az-Cyrl\\\",\\n 1122: \\\"fy\\\",\\n 1044: \\\"nb\\\",\\n 21514: \\\"es-US\\\",\\n 1068: \\\"az\\\",\\n 1110: \\\"gl\\\",\\n 2068: \\\"nn\\\",\\n 14346: \\\"es-UY\\\",\\n 1133: \\\"ba\\\",\\n 1079: \\\"ka\\\",\\n 1154: \\\"oc\\\",\\n 8202: \\\"es-VE\\\",\\n 1069: \\\"eu\\\",\\n 3079: \\\"de-AT\\\",\\n 1096: \\\"or\\\",\\n 2077: \\\"sv-FI\\\",\\n 1059: \\\"be\\\",\\n 1031: \\\"de\\\",\\n 1123: \\\"ps\\\",\\n 1053: \\\"sv\\\",\\n 2117: \\\"bn\\\",\\n 5127: \\\"de-LI\\\",\\n 1045: \\\"pl\\\",\\n 1114: \\\"syr\\\",\\n 1093: \\\"bn-IN\\\",\\n 4103: \\\"de-LU\\\",\\n 1046: \\\"pt\\\",\\n 1064: \\\"tg\\\",\\n 8218: \\\"bs-Cyrl\\\",\\n 2055: \\\"de-CH\\\",\\n 2070: \\\"pt-PT\\\",\\n 2143: \\\"tzm\\\",\\n 5146: \\\"bs\\\",\\n 1032: \\\"el\\\",\\n 1094: \\\"pa\\\",\\n 1097: \\\"ta\\\",\\n 1150: \\\"br\\\",\\n 1135: \\\"kl\\\",\\n 1131: \\\"qu-BO\\\",\\n 1092: \\\"tt\\\",\\n 1026: \\\"bg\\\",\\n 1095: \\\"gu\\\",\\n 2155: \\\"qu-EC\\\",\\n 1098: \\\"te\\\",\\n 1027: \\\"ca\\\",\\n 1128: \\\"ha\\\",\\n 3179: \\\"qu\\\",\\n 1054: \\\"th\\\",\\n 3076: \\\"zh-HK\\\",\\n 1037: \\\"he\\\",\\n 1048: \\\"ro\\\",\\n 1105: \\\"bo\\\",\\n 5124: \\\"zh-MO\\\",\\n 1081: \\\"hi\\\",\\n 1047: \\\"rm\\\",\\n 1055: \\\"tr\\\",\\n 2052: \\\"zh\\\",\\n 1038: \\\"hu\\\",\\n 1049: \\\"ru\\\",\\n 1090: \\\"tk\\\",\\n 4100: \\\"zh-SG\\\",\\n 1039: \\\"is\\\",\\n 9275: \\\"smn\\\",\\n 1152: \\\"ug\\\",\\n 1028: \\\"zh-TW\\\",\\n 1136: \\\"ig\\\",\\n 4155: \\\"smj-NO\\\",\\n 1058: \\\"uk\\\",\\n 1155: \\\"co\\\",\\n 1057: \\\"id\\\",\\n 5179: \\\"smj\\\",\\n 1070: \\\"hsb\\\",\\n 1050: \\\"hr\\\",\\n 1117: \\\"iu\\\",\\n 3131: \\\"se-FI\\\",\\n 1056: \\\"ur\\\",\\n 4122: \\\"hr-BA\\\",\\n 2141: \\\"iu-Latn\\\",\\n 1083: \\\"se\\\",\\n 2115: \\\"uz-Cyrl\\\",\\n 1029: \\\"cs\\\",\\n 2108: \\\"ga\\\",\\n 2107: \\\"se-SE\\\",\\n 1091: \\\"uz\\\",\\n 1030: \\\"da\\\",\\n 1076: \\\"xh\\\",\\n 8251: \\\"sms\\\",\\n 1066: \\\"vi\\\",\\n 1164: \\\"prs\\\",\\n 1077: \\\"zu\\\",\\n 6203: \\\"sma-NO\\\",\\n 1106: \\\"cy\\\",\\n 1125: \\\"dv\\\",\\n 1040: \\\"it\\\",\\n 7227: \\\"sms\\\",\\n 1160: \\\"wo\\\",\\n 2067: \\\"nl-BE\\\",\\n 2064: \\\"it-CH\\\",\\n 1103: \\\"sa\\\",\\n 1157: \\\"sah\\\",\\n 1043: \\\"nl\\\",\\n 1041: \\\"ja\\\",\\n 7194: \\\"sr-Cyrl-BA\\\",\\n 1144: \\\"ii\\\",\\n 3081: \\\"en-AU\\\",\\n 1099: \\\"kn\\\",\\n 3098: \\\"sr\\\",\\n 1130: \\\"yo\\\",\\n 10249: \\\"en-BZ\\\",\\n 1087: \\\"kk\\\",\\n 6170: \\\"sr-Latn-BA\\\",\\n 4105: \\\"en-CA\\\",\\n 1107: \\\"km\\\",\\n 2074: \\\"sr-Latn\\\",\\n 9225: \\\"en-029\\\",\\n 1158: \\\"quc\\\",\\n 1132: \\\"nso\\\"\\n }\\n ];\\n $2bcf221753ec8e32$var$NameRecord = new Struct({\\n platformID: uint16,\\n encodingID: uint16,\\n languageID: uint16,\\n nameID: uint16,\\n length: uint16,\\n string: new Pointer(uint16, new StringT(\\\"length\\\", (t) => (0, $e449ad78d50845fe$export$badc544e0651b6b1)(t.platformID, t.encodingID, t.languageID)), {\\n type: \\\"parent\\\",\\n relativeTo: (ctx) => ctx.parent.stringOffset,\\n allowNull: false\\n })\\n });\\n $2bcf221753ec8e32$var$LangTagRecord = new Struct({\\n length: uint16,\\n tag: new Pointer(uint16, new StringT(\\\"length\\\", \\\"utf16be\\\"), {\\n type: \\\"parent\\\",\\n relativeTo: (ctx) => ctx.stringOffset\\n })\\n });\\n $2bcf221753ec8e32$var$NameTable = new VersionedStruct(uint16, {\\n 0: {\\n count: uint16,\\n stringOffset: uint16,\\n records: new ArrayT($2bcf221753ec8e32$var$NameRecord, \\\"count\\\")\\n },\\n 1: {\\n count: uint16,\\n stringOffset: uint16,\\n records: new ArrayT($2bcf221753ec8e32$var$NameRecord, \\\"count\\\"),\\n langTagCount: uint16,\\n langTags: new ArrayT($2bcf221753ec8e32$var$LangTagRecord, \\\"langTagCount\\\")\\n }\\n });\\n $2bcf221753ec8e32$export$2e2bcd8739ae039 = $2bcf221753ec8e32$var$NameTable;\\n $2bcf221753ec8e32$var$NAMES = [\\n \\\"copyright\\\",\\n \\\"fontFamily\\\",\\n \\\"fontSubfamily\\\",\\n \\\"uniqueSubfamily\\\",\\n \\\"fullName\\\",\\n \\\"version\\\",\\n \\\"postscriptName\\\",\\n \\\"trademark\\\",\\n \\\"manufacturer\\\",\\n \\\"designer\\\",\\n \\\"description\\\",\\n \\\"vendorURL\\\",\\n \\\"designerURL\\\",\\n \\\"license\\\",\\n \\\"licenseURL\\\",\\n null,\\n \\\"preferredFamily\\\",\\n \\\"preferredSubfamily\\\",\\n \\\"compatibleFull\\\",\\n \\\"sampleText\\\",\\n \\\"postscriptCIDFontName\\\",\\n \\\"wwsFamilyName\\\",\\n \\\"wwsSubfamilyName\\\"\\n ];\\n $2bcf221753ec8e32$var$NameTable.process = function(stream) {\\n var records = {};\\n for (let record of this.records) {\\n let language = (0, $e449ad78d50845fe$export$2092376fd002e13)[record.platformID][record.languageID];\\n if (language == null && this.langTags != null && record.languageID >= 32768) language = this.langTags[record.languageID - 32768].tag;\\n if (language == null) language = record.platformID + \\\"-\\\" + record.languageID;\\n let key = record.nameID >= 256 ? \\\"fontFeatures\\\" : $2bcf221753ec8e32$var$NAMES[record.nameID] || record.nameID;\\n if (records[key] == null) records[key] = {};\\n let obj = records[key];\\n if (record.nameID >= 256) obj = obj[record.nameID] || (obj[record.nameID] = {});\\n if (typeof record.string === \\\"string\\\" || typeof obj[language] !== \\\"string\\\") obj[language] = record.string;\\n }\\n this.records = records;\\n };\\n $2bcf221753ec8e32$var$NameTable.preEncode = function() {\\n if (Array.isArray(this.records)) return;\\n this.version = 0;\\n let records = [];\\n for (let key in this.records) {\\n let val = this.records[key];\\n if (key === \\\"fontFeatures\\\") continue;\\n records.push({\\n platformID: 3,\\n encodingID: 1,\\n languageID: 1033,\\n nameID: $2bcf221753ec8e32$var$NAMES.indexOf(key),\\n length: val.en.length * 2,\\n string: val.en\\n });\\n if (key === \\\"postscriptName\\\") records.push({\\n platformID: 1,\\n encodingID: 0,\\n languageID: 0,\\n nameID: $2bcf221753ec8e32$var$NAMES.indexOf(key),\\n length: val.en.length,\\n string: val.en\\n });\\n }\\n this.records = records;\\n this.count = records.length;\\n this.stringOffset = $2bcf221753ec8e32$var$NameTable.size(this, null, false);\\n };\\n $84b272aa31b70606$var$OS2 = new VersionedStruct(uint16, {\\n header: {\\n xAvgCharWidth: int16,\\n usWeightClass: uint16,\\n usWidthClass: uint16,\\n fsType: new Bitfield(uint16, [\\n null,\\n \\\"noEmbedding\\\",\\n \\\"viewOnly\\\",\\n \\\"editable\\\",\\n null,\\n null,\\n null,\\n null,\\n \\\"noSubsetting\\\",\\n \\\"bitmapOnly\\\"\\n ]),\\n ySubscriptXSize: int16,\\n ySubscriptYSize: int16,\\n ySubscriptXOffset: int16,\\n ySubscriptYOffset: int16,\\n ySuperscriptXSize: int16,\\n ySuperscriptYSize: int16,\\n ySuperscriptXOffset: int16,\\n ySuperscriptYOffset: int16,\\n yStrikeoutSize: int16,\\n yStrikeoutPosition: int16,\\n sFamilyClass: int16,\\n panose: new ArrayT(uint8, 10),\\n ulCharRange: new ArrayT(uint32, 4),\\n vendorID: new StringT(4),\\n fsSelection: new Bitfield(uint16, [\\n \\\"italic\\\",\\n \\\"underscore\\\",\\n \\\"negative\\\",\\n \\\"outlined\\\",\\n \\\"strikeout\\\",\\n \\\"bold\\\",\\n \\\"regular\\\",\\n \\\"useTypoMetrics\\\",\\n \\\"wws\\\",\\n \\\"oblique\\\"\\n ]),\\n usFirstCharIndex: uint16,\\n usLastCharIndex: uint16\\n // The maximum Unicode index in this font\\n },\\n // The Apple version of this table ends here, but the Microsoft one continues on...\\n 0: {},\\n 1: {\\n typoAscender: int16,\\n typoDescender: int16,\\n typoLineGap: int16,\\n winAscent: uint16,\\n winDescent: uint16,\\n codePageRange: new ArrayT(uint32, 2)\\n },\\n 2: {\\n // these should be common with version 1 somehow\\n typoAscender: int16,\\n typoDescender: int16,\\n typoLineGap: int16,\\n winAscent: uint16,\\n winDescent: uint16,\\n codePageRange: new ArrayT(uint32, 2),\\n xHeight: int16,\\n capHeight: int16,\\n defaultChar: uint16,\\n breakChar: uint16,\\n maxContent: uint16\\n },\\n 5: {\\n typoAscender: int16,\\n typoDescender: int16,\\n typoLineGap: int16,\\n winAscent: uint16,\\n winDescent: uint16,\\n codePageRange: new ArrayT(uint32, 2),\\n xHeight: int16,\\n capHeight: int16,\\n defaultChar: uint16,\\n breakChar: uint16,\\n maxContent: uint16,\\n usLowerOpticalPointSize: uint16,\\n usUpperOpticalPointSize: uint16\\n }\\n });\\n $84b272aa31b70606$var$versions = $84b272aa31b70606$var$OS2.versions;\\n $84b272aa31b70606$var$versions[3] = $84b272aa31b70606$var$versions[4] = $84b272aa31b70606$var$versions[2];\\n $84b272aa31b70606$export$2e2bcd8739ae039 = $84b272aa31b70606$var$OS2;\\n $32d9e2eb9565d93c$export$2e2bcd8739ae039 = new VersionedStruct(fixed32, {\\n header: {\\n italicAngle: fixed32,\\n underlinePosition: int16,\\n underlineThickness: int16,\\n isFixedPitch: uint32,\\n minMemType42: uint32,\\n maxMemType42: uint32,\\n minMemType1: uint32,\\n maxMemType1: uint32\\n // Maximum memory usage when a TrueType font is downloaded as a Type 1 font\\n },\\n 1: {},\\n 2: {\\n numberOfGlyphs: uint16,\\n glyphNameIndex: new ArrayT(uint16, \\\"numberOfGlyphs\\\"),\\n names: new ArrayT(new StringT(uint8))\\n },\\n 2.5: {\\n numberOfGlyphs: uint16,\\n offsets: new ArrayT(uint8, \\\"numberOfGlyphs\\\")\\n },\\n 3: {},\\n 4: {\\n map: new ArrayT(uint32, (t) => t.parent.maxp.numGlyphs)\\n }\\n });\\n $5202bd9d9ad8eaac$export$2e2bcd8739ae039 = new Struct({\\n controlValues: new ArrayT(int16)\\n });\\n $5c0f37ca5ffb1850$export$2e2bcd8739ae039 = new Struct({\\n instructions: new ArrayT(uint8)\\n });\\n $2b2b260902b1c57e$var$loca = new VersionedStruct(\\\"head.indexToLocFormat\\\", {\\n 0: {\\n offsets: new ArrayT(uint16)\\n },\\n 1: {\\n offsets: new ArrayT(uint32)\\n }\\n });\\n $2b2b260902b1c57e$var$loca.process = function() {\\n if (this.version === 0 && !this._processed) {\\n for (let i = 0; i < this.offsets.length; i++) this.offsets[i] <<= 1;\\n this._processed = true;\\n }\\n };\\n $2b2b260902b1c57e$var$loca.preEncode = function() {\\n if (this.version === 0 && this._processed !== false) {\\n for (let i = 0; i < this.offsets.length; i++) this.offsets[i] >>>= 1;\\n this._processed = false;\\n }\\n };\\n $2b2b260902b1c57e$export$2e2bcd8739ae039 = $2b2b260902b1c57e$var$loca;\\n $7afb878c7bea4f66$export$2e2bcd8739ae039 = new Struct({\\n controlValueProgram: new ArrayT(uint8)\\n });\\n $6c92b6371bce8bd9$export$2e2bcd8739ae039 = new ArrayT(new BufferT());\\n $43e9821ef3717eec$export$2e2bcd8739ae039 = class {\\n getCFFVersion(ctx) {\\n while (ctx && !ctx.hdrSize) ctx = ctx.parent;\\n return ctx ? ctx.version : -1;\\n }\\n decode(stream, parent) {\\n let version = this.getCFFVersion(parent);\\n let count = version >= 2 ? stream.readUInt32BE() : stream.readUInt16BE();\\n if (count === 0) return [];\\n let offSize = stream.readUInt8();\\n let offsetType;\\n if (offSize === 1) offsetType = uint8;\\n else if (offSize === 2) offsetType = uint16;\\n else if (offSize === 3) offsetType = uint24;\\n else if (offSize === 4) offsetType = uint32;\\n else throw new Error(`Bad offset size in CFFIndex: ${offSize} ${stream.pos}`);\\n let ret = [];\\n let startPos = stream.pos + (count + 1) * offSize - 1;\\n let start = offsetType.decode(stream);\\n for (let i = 0; i < count; i++) {\\n let end = offsetType.decode(stream);\\n if (this.type != null) {\\n let pos = stream.pos;\\n stream.pos = startPos + start;\\n parent.length = end - start;\\n ret.push(this.type.decode(stream, parent));\\n stream.pos = pos;\\n } else ret.push({\\n offset: startPos + start,\\n length: end - start\\n });\\n start = end;\\n }\\n stream.pos = startPos + start;\\n return ret;\\n }\\n size(arr, parent) {\\n let size = 2;\\n if (arr.length === 0) return size;\\n let type = this.type || new BufferT();\\n let offset = 1;\\n for (let i = 0; i < arr.length; i++) {\\n let item = arr[i];\\n offset += type.size(item, parent);\\n }\\n let offsetType;\\n if (offset <= 255) offsetType = uint8;\\n else if (offset <= 65535) offsetType = uint16;\\n else if (offset <= 16777215) offsetType = uint24;\\n else if (offset <= 4294967295) offsetType = uint32;\\n else throw new Error(\\\"Bad offset in CFFIndex\\\");\\n size += 1 + offsetType.size() * (arr.length + 1);\\n size += offset - 1;\\n return size;\\n }\\n encode(stream, arr, parent) {\\n stream.writeUInt16BE(arr.length);\\n if (arr.length === 0) return;\\n let type = this.type || new BufferT();\\n let sizes = [];\\n let offset = 1;\\n for (let item of arr) {\\n let s = type.size(item, parent);\\n sizes.push(s);\\n offset += s;\\n }\\n let offsetType;\\n if (offset <= 255) offsetType = uint8;\\n else if (offset <= 65535) offsetType = uint16;\\n else if (offset <= 16777215) offsetType = uint24;\\n else if (offset <= 4294967295) offsetType = uint32;\\n else throw new Error(\\\"Bad offset in CFFIndex\\\");\\n stream.writeUInt8(offsetType.size());\\n offset = 1;\\n offsetType.encode(stream, offset);\\n for (let size of sizes) {\\n offset += size;\\n offsetType.encode(stream, offset);\\n }\\n for (let item of arr) type.encode(stream, item, parent);\\n return;\\n }\\n constructor(type) {\\n this.type = type;\\n }\\n };\\n $c2d28e92708f99da$var$FLOAT_EOF = 15;\\n $c2d28e92708f99da$var$FLOAT_LOOKUP = [\\n \\\"0\\\",\\n \\\"1\\\",\\n \\\"2\\\",\\n \\\"3\\\",\\n \\\"4\\\",\\n \\\"5\\\",\\n \\\"6\\\",\\n \\\"7\\\",\\n \\\"8\\\",\\n \\\"9\\\",\\n \\\".\\\",\\n \\\"E\\\",\\n \\\"E-\\\",\\n null,\\n \\\"-\\\"\\n ];\\n $c2d28e92708f99da$var$FLOAT_ENCODE_LOOKUP = {\\n \\\".\\\": 10,\\n \\\"E\\\": 11,\\n \\\"E-\\\": 12,\\n \\\"-\\\": 14\\n };\\n $c2d28e92708f99da$export$2e2bcd8739ae039 = class {\\n static decode(stream, value) {\\n if (32 <= value && value <= 246) return value - 139;\\n if (247 <= value && value <= 250) return (value - 247) * 256 + stream.readUInt8() + 108;\\n if (251 <= value && value <= 254) return -(value - 251) * 256 - stream.readUInt8() - 108;\\n if (value === 28) return stream.readInt16BE();\\n if (value === 29) return stream.readInt32BE();\\n if (value === 30) {\\n let str = \\\"\\\";\\n while (true) {\\n let b = stream.readUInt8();\\n let n1 = b >> 4;\\n if (n1 === $c2d28e92708f99da$var$FLOAT_EOF) break;\\n str += $c2d28e92708f99da$var$FLOAT_LOOKUP[n1];\\n let n2 = b & 15;\\n if (n2 === $c2d28e92708f99da$var$FLOAT_EOF) break;\\n str += $c2d28e92708f99da$var$FLOAT_LOOKUP[n2];\\n }\\n return parseFloat(str);\\n }\\n return null;\\n }\\n static size(value) {\\n if (value.forceLarge) value = 32768;\\n if ((value | 0) !== value) {\\n let str = \\\"\\\" + value;\\n return 1 + Math.ceil((str.length + 1) / 2);\\n } else if (-107 <= value && value <= 107) return 1;\\n else if (108 <= value && value <= 1131 || -1131 <= value && value <= -108) return 2;\\n else if (-32768 <= value && value <= 32767) return 3;\\n else return 5;\\n }\\n static encode(stream, value) {\\n let val = Number(value);\\n if (value.forceLarge) {\\n stream.writeUInt8(29);\\n return stream.writeInt32BE(val);\\n } else if ((val | 0) !== val) {\\n stream.writeUInt8(30);\\n let str = \\\"\\\" + val;\\n for (let i = 0; i < str.length; i += 2) {\\n let c1 = str[i];\\n let n1 = $c2d28e92708f99da$var$FLOAT_ENCODE_LOOKUP[c1] || +c1;\\n if (i === str.length - 1) var n2 = $c2d28e92708f99da$var$FLOAT_EOF;\\n else {\\n let c2 = str[i + 1];\\n var n2 = $c2d28e92708f99da$var$FLOAT_ENCODE_LOOKUP[c2] || +c2;\\n }\\n stream.writeUInt8(n1 << 4 | n2 & 15);\\n }\\n if (n2 !== $c2d28e92708f99da$var$FLOAT_EOF) return stream.writeUInt8($c2d28e92708f99da$var$FLOAT_EOF << 4);\\n } else if (-107 <= val && val <= 107) return stream.writeUInt8(val + 139);\\n else if (108 <= val && val <= 1131) {\\n val -= 108;\\n stream.writeUInt8((val >> 8) + 247);\\n return stream.writeUInt8(val & 255);\\n } else if (-1131 <= val && val <= -108) {\\n val = -val - 108;\\n stream.writeUInt8((val >> 8) + 251);\\n return stream.writeUInt8(val & 255);\\n } else if (-32768 <= val && val <= 32767) {\\n stream.writeUInt8(28);\\n return stream.writeInt16BE(val);\\n } else {\\n stream.writeUInt8(29);\\n return stream.writeInt32BE(val);\\n }\\n }\\n };\\n $61aa549f16d58b9b$export$2e2bcd8739ae039 = class {\\n decodeOperands(type, stream, ret, operands) {\\n if (Array.isArray(type)) return operands.map((op, i) => this.decodeOperands(type[i], stream, ret, [\\n op\\n ]));\\n else if (type.decode != null) return type.decode(stream, ret, operands);\\n else switch (type) {\\n case \\\"number\\\":\\n case \\\"offset\\\":\\n case \\\"sid\\\":\\n return operands[0];\\n case \\\"boolean\\\":\\n return !!operands[0];\\n default:\\n return operands;\\n }\\n }\\n encodeOperands(type, stream, ctx, operands) {\\n if (Array.isArray(type)) return operands.map((op, i) => this.encodeOperands(type[i], stream, ctx, op)[0]);\\n else if (type.encode != null) return type.encode(stream, operands, ctx);\\n else if (typeof operands === \\\"number\\\") return [\\n operands\\n ];\\n else if (typeof operands === \\\"boolean\\\") return [\\n +operands\\n ];\\n else if (Array.isArray(operands)) return operands;\\n else return [\\n operands\\n ];\\n }\\n decode(stream, parent) {\\n let end = stream.pos + parent.length;\\n let ret = {};\\n let operands = [];\\n Object.defineProperties(ret, {\\n parent: {\\n value: parent\\n },\\n _startOffset: {\\n value: stream.pos\\n }\\n });\\n for (let key in this.fields) {\\n let field = this.fields[key];\\n ret[field[1]] = field[3];\\n }\\n while (stream.pos < end) {\\n let b = stream.readUInt8();\\n if (b < 28) {\\n if (b === 12) b = b << 8 | stream.readUInt8();\\n let field = this.fields[b];\\n if (!field) throw new Error(`Unknown operator ${b}`);\\n let val = this.decodeOperands(field[2], stream, ret, operands);\\n if (val != null) {\\n if (val instanceof (0, PropertyDescriptor)) Object.defineProperty(ret, field[1], val);\\n else ret[field[1]] = val;\\n }\\n operands = [];\\n } else operands.push((0, $c2d28e92708f99da$export$2e2bcd8739ae039).decode(stream, b));\\n }\\n return ret;\\n }\\n size(dict, parent, includePointers = true) {\\n let ctx = {\\n parent,\\n val: dict,\\n pointerSize: 0,\\n startOffset: parent.startOffset || 0\\n };\\n let len = 0;\\n for (let k in this.fields) {\\n let field = this.fields[k];\\n let val = dict[field[1]];\\n if (val == null || (0, import_fast_deep_equal.default)(val, field[3])) continue;\\n let operands = this.encodeOperands(field[2], null, ctx, val);\\n for (let op of operands) len += (0, $c2d28e92708f99da$export$2e2bcd8739ae039).size(op);\\n let key = Array.isArray(field[0]) ? field[0] : [\\n field[0]\\n ];\\n len += key.length;\\n }\\n if (includePointers) len += ctx.pointerSize;\\n return len;\\n }\\n encode(stream, dict, parent) {\\n let ctx = {\\n pointers: [],\\n startOffset: stream.pos,\\n parent,\\n val: dict,\\n pointerSize: 0\\n };\\n ctx.pointerOffset = stream.pos + this.size(dict, ctx, false);\\n for (let field of this.ops) {\\n let val = dict[field[1]];\\n if (val == null || (0, import_fast_deep_equal.default)(val, field[3])) continue;\\n let operands = this.encodeOperands(field[2], stream, ctx, val);\\n for (let op of operands) (0, $c2d28e92708f99da$export$2e2bcd8739ae039).encode(stream, op);\\n let key = Array.isArray(field[0]) ? field[0] : [\\n field[0]\\n ];\\n for (let op of key) stream.writeUInt8(op);\\n }\\n let i = 0;\\n while (i < ctx.pointers.length) {\\n let ptr = ctx.pointers[i++];\\n ptr.type.encode(stream, ptr.val, ptr.parent);\\n }\\n return;\\n }\\n constructor(ops = []) {\\n this.ops = ops;\\n this.fields = {};\\n for (let field of ops) {\\n let key = Array.isArray(field[0]) ? field[0][0] << 8 | field[0][1] : field[0];\\n this.fields[key] = field;\\n }\\n }\\n };\\n $0e34a43d05bde82c$export$2e2bcd8739ae039 = class extends Pointer {\\n decode(stream, parent, operands) {\\n this.offsetType = {\\n decode: () => operands[0]\\n };\\n return super.decode(stream, parent, operands);\\n }\\n encode(stream, value, ctx) {\\n if (!stream) {\\n this.offsetType = {\\n size: () => 0\\n };\\n this.size(value, ctx);\\n return [\\n new $0e34a43d05bde82c$var$Ptr(0)\\n ];\\n }\\n let ptr = null;\\n this.offsetType = {\\n encode: (stream2, val) => ptr = val\\n };\\n super.encode(stream, value, ctx);\\n return [\\n new $0e34a43d05bde82c$var$Ptr(ptr)\\n ];\\n }\\n constructor(type, options = {}) {\\n if (options.type == null) options.type = \\\"global\\\";\\n super(null, type, options);\\n }\\n };\\n $0e34a43d05bde82c$var$Ptr = class {\\n valueOf() {\\n return this.val;\\n }\\n constructor(val) {\\n this.val = val;\\n this.forceLarge = true;\\n }\\n };\\n $6d59db2e29cc77b3$var$CFFBlendOp = class {\\n static decode(stream, parent, operands) {\\n let numBlends = operands.pop();\\n while (operands.length > numBlends) operands.pop();\\n }\\n };\\n $6d59db2e29cc77b3$export$2e2bcd8739ae039 = new (0, $61aa549f16d58b9b$export$2e2bcd8739ae039)([\\n // key name type default\\n [\\n 6,\\n \\\"BlueValues\\\",\\n \\\"delta\\\",\\n null\\n ],\\n [\\n 7,\\n \\\"OtherBlues\\\",\\n \\\"delta\\\",\\n null\\n ],\\n [\\n 8,\\n \\\"FamilyBlues\\\",\\n \\\"delta\\\",\\n null\\n ],\\n [\\n 9,\\n \\\"FamilyOtherBlues\\\",\\n \\\"delta\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 9\\n ],\\n \\\"BlueScale\\\",\\n \\\"number\\\",\\n 0.039625\\n ],\\n [\\n [\\n 12,\\n 10\\n ],\\n \\\"BlueShift\\\",\\n \\\"number\\\",\\n 7\\n ],\\n [\\n [\\n 12,\\n 11\\n ],\\n \\\"BlueFuzz\\\",\\n \\\"number\\\",\\n 1\\n ],\\n [\\n 10,\\n \\\"StdHW\\\",\\n \\\"number\\\",\\n null\\n ],\\n [\\n 11,\\n \\\"StdVW\\\",\\n \\\"number\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 12\\n ],\\n \\\"StemSnapH\\\",\\n \\\"delta\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 13\\n ],\\n \\\"StemSnapV\\\",\\n \\\"delta\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 14\\n ],\\n \\\"ForceBold\\\",\\n \\\"boolean\\\",\\n false\\n ],\\n [\\n [\\n 12,\\n 17\\n ],\\n \\\"LanguageGroup\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n [\\n 12,\\n 18\\n ],\\n \\\"ExpansionFactor\\\",\\n \\\"number\\\",\\n 0.06\\n ],\\n [\\n [\\n 12,\\n 19\\n ],\\n \\\"initialRandomSeed\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n 20,\\n \\\"defaultWidthX\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n 21,\\n \\\"nominalWidthX\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n 22,\\n \\\"vsindex\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n 23,\\n \\\"blend\\\",\\n $6d59db2e29cc77b3$var$CFFBlendOp,\\n null\\n ],\\n [\\n 19,\\n \\\"Subrs\\\",\\n new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)(new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)(), {\\n type: \\\"local\\\"\\n }),\\n null\\n ]\\n ]);\\n $229224aec43783c5$export$2e2bcd8739ae039 = [\\n \\\".notdef\\\",\\n \\\"space\\\",\\n \\\"exclam\\\",\\n \\\"quotedbl\\\",\\n \\\"numbersign\\\",\\n \\\"dollar\\\",\\n \\\"percent\\\",\\n \\\"ampersand\\\",\\n \\\"quoteright\\\",\\n \\\"parenleft\\\",\\n \\\"parenright\\\",\\n \\\"asterisk\\\",\\n \\\"plus\\\",\\n \\\"comma\\\",\\n \\\"hyphen\\\",\\n \\\"period\\\",\\n \\\"slash\\\",\\n \\\"zero\\\",\\n \\\"one\\\",\\n \\\"two\\\",\\n \\\"three\\\",\\n \\\"four\\\",\\n \\\"five\\\",\\n \\\"six\\\",\\n \\\"seven\\\",\\n \\\"eight\\\",\\n \\\"nine\\\",\\n \\\"colon\\\",\\n \\\"semicolon\\\",\\n \\\"less\\\",\\n \\\"equal\\\",\\n \\\"greater\\\",\\n \\\"question\\\",\\n \\\"at\\\",\\n \\\"A\\\",\\n \\\"B\\\",\\n \\\"C\\\",\\n \\\"D\\\",\\n \\\"E\\\",\\n \\\"F\\\",\\n \\\"G\\\",\\n \\\"H\\\",\\n \\\"I\\\",\\n \\\"J\\\",\\n \\\"K\\\",\\n \\\"L\\\",\\n \\\"M\\\",\\n \\\"N\\\",\\n \\\"O\\\",\\n \\\"P\\\",\\n \\\"Q\\\",\\n \\\"R\\\",\\n \\\"S\\\",\\n \\\"T\\\",\\n \\\"U\\\",\\n \\\"V\\\",\\n \\\"W\\\",\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\",\\n \\\"bracketleft\\\",\\n \\\"backslash\\\",\\n \\\"bracketright\\\",\\n \\\"asciicircum\\\",\\n \\\"underscore\\\",\\n \\\"quoteleft\\\",\\n \\\"a\\\",\\n \\\"b\\\",\\n \\\"c\\\",\\n \\\"d\\\",\\n \\\"e\\\",\\n \\\"f\\\",\\n \\\"g\\\",\\n \\\"h\\\",\\n \\\"i\\\",\\n \\\"j\\\",\\n \\\"k\\\",\\n \\\"l\\\",\\n \\\"m\\\",\\n \\\"n\\\",\\n \\\"o\\\",\\n \\\"p\\\",\\n \\\"q\\\",\\n \\\"r\\\",\\n \\\"s\\\",\\n \\\"t\\\",\\n \\\"u\\\",\\n \\\"v\\\",\\n \\\"w\\\",\\n \\\"x\\\",\\n \\\"y\\\",\\n \\\"z\\\",\\n \\\"braceleft\\\",\\n \\\"bar\\\",\\n \\\"braceright\\\",\\n \\\"asciitilde\\\",\\n \\\"exclamdown\\\",\\n \\\"cent\\\",\\n \\\"sterling\\\",\\n \\\"fraction\\\",\\n \\\"yen\\\",\\n \\\"florin\\\",\\n \\\"section\\\",\\n \\\"currency\\\",\\n \\\"quotesingle\\\",\\n \\\"quotedblleft\\\",\\n \\\"guillemotleft\\\",\\n \\\"guilsinglleft\\\",\\n \\\"guilsinglright\\\",\\n \\\"fi\\\",\\n \\\"fl\\\",\\n \\\"endash\\\",\\n \\\"dagger\\\",\\n \\\"daggerdbl\\\",\\n \\\"periodcentered\\\",\\n \\\"paragraph\\\",\\n \\\"bullet\\\",\\n \\\"quotesinglbase\\\",\\n \\\"quotedblbase\\\",\\n \\\"quotedblright\\\",\\n \\\"guillemotright\\\",\\n \\\"ellipsis\\\",\\n \\\"perthousand\\\",\\n \\\"questiondown\\\",\\n \\\"grave\\\",\\n \\\"acute\\\",\\n \\\"circumflex\\\",\\n \\\"tilde\\\",\\n \\\"macron\\\",\\n \\\"breve\\\",\\n \\\"dotaccent\\\",\\n \\\"dieresis\\\",\\n \\\"ring\\\",\\n \\\"cedilla\\\",\\n \\\"hungarumlaut\\\",\\n \\\"ogonek\\\",\\n \\\"caron\\\",\\n \\\"emdash\\\",\\n \\\"AE\\\",\\n \\\"ordfeminine\\\",\\n \\\"Lslash\\\",\\n \\\"Oslash\\\",\\n \\\"OE\\\",\\n \\\"ordmasculine\\\",\\n \\\"ae\\\",\\n \\\"dotlessi\\\",\\n \\\"lslash\\\",\\n \\\"oslash\\\",\\n \\\"oe\\\",\\n \\\"germandbls\\\",\\n \\\"onesuperior\\\",\\n \\\"logicalnot\\\",\\n \\\"mu\\\",\\n \\\"trademark\\\",\\n \\\"Eth\\\",\\n \\\"onehalf\\\",\\n \\\"plusminus\\\",\\n \\\"Thorn\\\",\\n \\\"onequarter\\\",\\n \\\"divide\\\",\\n \\\"brokenbar\\\",\\n \\\"degree\\\",\\n \\\"thorn\\\",\\n \\\"threequarters\\\",\\n \\\"twosuperior\\\",\\n \\\"registered\\\",\\n \\\"minus\\\",\\n \\\"eth\\\",\\n \\\"multiply\\\",\\n \\\"threesuperior\\\",\\n \\\"copyright\\\",\\n \\\"Aacute\\\",\\n \\\"Acircumflex\\\",\\n \\\"Adieresis\\\",\\n \\\"Agrave\\\",\\n \\\"Aring\\\",\\n \\\"Atilde\\\",\\n \\\"Ccedilla\\\",\\n \\\"Eacute\\\",\\n \\\"Ecircumflex\\\",\\n \\\"Edieresis\\\",\\n \\\"Egrave\\\",\\n \\\"Iacute\\\",\\n \\\"Icircumflex\\\",\\n \\\"Idieresis\\\",\\n \\\"Igrave\\\",\\n \\\"Ntilde\\\",\\n \\\"Oacute\\\",\\n \\\"Ocircumflex\\\",\\n \\\"Odieresis\\\",\\n \\\"Ograve\\\",\\n \\\"Otilde\\\",\\n \\\"Scaron\\\",\\n \\\"Uacute\\\",\\n \\\"Ucircumflex\\\",\\n \\\"Udieresis\\\",\\n \\\"Ugrave\\\",\\n \\\"Yacute\\\",\\n \\\"Ydieresis\\\",\\n \\\"Zcaron\\\",\\n \\\"aacute\\\",\\n \\\"acircumflex\\\",\\n \\\"adieresis\\\",\\n \\\"agrave\\\",\\n \\\"aring\\\",\\n \\\"atilde\\\",\\n \\\"ccedilla\\\",\\n \\\"eacute\\\",\\n \\\"ecircumflex\\\",\\n \\\"edieresis\\\",\\n \\\"egrave\\\",\\n \\\"iacute\\\",\\n \\\"icircumflex\\\",\\n \\\"idieresis\\\",\\n \\\"igrave\\\",\\n \\\"ntilde\\\",\\n \\\"oacute\\\",\\n \\\"ocircumflex\\\",\\n \\\"odieresis\\\",\\n \\\"ograve\\\",\\n \\\"otilde\\\",\\n \\\"scaron\\\",\\n \\\"uacute\\\",\\n \\\"ucircumflex\\\",\\n \\\"udieresis\\\",\\n \\\"ugrave\\\",\\n \\\"yacute\\\",\\n \\\"ydieresis\\\",\\n \\\"zcaron\\\",\\n \\\"exclamsmall\\\",\\n \\\"Hungarumlautsmall\\\",\\n \\\"dollaroldstyle\\\",\\n \\\"dollarsuperior\\\",\\n \\\"ampersandsmall\\\",\\n \\\"Acutesmall\\\",\\n \\\"parenleftsuperior\\\",\\n \\\"parenrightsuperior\\\",\\n \\\"twodotenleader\\\",\\n \\\"onedotenleader\\\",\\n \\\"zerooldstyle\\\",\\n \\\"oneoldstyle\\\",\\n \\\"twooldstyle\\\",\\n \\\"threeoldstyle\\\",\\n \\\"fouroldstyle\\\",\\n \\\"fiveoldstyle\\\",\\n \\\"sixoldstyle\\\",\\n \\\"sevenoldstyle\\\",\\n \\\"eightoldstyle\\\",\\n \\\"nineoldstyle\\\",\\n \\\"commasuperior\\\",\\n \\\"threequartersemdash\\\",\\n \\\"periodsuperior\\\",\\n \\\"questionsmall\\\",\\n \\\"asuperior\\\",\\n \\\"bsuperior\\\",\\n \\\"centsuperior\\\",\\n \\\"dsuperior\\\",\\n \\\"esuperior\\\",\\n \\\"isuperior\\\",\\n \\\"lsuperior\\\",\\n \\\"msuperior\\\",\\n \\\"nsuperior\\\",\\n \\\"osuperior\\\",\\n \\\"rsuperior\\\",\\n \\\"ssuperior\\\",\\n \\\"tsuperior\\\",\\n \\\"ff\\\",\\n \\\"ffi\\\",\\n \\\"ffl\\\",\\n \\\"parenleftinferior\\\",\\n \\\"parenrightinferior\\\",\\n \\\"Circumflexsmall\\\",\\n \\\"hyphensuperior\\\",\\n \\\"Gravesmall\\\",\\n \\\"Asmall\\\",\\n \\\"Bsmall\\\",\\n \\\"Csmall\\\",\\n \\\"Dsmall\\\",\\n \\\"Esmall\\\",\\n \\\"Fsmall\\\",\\n \\\"Gsmall\\\",\\n \\\"Hsmall\\\",\\n \\\"Ismall\\\",\\n \\\"Jsmall\\\",\\n \\\"Ksmall\\\",\\n \\\"Lsmall\\\",\\n \\\"Msmall\\\",\\n \\\"Nsmall\\\",\\n \\\"Osmall\\\",\\n \\\"Psmall\\\",\\n \\\"Qsmall\\\",\\n \\\"Rsmall\\\",\\n \\\"Ssmall\\\",\\n \\\"Tsmall\\\",\\n \\\"Usmall\\\",\\n \\\"Vsmall\\\",\\n \\\"Wsmall\\\",\\n \\\"Xsmall\\\",\\n \\\"Ysmall\\\",\\n \\\"Zsmall\\\",\\n \\\"colonmonetary\\\",\\n \\\"onefitted\\\",\\n \\\"rupiah\\\",\\n \\\"Tildesmall\\\",\\n \\\"exclamdownsmall\\\",\\n \\\"centoldstyle\\\",\\n \\\"Lslashsmall\\\",\\n \\\"Scaronsmall\\\",\\n \\\"Zcaronsmall\\\",\\n \\\"Dieresissmall\\\",\\n \\\"Brevesmall\\\",\\n \\\"Caronsmall\\\",\\n \\\"Dotaccentsmall\\\",\\n \\\"Macronsmall\\\",\\n \\\"figuredash\\\",\\n \\\"hypheninferior\\\",\\n \\\"Ogoneksmall\\\",\\n \\\"Ringsmall\\\",\\n \\\"Cedillasmall\\\",\\n \\\"questiondownsmall\\\",\\n \\\"oneeighth\\\",\\n \\\"threeeighths\\\",\\n \\\"fiveeighths\\\",\\n \\\"seveneighths\\\",\\n \\\"onethird\\\",\\n \\\"twothirds\\\",\\n \\\"zerosuperior\\\",\\n \\\"foursuperior\\\",\\n \\\"fivesuperior\\\",\\n \\\"sixsuperior\\\",\\n \\\"sevensuperior\\\",\\n \\\"eightsuperior\\\",\\n \\\"ninesuperior\\\",\\n \\\"zeroinferior\\\",\\n \\\"oneinferior\\\",\\n \\\"twoinferior\\\",\\n \\\"threeinferior\\\",\\n \\\"fourinferior\\\",\\n \\\"fiveinferior\\\",\\n \\\"sixinferior\\\",\\n \\\"seveninferior\\\",\\n \\\"eightinferior\\\",\\n \\\"nineinferior\\\",\\n \\\"centinferior\\\",\\n \\\"dollarinferior\\\",\\n \\\"periodinferior\\\",\\n \\\"commainferior\\\",\\n \\\"Agravesmall\\\",\\n \\\"Aacutesmall\\\",\\n \\\"Acircumflexsmall\\\",\\n \\\"Atildesmall\\\",\\n \\\"Adieresissmall\\\",\\n \\\"Aringsmall\\\",\\n \\\"AEsmall\\\",\\n \\\"Ccedillasmall\\\",\\n \\\"Egravesmall\\\",\\n \\\"Eacutesmall\\\",\\n \\\"Ecircumflexsmall\\\",\\n \\\"Edieresissmall\\\",\\n \\\"Igravesmall\\\",\\n \\\"Iacutesmall\\\",\\n \\\"Icircumflexsmall\\\",\\n \\\"Idieresissmall\\\",\\n \\\"Ethsmall\\\",\\n \\\"Ntildesmall\\\",\\n \\\"Ogravesmall\\\",\\n \\\"Oacutesmall\\\",\\n \\\"Ocircumflexsmall\\\",\\n \\\"Otildesmall\\\",\\n \\\"Odieresissmall\\\",\\n \\\"OEsmall\\\",\\n \\\"Oslashsmall\\\",\\n \\\"Ugravesmall\\\",\\n \\\"Uacutesmall\\\",\\n \\\"Ucircumflexsmall\\\",\\n \\\"Udieresissmall\\\",\\n \\\"Yacutesmall\\\",\\n \\\"Thornsmall\\\",\\n \\\"Ydieresissmall\\\",\\n \\\"001.000\\\",\\n \\\"001.001\\\",\\n \\\"001.002\\\",\\n \\\"001.003\\\",\\n \\\"Black\\\",\\n \\\"Bold\\\",\\n \\\"Book\\\",\\n \\\"Light\\\",\\n \\\"Medium\\\",\\n \\\"Regular\\\",\\n \\\"Roman\\\",\\n \\\"Semibold\\\"\\n ];\\n $bc0433d9b7e41f5f$export$dee0027060fa13bd = [\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"space\\\",\\n \\\"exclam\\\",\\n \\\"quotedbl\\\",\\n \\\"numbersign\\\",\\n \\\"dollar\\\",\\n \\\"percent\\\",\\n \\\"ampersand\\\",\\n \\\"quoteright\\\",\\n \\\"parenleft\\\",\\n \\\"parenright\\\",\\n \\\"asterisk\\\",\\n \\\"plus\\\",\\n \\\"comma\\\",\\n \\\"hyphen\\\",\\n \\\"period\\\",\\n \\\"slash\\\",\\n \\\"zero\\\",\\n \\\"one\\\",\\n \\\"two\\\",\\n \\\"three\\\",\\n \\\"four\\\",\\n \\\"five\\\",\\n \\\"six\\\",\\n \\\"seven\\\",\\n \\\"eight\\\",\\n \\\"nine\\\",\\n \\\"colon\\\",\\n \\\"semicolon\\\",\\n \\\"less\\\",\\n \\\"equal\\\",\\n \\\"greater\\\",\\n \\\"question\\\",\\n \\\"at\\\",\\n \\\"A\\\",\\n \\\"B\\\",\\n \\\"C\\\",\\n \\\"D\\\",\\n \\\"E\\\",\\n \\\"F\\\",\\n \\\"G\\\",\\n \\\"H\\\",\\n \\\"I\\\",\\n \\\"J\\\",\\n \\\"K\\\",\\n \\\"L\\\",\\n \\\"M\\\",\\n \\\"N\\\",\\n \\\"O\\\",\\n \\\"P\\\",\\n \\\"Q\\\",\\n \\\"R\\\",\\n \\\"S\\\",\\n \\\"T\\\",\\n \\\"U\\\",\\n \\\"V\\\",\\n \\\"W\\\",\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\",\\n \\\"bracketleft\\\",\\n \\\"backslash\\\",\\n \\\"bracketright\\\",\\n \\\"asciicircum\\\",\\n \\\"underscore\\\",\\n \\\"quoteleft\\\",\\n \\\"a\\\",\\n \\\"b\\\",\\n \\\"c\\\",\\n \\\"d\\\",\\n \\\"e\\\",\\n \\\"f\\\",\\n \\\"g\\\",\\n \\\"h\\\",\\n \\\"i\\\",\\n \\\"j\\\",\\n \\\"k\\\",\\n \\\"l\\\",\\n \\\"m\\\",\\n \\\"n\\\",\\n \\\"o\\\",\\n \\\"p\\\",\\n \\\"q\\\",\\n \\\"r\\\",\\n \\\"s\\\",\\n \\\"t\\\",\\n \\\"u\\\",\\n \\\"v\\\",\\n \\\"w\\\",\\n \\\"x\\\",\\n \\\"y\\\",\\n \\\"z\\\",\\n \\\"braceleft\\\",\\n \\\"bar\\\",\\n \\\"braceright\\\",\\n \\\"asciitilde\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"exclamdown\\\",\\n \\\"cent\\\",\\n \\\"sterling\\\",\\n \\\"fraction\\\",\\n \\\"yen\\\",\\n \\\"florin\\\",\\n \\\"section\\\",\\n \\\"currency\\\",\\n \\\"quotesingle\\\",\\n \\\"quotedblleft\\\",\\n \\\"guillemotleft\\\",\\n \\\"guilsinglleft\\\",\\n \\\"guilsinglright\\\",\\n \\\"fi\\\",\\n \\\"fl\\\",\\n \\\"\\\",\\n \\\"endash\\\",\\n \\\"dagger\\\",\\n \\\"daggerdbl\\\",\\n \\\"periodcentered\\\",\\n \\\"\\\",\\n \\\"paragraph\\\",\\n \\\"bullet\\\",\\n \\\"quotesinglbase\\\",\\n \\\"quotedblbase\\\",\\n \\\"quotedblright\\\",\\n \\\"guillemotright\\\",\\n \\\"ellipsis\\\",\\n \\\"perthousand\\\",\\n \\\"\\\",\\n \\\"questiondown\\\",\\n \\\"\\\",\\n \\\"grave\\\",\\n \\\"acute\\\",\\n \\\"circumflex\\\",\\n \\\"tilde\\\",\\n \\\"macron\\\",\\n \\\"breve\\\",\\n \\\"dotaccent\\\",\\n \\\"dieresis\\\",\\n \\\"\\\",\\n \\\"ring\\\",\\n \\\"cedilla\\\",\\n \\\"\\\",\\n \\\"hungarumlaut\\\",\\n \\\"ogonek\\\",\\n \\\"caron\\\",\\n \\\"emdash\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"AE\\\",\\n \\\"\\\",\\n \\\"ordfeminine\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"Lslash\\\",\\n \\\"Oslash\\\",\\n \\\"OE\\\",\\n \\\"ordmasculine\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"ae\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"dotlessi\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"lslash\\\",\\n \\\"oslash\\\",\\n \\\"oe\\\",\\n \\\"germandbls\\\"\\n ];\\n $bc0433d9b7e41f5f$export$4f58f497e14a53c3 = [\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"space\\\",\\n \\\"exclamsmall\\\",\\n \\\"Hungarumlautsmall\\\",\\n \\\"\\\",\\n \\\"dollaroldstyle\\\",\\n \\\"dollarsuperior\\\",\\n \\\"ampersandsmall\\\",\\n \\\"Acutesmall\\\",\\n \\\"parenleftsuperior\\\",\\n \\\"parenrightsuperior\\\",\\n \\\"twodotenleader\\\",\\n \\\"onedotenleader\\\",\\n \\\"comma\\\",\\n \\\"hyphen\\\",\\n \\\"period\\\",\\n \\\"fraction\\\",\\n \\\"zerooldstyle\\\",\\n \\\"oneoldstyle\\\",\\n \\\"twooldstyle\\\",\\n \\\"threeoldstyle\\\",\\n \\\"fouroldstyle\\\",\\n \\\"fiveoldstyle\\\",\\n \\\"sixoldstyle\\\",\\n \\\"sevenoldstyle\\\",\\n \\\"eightoldstyle\\\",\\n \\\"nineoldstyle\\\",\\n \\\"colon\\\",\\n \\\"semicolon\\\",\\n \\\"commasuperior\\\",\\n \\\"threequartersemdash\\\",\\n \\\"periodsuperior\\\",\\n \\\"questionsmall\\\",\\n \\\"\\\",\\n \\\"asuperior\\\",\\n \\\"bsuperior\\\",\\n \\\"centsuperior\\\",\\n \\\"dsuperior\\\",\\n \\\"esuperior\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"isuperior\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"lsuperior\\\",\\n \\\"msuperior\\\",\\n \\\"nsuperior\\\",\\n \\\"osuperior\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"rsuperior\\\",\\n \\\"ssuperior\\\",\\n \\\"tsuperior\\\",\\n \\\"\\\",\\n \\\"ff\\\",\\n \\\"fi\\\",\\n \\\"fl\\\",\\n \\\"ffi\\\",\\n \\\"ffl\\\",\\n \\\"parenleftinferior\\\",\\n \\\"\\\",\\n \\\"parenrightinferior\\\",\\n \\\"Circumflexsmall\\\",\\n \\\"hyphensuperior\\\",\\n \\\"Gravesmall\\\",\\n \\\"Asmall\\\",\\n \\\"Bsmall\\\",\\n \\\"Csmall\\\",\\n \\\"Dsmall\\\",\\n \\\"Esmall\\\",\\n \\\"Fsmall\\\",\\n \\\"Gsmall\\\",\\n \\\"Hsmall\\\",\\n \\\"Ismall\\\",\\n \\\"Jsmall\\\",\\n \\\"Ksmall\\\",\\n \\\"Lsmall\\\",\\n \\\"Msmall\\\",\\n \\\"Nsmall\\\",\\n \\\"Osmall\\\",\\n \\\"Psmall\\\",\\n \\\"Qsmall\\\",\\n \\\"Rsmall\\\",\\n \\\"Ssmall\\\",\\n \\\"Tsmall\\\",\\n \\\"Usmall\\\",\\n \\\"Vsmall\\\",\\n \\\"Wsmall\\\",\\n \\\"Xsmall\\\",\\n \\\"Ysmall\\\",\\n \\\"Zsmall\\\",\\n \\\"colonmonetary\\\",\\n \\\"onefitted\\\",\\n \\\"rupiah\\\",\\n \\\"Tildesmall\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"exclamdownsmall\\\",\\n \\\"centoldstyle\\\",\\n \\\"Lslashsmall\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"Scaronsmall\\\",\\n \\\"Zcaronsmall\\\",\\n \\\"Dieresissmall\\\",\\n \\\"Brevesmall\\\",\\n \\\"Caronsmall\\\",\\n \\\"\\\",\\n \\\"Dotaccentsmall\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"Macronsmall\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"figuredash\\\",\\n \\\"hypheninferior\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"Ogoneksmall\\\",\\n \\\"Ringsmall\\\",\\n \\\"Cedillasmall\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"onequarter\\\",\\n \\\"onehalf\\\",\\n \\\"threequarters\\\",\\n \\\"questiondownsmall\\\",\\n \\\"oneeighth\\\",\\n \\\"threeeighths\\\",\\n \\\"fiveeighths\\\",\\n \\\"seveneighths\\\",\\n \\\"onethird\\\",\\n \\\"twothirds\\\",\\n \\\"\\\",\\n \\\"\\\",\\n \\\"zerosuperior\\\",\\n \\\"onesuperior\\\",\\n \\\"twosuperior\\\",\\n \\\"threesuperior\\\",\\n \\\"foursuperior\\\",\\n \\\"fivesuperior\\\",\\n \\\"sixsuperior\\\",\\n \\\"sevensuperior\\\",\\n \\\"eightsuperior\\\",\\n \\\"ninesuperior\\\",\\n \\\"zeroinferior\\\",\\n \\\"oneinferior\\\",\\n \\\"twoinferior\\\",\\n \\\"threeinferior\\\",\\n \\\"fourinferior\\\",\\n \\\"fiveinferior\\\",\\n \\\"sixinferior\\\",\\n \\\"seveninferior\\\",\\n \\\"eightinferior\\\",\\n \\\"nineinferior\\\",\\n \\\"centinferior\\\",\\n \\\"dollarinferior\\\",\\n \\\"periodinferior\\\",\\n \\\"commainferior\\\",\\n \\\"Agravesmall\\\",\\n \\\"Aacutesmall\\\",\\n \\\"Acircumflexsmall\\\",\\n \\\"Atildesmall\\\",\\n \\\"Adieresissmall\\\",\\n \\\"Aringsmall\\\",\\n \\\"AEsmall\\\",\\n \\\"Ccedillasmall\\\",\\n \\\"Egravesmall\\\",\\n \\\"Eacutesmall\\\",\\n \\\"Ecircumflexsmall\\\",\\n \\\"Edieresissmall\\\",\\n \\\"Igravesmall\\\",\\n \\\"Iacutesmall\\\",\\n \\\"Icircumflexsmall\\\",\\n \\\"Idieresissmall\\\",\\n \\\"Ethsmall\\\",\\n \\\"Ntildesmall\\\",\\n \\\"Ogravesmall\\\",\\n \\\"Oacutesmall\\\",\\n \\\"Ocircumflexsmall\\\",\\n \\\"Otildesmall\\\",\\n \\\"Odieresissmall\\\",\\n \\\"OEsmall\\\",\\n \\\"Oslashsmall\\\",\\n \\\"Ugravesmall\\\",\\n \\\"Uacutesmall\\\",\\n \\\"Ucircumflexsmall\\\",\\n \\\"Udieresissmall\\\",\\n \\\"Yacutesmall\\\",\\n \\\"Thornsmall\\\",\\n \\\"Ydieresissmall\\\"\\n ];\\n $ef658f5c9a1488b2$export$c33b50336c234f16 = [\\n \\\".notdef\\\",\\n \\\"space\\\",\\n \\\"exclam\\\",\\n \\\"quotedbl\\\",\\n \\\"numbersign\\\",\\n \\\"dollar\\\",\\n \\\"percent\\\",\\n \\\"ampersand\\\",\\n \\\"quoteright\\\",\\n \\\"parenleft\\\",\\n \\\"parenright\\\",\\n \\\"asterisk\\\",\\n \\\"plus\\\",\\n \\\"comma\\\",\\n \\\"hyphen\\\",\\n \\\"period\\\",\\n \\\"slash\\\",\\n \\\"zero\\\",\\n \\\"one\\\",\\n \\\"two\\\",\\n \\\"three\\\",\\n \\\"four\\\",\\n \\\"five\\\",\\n \\\"six\\\",\\n \\\"seven\\\",\\n \\\"eight\\\",\\n \\\"nine\\\",\\n \\\"colon\\\",\\n \\\"semicolon\\\",\\n \\\"less\\\",\\n \\\"equal\\\",\\n \\\"greater\\\",\\n \\\"question\\\",\\n \\\"at\\\",\\n \\\"A\\\",\\n \\\"B\\\",\\n \\\"C\\\",\\n \\\"D\\\",\\n \\\"E\\\",\\n \\\"F\\\",\\n \\\"G\\\",\\n \\\"H\\\",\\n \\\"I\\\",\\n \\\"J\\\",\\n \\\"K\\\",\\n \\\"L\\\",\\n \\\"M\\\",\\n \\\"N\\\",\\n \\\"O\\\",\\n \\\"P\\\",\\n \\\"Q\\\",\\n \\\"R\\\",\\n \\\"S\\\",\\n \\\"T\\\",\\n \\\"U\\\",\\n \\\"V\\\",\\n \\\"W\\\",\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\",\\n \\\"bracketleft\\\",\\n \\\"backslash\\\",\\n \\\"bracketright\\\",\\n \\\"asciicircum\\\",\\n \\\"underscore\\\",\\n \\\"quoteleft\\\",\\n \\\"a\\\",\\n \\\"b\\\",\\n \\\"c\\\",\\n \\\"d\\\",\\n \\\"e\\\",\\n \\\"f\\\",\\n \\\"g\\\",\\n \\\"h\\\",\\n \\\"i\\\",\\n \\\"j\\\",\\n \\\"k\\\",\\n \\\"l\\\",\\n \\\"m\\\",\\n \\\"n\\\",\\n \\\"o\\\",\\n \\\"p\\\",\\n \\\"q\\\",\\n \\\"r\\\",\\n \\\"s\\\",\\n \\\"t\\\",\\n \\\"u\\\",\\n \\\"v\\\",\\n \\\"w\\\",\\n \\\"x\\\",\\n \\\"y\\\",\\n \\\"z\\\",\\n \\\"braceleft\\\",\\n \\\"bar\\\",\\n \\\"braceright\\\",\\n \\\"asciitilde\\\",\\n \\\"exclamdown\\\",\\n \\\"cent\\\",\\n \\\"sterling\\\",\\n \\\"fraction\\\",\\n \\\"yen\\\",\\n \\\"florin\\\",\\n \\\"section\\\",\\n \\\"currency\\\",\\n \\\"quotesingle\\\",\\n \\\"quotedblleft\\\",\\n \\\"guillemotleft\\\",\\n \\\"guilsinglleft\\\",\\n \\\"guilsinglright\\\",\\n \\\"fi\\\",\\n \\\"fl\\\",\\n \\\"endash\\\",\\n \\\"dagger\\\",\\n \\\"daggerdbl\\\",\\n \\\"periodcentered\\\",\\n \\\"paragraph\\\",\\n \\\"bullet\\\",\\n \\\"quotesinglbase\\\",\\n \\\"quotedblbase\\\",\\n \\\"quotedblright\\\",\\n \\\"guillemotright\\\",\\n \\\"ellipsis\\\",\\n \\\"perthousand\\\",\\n \\\"questiondown\\\",\\n \\\"grave\\\",\\n \\\"acute\\\",\\n \\\"circumflex\\\",\\n \\\"tilde\\\",\\n \\\"macron\\\",\\n \\\"breve\\\",\\n \\\"dotaccent\\\",\\n \\\"dieresis\\\",\\n \\\"ring\\\",\\n \\\"cedilla\\\",\\n \\\"hungarumlaut\\\",\\n \\\"ogonek\\\",\\n \\\"caron\\\",\\n \\\"emdash\\\",\\n \\\"AE\\\",\\n \\\"ordfeminine\\\",\\n \\\"Lslash\\\",\\n \\\"Oslash\\\",\\n \\\"OE\\\",\\n \\\"ordmasculine\\\",\\n \\\"ae\\\",\\n \\\"dotlessi\\\",\\n \\\"lslash\\\",\\n \\\"oslash\\\",\\n \\\"oe\\\",\\n \\\"germandbls\\\",\\n \\\"onesuperior\\\",\\n \\\"logicalnot\\\",\\n \\\"mu\\\",\\n \\\"trademark\\\",\\n \\\"Eth\\\",\\n \\\"onehalf\\\",\\n \\\"plusminus\\\",\\n \\\"Thorn\\\",\\n \\\"onequarter\\\",\\n \\\"divide\\\",\\n \\\"brokenbar\\\",\\n \\\"degree\\\",\\n \\\"thorn\\\",\\n \\\"threequarters\\\",\\n \\\"twosuperior\\\",\\n \\\"registered\\\",\\n \\\"minus\\\",\\n \\\"eth\\\",\\n \\\"multiply\\\",\\n \\\"threesuperior\\\",\\n \\\"copyright\\\",\\n \\\"Aacute\\\",\\n \\\"Acircumflex\\\",\\n \\\"Adieresis\\\",\\n \\\"Agrave\\\",\\n \\\"Aring\\\",\\n \\\"Atilde\\\",\\n \\\"Ccedilla\\\",\\n \\\"Eacute\\\",\\n \\\"Ecircumflex\\\",\\n \\\"Edieresis\\\",\\n \\\"Egrave\\\",\\n \\\"Iacute\\\",\\n \\\"Icircumflex\\\",\\n \\\"Idieresis\\\",\\n \\\"Igrave\\\",\\n \\\"Ntilde\\\",\\n \\\"Oacute\\\",\\n \\\"Ocircumflex\\\",\\n \\\"Odieresis\\\",\\n \\\"Ograve\\\",\\n \\\"Otilde\\\",\\n \\\"Scaron\\\",\\n \\\"Uacute\\\",\\n \\\"Ucircumflex\\\",\\n \\\"Udieresis\\\",\\n \\\"Ugrave\\\",\\n \\\"Yacute\\\",\\n \\\"Ydieresis\\\",\\n \\\"Zcaron\\\",\\n \\\"aacute\\\",\\n \\\"acircumflex\\\",\\n \\\"adieresis\\\",\\n \\\"agrave\\\",\\n \\\"aring\\\",\\n \\\"atilde\\\",\\n \\\"ccedilla\\\",\\n \\\"eacute\\\",\\n \\\"ecircumflex\\\",\\n \\\"edieresis\\\",\\n \\\"egrave\\\",\\n \\\"iacute\\\",\\n \\\"icircumflex\\\",\\n \\\"idieresis\\\",\\n \\\"igrave\\\",\\n \\\"ntilde\\\",\\n \\\"oacute\\\",\\n \\\"ocircumflex\\\",\\n \\\"odieresis\\\",\\n \\\"ograve\\\",\\n \\\"otilde\\\",\\n \\\"scaron\\\",\\n \\\"uacute\\\",\\n \\\"ucircumflex\\\",\\n \\\"udieresis\\\",\\n \\\"ugrave\\\",\\n \\\"yacute\\\",\\n \\\"ydieresis\\\",\\n \\\"zcaron\\\"\\n ];\\n $ef658f5c9a1488b2$export$3ed0f9e1fee8d489 = [\\n \\\".notdef\\\",\\n \\\"space\\\",\\n \\\"exclamsmall\\\",\\n \\\"Hungarumlautsmall\\\",\\n \\\"dollaroldstyle\\\",\\n \\\"dollarsuperior\\\",\\n \\\"ampersandsmall\\\",\\n \\\"Acutesmall\\\",\\n \\\"parenleftsuperior\\\",\\n \\\"parenrightsuperior\\\",\\n \\\"twodotenleader\\\",\\n \\\"onedotenleader\\\",\\n \\\"comma\\\",\\n \\\"hyphen\\\",\\n \\\"period\\\",\\n \\\"fraction\\\",\\n \\\"zerooldstyle\\\",\\n \\\"oneoldstyle\\\",\\n \\\"twooldstyle\\\",\\n \\\"threeoldstyle\\\",\\n \\\"fouroldstyle\\\",\\n \\\"fiveoldstyle\\\",\\n \\\"sixoldstyle\\\",\\n \\\"sevenoldstyle\\\",\\n \\\"eightoldstyle\\\",\\n \\\"nineoldstyle\\\",\\n \\\"colon\\\",\\n \\\"semicolon\\\",\\n \\\"commasuperior\\\",\\n \\\"threequartersemdash\\\",\\n \\\"periodsuperior\\\",\\n \\\"questionsmall\\\",\\n \\\"asuperior\\\",\\n \\\"bsuperior\\\",\\n \\\"centsuperior\\\",\\n \\\"dsuperior\\\",\\n \\\"esuperior\\\",\\n \\\"isuperior\\\",\\n \\\"lsuperior\\\",\\n \\\"msuperior\\\",\\n \\\"nsuperior\\\",\\n \\\"osuperior\\\",\\n \\\"rsuperior\\\",\\n \\\"ssuperior\\\",\\n \\\"tsuperior\\\",\\n \\\"ff\\\",\\n \\\"fi\\\",\\n \\\"fl\\\",\\n \\\"ffi\\\",\\n \\\"ffl\\\",\\n \\\"parenleftinferior\\\",\\n \\\"parenrightinferior\\\",\\n \\\"Circumflexsmall\\\",\\n \\\"hyphensuperior\\\",\\n \\\"Gravesmall\\\",\\n \\\"Asmall\\\",\\n \\\"Bsmall\\\",\\n \\\"Csmall\\\",\\n \\\"Dsmall\\\",\\n \\\"Esmall\\\",\\n \\\"Fsmall\\\",\\n \\\"Gsmall\\\",\\n \\\"Hsmall\\\",\\n \\\"Ismall\\\",\\n \\\"Jsmall\\\",\\n \\\"Ksmall\\\",\\n \\\"Lsmall\\\",\\n \\\"Msmall\\\",\\n \\\"Nsmall\\\",\\n \\\"Osmall\\\",\\n \\\"Psmall\\\",\\n \\\"Qsmall\\\",\\n \\\"Rsmall\\\",\\n \\\"Ssmall\\\",\\n \\\"Tsmall\\\",\\n \\\"Usmall\\\",\\n \\\"Vsmall\\\",\\n \\\"Wsmall\\\",\\n \\\"Xsmall\\\",\\n \\\"Ysmall\\\",\\n \\\"Zsmall\\\",\\n \\\"colonmonetary\\\",\\n \\\"onefitted\\\",\\n \\\"rupiah\\\",\\n \\\"Tildesmall\\\",\\n \\\"exclamdownsmall\\\",\\n \\\"centoldstyle\\\",\\n \\\"Lslashsmall\\\",\\n \\\"Scaronsmall\\\",\\n \\\"Zcaronsmall\\\",\\n \\\"Dieresissmall\\\",\\n \\\"Brevesmall\\\",\\n \\\"Caronsmall\\\",\\n \\\"Dotaccentsmall\\\",\\n \\\"Macronsmall\\\",\\n \\\"figuredash\\\",\\n \\\"hypheninferior\\\",\\n \\\"Ogoneksmall\\\",\\n \\\"Ringsmall\\\",\\n \\\"Cedillasmall\\\",\\n \\\"onequarter\\\",\\n \\\"onehalf\\\",\\n \\\"threequarters\\\",\\n \\\"questiondownsmall\\\",\\n \\\"oneeighth\\\",\\n \\\"threeeighths\\\",\\n \\\"fiveeighths\\\",\\n \\\"seveneighths\\\",\\n \\\"onethird\\\",\\n \\\"twothirds\\\",\\n \\\"zerosuperior\\\",\\n \\\"onesuperior\\\",\\n \\\"twosuperior\\\",\\n \\\"threesuperior\\\",\\n \\\"foursuperior\\\",\\n \\\"fivesuperior\\\",\\n \\\"sixsuperior\\\",\\n \\\"sevensuperior\\\",\\n \\\"eightsuperior\\\",\\n \\\"ninesuperior\\\",\\n \\\"zeroinferior\\\",\\n \\\"oneinferior\\\",\\n \\\"twoinferior\\\",\\n \\\"threeinferior\\\",\\n \\\"fourinferior\\\",\\n \\\"fiveinferior\\\",\\n \\\"sixinferior\\\",\\n \\\"seveninferior\\\",\\n \\\"eightinferior\\\",\\n \\\"nineinferior\\\",\\n \\\"centinferior\\\",\\n \\\"dollarinferior\\\",\\n \\\"periodinferior\\\",\\n \\\"commainferior\\\",\\n \\\"Agravesmall\\\",\\n \\\"Aacutesmall\\\",\\n \\\"Acircumflexsmall\\\",\\n \\\"Atildesmall\\\",\\n \\\"Adieresissmall\\\",\\n \\\"Aringsmall\\\",\\n \\\"AEsmall\\\",\\n \\\"Ccedillasmall\\\",\\n \\\"Egravesmall\\\",\\n \\\"Eacutesmall\\\",\\n \\\"Ecircumflexsmall\\\",\\n \\\"Edieresissmall\\\",\\n \\\"Igravesmall\\\",\\n \\\"Iacutesmall\\\",\\n \\\"Icircumflexsmall\\\",\\n \\\"Idieresissmall\\\",\\n \\\"Ethsmall\\\",\\n \\\"Ntildesmall\\\",\\n \\\"Ogravesmall\\\",\\n \\\"Oacutesmall\\\",\\n \\\"Ocircumflexsmall\\\",\\n \\\"Otildesmall\\\",\\n \\\"Odieresissmall\\\",\\n \\\"OEsmall\\\",\\n \\\"Oslashsmall\\\",\\n \\\"Ugravesmall\\\",\\n \\\"Uacutesmall\\\",\\n \\\"Ucircumflexsmall\\\",\\n \\\"Udieresissmall\\\",\\n \\\"Yacutesmall\\\",\\n \\\"Thornsmall\\\",\\n \\\"Ydieresissmall\\\"\\n ];\\n $ef658f5c9a1488b2$export$dc28be11139d4120 = [\\n \\\".notdef\\\",\\n \\\"space\\\",\\n \\\"dollaroldstyle\\\",\\n \\\"dollarsuperior\\\",\\n \\\"parenleftsuperior\\\",\\n \\\"parenrightsuperior\\\",\\n \\\"twodotenleader\\\",\\n \\\"onedotenleader\\\",\\n \\\"comma\\\",\\n \\\"hyphen\\\",\\n \\\"period\\\",\\n \\\"fraction\\\",\\n \\\"zerooldstyle\\\",\\n \\\"oneoldstyle\\\",\\n \\\"twooldstyle\\\",\\n \\\"threeoldstyle\\\",\\n \\\"fouroldstyle\\\",\\n \\\"fiveoldstyle\\\",\\n \\\"sixoldstyle\\\",\\n \\\"sevenoldstyle\\\",\\n \\\"eightoldstyle\\\",\\n \\\"nineoldstyle\\\",\\n \\\"colon\\\",\\n \\\"semicolon\\\",\\n \\\"commasuperior\\\",\\n \\\"threequartersemdash\\\",\\n \\\"periodsuperior\\\",\\n \\\"asuperior\\\",\\n \\\"bsuperior\\\",\\n \\\"centsuperior\\\",\\n \\\"dsuperior\\\",\\n \\\"esuperior\\\",\\n \\\"isuperior\\\",\\n \\\"lsuperior\\\",\\n \\\"msuperior\\\",\\n \\\"nsuperior\\\",\\n \\\"osuperior\\\",\\n \\\"rsuperior\\\",\\n \\\"ssuperior\\\",\\n \\\"tsuperior\\\",\\n \\\"ff\\\",\\n \\\"fi\\\",\\n \\\"fl\\\",\\n \\\"ffi\\\",\\n \\\"ffl\\\",\\n \\\"parenleftinferior\\\",\\n \\\"parenrightinferior\\\",\\n \\\"hyphensuperior\\\",\\n \\\"colonmonetary\\\",\\n \\\"onefitted\\\",\\n \\\"rupiah\\\",\\n \\\"centoldstyle\\\",\\n \\\"figuredash\\\",\\n \\\"hypheninferior\\\",\\n \\\"onequarter\\\",\\n \\\"onehalf\\\",\\n \\\"threequarters\\\",\\n \\\"oneeighth\\\",\\n \\\"threeeighths\\\",\\n \\\"fiveeighths\\\",\\n \\\"seveneighths\\\",\\n \\\"onethird\\\",\\n \\\"twothirds\\\",\\n \\\"zerosuperior\\\",\\n \\\"onesuperior\\\",\\n \\\"twosuperior\\\",\\n \\\"threesuperior\\\",\\n \\\"foursuperior\\\",\\n \\\"fivesuperior\\\",\\n \\\"sixsuperior\\\",\\n \\\"sevensuperior\\\",\\n \\\"eightsuperior\\\",\\n \\\"ninesuperior\\\",\\n \\\"zeroinferior\\\",\\n \\\"oneinferior\\\",\\n \\\"twoinferior\\\",\\n \\\"threeinferior\\\",\\n \\\"fourinferior\\\",\\n \\\"fiveinferior\\\",\\n \\\"sixinferior\\\",\\n \\\"seveninferior\\\",\\n \\\"eightinferior\\\",\\n \\\"nineinferior\\\",\\n \\\"centinferior\\\",\\n \\\"dollarinferior\\\",\\n \\\"periodinferior\\\",\\n \\\"commainferior\\\"\\n ];\\n $7cbbe4e24ef3cb75$var$LangSysTable = new Struct({\\n reserved: new Reserved(uint16),\\n reqFeatureIndex: uint16,\\n featureCount: uint16,\\n featureIndexes: new ArrayT(uint16, \\\"featureCount\\\")\\n });\\n $7cbbe4e24ef3cb75$var$LangSysRecord = new Struct({\\n tag: new StringT(4),\\n langSys: new Pointer(uint16, $7cbbe4e24ef3cb75$var$LangSysTable, {\\n type: \\\"parent\\\"\\n })\\n });\\n $7cbbe4e24ef3cb75$var$Script = new Struct({\\n defaultLangSys: new Pointer(uint16, $7cbbe4e24ef3cb75$var$LangSysTable),\\n count: uint16,\\n langSysRecords: new ArrayT($7cbbe4e24ef3cb75$var$LangSysRecord, \\\"count\\\")\\n });\\n $7cbbe4e24ef3cb75$var$ScriptRecord = new Struct({\\n tag: new StringT(4),\\n script: new Pointer(uint16, $7cbbe4e24ef3cb75$var$Script, {\\n type: \\\"parent\\\"\\n })\\n });\\n $7cbbe4e24ef3cb75$export$3e15fc05ce864229 = new ArrayT($7cbbe4e24ef3cb75$var$ScriptRecord, uint16);\\n $7cbbe4e24ef3cb75$var$FeatureParams = new Struct({\\n version: uint16,\\n nameID: uint16\\n });\\n $7cbbe4e24ef3cb75$export$6e91cf7616333d5 = new Struct({\\n featureParams: new Pointer(uint16, $7cbbe4e24ef3cb75$var$FeatureParams),\\n lookupCount: uint16,\\n lookupListIndexes: new ArrayT(uint16, \\\"lookupCount\\\")\\n });\\n $7cbbe4e24ef3cb75$var$FeatureRecord = new Struct({\\n tag: new StringT(4),\\n feature: new Pointer(uint16, $7cbbe4e24ef3cb75$export$6e91cf7616333d5, {\\n type: \\\"parent\\\"\\n })\\n });\\n $7cbbe4e24ef3cb75$export$aa18130def4b6cb4 = new ArrayT($7cbbe4e24ef3cb75$var$FeatureRecord, uint16);\\n $7cbbe4e24ef3cb75$var$LookupFlags = new Struct({\\n markAttachmentType: uint8,\\n flags: new Bitfield(uint8, [\\n \\\"rightToLeft\\\",\\n \\\"ignoreBaseGlyphs\\\",\\n \\\"ignoreLigatures\\\",\\n \\\"ignoreMarks\\\",\\n \\\"useMarkFilteringSet\\\"\\n ])\\n });\\n $7cbbe4e24ef3cb75$var$RangeRecord = new Struct({\\n start: uint16,\\n end: uint16,\\n startCoverageIndex: uint16\\n });\\n $7cbbe4e24ef3cb75$export$17608c3f81a6111 = new VersionedStruct(uint16, {\\n 1: {\\n glyphCount: uint16,\\n glyphs: new ArrayT(uint16, \\\"glyphCount\\\")\\n },\\n 2: {\\n rangeCount: uint16,\\n rangeRecords: new ArrayT($7cbbe4e24ef3cb75$var$RangeRecord, \\\"rangeCount\\\")\\n }\\n });\\n $7cbbe4e24ef3cb75$var$ClassRangeRecord = new Struct({\\n start: uint16,\\n end: uint16,\\n class: uint16\\n });\\n $7cbbe4e24ef3cb75$export$843d551fbbafef71 = new VersionedStruct(uint16, {\\n 1: {\\n startGlyph: uint16,\\n glyphCount: uint16,\\n classValueArray: new ArrayT(uint16, \\\"glyphCount\\\")\\n },\\n 2: {\\n classRangeCount: uint16,\\n classRangeRecord: new ArrayT($7cbbe4e24ef3cb75$var$ClassRangeRecord, \\\"classRangeCount\\\")\\n }\\n });\\n $7cbbe4e24ef3cb75$export$8215d14a63d9fb10 = new Struct({\\n a: uint16,\\n b: uint16,\\n deltaFormat: uint16\\n });\\n $7cbbe4e24ef3cb75$var$LookupRecord = new Struct({\\n sequenceIndex: uint16,\\n lookupListIndex: uint16\\n });\\n $7cbbe4e24ef3cb75$var$Rule = new Struct({\\n glyphCount: uint16,\\n lookupCount: uint16,\\n input: new ArrayT(uint16, (t) => t.glyphCount - 1),\\n lookupRecords: new ArrayT($7cbbe4e24ef3cb75$var$LookupRecord, \\\"lookupCount\\\")\\n });\\n $7cbbe4e24ef3cb75$var$RuleSet = new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$var$Rule), uint16);\\n $7cbbe4e24ef3cb75$var$ClassRule = new Struct({\\n glyphCount: uint16,\\n lookupCount: uint16,\\n classes: new ArrayT(uint16, (t) => t.glyphCount - 1),\\n lookupRecords: new ArrayT($7cbbe4e24ef3cb75$var$LookupRecord, \\\"lookupCount\\\")\\n });\\n $7cbbe4e24ef3cb75$var$ClassSet = new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$var$ClassRule), uint16);\\n $7cbbe4e24ef3cb75$export$841858b892ce1f4c = new VersionedStruct(uint16, {\\n 1: {\\n coverage: new Pointer(uint16, $7cbbe4e24ef3cb75$export$17608c3f81a6111),\\n ruleSetCount: uint16,\\n ruleSets: new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$var$RuleSet), \\\"ruleSetCount\\\")\\n },\\n 2: {\\n coverage: new Pointer(uint16, $7cbbe4e24ef3cb75$export$17608c3f81a6111),\\n classDef: new Pointer(uint16, $7cbbe4e24ef3cb75$export$843d551fbbafef71),\\n classSetCnt: uint16,\\n classSet: new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$var$ClassSet), \\\"classSetCnt\\\")\\n },\\n 3: {\\n glyphCount: uint16,\\n lookupCount: uint16,\\n coverages: new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$export$17608c3f81a6111), \\\"glyphCount\\\"),\\n lookupRecords: new ArrayT($7cbbe4e24ef3cb75$var$LookupRecord, \\\"lookupCount\\\")\\n }\\n });\\n $7cbbe4e24ef3cb75$var$ChainRule = new Struct({\\n backtrackGlyphCount: uint16,\\n backtrack: new ArrayT(uint16, \\\"backtrackGlyphCount\\\"),\\n inputGlyphCount: uint16,\\n input: new ArrayT(uint16, (t) => t.inputGlyphCount - 1),\\n lookaheadGlyphCount: uint16,\\n lookahead: new ArrayT(uint16, \\\"lookaheadGlyphCount\\\"),\\n lookupCount: uint16,\\n lookupRecords: new ArrayT($7cbbe4e24ef3cb75$var$LookupRecord, \\\"lookupCount\\\")\\n });\\n $7cbbe4e24ef3cb75$var$ChainRuleSet = new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$var$ChainRule), uint16);\\n $7cbbe4e24ef3cb75$export$5e6d09e6861162f6 = new VersionedStruct(uint16, {\\n 1: {\\n coverage: new Pointer(uint16, $7cbbe4e24ef3cb75$export$17608c3f81a6111),\\n chainCount: uint16,\\n chainRuleSets: new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$var$ChainRuleSet), \\\"chainCount\\\")\\n },\\n 2: {\\n coverage: new Pointer(uint16, $7cbbe4e24ef3cb75$export$17608c3f81a6111),\\n backtrackClassDef: new Pointer(uint16, $7cbbe4e24ef3cb75$export$843d551fbbafef71),\\n inputClassDef: new Pointer(uint16, $7cbbe4e24ef3cb75$export$843d551fbbafef71),\\n lookaheadClassDef: new Pointer(uint16, $7cbbe4e24ef3cb75$export$843d551fbbafef71),\\n chainCount: uint16,\\n chainClassSet: new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$var$ChainRuleSet), \\\"chainCount\\\")\\n },\\n 3: {\\n backtrackGlyphCount: uint16,\\n backtrackCoverage: new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$export$17608c3f81a6111), \\\"backtrackGlyphCount\\\"),\\n inputGlyphCount: uint16,\\n inputCoverage: new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$export$17608c3f81a6111), \\\"inputGlyphCount\\\"),\\n lookaheadGlyphCount: uint16,\\n lookaheadCoverage: new ArrayT(new Pointer(uint16, $7cbbe4e24ef3cb75$export$17608c3f81a6111), \\\"lookaheadGlyphCount\\\"),\\n lookupCount: uint16,\\n lookupRecords: new ArrayT($7cbbe4e24ef3cb75$var$LookupRecord, \\\"lookupCount\\\")\\n }\\n });\\n $1a47b0c45c1c22fe$var$F2DOT14 = new Fixed(16, \\\"BE\\\", 14);\\n $1a47b0c45c1c22fe$var$RegionAxisCoordinates = new Struct({\\n startCoord: $1a47b0c45c1c22fe$var$F2DOT14,\\n peakCoord: $1a47b0c45c1c22fe$var$F2DOT14,\\n endCoord: $1a47b0c45c1c22fe$var$F2DOT14\\n });\\n $1a47b0c45c1c22fe$var$VariationRegionList = new Struct({\\n axisCount: uint16,\\n regionCount: uint16,\\n variationRegions: new ArrayT(new ArrayT($1a47b0c45c1c22fe$var$RegionAxisCoordinates, \\\"axisCount\\\"), \\\"regionCount\\\")\\n });\\n $1a47b0c45c1c22fe$var$DeltaSet = new Struct({\\n shortDeltas: new ArrayT(int16, (t) => t.parent.shortDeltaCount),\\n regionDeltas: new ArrayT(int8, (t) => t.parent.regionIndexCount - t.parent.shortDeltaCount),\\n deltas: (t) => t.shortDeltas.concat(t.regionDeltas)\\n });\\n $1a47b0c45c1c22fe$var$ItemVariationData = new Struct({\\n itemCount: uint16,\\n shortDeltaCount: uint16,\\n regionIndexCount: uint16,\\n regionIndexes: new ArrayT(uint16, \\\"regionIndexCount\\\"),\\n deltaSets: new ArrayT($1a47b0c45c1c22fe$var$DeltaSet, \\\"itemCount\\\")\\n });\\n $1a47b0c45c1c22fe$export$fe1b122a2710f241 = new Struct({\\n format: uint16,\\n variationRegionList: new Pointer(uint32, $1a47b0c45c1c22fe$var$VariationRegionList),\\n variationDataCount: uint16,\\n itemVariationData: new ArrayT(new Pointer(uint32, $1a47b0c45c1c22fe$var$ItemVariationData), \\\"variationDataCount\\\")\\n });\\n $1a47b0c45c1c22fe$var$ConditionTable = new VersionedStruct(uint16, {\\n 1: {\\n axisIndex: uint16,\\n axisIndex: uint16,\\n filterRangeMinValue: $1a47b0c45c1c22fe$var$F2DOT14,\\n filterRangeMaxValue: $1a47b0c45c1c22fe$var$F2DOT14\\n }\\n });\\n $1a47b0c45c1c22fe$var$ConditionSet = new Struct({\\n conditionCount: uint16,\\n conditionTable: new ArrayT(new Pointer(uint32, $1a47b0c45c1c22fe$var$ConditionTable), \\\"conditionCount\\\")\\n });\\n $1a47b0c45c1c22fe$var$FeatureTableSubstitutionRecord = new Struct({\\n featureIndex: uint16,\\n alternateFeatureTable: new Pointer(uint32, (0, $7cbbe4e24ef3cb75$export$6e91cf7616333d5), {\\n type: \\\"parent\\\"\\n })\\n });\\n $1a47b0c45c1c22fe$var$FeatureTableSubstitution = new Struct({\\n version: fixed32,\\n substitutionCount: uint16,\\n substitutions: new ArrayT($1a47b0c45c1c22fe$var$FeatureTableSubstitutionRecord, \\\"substitutionCount\\\")\\n });\\n $1a47b0c45c1c22fe$var$FeatureVariationRecord = new Struct({\\n conditionSet: new Pointer(uint32, $1a47b0c45c1c22fe$var$ConditionSet, {\\n type: \\\"parent\\\"\\n }),\\n featureTableSubstitution: new Pointer(uint32, $1a47b0c45c1c22fe$var$FeatureTableSubstitution, {\\n type: \\\"parent\\\"\\n })\\n });\\n $1a47b0c45c1c22fe$export$441b70b7971dd419 = new Struct({\\n majorVersion: uint16,\\n minorVersion: uint16,\\n featureVariationRecordCount: uint32,\\n featureVariationRecords: new ArrayT($1a47b0c45c1c22fe$var$FeatureVariationRecord, \\\"featureVariationRecordCount\\\")\\n });\\n $b84fd3dd9d8eddb2$var$PredefinedOp = class {\\n decode(stream, parent, operands) {\\n if (this.predefinedOps[operands[0]]) return this.predefinedOps[operands[0]];\\n return this.type.decode(stream, parent, operands);\\n }\\n size(value, ctx) {\\n return this.type.size(value, ctx);\\n }\\n encode(stream, value, ctx) {\\n let index = this.predefinedOps.indexOf(value);\\n if (index !== -1) return index;\\n return this.type.encode(stream, value, ctx);\\n }\\n constructor(predefinedOps, type) {\\n this.predefinedOps = predefinedOps;\\n this.type = type;\\n }\\n };\\n $b84fd3dd9d8eddb2$var$CFFEncodingVersion = class extends NumberT {\\n decode(stream) {\\n return uint8.decode(stream) & 127;\\n }\\n constructor() {\\n super(\\\"UInt8\\\");\\n }\\n };\\n $b84fd3dd9d8eddb2$var$Range1 = new Struct({\\n first: uint16,\\n nLeft: uint8\\n });\\n $b84fd3dd9d8eddb2$var$Range2 = new Struct({\\n first: uint16,\\n nLeft: uint16\\n });\\n $b84fd3dd9d8eddb2$var$CFFCustomEncoding = new VersionedStruct(new $b84fd3dd9d8eddb2$var$CFFEncodingVersion(), {\\n 0: {\\n nCodes: uint8,\\n codes: new ArrayT(uint8, \\\"nCodes\\\")\\n },\\n 1: {\\n nRanges: uint8,\\n ranges: new ArrayT($b84fd3dd9d8eddb2$var$Range1, \\\"nRanges\\\")\\n }\\n });\\n $b84fd3dd9d8eddb2$var$CFFEncoding = new $b84fd3dd9d8eddb2$var$PredefinedOp([\\n (0, $bc0433d9b7e41f5f$export$dee0027060fa13bd),\\n (0, $bc0433d9b7e41f5f$export$4f58f497e14a53c3)\\n ], new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)($b84fd3dd9d8eddb2$var$CFFCustomEncoding, {\\n lazy: true\\n }));\\n $b84fd3dd9d8eddb2$var$RangeArray = class extends ArrayT {\\n decode(stream, parent) {\\n let length = (0, resolveLength)(this.length, stream, parent);\\n let count = 0;\\n let res = [];\\n while (count < length) {\\n let range = this.type.decode(stream, parent);\\n range.offset = count;\\n count += range.nLeft + 1;\\n res.push(range);\\n }\\n return res;\\n }\\n };\\n $b84fd3dd9d8eddb2$var$CFFCustomCharset = new VersionedStruct(uint8, {\\n 0: {\\n glyphs: new ArrayT(uint16, (t) => t.parent.CharStrings.length - 1)\\n },\\n 1: {\\n ranges: new $b84fd3dd9d8eddb2$var$RangeArray($b84fd3dd9d8eddb2$var$Range1, (t) => t.parent.CharStrings.length - 1)\\n },\\n 2: {\\n ranges: new $b84fd3dd9d8eddb2$var$RangeArray($b84fd3dd9d8eddb2$var$Range2, (t) => t.parent.CharStrings.length - 1)\\n }\\n });\\n $b84fd3dd9d8eddb2$var$CFFCharset = new $b84fd3dd9d8eddb2$var$PredefinedOp([\\n (0, $ef658f5c9a1488b2$export$c33b50336c234f16),\\n (0, $ef658f5c9a1488b2$export$3ed0f9e1fee8d489),\\n (0, $ef658f5c9a1488b2$export$dc28be11139d4120)\\n ], new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)($b84fd3dd9d8eddb2$var$CFFCustomCharset, {\\n lazy: true\\n }));\\n $b84fd3dd9d8eddb2$var$FDRange3 = new Struct({\\n first: uint16,\\n fd: uint8\\n });\\n $b84fd3dd9d8eddb2$var$FDRange4 = new Struct({\\n first: uint32,\\n fd: uint16\\n });\\n $b84fd3dd9d8eddb2$var$FDSelect = new VersionedStruct(uint8, {\\n 0: {\\n fds: new ArrayT(uint8, (t) => t.parent.CharStrings.length)\\n },\\n 3: {\\n nRanges: uint16,\\n ranges: new ArrayT($b84fd3dd9d8eddb2$var$FDRange3, \\\"nRanges\\\"),\\n sentinel: uint16\\n },\\n 4: {\\n nRanges: uint32,\\n ranges: new ArrayT($b84fd3dd9d8eddb2$var$FDRange4, \\\"nRanges\\\"),\\n sentinel: uint32\\n }\\n });\\n $b84fd3dd9d8eddb2$var$ptr = new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)((0, $6d59db2e29cc77b3$export$2e2bcd8739ae039));\\n $b84fd3dd9d8eddb2$var$CFFPrivateOp = class {\\n decode(stream, parent, operands) {\\n parent.length = operands[0];\\n return $b84fd3dd9d8eddb2$var$ptr.decode(stream, parent, [\\n operands[1]\\n ]);\\n }\\n size(dict, ctx) {\\n return [\\n (0, $6d59db2e29cc77b3$export$2e2bcd8739ae039).size(dict, ctx, false),\\n $b84fd3dd9d8eddb2$var$ptr.size(dict, ctx)[0]\\n ];\\n }\\n encode(stream, dict, ctx) {\\n return [\\n (0, $6d59db2e29cc77b3$export$2e2bcd8739ae039).size(dict, ctx, false),\\n $b84fd3dd9d8eddb2$var$ptr.encode(stream, dict, ctx)[0]\\n ];\\n }\\n };\\n $b84fd3dd9d8eddb2$var$FontDict = new (0, $61aa549f16d58b9b$export$2e2bcd8739ae039)([\\n // key name type(s) default\\n [\\n 18,\\n \\\"Private\\\",\\n new $b84fd3dd9d8eddb2$var$CFFPrivateOp(),\\n null\\n ],\\n [\\n [\\n 12,\\n 38\\n ],\\n \\\"FontName\\\",\\n \\\"sid\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 7\\n ],\\n \\\"FontMatrix\\\",\\n \\\"array\\\",\\n [\\n 1e-3,\\n 0,\\n 0,\\n 1e-3,\\n 0,\\n 0\\n ]\\n ],\\n [\\n [\\n 12,\\n 5\\n ],\\n \\\"PaintType\\\",\\n \\\"number\\\",\\n 0\\n ]\\n ]);\\n $b84fd3dd9d8eddb2$var$CFFTopDict = new (0, $61aa549f16d58b9b$export$2e2bcd8739ae039)([\\n // key name type(s) default\\n [\\n [\\n 12,\\n 30\\n ],\\n \\\"ROS\\\",\\n [\\n \\\"sid\\\",\\n \\\"sid\\\",\\n \\\"number\\\"\\n ],\\n null\\n ],\\n [\\n 0,\\n \\\"version\\\",\\n \\\"sid\\\",\\n null\\n ],\\n [\\n 1,\\n \\\"Notice\\\",\\n \\\"sid\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 0\\n ],\\n \\\"Copyright\\\",\\n \\\"sid\\\",\\n null\\n ],\\n [\\n 2,\\n \\\"FullName\\\",\\n \\\"sid\\\",\\n null\\n ],\\n [\\n 3,\\n \\\"FamilyName\\\",\\n \\\"sid\\\",\\n null\\n ],\\n [\\n 4,\\n \\\"Weight\\\",\\n \\\"sid\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 1\\n ],\\n \\\"isFixedPitch\\\",\\n \\\"boolean\\\",\\n false\\n ],\\n [\\n [\\n 12,\\n 2\\n ],\\n \\\"ItalicAngle\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n [\\n 12,\\n 3\\n ],\\n \\\"UnderlinePosition\\\",\\n \\\"number\\\",\\n -100\\n ],\\n [\\n [\\n 12,\\n 4\\n ],\\n \\\"UnderlineThickness\\\",\\n \\\"number\\\",\\n 50\\n ],\\n [\\n [\\n 12,\\n 5\\n ],\\n \\\"PaintType\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n [\\n 12,\\n 6\\n ],\\n \\\"CharstringType\\\",\\n \\\"number\\\",\\n 2\\n ],\\n [\\n [\\n 12,\\n 7\\n ],\\n \\\"FontMatrix\\\",\\n \\\"array\\\",\\n [\\n 1e-3,\\n 0,\\n 0,\\n 1e-3,\\n 0,\\n 0\\n ]\\n ],\\n [\\n 13,\\n \\\"UniqueID\\\",\\n \\\"number\\\",\\n null\\n ],\\n [\\n 5,\\n \\\"FontBBox\\\",\\n \\\"array\\\",\\n [\\n 0,\\n 0,\\n 0,\\n 0\\n ]\\n ],\\n [\\n [\\n 12,\\n 8\\n ],\\n \\\"StrokeWidth\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n 14,\\n \\\"XUID\\\",\\n \\\"array\\\",\\n null\\n ],\\n [\\n 15,\\n \\\"charset\\\",\\n $b84fd3dd9d8eddb2$var$CFFCharset,\\n (0, $ef658f5c9a1488b2$export$c33b50336c234f16)\\n ],\\n [\\n 16,\\n \\\"Encoding\\\",\\n $b84fd3dd9d8eddb2$var$CFFEncoding,\\n (0, $bc0433d9b7e41f5f$export$dee0027060fa13bd)\\n ],\\n [\\n 17,\\n \\\"CharStrings\\\",\\n new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)(new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)()),\\n null\\n ],\\n [\\n 18,\\n \\\"Private\\\",\\n new $b84fd3dd9d8eddb2$var$CFFPrivateOp(),\\n null\\n ],\\n [\\n [\\n 12,\\n 20\\n ],\\n \\\"SyntheticBase\\\",\\n \\\"number\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 21\\n ],\\n \\\"PostScript\\\",\\n \\\"sid\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 22\\n ],\\n \\\"BaseFontName\\\",\\n \\\"sid\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 23\\n ],\\n \\\"BaseFontBlend\\\",\\n \\\"delta\\\",\\n null\\n ],\\n // CID font specific\\n [\\n [\\n 12,\\n 31\\n ],\\n \\\"CIDFontVersion\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n [\\n 12,\\n 32\\n ],\\n \\\"CIDFontRevision\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n [\\n 12,\\n 33\\n ],\\n \\\"CIDFontType\\\",\\n \\\"number\\\",\\n 0\\n ],\\n [\\n [\\n 12,\\n 34\\n ],\\n \\\"CIDCount\\\",\\n \\\"number\\\",\\n 8720\\n ],\\n [\\n [\\n 12,\\n 35\\n ],\\n \\\"UIDBase\\\",\\n \\\"number\\\",\\n null\\n ],\\n [\\n [\\n 12,\\n 37\\n ],\\n \\\"FDSelect\\\",\\n new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)($b84fd3dd9d8eddb2$var$FDSelect),\\n null\\n ],\\n [\\n [\\n 12,\\n 36\\n ],\\n \\\"FDArray\\\",\\n new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)(new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)($b84fd3dd9d8eddb2$var$FontDict)),\\n null\\n ],\\n [\\n [\\n 12,\\n 38\\n ],\\n \\\"FontName\\\",\\n \\\"sid\\\",\\n null\\n ]\\n ]);\\n $b84fd3dd9d8eddb2$var$VariationStore = new Struct({\\n length: uint16,\\n itemVariationStore: (0, $1a47b0c45c1c22fe$export$fe1b122a2710f241)\\n });\\n $b84fd3dd9d8eddb2$var$CFF2TopDict = new (0, $61aa549f16d58b9b$export$2e2bcd8739ae039)([\\n [\\n [\\n 12,\\n 7\\n ],\\n \\\"FontMatrix\\\",\\n \\\"array\\\",\\n [\\n 1e-3,\\n 0,\\n 0,\\n 1e-3,\\n 0,\\n 0\\n ]\\n ],\\n [\\n 17,\\n \\\"CharStrings\\\",\\n new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)(new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)()),\\n null\\n ],\\n [\\n [\\n 12,\\n 37\\n ],\\n \\\"FDSelect\\\",\\n new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)($b84fd3dd9d8eddb2$var$FDSelect),\\n null\\n ],\\n [\\n [\\n 12,\\n 36\\n ],\\n \\\"FDArray\\\",\\n new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)(new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)($b84fd3dd9d8eddb2$var$FontDict)),\\n null\\n ],\\n [\\n 24,\\n \\\"vstore\\\",\\n new (0, $0e34a43d05bde82c$export$2e2bcd8739ae039)($b84fd3dd9d8eddb2$var$VariationStore),\\n null\\n ],\\n [\\n 25,\\n \\\"maxstack\\\",\\n \\\"number\\\",\\n 193\\n ]\\n ]);\\n $b84fd3dd9d8eddb2$var$CFFTop = new VersionedStruct(fixed16, {\\n 1: {\\n hdrSize: uint8,\\n offSize: uint8,\\n nameIndex: new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)(new StringT(\\\"length\\\")),\\n topDictIndex: new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)($b84fd3dd9d8eddb2$var$CFFTopDict),\\n stringIndex: new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)(new StringT(\\\"length\\\")),\\n globalSubrIndex: new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)()\\n },\\n 2: {\\n hdrSize: uint8,\\n length: uint16,\\n topDict: $b84fd3dd9d8eddb2$var$CFF2TopDict,\\n globalSubrIndex: new (0, $43e9821ef3717eec$export$2e2bcd8739ae039)()\\n }\\n });\\n $b84fd3dd9d8eddb2$export$2e2bcd8739ae039 = $b84fd3dd9d8eddb2$var$CFFTop;\\n $822ac0d589e4e237$var$CFFFont = class _$822ac0d589e4e237$var$CFFFont {\\n static decode(stream) {\\n return new _$822ac0d589e4e237$var$CFFFont(stream);\\n }\\n decode() {\\n let start = this.stream.pos;\\n let top = (0, $b84fd3dd9d8eddb2$export$2e2bcd8739ae039).decode(this.stream);\\n for (let key in top) {\\n let val = top[key];\\n this[key] = val;\\n }\\n if (this.version < 2) {\\n if (this.topDictIndex.length !== 1) throw new Error(\\\"Only a single font is allowed in CFF\\\");\\n this.topDict = this.topDictIndex[0];\\n }\\n this.isCIDFont = this.topDict.ROS != null;\\n return this;\\n }\\n string(sid) {\\n if (this.version >= 2) return null;\\n if (sid < (0, $229224aec43783c5$export$2e2bcd8739ae039).length) return (0, $229224aec43783c5$export$2e2bcd8739ae039)[sid];\\n return this.stringIndex[sid - (0, $229224aec43783c5$export$2e2bcd8739ae039).length];\\n }\\n get postscriptName() {\\n if (this.version < 2) return this.nameIndex[0];\\n return null;\\n }\\n get fullName() {\\n return this.string(this.topDict.FullName);\\n }\\n get familyName() {\\n return this.string(this.topDict.FamilyName);\\n }\\n getCharString(glyph) {\\n this.stream.pos = this.topDict.CharStrings[glyph].offset;\\n return this.stream.readBuffer(this.topDict.CharStrings[glyph].length);\\n }\\n getGlyphName(gid) {\\n if (this.version >= 2) return null;\\n if (this.isCIDFont) return null;\\n let { charset } = this.topDict;\\n if (Array.isArray(charset)) return charset[gid];\\n if (gid === 0) return \\\".notdef\\\";\\n gid -= 1;\\n switch (charset.version) {\\n case 0:\\n return this.string(charset.glyphs[gid]);\\n case 1:\\n case 2:\\n for (let i = 0; i < charset.ranges.length; i++) {\\n let range = charset.ranges[i];\\n if (range.offset <= gid && gid <= range.offset + range.nLeft) return this.string(range.first + (gid - range.offset));\\n }\\n break;\\n }\\n return null;\\n }\\n fdForGlyph(gid) {\\n if (!this.topDict.FDSelect) return null;\\n switch (this.topDict.FDSelect.version) {\\n case 0:\\n return this.topDict.FDSelect.fds[gid];\\n case 3:\\n case 4:\\n let { ranges } = this.topDict.FDSelect;\\n let low = 0;\\n let high = ranges.length - 1;\\n while (low <= high) {\\n let mid = low + high >> 1;\\n if (gid < ranges[mid].first) high = mid - 1;\\n else if (mid < high && gid >= ranges[mid + 1].first) low = mid + 1;\\n else return ranges[mid].fd;\\n }\\n default:\\n throw new Error(`Unknown FDSelect version: ${this.topDict.FDSelect.version}`);\\n }\\n }\\n privateDictForGlyph(gid) {\\n if (this.topDict.FDSelect) {\\n let fd = this.fdForGlyph(gid);\\n if (this.topDict.FDArray[fd]) return this.topDict.FDArray[fd].Private;\\n return null;\\n }\\n if (this.version < 2) return this.topDict.Private;\\n return this.topDict.FDArray[0].Private;\\n }\\n constructor(stream) {\\n this.stream = stream;\\n this.decode();\\n }\\n };\\n $822ac0d589e4e237$export$2e2bcd8739ae039 = $822ac0d589e4e237$var$CFFFont;\\n $2bbf2bc1ce37cd8f$var$VerticalOrigin = new Struct({\\n glyphIndex: uint16,\\n vertOriginY: int16\\n });\\n $2bbf2bc1ce37cd8f$export$2e2bcd8739ae039 = new Struct({\\n majorVersion: uint16,\\n minorVersion: uint16,\\n defaultVertOriginY: int16,\\n numVertOriginYMetrics: uint16,\\n metrics: new ArrayT($2bbf2bc1ce37cd8f$var$VerticalOrigin, \\\"numVertOriginYMetrics\\\")\\n });\\n $0941618dc22a946d$export$16b227cb15d716a0 = new Struct({\\n height: uint8,\\n width: uint8,\\n horiBearingX: int8,\\n horiBearingY: int8,\\n horiAdvance: uint8,\\n vertBearingX: int8,\\n vertBearingY: int8,\\n vertAdvance: uint8\\n });\\n $0941618dc22a946d$export$62c53e75f69bfe12 = new Struct({\\n height: uint8,\\n width: uint8,\\n bearingX: int8,\\n bearingY: int8,\\n advance: uint8\\n });\\n $0941618dc22a946d$var$EBDTComponent = new Struct({\\n glyph: uint16,\\n xOffset: int8,\\n yOffset: int8\\n });\\n $0941618dc22a946d$var$ByteAligned = class {\\n };\\n $0941618dc22a946d$var$BitAligned = class {\\n };\\n $0941618dc22a946d$export$f1f5ddeb20d14f = new VersionedStruct(\\\"version\\\", {\\n 1: {\\n metrics: $0941618dc22a946d$export$62c53e75f69bfe12,\\n data: $0941618dc22a946d$var$ByteAligned\\n },\\n 2: {\\n metrics: $0941618dc22a946d$export$62c53e75f69bfe12,\\n data: $0941618dc22a946d$var$BitAligned\\n },\\n // format 3 is deprecated\\n // format 4 is not supported by Microsoft\\n 5: {\\n data: $0941618dc22a946d$var$BitAligned\\n },\\n 6: {\\n metrics: $0941618dc22a946d$export$16b227cb15d716a0,\\n data: $0941618dc22a946d$var$ByteAligned\\n },\\n 7: {\\n metrics: $0941618dc22a946d$export$16b227cb15d716a0,\\n data: $0941618dc22a946d$var$BitAligned\\n },\\n 8: {\\n metrics: $0941618dc22a946d$export$62c53e75f69bfe12,\\n pad: new Reserved(uint8),\\n numComponents: uint16,\\n components: new ArrayT($0941618dc22a946d$var$EBDTComponent, \\\"numComponents\\\")\\n },\\n 9: {\\n metrics: $0941618dc22a946d$export$16b227cb15d716a0,\\n pad: new Reserved(uint8),\\n numComponents: uint16,\\n components: new ArrayT($0941618dc22a946d$var$EBDTComponent, \\\"numComponents\\\")\\n },\\n 17: {\\n metrics: $0941618dc22a946d$export$62c53e75f69bfe12,\\n dataLen: uint32,\\n data: new BufferT(\\\"dataLen\\\")\\n },\\n 18: {\\n metrics: $0941618dc22a946d$export$16b227cb15d716a0,\\n dataLen: uint32,\\n data: new BufferT(\\\"dataLen\\\")\\n },\\n 19: {\\n dataLen: uint32,\\n data: new BufferT(\\\"dataLen\\\")\\n }\\n });\\n $9911c4c7201c13de$var$SBitLineMetrics = new Struct({\\n ascender: int8,\\n descender: int8,\\n widthMax: uint8,\\n caretSlopeNumerator: int8,\\n caretSlopeDenominator: int8,\\n caretOffset: int8,\\n minOriginSB: int8,\\n minAdvanceSB: int8,\\n maxBeforeBL: int8,\\n minAfterBL: int8,\\n pad: new Reserved(int8, 2)\\n });\\n $9911c4c7201c13de$var$CodeOffsetPair = new Struct({\\n glyphCode: uint16,\\n offset: uint16\\n });\\n $9911c4c7201c13de$var$IndexSubtable = new VersionedStruct(uint16, {\\n header: {\\n imageFormat: uint16,\\n imageDataOffset: uint32\\n },\\n 1: {\\n offsetArray: new ArrayT(uint32, (t) => t.parent.lastGlyphIndex - t.parent.firstGlyphIndex + 1)\\n },\\n 2: {\\n imageSize: uint32,\\n bigMetrics: (0, $0941618dc22a946d$export$16b227cb15d716a0)\\n },\\n 3: {\\n offsetArray: new ArrayT(uint16, (t) => t.parent.lastGlyphIndex - t.parent.firstGlyphIndex + 1)\\n },\\n 4: {\\n numGlyphs: uint32,\\n glyphArray: new ArrayT($9911c4c7201c13de$var$CodeOffsetPair, (t) => t.numGlyphs + 1)\\n },\\n 5: {\\n imageSize: uint32,\\n bigMetrics: (0, $0941618dc22a946d$export$16b227cb15d716a0),\\n numGlyphs: uint32,\\n glyphCodeArray: new ArrayT(uint16, \\\"numGlyphs\\\")\\n }\\n });\\n $9911c4c7201c13de$var$IndexSubtableArray = new Struct({\\n firstGlyphIndex: uint16,\\n lastGlyphIndex: uint16,\\n subtable: new Pointer(uint32, $9911c4c7201c13de$var$IndexSubtable)\\n });\\n $9911c4c7201c13de$var$BitmapSizeTable = new Struct({\\n indexSubTableArray: new Pointer(uint32, new ArrayT($9911c4c7201c13de$var$IndexSubtableArray, 1), {\\n type: \\\"parent\\\"\\n }),\\n indexTablesSize: uint32,\\n numberOfIndexSubTables: uint32,\\n colorRef: uint32,\\n hori: $9911c4c7201c13de$var$SBitLineMetrics,\\n vert: $9911c4c7201c13de$var$SBitLineMetrics,\\n startGlyphIndex: uint16,\\n endGlyphIndex: uint16,\\n ppemX: uint8,\\n ppemY: uint8,\\n bitDepth: uint8,\\n flags: new Bitfield(uint8, [\\n \\\"horizontal\\\",\\n \\\"vertical\\\"\\n ])\\n });\\n $9911c4c7201c13de$export$2e2bcd8739ae039 = new Struct({\\n version: uint32,\\n numSizes: uint32,\\n sizes: new ArrayT($9911c4c7201c13de$var$BitmapSizeTable, \\\"numSizes\\\")\\n });\\n $abb847051efd51b1$var$ImageTable = new Struct({\\n ppem: uint16,\\n resolution: uint16,\\n imageOffsets: new ArrayT(new Pointer(uint32, \\\"void\\\"), (t) => t.parent.parent.maxp.numGlyphs + 1)\\n });\\n $abb847051efd51b1$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n flags: new Bitfield(uint16, [\\n \\\"renderOutlines\\\"\\n ]),\\n numImgTables: uint32,\\n imageTables: new ArrayT(new Pointer(uint32, $abb847051efd51b1$var$ImageTable), \\\"numImgTables\\\")\\n });\\n $eb629188f3dfefdd$var$LayerRecord = new Struct({\\n gid: uint16,\\n paletteIndex: uint16\\n // Index value to use in the appropriate palette. This value must\\n });\\n $eb629188f3dfefdd$var$BaseGlyphRecord = new Struct({\\n gid: uint16,\\n // and is not rendered for color.\\n firstLayerIndex: uint16,\\n // There will be numLayers consecutive entries for this base glyph.\\n numLayers: uint16\\n });\\n $eb629188f3dfefdd$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n numBaseGlyphRecords: uint16,\\n baseGlyphRecord: new Pointer(uint32, new ArrayT($eb629188f3dfefdd$var$BaseGlyphRecord, \\\"numBaseGlyphRecords\\\")),\\n layerRecords: new Pointer(uint32, new ArrayT($eb629188f3dfefdd$var$LayerRecord, \\\"numLayerRecords\\\"), {\\n lazy: true\\n }),\\n numLayerRecords: uint16\\n });\\n $08734b8e7dc64587$var$ColorRecord = new Struct({\\n blue: uint8,\\n green: uint8,\\n red: uint8,\\n alpha: uint8\\n });\\n $08734b8e7dc64587$export$2e2bcd8739ae039 = new VersionedStruct(uint16, {\\n header: {\\n numPaletteEntries: uint16,\\n numPalettes: uint16,\\n numColorRecords: uint16,\\n colorRecords: new Pointer(uint32, new ArrayT($08734b8e7dc64587$var$ColorRecord, \\\"numColorRecords\\\")),\\n colorRecordIndices: new ArrayT(uint16, \\\"numPalettes\\\")\\n },\\n 0: {},\\n 1: {\\n offsetPaletteTypeArray: new Pointer(uint32, new ArrayT(uint32, \\\"numPalettes\\\")),\\n offsetPaletteLabelArray: new Pointer(uint32, new ArrayT(uint16, \\\"numPalettes\\\")),\\n offsetPaletteEntryLabelArray: new Pointer(uint32, new ArrayT(uint16, \\\"numPaletteEntries\\\"))\\n }\\n });\\n $497cef411d884e34$var$BaseCoord = new VersionedStruct(uint16, {\\n 1: {\\n coordinate: int16\\n // X or Y value, in design units\\n },\\n 2: {\\n coordinate: int16,\\n referenceGlyph: uint16,\\n baseCoordPoint: uint16\\n // Index of contour point on the referenceGlyph\\n },\\n 3: {\\n coordinate: int16,\\n deviceTable: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$8215d14a63d9fb10))\\n // Device table for X or Y value\\n }\\n });\\n $497cef411d884e34$var$BaseValues = new Struct({\\n defaultIndex: uint16,\\n baseCoordCount: uint16,\\n baseCoords: new ArrayT(new Pointer(uint16, $497cef411d884e34$var$BaseCoord), \\\"baseCoordCount\\\")\\n });\\n $497cef411d884e34$var$FeatMinMaxRecord = new Struct({\\n tag: new StringT(4),\\n minCoord: new Pointer(uint16, $497cef411d884e34$var$BaseCoord, {\\n type: \\\"parent\\\"\\n }),\\n maxCoord: new Pointer(uint16, $497cef411d884e34$var$BaseCoord, {\\n type: \\\"parent\\\"\\n })\\n // May be NULL\\n });\\n $497cef411d884e34$var$MinMax = new Struct({\\n minCoord: new Pointer(uint16, $497cef411d884e34$var$BaseCoord),\\n maxCoord: new Pointer(uint16, $497cef411d884e34$var$BaseCoord),\\n featMinMaxCount: uint16,\\n featMinMaxRecords: new ArrayT($497cef411d884e34$var$FeatMinMaxRecord, \\\"featMinMaxCount\\\")\\n // In alphabetical order\\n });\\n $497cef411d884e34$var$BaseLangSysRecord = new Struct({\\n tag: new StringT(4),\\n minMax: new Pointer(uint16, $497cef411d884e34$var$MinMax, {\\n type: \\\"parent\\\"\\n })\\n });\\n $497cef411d884e34$var$BaseScript = new Struct({\\n baseValues: new Pointer(uint16, $497cef411d884e34$var$BaseValues),\\n defaultMinMax: new Pointer(uint16, $497cef411d884e34$var$MinMax),\\n baseLangSysCount: uint16,\\n baseLangSysRecords: new ArrayT($497cef411d884e34$var$BaseLangSysRecord, \\\"baseLangSysCount\\\")\\n // in alphabetical order by BaseLangSysTag\\n });\\n $497cef411d884e34$var$BaseScriptRecord = new Struct({\\n tag: new StringT(4),\\n script: new Pointer(uint16, $497cef411d884e34$var$BaseScript, {\\n type: \\\"parent\\\"\\n })\\n });\\n $497cef411d884e34$var$BaseScriptList = new ArrayT($497cef411d884e34$var$BaseScriptRecord, uint16);\\n $497cef411d884e34$var$BaseTagList = new ArrayT(new StringT(4), uint16);\\n $497cef411d884e34$var$Axis = new Struct({\\n baseTagList: new Pointer(uint16, $497cef411d884e34$var$BaseTagList),\\n baseScriptList: new Pointer(uint16, $497cef411d884e34$var$BaseScriptList)\\n });\\n $497cef411d884e34$export$2e2bcd8739ae039 = new VersionedStruct(uint32, {\\n header: {\\n horizAxis: new Pointer(uint16, $497cef411d884e34$var$Axis),\\n vertAxis: new Pointer(uint16, $497cef411d884e34$var$Axis)\\n // May be NULL\\n },\\n 65536: {},\\n 65537: {\\n itemVariationStore: new Pointer(uint32, (0, $1a47b0c45c1c22fe$export$fe1b122a2710f241))\\n }\\n });\\n $cf5f33c63ef209e6$var$AttachPoint = new ArrayT(uint16, uint16);\\n $cf5f33c63ef209e6$var$AttachList = new Struct({\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n glyphCount: uint16,\\n attachPoints: new ArrayT(new Pointer(uint16, $cf5f33c63ef209e6$var$AttachPoint), \\\"glyphCount\\\")\\n });\\n $cf5f33c63ef209e6$var$CaretValue = new VersionedStruct(uint16, {\\n 1: {\\n coordinate: int16\\n },\\n 2: {\\n caretValuePoint: uint16\\n },\\n 3: {\\n coordinate: int16,\\n deviceTable: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$8215d14a63d9fb10))\\n }\\n });\\n $cf5f33c63ef209e6$var$LigGlyph = new ArrayT(new Pointer(uint16, $cf5f33c63ef209e6$var$CaretValue), uint16);\\n $cf5f33c63ef209e6$var$LigCaretList = new Struct({\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n ligGlyphCount: uint16,\\n ligGlyphs: new ArrayT(new Pointer(uint16, $cf5f33c63ef209e6$var$LigGlyph), \\\"ligGlyphCount\\\")\\n });\\n $cf5f33c63ef209e6$var$MarkGlyphSetsDef = new Struct({\\n markSetTableFormat: uint16,\\n markSetCount: uint16,\\n coverage: new ArrayT(new Pointer(uint32, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)), \\\"markSetCount\\\")\\n });\\n $cf5f33c63ef209e6$export$2e2bcd8739ae039 = new VersionedStruct(uint32, {\\n header: {\\n glyphClassDef: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$843d551fbbafef71)),\\n attachList: new Pointer(uint16, $cf5f33c63ef209e6$var$AttachList),\\n ligCaretList: new Pointer(uint16, $cf5f33c63ef209e6$var$LigCaretList),\\n markAttachClassDef: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$843d551fbbafef71))\\n },\\n 65536: {},\\n 65538: {\\n markGlyphSetsDef: new Pointer(uint16, $cf5f33c63ef209e6$var$MarkGlyphSetsDef)\\n },\\n 65539: {\\n markGlyphSetsDef: new Pointer(uint16, $cf5f33c63ef209e6$var$MarkGlyphSetsDef),\\n itemVariationStore: new Pointer(uint32, (0, $1a47b0c45c1c22fe$export$fe1b122a2710f241))\\n }\\n });\\n $47e0e8ef515d9903$var$ValueFormat = new Bitfield(uint16, [\\n \\\"xPlacement\\\",\\n \\\"yPlacement\\\",\\n \\\"xAdvance\\\",\\n \\\"yAdvance\\\",\\n \\\"xPlaDevice\\\",\\n \\\"yPlaDevice\\\",\\n \\\"xAdvDevice\\\",\\n \\\"yAdvDevice\\\"\\n ]);\\n $47e0e8ef515d9903$var$types = {\\n xPlacement: int16,\\n yPlacement: int16,\\n xAdvance: int16,\\n yAdvance: int16,\\n xPlaDevice: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$8215d14a63d9fb10), {\\n type: \\\"global\\\",\\n relativeTo: (ctx) => ctx.rel\\n }),\\n yPlaDevice: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$8215d14a63d9fb10), {\\n type: \\\"global\\\",\\n relativeTo: (ctx) => ctx.rel\\n }),\\n xAdvDevice: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$8215d14a63d9fb10), {\\n type: \\\"global\\\",\\n relativeTo: (ctx) => ctx.rel\\n }),\\n yAdvDevice: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$8215d14a63d9fb10), {\\n type: \\\"global\\\",\\n relativeTo: (ctx) => ctx.rel\\n })\\n };\\n $47e0e8ef515d9903$var$ValueRecord = class {\\n buildStruct(parent) {\\n let struct = parent;\\n while (!struct[this.key] && struct.parent) struct = struct.parent;\\n if (!struct[this.key]) return;\\n let fields = {};\\n fields.rel = () => struct._startOffset;\\n let format = struct[this.key];\\n for (let key in format) if (format[key]) fields[key] = $47e0e8ef515d9903$var$types[key];\\n return new Struct(fields);\\n }\\n size(val, ctx) {\\n return this.buildStruct(ctx).size(val, ctx);\\n }\\n decode(stream, parent) {\\n let res = this.buildStruct(parent).decode(stream, parent);\\n delete res.rel;\\n return res;\\n }\\n constructor(key = \\\"valueFormat\\\") {\\n this.key = key;\\n }\\n };\\n $47e0e8ef515d9903$var$PairValueRecord = new Struct({\\n secondGlyph: uint16,\\n value1: new $47e0e8ef515d9903$var$ValueRecord(\\\"valueFormat1\\\"),\\n value2: new $47e0e8ef515d9903$var$ValueRecord(\\\"valueFormat2\\\")\\n });\\n $47e0e8ef515d9903$var$PairSet = new ArrayT($47e0e8ef515d9903$var$PairValueRecord, uint16);\\n $47e0e8ef515d9903$var$Class2Record = new Struct({\\n value1: new $47e0e8ef515d9903$var$ValueRecord(\\\"valueFormat1\\\"),\\n value2: new $47e0e8ef515d9903$var$ValueRecord(\\\"valueFormat2\\\")\\n });\\n $47e0e8ef515d9903$var$Anchor = new VersionedStruct(uint16, {\\n 1: {\\n xCoordinate: int16,\\n yCoordinate: int16\\n },\\n 2: {\\n xCoordinate: int16,\\n yCoordinate: int16,\\n anchorPoint: uint16\\n },\\n 3: {\\n xCoordinate: int16,\\n yCoordinate: int16,\\n xDeviceTable: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$8215d14a63d9fb10)),\\n yDeviceTable: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$8215d14a63d9fb10))\\n }\\n });\\n $47e0e8ef515d9903$var$EntryExitRecord = new Struct({\\n entryAnchor: new Pointer(uint16, $47e0e8ef515d9903$var$Anchor, {\\n type: \\\"parent\\\"\\n }),\\n exitAnchor: new Pointer(uint16, $47e0e8ef515d9903$var$Anchor, {\\n type: \\\"parent\\\"\\n })\\n });\\n $47e0e8ef515d9903$var$MarkRecord = new Struct({\\n class: uint16,\\n markAnchor: new Pointer(uint16, $47e0e8ef515d9903$var$Anchor, {\\n type: \\\"parent\\\"\\n })\\n });\\n $47e0e8ef515d9903$var$MarkArray = new ArrayT($47e0e8ef515d9903$var$MarkRecord, uint16);\\n $47e0e8ef515d9903$var$BaseRecord = new ArrayT(new Pointer(uint16, $47e0e8ef515d9903$var$Anchor), (t) => t.parent.classCount);\\n $47e0e8ef515d9903$var$BaseArray = new ArrayT($47e0e8ef515d9903$var$BaseRecord, uint16);\\n $47e0e8ef515d9903$var$ComponentRecord = new ArrayT(new Pointer(uint16, $47e0e8ef515d9903$var$Anchor), (t) => t.parent.parent.classCount);\\n $47e0e8ef515d9903$var$LigatureAttach = new ArrayT($47e0e8ef515d9903$var$ComponentRecord, uint16);\\n $47e0e8ef515d9903$var$LigatureArray = new ArrayT(new Pointer(uint16, $47e0e8ef515d9903$var$LigatureAttach), uint16);\\n $47e0e8ef515d9903$export$73a8cfb19cd43a0f = new VersionedStruct(\\\"lookupType\\\", {\\n 1: new VersionedStruct(uint16, {\\n 1: {\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n valueFormat: $47e0e8ef515d9903$var$ValueFormat,\\n value: new $47e0e8ef515d9903$var$ValueRecord()\\n },\\n 2: {\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n valueFormat: $47e0e8ef515d9903$var$ValueFormat,\\n valueCount: uint16,\\n values: new LazyArray(new $47e0e8ef515d9903$var$ValueRecord(), \\\"valueCount\\\")\\n }\\n }),\\n 2: new VersionedStruct(uint16, {\\n 1: {\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n valueFormat1: $47e0e8ef515d9903$var$ValueFormat,\\n valueFormat2: $47e0e8ef515d9903$var$ValueFormat,\\n pairSetCount: uint16,\\n pairSets: new LazyArray(new Pointer(uint16, $47e0e8ef515d9903$var$PairSet), \\\"pairSetCount\\\")\\n },\\n 2: {\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n valueFormat1: $47e0e8ef515d9903$var$ValueFormat,\\n valueFormat2: $47e0e8ef515d9903$var$ValueFormat,\\n classDef1: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$843d551fbbafef71)),\\n classDef2: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$843d551fbbafef71)),\\n class1Count: uint16,\\n class2Count: uint16,\\n classRecords: new LazyArray(new LazyArray($47e0e8ef515d9903$var$Class2Record, \\\"class2Count\\\"), \\\"class1Count\\\")\\n }\\n }),\\n 3: {\\n format: uint16,\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n entryExitCount: uint16,\\n entryExitRecords: new ArrayT($47e0e8ef515d9903$var$EntryExitRecord, \\\"entryExitCount\\\")\\n },\\n 4: {\\n format: uint16,\\n markCoverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n baseCoverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n classCount: uint16,\\n markArray: new Pointer(uint16, $47e0e8ef515d9903$var$MarkArray),\\n baseArray: new Pointer(uint16, $47e0e8ef515d9903$var$BaseArray)\\n },\\n 5: {\\n format: uint16,\\n markCoverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n ligatureCoverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n classCount: uint16,\\n markArray: new Pointer(uint16, $47e0e8ef515d9903$var$MarkArray),\\n ligatureArray: new Pointer(uint16, $47e0e8ef515d9903$var$LigatureArray)\\n },\\n 6: {\\n format: uint16,\\n mark1Coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n mark2Coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n classCount: uint16,\\n mark1Array: new Pointer(uint16, $47e0e8ef515d9903$var$MarkArray),\\n mark2Array: new Pointer(uint16, $47e0e8ef515d9903$var$BaseArray)\\n },\\n 7: (0, $7cbbe4e24ef3cb75$export$841858b892ce1f4c),\\n 8: (0, $7cbbe4e24ef3cb75$export$5e6d09e6861162f6),\\n 9: {\\n posFormat: uint16,\\n lookupType: uint16,\\n extension: new Pointer(uint32, null)\\n }\\n });\\n $47e0e8ef515d9903$export$73a8cfb19cd43a0f.versions[9].extension.type = $47e0e8ef515d9903$export$73a8cfb19cd43a0f;\\n $47e0e8ef515d9903$export$2e2bcd8739ae039 = new VersionedStruct(uint32, {\\n header: {\\n scriptList: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$3e15fc05ce864229)),\\n featureList: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$aa18130def4b6cb4)),\\n lookupList: new Pointer(uint16, new (0, $7cbbe4e24ef3cb75$export$df0008c6ff2da22a)($47e0e8ef515d9903$export$73a8cfb19cd43a0f))\\n },\\n 65536: {},\\n 65537: {\\n featureVariations: new Pointer(uint32, (0, $1a47b0c45c1c22fe$export$441b70b7971dd419))\\n }\\n });\\n $d3f442064af66e06$var$Sequence = new ArrayT(uint16, uint16);\\n $d3f442064af66e06$var$AlternateSet = $d3f442064af66e06$var$Sequence;\\n $d3f442064af66e06$var$Ligature = new Struct({\\n glyph: uint16,\\n compCount: uint16,\\n components: new ArrayT(uint16, (t) => t.compCount - 1)\\n });\\n $d3f442064af66e06$var$LigatureSet = new ArrayT(new Pointer(uint16, $d3f442064af66e06$var$Ligature), uint16);\\n $d3f442064af66e06$var$GSUBLookup = new VersionedStruct(\\\"lookupType\\\", {\\n 1: new VersionedStruct(uint16, {\\n 1: {\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n deltaGlyphID: int16\\n },\\n 2: {\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n glyphCount: uint16,\\n substitute: new LazyArray(uint16, \\\"glyphCount\\\")\\n }\\n }),\\n 2: {\\n substFormat: uint16,\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n count: uint16,\\n sequences: new LazyArray(new Pointer(uint16, $d3f442064af66e06$var$Sequence), \\\"count\\\")\\n },\\n 3: {\\n substFormat: uint16,\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n count: uint16,\\n alternateSet: new LazyArray(new Pointer(uint16, $d3f442064af66e06$var$AlternateSet), \\\"count\\\")\\n },\\n 4: {\\n substFormat: uint16,\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n count: uint16,\\n ligatureSets: new LazyArray(new Pointer(uint16, $d3f442064af66e06$var$LigatureSet), \\\"count\\\")\\n },\\n 5: (0, $7cbbe4e24ef3cb75$export$841858b892ce1f4c),\\n 6: (0, $7cbbe4e24ef3cb75$export$5e6d09e6861162f6),\\n 7: {\\n substFormat: uint16,\\n lookupType: uint16,\\n extension: new Pointer(uint32, null)\\n },\\n 8: {\\n substFormat: uint16,\\n coverage: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)),\\n backtrackCoverage: new ArrayT(new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)), \\\"backtrackGlyphCount\\\"),\\n lookaheadGlyphCount: uint16,\\n lookaheadCoverage: new ArrayT(new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$17608c3f81a6111)), \\\"lookaheadGlyphCount\\\"),\\n glyphCount: uint16,\\n substitutes: new ArrayT(uint16, \\\"glyphCount\\\")\\n }\\n });\\n $d3f442064af66e06$var$GSUBLookup.versions[7].extension.type = $d3f442064af66e06$var$GSUBLookup;\\n $d3f442064af66e06$export$2e2bcd8739ae039 = new VersionedStruct(uint32, {\\n header: {\\n scriptList: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$3e15fc05ce864229)),\\n featureList: new Pointer(uint16, (0, $7cbbe4e24ef3cb75$export$aa18130def4b6cb4)),\\n lookupList: new Pointer(uint16, new (0, $7cbbe4e24ef3cb75$export$df0008c6ff2da22a)($d3f442064af66e06$var$GSUBLookup))\\n },\\n 65536: {},\\n 65537: {\\n featureVariations: new Pointer(uint32, (0, $1a47b0c45c1c22fe$export$441b70b7971dd419))\\n }\\n });\\n $71cfb3c4767fbd0c$var$JstfGSUBModList = new ArrayT(uint16, uint16);\\n $71cfb3c4767fbd0c$var$JstfPriority = new Struct({\\n shrinkageEnableGSUB: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfGSUBModList),\\n shrinkageDisableGSUB: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfGSUBModList),\\n shrinkageEnableGPOS: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfGSUBModList),\\n shrinkageDisableGPOS: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfGSUBModList),\\n shrinkageJstfMax: new Pointer(uint16, new (0, $7cbbe4e24ef3cb75$export$df0008c6ff2da22a)((0, $47e0e8ef515d9903$export$73a8cfb19cd43a0f))),\\n extensionEnableGSUB: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfGSUBModList),\\n extensionDisableGSUB: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfGSUBModList),\\n extensionEnableGPOS: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfGSUBModList),\\n extensionDisableGPOS: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfGSUBModList),\\n extensionJstfMax: new Pointer(uint16, new (0, $7cbbe4e24ef3cb75$export$df0008c6ff2da22a)((0, $47e0e8ef515d9903$export$73a8cfb19cd43a0f)))\\n });\\n $71cfb3c4767fbd0c$var$JstfLangSys = new ArrayT(new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfPriority), uint16);\\n $71cfb3c4767fbd0c$var$JstfLangSysRecord = new Struct({\\n tag: new StringT(4),\\n jstfLangSys: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfLangSys)\\n });\\n $71cfb3c4767fbd0c$var$JstfScript = new Struct({\\n extenderGlyphs: new Pointer(uint16, new ArrayT(uint16, uint16)),\\n defaultLangSys: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfLangSys),\\n langSysCount: uint16,\\n langSysRecords: new ArrayT($71cfb3c4767fbd0c$var$JstfLangSysRecord, \\\"langSysCount\\\")\\n });\\n $71cfb3c4767fbd0c$var$JstfScriptRecord = new Struct({\\n tag: new StringT(4),\\n script: new Pointer(uint16, $71cfb3c4767fbd0c$var$JstfScript, {\\n type: \\\"parent\\\"\\n })\\n });\\n $71cfb3c4767fbd0c$export$2e2bcd8739ae039 = new Struct({\\n version: uint32,\\n scriptCount: uint16,\\n scriptList: new ArrayT($71cfb3c4767fbd0c$var$JstfScriptRecord, \\\"scriptCount\\\")\\n });\\n $d059a6bd2d3b5b63$var$VariableSizeNumber = class {\\n decode(stream, parent) {\\n switch (this.size(0, parent)) {\\n case 1:\\n return stream.readUInt8();\\n case 2:\\n return stream.readUInt16BE();\\n case 3:\\n return stream.readUInt24BE();\\n case 4:\\n return stream.readUInt32BE();\\n }\\n }\\n size(val, parent) {\\n return (0, resolveLength)(this._size, null, parent);\\n }\\n constructor(size) {\\n this._size = size;\\n }\\n };\\n $d059a6bd2d3b5b63$var$MapDataEntry = new Struct({\\n entry: new $d059a6bd2d3b5b63$var$VariableSizeNumber((t) => ((t.parent.entryFormat & 48) >> 4) + 1),\\n outerIndex: (t) => t.entry >> (t.parent.entryFormat & 15) + 1,\\n innerIndex: (t) => t.entry & (1 << (t.parent.entryFormat & 15) + 1) - 1\\n });\\n $d059a6bd2d3b5b63$var$DeltaSetIndexMap = new Struct({\\n entryFormat: uint16,\\n mapCount: uint16,\\n mapData: new ArrayT($d059a6bd2d3b5b63$var$MapDataEntry, \\\"mapCount\\\")\\n });\\n $d059a6bd2d3b5b63$export$2e2bcd8739ae039 = new Struct({\\n majorVersion: uint16,\\n minorVersion: uint16,\\n itemVariationStore: new Pointer(uint32, (0, $1a47b0c45c1c22fe$export$fe1b122a2710f241)),\\n advanceWidthMapping: new Pointer(uint32, $d059a6bd2d3b5b63$var$DeltaSetIndexMap),\\n LSBMapping: new Pointer(uint32, $d059a6bd2d3b5b63$var$DeltaSetIndexMap),\\n RSBMapping: new Pointer(uint32, $d059a6bd2d3b5b63$var$DeltaSetIndexMap)\\n });\\n $dceeca3e1977ce30$var$Signature = new Struct({\\n format: uint32,\\n length: uint32,\\n offset: uint32\\n });\\n $dceeca3e1977ce30$var$SignatureBlock = new Struct({\\n reserved: new Reserved(uint16, 2),\\n cbSignature: uint32,\\n signature: new BufferT(\\\"cbSignature\\\")\\n });\\n $dceeca3e1977ce30$export$2e2bcd8739ae039 = new Struct({\\n ulVersion: uint32,\\n usNumSigs: uint16,\\n usFlag: uint16,\\n signatures: new ArrayT($dceeca3e1977ce30$var$Signature, \\\"usNumSigs\\\"),\\n signatureBlocks: new ArrayT($dceeca3e1977ce30$var$SignatureBlock, \\\"usNumSigs\\\")\\n });\\n $8acd740a9435aad0$var$GaspRange = new Struct({\\n rangeMaxPPEM: uint16,\\n rangeGaspBehavior: new Bitfield(uint16, [\\n \\\"grayscale\\\",\\n \\\"gridfit\\\",\\n \\\"symmetricSmoothing\\\",\\n \\\"symmetricGridfit\\\"\\n // only in version 1, for ClearType\\n ])\\n });\\n $8acd740a9435aad0$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n numRanges: uint16,\\n gaspRanges: new ArrayT($8acd740a9435aad0$var$GaspRange, \\\"numRanges\\\")\\n // Sorted by ppem\\n });\\n $b5f380243c34d6a0$var$DeviceRecord = new Struct({\\n pixelSize: uint8,\\n maximumWidth: uint8,\\n widths: new ArrayT(uint8, (t) => t.parent.parent.maxp.numGlyphs)\\n });\\n $b5f380243c34d6a0$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n numRecords: int16,\\n sizeDeviceRecord: int32,\\n records: new ArrayT($b5f380243c34d6a0$var$DeviceRecord, \\\"numRecords\\\")\\n });\\n $ca2df1256966e313$var$KernPair = new Struct({\\n left: uint16,\\n right: uint16,\\n value: int16\\n });\\n $ca2df1256966e313$var$ClassTable = new Struct({\\n firstGlyph: uint16,\\n nGlyphs: uint16,\\n offsets: new ArrayT(uint16, \\\"nGlyphs\\\"),\\n max: (t) => t.offsets.length && Math.max.apply(Math, t.offsets)\\n });\\n $ca2df1256966e313$var$Kern2Array = new Struct({\\n off: (t) => t._startOffset - t.parent.parent._startOffset,\\n len: (t) => ((t.parent.leftTable.max - t.off) / t.parent.rowWidth + 1) * (t.parent.rowWidth / 2),\\n values: new LazyArray(int16, \\\"len\\\")\\n });\\n $ca2df1256966e313$var$KernSubtable = new VersionedStruct(\\\"format\\\", {\\n 0: {\\n nPairs: uint16,\\n searchRange: uint16,\\n entrySelector: uint16,\\n rangeShift: uint16,\\n pairs: new ArrayT($ca2df1256966e313$var$KernPair, \\\"nPairs\\\")\\n },\\n 2: {\\n rowWidth: uint16,\\n leftTable: new Pointer(uint16, $ca2df1256966e313$var$ClassTable, {\\n type: \\\"parent\\\"\\n }),\\n rightTable: new Pointer(uint16, $ca2df1256966e313$var$ClassTable, {\\n type: \\\"parent\\\"\\n }),\\n array: new Pointer(uint16, $ca2df1256966e313$var$Kern2Array, {\\n type: \\\"parent\\\"\\n })\\n },\\n 3: {\\n glyphCount: uint16,\\n kernValueCount: uint8,\\n leftClassCount: uint8,\\n rightClassCount: uint8,\\n flags: uint8,\\n kernValue: new ArrayT(int16, \\\"kernValueCount\\\"),\\n leftClass: new ArrayT(uint8, \\\"glyphCount\\\"),\\n rightClass: new ArrayT(uint8, \\\"glyphCount\\\"),\\n kernIndex: new ArrayT(uint8, (t) => t.leftClassCount * t.rightClassCount)\\n }\\n });\\n $ca2df1256966e313$var$KernTable = new VersionedStruct(\\\"version\\\", {\\n 0: {\\n subVersion: uint16,\\n length: uint16,\\n format: uint8,\\n coverage: new Bitfield(uint8, [\\n \\\"horizontal\\\",\\n \\\"minimum\\\",\\n \\\"crossStream\\\",\\n \\\"override\\\"\\n // If set to 1 the value in this table replaces the accumulated value\\n ]),\\n subtable: $ca2df1256966e313$var$KernSubtable,\\n padding: new Reserved(uint8, (t) => t.length - t._currentOffset)\\n },\\n 1: {\\n length: uint32,\\n coverage: new Bitfield(uint8, [\\n null,\\n null,\\n null,\\n null,\\n null,\\n \\\"variation\\\",\\n \\\"crossStream\\\",\\n \\\"vertical\\\"\\n // Set if table has vertical kerning values\\n ]),\\n format: uint8,\\n tupleIndex: uint16,\\n subtable: $ca2df1256966e313$var$KernSubtable,\\n padding: new Reserved(uint8, (t) => t.length - t._currentOffset)\\n }\\n });\\n $ca2df1256966e313$export$2e2bcd8739ae039 = new VersionedStruct(uint16, {\\n 0: {\\n nTables: uint16,\\n tables: new ArrayT($ca2df1256966e313$var$KernTable, \\\"nTables\\\")\\n },\\n 1: {\\n reserved: new Reserved(uint16),\\n nTables: uint32,\\n tables: new ArrayT($ca2df1256966e313$var$KernTable, \\\"nTables\\\")\\n }\\n });\\n $7a9f92b0c46ebe33$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n numGlyphs: uint16,\\n yPels: new ArrayT(uint8, \\\"numGlyphs\\\")\\n });\\n $2b2ccc419d152631$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n fontNumber: uint32,\\n pitch: uint16,\\n xHeight: uint16,\\n style: uint16,\\n typeFamily: uint16,\\n capHeight: uint16,\\n symbolSet: uint16,\\n typeface: new StringT(16),\\n characterComplement: new StringT(8),\\n fileName: new StringT(6),\\n strokeWeight: new StringT(1),\\n widthType: new StringT(1),\\n serifStyle: uint8,\\n reserved: new Reserved(uint8)\\n });\\n $ca5b40b9bcda9c9b$var$Ratio = new Struct({\\n bCharSet: uint8,\\n xRatio: uint8,\\n yStartRatio: uint8,\\n yEndRatio: uint8\\n // Ending y-Ratio value\\n });\\n $ca5b40b9bcda9c9b$var$vTable = new Struct({\\n yPelHeight: uint16,\\n yMax: int16,\\n yMin: int16\\n // Minimum value (in pels) for this yPelHeight\\n });\\n $ca5b40b9bcda9c9b$var$VdmxGroup = new Struct({\\n recs: uint16,\\n startsz: uint8,\\n endsz: uint8,\\n entries: new ArrayT($ca5b40b9bcda9c9b$var$vTable, \\\"recs\\\")\\n // The VDMX records\\n });\\n $ca5b40b9bcda9c9b$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n numRecs: uint16,\\n numRatios: uint16,\\n ratioRanges: new ArrayT($ca5b40b9bcda9c9b$var$Ratio, \\\"numRatios\\\"),\\n offsets: new ArrayT(uint16, \\\"numRatios\\\"),\\n groups: new ArrayT($ca5b40b9bcda9c9b$var$VdmxGroup, \\\"numRecs\\\")\\n // The actual VDMX groupings\\n });\\n $69530a3c40755af0$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n ascent: int16,\\n descent: int16,\\n lineGap: int16,\\n advanceHeightMax: int16,\\n minTopSideBearing: int16,\\n minBottomSideBearing: int16,\\n yMaxExtent: int16,\\n caretSlopeRise: int16,\\n caretSlopeRun: int16,\\n caretOffset: int16,\\n reserved: new Reserved(int16, 4),\\n metricDataFormat: int16,\\n numberOfMetrics: uint16\\n // Number of advance heights in the Vertical Metrics table\\n });\\n $344073dd270f0e62$var$VmtxEntry = new Struct({\\n advance: uint16,\\n bearing: int16\\n // The top sidebearing of the glyph\\n });\\n $344073dd270f0e62$export$2e2bcd8739ae039 = new Struct({\\n metrics: new LazyArray($344073dd270f0e62$var$VmtxEntry, (t) => t.parent.vhea.numberOfMetrics),\\n bearings: new LazyArray(int16, (t) => t.parent.maxp.numGlyphs - t.parent.vhea.numberOfMetrics)\\n });\\n $3793b781918cfced$var$shortFrac = new Fixed(16, \\\"BE\\\", 14);\\n $3793b781918cfced$var$Correspondence = new Struct({\\n fromCoord: $3793b781918cfced$var$shortFrac,\\n toCoord: $3793b781918cfced$var$shortFrac\\n });\\n $3793b781918cfced$var$Segment = new Struct({\\n pairCount: uint16,\\n correspondence: new ArrayT($3793b781918cfced$var$Correspondence, \\\"pairCount\\\")\\n });\\n $3793b781918cfced$export$2e2bcd8739ae039 = new Struct({\\n version: fixed32,\\n axisCount: uint32,\\n segment: new ArrayT($3793b781918cfced$var$Segment, \\\"axisCount\\\")\\n });\\n $6cb7dd5f47d82580$var$UnboundedArrayAccessor = class {\\n getItem(index) {\\n if (this._items[index] == null) {\\n let pos = this.stream.pos;\\n this.stream.pos = this.base + this.type.size(null, this.parent) * index;\\n this._items[index] = this.type.decode(this.stream, this.parent);\\n this.stream.pos = pos;\\n }\\n return this._items[index];\\n }\\n inspect() {\\n return `[UnboundedArray ${this.type.constructor.name}]`;\\n }\\n constructor(type, stream, parent) {\\n this.type = type;\\n this.stream = stream;\\n this.parent = parent;\\n this.base = this.stream.pos;\\n this._items = [];\\n }\\n };\\n $6cb7dd5f47d82580$export$c5af1eebc882e39a = class extends ArrayT {\\n decode(stream, parent) {\\n return new $6cb7dd5f47d82580$var$UnboundedArrayAccessor(this.type, stream, parent);\\n }\\n constructor(type) {\\n super(type, 0);\\n }\\n };\\n $6cb7dd5f47d82580$export$8351f8c2ae2f103c = function(ValueType = uint16) {\\n class Shadow {\\n decode(stream, ctx) {\\n ctx = ctx.parent.parent;\\n return this.type.decode(stream, ctx);\\n }\\n size(val, ctx) {\\n ctx = ctx.parent.parent;\\n return this.type.size(val, ctx);\\n }\\n encode(stream, val, ctx) {\\n ctx = ctx.parent.parent;\\n return this.type.encode(stream, val, ctx);\\n }\\n constructor(type) {\\n this.type = type;\\n }\\n }\\n ValueType = new Shadow(ValueType);\\n let BinarySearchHeader = new Struct({\\n unitSize: uint16,\\n nUnits: uint16,\\n searchRange: uint16,\\n entrySelector: uint16,\\n rangeShift: uint16\\n });\\n let LookupSegmentSingle = new Struct({\\n lastGlyph: uint16,\\n firstGlyph: uint16,\\n value: ValueType\\n });\\n let LookupSegmentArray = new Struct({\\n lastGlyph: uint16,\\n firstGlyph: uint16,\\n values: new Pointer(uint16, new ArrayT(ValueType, (t) => t.lastGlyph - t.firstGlyph + 1), {\\n type: \\\"parent\\\"\\n })\\n });\\n let LookupSingle = new Struct({\\n glyph: uint16,\\n value: ValueType\\n });\\n return new VersionedStruct(uint16, {\\n 0: {\\n values: new $6cb7dd5f47d82580$export$c5af1eebc882e39a(ValueType)\\n // length == number of glyphs maybe?\\n },\\n 2: {\\n binarySearchHeader: BinarySearchHeader,\\n segments: new ArrayT(LookupSegmentSingle, (t) => t.binarySearchHeader.nUnits)\\n },\\n 4: {\\n binarySearchHeader: BinarySearchHeader,\\n segments: new ArrayT(LookupSegmentArray, (t) => t.binarySearchHeader.nUnits)\\n },\\n 6: {\\n binarySearchHeader: BinarySearchHeader,\\n segments: new ArrayT(LookupSingle, (t) => t.binarySearchHeader.nUnits)\\n },\\n 8: {\\n firstGlyph: uint16,\\n count: uint16,\\n values: new ArrayT(ValueType, \\\"count\\\")\\n }\\n });\\n };\\n $6a3746e8c708f5a3$var$BslnSubtable = new VersionedStruct(\\\"format\\\", {\\n 0: {\\n deltas: new ArrayT(int16, 32)\\n },\\n 1: {\\n deltas: new ArrayT(int16, 32),\\n mappingData: new (0, $6cb7dd5f47d82580$export$8351f8c2ae2f103c)(uint16)\\n },\\n 2: {\\n standardGlyph: uint16,\\n controlPoints: new ArrayT(uint16, 32)\\n },\\n 3: {\\n standardGlyph: uint16,\\n controlPoints: new ArrayT(uint16, 32),\\n mappingData: new (0, $6cb7dd5f47d82580$export$8351f8c2ae2f103c)(uint16)\\n }\\n });\\n $6a3746e8c708f5a3$export$2e2bcd8739ae039 = new Struct({\\n version: fixed32,\\n format: uint16,\\n defaultBaseline: uint16,\\n subtable: $6a3746e8c708f5a3$var$BslnSubtable\\n });\\n $d0c76fac617b308a$var$Setting = new Struct({\\n setting: uint16,\\n nameIndex: int16,\\n name: (t) => t.parent.parent.parent.name.records.fontFeatures[t.nameIndex]\\n });\\n $d0c76fac617b308a$var$FeatureName = new Struct({\\n feature: uint16,\\n nSettings: uint16,\\n settingTable: new Pointer(uint32, new ArrayT($d0c76fac617b308a$var$Setting, \\\"nSettings\\\"), {\\n type: \\\"parent\\\"\\n }),\\n featureFlags: new Bitfield(uint8, [\\n null,\\n null,\\n null,\\n null,\\n null,\\n null,\\n \\\"hasDefault\\\",\\n \\\"exclusive\\\"\\n ]),\\n defaultSetting: uint8,\\n nameIndex: int16,\\n name: (t) => t.parent.parent.name.records.fontFeatures[t.nameIndex]\\n });\\n $d0c76fac617b308a$export$2e2bcd8739ae039 = new Struct({\\n version: fixed32,\\n featureNameCount: uint16,\\n reserved1: new Reserved(uint16),\\n reserved2: new Reserved(uint32),\\n featureNames: new ArrayT($d0c76fac617b308a$var$FeatureName, \\\"featureNameCount\\\")\\n });\\n $e83fd065f00fcd01$var$Axis = new Struct({\\n axisTag: new StringT(4),\\n minValue: fixed32,\\n defaultValue: fixed32,\\n maxValue: fixed32,\\n flags: uint16,\\n nameID: uint16,\\n name: (t) => t.parent.parent.name.records.fontFeatures[t.nameID]\\n });\\n $e83fd065f00fcd01$var$Instance = new Struct({\\n nameID: uint16,\\n name: (t) => t.parent.parent.name.records.fontFeatures[t.nameID],\\n flags: uint16,\\n coord: new ArrayT(fixed32, (t) => t.parent.axisCount),\\n postscriptNameID: new Optional(uint16, (t) => t.parent.instanceSize - t._currentOffset > 0)\\n });\\n $e83fd065f00fcd01$export$2e2bcd8739ae039 = new Struct({\\n version: fixed32,\\n offsetToData: uint16,\\n countSizePairs: uint16,\\n axisCount: uint16,\\n axisSize: uint16,\\n instanceCount: uint16,\\n instanceSize: uint16,\\n axis: new ArrayT($e83fd065f00fcd01$var$Axis, \\\"axisCount\\\"),\\n instance: new ArrayT($e83fd065f00fcd01$var$Instance, \\\"instanceCount\\\")\\n });\\n $dbe33c8d3a7f131c$var$shortFrac = new Fixed(16, \\\"BE\\\", 14);\\n $dbe33c8d3a7f131c$var$Offset = class {\\n static decode(stream, parent) {\\n return parent.flags ? stream.readUInt32BE() : stream.readUInt16BE() * 2;\\n }\\n };\\n $dbe33c8d3a7f131c$var$gvar = new Struct({\\n version: uint16,\\n reserved: new Reserved(uint16),\\n axisCount: uint16,\\n globalCoordCount: uint16,\\n globalCoords: new Pointer(uint32, new ArrayT(new ArrayT($dbe33c8d3a7f131c$var$shortFrac, \\\"axisCount\\\"), \\\"globalCoordCount\\\")),\\n glyphCount: uint16,\\n flags: uint16,\\n offsetToData: uint32,\\n offsets: new ArrayT(new Pointer($dbe33c8d3a7f131c$var$Offset, \\\"void\\\", {\\n relativeTo: (ctx) => ctx.offsetToData,\\n allowNull: false\\n }), (t) => t.glyphCount + 1)\\n });\\n $dbe33c8d3a7f131c$export$2e2bcd8739ae039 = $dbe33c8d3a7f131c$var$gvar;\\n $05b01887df96c4ee$var$ClassTable = new Struct({\\n length: uint16,\\n coverage: uint16,\\n subFeatureFlags: uint32,\\n stateTable: new (0, $6cb7dd5f47d82580$export$105027425199cc51)()\\n });\\n $05b01887df96c4ee$var$WidthDeltaRecord = new Struct({\\n justClass: uint32,\\n beforeGrowLimit: fixed32,\\n beforeShrinkLimit: fixed32,\\n afterGrowLimit: fixed32,\\n afterShrinkLimit: fixed32,\\n growFlags: uint16,\\n shrinkFlags: uint16\\n });\\n $05b01887df96c4ee$var$WidthDeltaCluster = new ArrayT($05b01887df96c4ee$var$WidthDeltaRecord, uint32);\\n $05b01887df96c4ee$var$ActionData = new VersionedStruct(\\\"actionType\\\", {\\n 0: {\\n lowerLimit: fixed32,\\n upperLimit: fixed32,\\n order: uint16,\\n glyphs: new ArrayT(uint16, uint16)\\n },\\n 1: {\\n addGlyph: uint16\\n },\\n 2: {\\n substThreshold: fixed32,\\n addGlyph: uint16,\\n substGlyph: uint16\\n },\\n 3: {},\\n 4: {\\n variationAxis: uint32,\\n minimumLimit: fixed32,\\n noStretchValue: fixed32,\\n maximumLimit: fixed32\\n },\\n 5: {\\n flags: uint16,\\n glyph: uint16\\n }\\n });\\n $05b01887df96c4ee$var$Action = new Struct({\\n actionClass: uint16,\\n actionType: uint16,\\n actionLength: uint32,\\n actionData: $05b01887df96c4ee$var$ActionData,\\n padding: new Reserved(uint8, (t) => t.actionLength - t._currentOffset)\\n });\\n $05b01887df96c4ee$var$PostcompensationAction = new ArrayT($05b01887df96c4ee$var$Action, uint32);\\n $05b01887df96c4ee$var$PostCompensationTable = new Struct({\\n lookupTable: new (0, $6cb7dd5f47d82580$export$8351f8c2ae2f103c)(new Pointer(uint16, $05b01887df96c4ee$var$PostcompensationAction))\\n });\\n $05b01887df96c4ee$var$JustificationTable = new Struct({\\n classTable: new Pointer(uint16, $05b01887df96c4ee$var$ClassTable, {\\n type: \\\"parent\\\"\\n }),\\n wdcOffset: uint16,\\n postCompensationTable: new Pointer(uint16, $05b01887df96c4ee$var$PostCompensationTable, {\\n type: \\\"parent\\\"\\n }),\\n widthDeltaClusters: new (0, $6cb7dd5f47d82580$export$8351f8c2ae2f103c)(new Pointer(uint16, $05b01887df96c4ee$var$WidthDeltaCluster, {\\n type: \\\"parent\\\",\\n relativeTo: (ctx) => ctx.wdcOffset\\n }))\\n });\\n $05b01887df96c4ee$export$2e2bcd8739ae039 = new Struct({\\n version: uint32,\\n format: uint16,\\n horizontal: new Pointer(uint16, $05b01887df96c4ee$var$JustificationTable),\\n vertical: new Pointer(uint16, $05b01887df96c4ee$var$JustificationTable)\\n });\\n $03ee6ebd54db1053$var$LigatureData = {\\n action: uint16\\n };\\n $03ee6ebd54db1053$var$ContextualData = {\\n markIndex: uint16,\\n currentIndex: uint16\\n };\\n $03ee6ebd54db1053$var$InsertionData = {\\n currentInsertIndex: uint16,\\n markedInsertIndex: uint16\\n };\\n $03ee6ebd54db1053$var$SubstitutionTable = new Struct({\\n items: new (0, $6cb7dd5f47d82580$export$c5af1eebc882e39a)(new Pointer(uint32, new (0, $6cb7dd5f47d82580$export$8351f8c2ae2f103c)()))\\n });\\n $03ee6ebd54db1053$var$SubtableData = new VersionedStruct(\\\"type\\\", {\\n 0: {\\n stateTable: new (0, $6cb7dd5f47d82580$export$79f7d93d790934ba)()\\n },\\n 1: {\\n stateTable: new (0, $6cb7dd5f47d82580$export$79f7d93d790934ba)($03ee6ebd54db1053$var$ContextualData),\\n substitutionTable: new Pointer(uint32, $03ee6ebd54db1053$var$SubstitutionTable)\\n },\\n 2: {\\n stateTable: new (0, $6cb7dd5f47d82580$export$79f7d93d790934ba)($03ee6ebd54db1053$var$LigatureData),\\n ligatureActions: new Pointer(uint32, new (0, $6cb7dd5f47d82580$export$c5af1eebc882e39a)(uint32)),\\n components: new Pointer(uint32, new (0, $6cb7dd5f47d82580$export$c5af1eebc882e39a)(uint16)),\\n ligatureList: new Pointer(uint32, new (0, $6cb7dd5f47d82580$export$c5af1eebc882e39a)(uint16))\\n },\\n 4: {\\n lookupTable: new (0, $6cb7dd5f47d82580$export$8351f8c2ae2f103c)()\\n },\\n 5: {\\n stateTable: new (0, $6cb7dd5f47d82580$export$79f7d93d790934ba)($03ee6ebd54db1053$var$InsertionData),\\n insertionActions: new Pointer(uint32, new (0, $6cb7dd5f47d82580$export$c5af1eebc882e39a)(uint16))\\n }\\n });\\n $03ee6ebd54db1053$var$Subtable = new Struct({\\n length: uint32,\\n coverage: uint24,\\n type: uint8,\\n subFeatureFlags: uint32,\\n table: $03ee6ebd54db1053$var$SubtableData,\\n padding: new Reserved(uint8, (t) => t.length - t._currentOffset)\\n });\\n $03ee6ebd54db1053$var$FeatureEntry = new Struct({\\n featureType: uint16,\\n featureSetting: uint16,\\n enableFlags: uint32,\\n disableFlags: uint32\\n });\\n $03ee6ebd54db1053$var$MorxChain = new Struct({\\n defaultFlags: uint32,\\n chainLength: uint32,\\n nFeatureEntries: uint32,\\n nSubtables: uint32,\\n features: new ArrayT($03ee6ebd54db1053$var$FeatureEntry, \\\"nFeatureEntries\\\"),\\n subtables: new ArrayT($03ee6ebd54db1053$var$Subtable, \\\"nSubtables\\\")\\n });\\n $03ee6ebd54db1053$export$2e2bcd8739ae039 = new Struct({\\n version: uint16,\\n unused: new Reserved(uint16),\\n nChains: uint32,\\n chains: new ArrayT($03ee6ebd54db1053$var$MorxChain, \\\"nChains\\\")\\n });\\n $b7492a80b0d1a056$var$OpticalBounds = new Struct({\\n left: int16,\\n top: int16,\\n right: int16,\\n bottom: int16\\n });\\n $b7492a80b0d1a056$export$2e2bcd8739ae039 = new Struct({\\n version: fixed32,\\n format: uint16,\\n lookupTable: new (0, $6cb7dd5f47d82580$export$8351f8c2ae2f103c)($b7492a80b0d1a056$var$OpticalBounds)\\n });\\n $c3395722bea751e2$var$tables = {};\\n $c3395722bea751e2$export$2e2bcd8739ae039 = $c3395722bea751e2$var$tables;\\n $c3395722bea751e2$var$tables.cmap = (0, $26a62205ad06574e$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.head = (0, $f2612a29f92ac062$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.hhea = (0, $2c179dd593583073$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.hmtx = (0, $bdc9060542264b85$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.maxp = (0, $dbf51cb3d3fe409d$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.name = (0, $2bcf221753ec8e32$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables[\\\"OS/2\\\"] = (0, $84b272aa31b70606$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.post = (0, $32d9e2eb9565d93c$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.fpgm = (0, $5c0f37ca5ffb1850$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.loca = (0, $2b2b260902b1c57e$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.prep = (0, $7afb878c7bea4f66$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables[\\\"cvt \\\"] = (0, $5202bd9d9ad8eaac$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.glyf = (0, $6c92b6371bce8bd9$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables[\\\"CFF \\\"] = (0, $822ac0d589e4e237$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables[\\\"CFF2\\\"] = (0, $822ac0d589e4e237$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.VORG = (0, $2bbf2bc1ce37cd8f$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.EBLC = (0, $9911c4c7201c13de$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.CBLC = $c3395722bea751e2$var$tables.EBLC;\\n $c3395722bea751e2$var$tables.sbix = (0, $abb847051efd51b1$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.COLR = (0, $eb629188f3dfefdd$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.CPAL = (0, $08734b8e7dc64587$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.BASE = (0, $497cef411d884e34$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.GDEF = (0, $cf5f33c63ef209e6$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.GPOS = (0, $47e0e8ef515d9903$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.GSUB = (0, $d3f442064af66e06$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.JSTF = (0, $71cfb3c4767fbd0c$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.HVAR = (0, $d059a6bd2d3b5b63$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.DSIG = (0, $dceeca3e1977ce30$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.gasp = (0, $8acd740a9435aad0$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.hdmx = (0, $b5f380243c34d6a0$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.kern = (0, $ca2df1256966e313$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.LTSH = (0, $7a9f92b0c46ebe33$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.PCLT = (0, $2b2ccc419d152631$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.VDMX = (0, $ca5b40b9bcda9c9b$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.vhea = (0, $69530a3c40755af0$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.vmtx = (0, $344073dd270f0e62$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.avar = (0, $3793b781918cfced$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.bsln = (0, $6a3746e8c708f5a3$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.feat = (0, $d0c76fac617b308a$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.fvar = (0, $e83fd065f00fcd01$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.gvar = (0, $dbe33c8d3a7f131c$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.just = (0, $05b01887df96c4ee$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.morx = (0, $03ee6ebd54db1053$export$2e2bcd8739ae039);\\n $c3395722bea751e2$var$tables.opbd = (0, $b7492a80b0d1a056$export$2e2bcd8739ae039);\\n $816c07a04b6dba87$var$TableEntry = new Struct({\\n tag: new StringT(4),\\n checkSum: uint32,\\n offset: new Pointer(uint32, \\\"void\\\", {\\n type: \\\"global\\\"\\n }),\\n length: uint32\\n });\\n $816c07a04b6dba87$var$Directory = new Struct({\\n tag: new StringT(4),\\n numTables: uint16,\\n searchRange: uint16,\\n entrySelector: uint16,\\n rangeShift: uint16,\\n tables: new ArrayT($816c07a04b6dba87$var$TableEntry, \\\"numTables\\\")\\n });\\n $816c07a04b6dba87$var$Directory.process = function() {\\n let tables = {};\\n for (let table of this.tables) tables[table.tag] = table;\\n this.tables = tables;\\n };\\n $816c07a04b6dba87$var$Directory.preEncode = function() {\\n if (!Array.isArray(this.tables)) {\\n let tables = [];\\n for (let tag in this.tables) {\\n let table = this.tables[tag];\\n if (table) tables.push({\\n tag,\\n checkSum: 0,\\n offset: new VoidPointer((0, $c3395722bea751e2$export$2e2bcd8739ae039)[tag], table),\\n length: (0, $c3395722bea751e2$export$2e2bcd8739ae039)[tag].size(table)\\n });\\n }\\n this.tables = tables;\\n }\\n this.tag = \\\"true\\\";\\n this.numTables = this.tables.length;\\n let maxExponentFor2 = Math.floor(Math.log(this.numTables) / Math.LN2);\\n let maxPowerOf2 = Math.pow(2, maxExponentFor2);\\n this.searchRange = maxPowerOf2 * 16;\\n this.entrySelector = Math.log(maxPowerOf2) / Math.LN2;\\n this.rangeShift = this.numTables * 16 - this.searchRange;\\n };\\n $816c07a04b6dba87$export$2e2bcd8739ae039 = $816c07a04b6dba87$var$Directory;\\n $12727730ddfc8bfe$export$3d28c1996ced1f14 = new TextDecoder(\\\"ascii\\\");\\n $12727730ddfc8bfe$var$CHARS = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n $12727730ddfc8bfe$var$LOOKUP = new Uint8Array(256);\\n for (let i = 0; i < $12727730ddfc8bfe$var$CHARS.length; i++) $12727730ddfc8bfe$var$LOOKUP[$12727730ddfc8bfe$var$CHARS.charCodeAt(i)] = i;\\n $f08dd41ef10b694c$export$2e2bcd8739ae039 = class {\\n findSubtable(cmapTable, pairs) {\\n for (let [platformID, encodingID] of pairs) for (let cmap of cmapTable.tables) {\\n if (cmap.platformID === platformID && cmap.encodingID === encodingID) return cmap.table;\\n }\\n return null;\\n }\\n lookup(codepoint, variationSelector) {\\n if (this.encoding) codepoint = this.encoding.get(codepoint) || codepoint;\\n else if (variationSelector) {\\n let gid = this.getVariationSelector(codepoint, variationSelector);\\n if (gid) return gid;\\n }\\n let cmap = this.cmap;\\n switch (cmap.version) {\\n case 0:\\n return cmap.codeMap.get(codepoint) || 0;\\n case 4: {\\n let min = 0;\\n let max = cmap.segCount - 1;\\n while (min <= max) {\\n let mid = min + max >> 1;\\n if (codepoint < cmap.startCode.get(mid)) max = mid - 1;\\n else if (codepoint > cmap.endCode.get(mid)) min = mid + 1;\\n else {\\n let rangeOffset = cmap.idRangeOffset.get(mid);\\n let gid;\\n if (rangeOffset === 0) gid = codepoint + cmap.idDelta.get(mid);\\n else {\\n let index = rangeOffset / 2 + (codepoint - cmap.startCode.get(mid)) - (cmap.segCount - mid);\\n gid = cmap.glyphIndexArray.get(index) || 0;\\n if (gid !== 0) gid += cmap.idDelta.get(mid);\\n }\\n return gid & 65535;\\n }\\n }\\n return 0;\\n }\\n case 8:\\n throw new Error(\\\"TODO: cmap format 8\\\");\\n case 6:\\n case 10:\\n return cmap.glyphIndices.get(codepoint - cmap.firstCode) || 0;\\n case 12:\\n case 13: {\\n let min = 0;\\n let max = cmap.nGroups - 1;\\n while (min <= max) {\\n let mid = min + max >> 1;\\n let group = cmap.groups.get(mid);\\n if (codepoint < group.startCharCode) max = mid - 1;\\n else if (codepoint > group.endCharCode) min = mid + 1;\\n else {\\n if (cmap.version === 12) return group.glyphID + (codepoint - group.startCharCode);\\n else return group.glyphID;\\n }\\n }\\n return 0;\\n }\\n case 14:\\n throw new Error(\\\"TODO: cmap format 14\\\");\\n default:\\n throw new Error(`Unknown cmap format ${cmap.version}`);\\n }\\n }\\n getVariationSelector(codepoint, variationSelector) {\\n if (!this.uvs) return 0;\\n let selectors = this.uvs.varSelectors.toArray();\\n let i = (0, $12727730ddfc8bfe$export$2e0ae67339d5f1ac)(selectors, (x) => variationSelector - x.varSelector);\\n let sel = selectors[i];\\n if (i !== -1 && sel.defaultUVS) i = (0, $12727730ddfc8bfe$export$2e0ae67339d5f1ac)(sel.defaultUVS, (x) => codepoint < x.startUnicodeValue ? -1 : codepoint > x.startUnicodeValue + x.additionalCount ? 1 : 0);\\n if (i !== -1 && sel.nonDefaultUVS) {\\n i = (0, $12727730ddfc8bfe$export$2e0ae67339d5f1ac)(sel.nonDefaultUVS, (x) => codepoint - x.unicodeValue);\\n if (i !== -1) return sel.nonDefaultUVS[i].glyphID;\\n }\\n return 0;\\n }\\n getCharacterSet() {\\n let cmap = this.cmap;\\n switch (cmap.version) {\\n case 0:\\n return (0, $12727730ddfc8bfe$export$d02631cccf789723)(0, cmap.codeMap.length);\\n case 4: {\\n let res = [];\\n let endCodes = cmap.endCode.toArray();\\n for (let i = 0; i < endCodes.length; i++) {\\n let tail = endCodes[i] + 1;\\n let start = cmap.startCode.get(i);\\n res.push(...(0, $12727730ddfc8bfe$export$d02631cccf789723)(start, tail));\\n }\\n return res;\\n }\\n case 8:\\n throw new Error(\\\"TODO: cmap format 8\\\");\\n case 6:\\n case 10:\\n return (0, $12727730ddfc8bfe$export$d02631cccf789723)(cmap.firstCode, cmap.firstCode + cmap.glyphIndices.length);\\n case 12:\\n case 13: {\\n let res = [];\\n for (let group of cmap.groups.toArray()) res.push(...(0, $12727730ddfc8bfe$export$d02631cccf789723)(group.startCharCode, group.endCharCode + 1));\\n return res;\\n }\\n case 14:\\n throw new Error(\\\"TODO: cmap format 14\\\");\\n default:\\n throw new Error(`Unknown cmap format ${cmap.version}`);\\n }\\n }\\n codePointsForGlyph(gid) {\\n let cmap = this.cmap;\\n switch (cmap.version) {\\n case 0: {\\n let res = [];\\n for (let i = 0; i < 256; i++) if (cmap.codeMap.get(i) === gid) res.push(i);\\n return res;\\n }\\n case 4: {\\n let res = [];\\n for (let i = 0; i < cmap.segCount; i++) {\\n let end = cmap.endCode.get(i);\\n let start = cmap.startCode.get(i);\\n let rangeOffset = cmap.idRangeOffset.get(i);\\n let delta = cmap.idDelta.get(i);\\n for (var c = start; c <= end; c++) {\\n let g = 0;\\n if (rangeOffset === 0) g = c + delta;\\n else {\\n let index = rangeOffset / 2 + (c - start) - (cmap.segCount - i);\\n g = cmap.glyphIndexArray.get(index) || 0;\\n if (g !== 0) g += delta;\\n }\\n if (g === gid) res.push(c);\\n }\\n }\\n return res;\\n }\\n case 12: {\\n let res = [];\\n for (let group of cmap.groups.toArray()) if (gid >= group.glyphID && gid <= group.glyphID + (group.endCharCode - group.startCharCode)) res.push(group.startCharCode + (gid - group.glyphID));\\n return res;\\n }\\n case 13: {\\n let res = [];\\n for (let group of cmap.groups.toArray()) if (gid === group.glyphID) res.push(...(0, $12727730ddfc8bfe$export$d02631cccf789723)(group.startCharCode, group.endCharCode + 1));\\n return res;\\n }\\n default:\\n throw new Error(`Unknown cmap format ${cmap.version}`);\\n }\\n }\\n constructor(cmapTable) {\\n this.encoding = null;\\n this.cmap = this.findSubtable(cmapTable, [\\n // 32-bit subtables\\n [\\n 3,\\n 10\\n ],\\n [\\n 0,\\n 6\\n ],\\n [\\n 0,\\n 4\\n ],\\n // 16-bit subtables\\n [\\n 3,\\n 1\\n ],\\n [\\n 0,\\n 3\\n ],\\n [\\n 0,\\n 2\\n ],\\n [\\n 0,\\n 1\\n ],\\n [\\n 0,\\n 0\\n ]\\n ]);\\n if (!this.cmap) for (let cmap of cmapTable.tables) {\\n let encoding = (0, $e449ad78d50845fe$export$badc544e0651b6b1)(cmap.platformID, cmap.encodingID, cmap.table.language - 1);\\n let mapping = (0, $e449ad78d50845fe$export$1dceb3c14ed68bee)(encoding);\\n if (mapping) {\\n this.cmap = cmap.table;\\n this.encoding = mapping;\\n }\\n }\\n if (!this.cmap) throw new Error(\\\"Could not find a supported cmap table\\\");\\n this.uvs = this.findSubtable(cmapTable, [\\n [\\n 0,\\n 5\\n ]\\n ]);\\n if (this.uvs && this.uvs.version !== 14) this.uvs = null;\\n }\\n };\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $f08dd41ef10b694c$export$2e2bcd8739ae039.prototype, \\\"getCharacterSet\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $f08dd41ef10b694c$export$2e2bcd8739ae039.prototype, \\\"codePointsForGlyph\\\", null);\\n $0bba3a9db57637f3$export$2e2bcd8739ae039 = class {\\n process(glyphs, positions) {\\n for (let glyphIndex = 0; glyphIndex < glyphs.length - 1; glyphIndex++) {\\n let left = glyphs[glyphIndex].id;\\n let right = glyphs[glyphIndex + 1].id;\\n positions[glyphIndex].xAdvance += this.getKerning(left, right);\\n }\\n }\\n getKerning(left, right) {\\n let res = 0;\\n for (let table of this.kern.tables) {\\n if (table.coverage.crossStream) continue;\\n switch (table.version) {\\n case 0:\\n if (!table.coverage.horizontal) continue;\\n break;\\n case 1:\\n if (table.coverage.vertical || table.coverage.variation) continue;\\n break;\\n default:\\n throw new Error(`Unsupported kerning table version ${table.version}`);\\n }\\n let val = 0;\\n let s = table.subtable;\\n switch (table.format) {\\n case 0:\\n let pairIdx = (0, $12727730ddfc8bfe$export$2e0ae67339d5f1ac)(s.pairs, function(pair) {\\n return left - pair.left || right - pair.right;\\n });\\n if (pairIdx >= 0) val = s.pairs[pairIdx].value;\\n break;\\n case 2:\\n let leftOffset = 0, rightOffset = 0;\\n if (left >= s.leftTable.firstGlyph && left < s.leftTable.firstGlyph + s.leftTable.nGlyphs) leftOffset = s.leftTable.offsets[left - s.leftTable.firstGlyph];\\n else leftOffset = s.array.off;\\n if (right >= s.rightTable.firstGlyph && right < s.rightTable.firstGlyph + s.rightTable.nGlyphs) rightOffset = s.rightTable.offsets[right - s.rightTable.firstGlyph];\\n let index = (leftOffset + rightOffset - s.array.off) / 2;\\n val = s.array.values.get(index);\\n break;\\n case 3:\\n if (left >= s.glyphCount || right >= s.glyphCount) return 0;\\n val = s.kernValue[s.kernIndex[s.leftClass[left] * s.rightClassCount + s.rightClass[right]]];\\n break;\\n default:\\n throw new Error(`Unsupported kerning sub-table format ${table.format}`);\\n }\\n if (table.coverage.override) res = val;\\n else res += val;\\n }\\n return res;\\n }\\n constructor(font) {\\n this.kern = font.kern;\\n }\\n };\\n $0a4bdfeb6dfd6f5e$export$2e2bcd8739ae039 = class {\\n positionGlyphs(glyphs, positions) {\\n let clusterStart = 0;\\n let clusterEnd = 0;\\n for (let index = 0; index < glyphs.length; index++) {\\n let glyph = glyphs[index];\\n if (glyph.isMark) clusterEnd = index;\\n else {\\n if (clusterStart !== clusterEnd) this.positionCluster(glyphs, positions, clusterStart, clusterEnd);\\n clusterStart = clusterEnd = index;\\n }\\n }\\n if (clusterStart !== clusterEnd) this.positionCluster(glyphs, positions, clusterStart, clusterEnd);\\n return positions;\\n }\\n positionCluster(glyphs, positions, clusterStart, clusterEnd) {\\n let base = glyphs[clusterStart];\\n let baseBox = base.cbox.copy();\\n if (base.codePoints.length > 1)\\n baseBox.minX += (base.codePoints.length - 1) * baseBox.width / base.codePoints.length;\\n let xOffset = -positions[clusterStart].xAdvance;\\n let yOffset = 0;\\n let yGap = this.font.unitsPerEm / 16;\\n for (let index = clusterStart + 1; index <= clusterEnd; index++) {\\n let mark = glyphs[index];\\n let markBox = mark.cbox;\\n let position = positions[index];\\n let combiningClass = this.getCombiningClass(mark.codePoints[0]);\\n if (combiningClass !== \\\"Not_Reordered\\\") {\\n position.xOffset = position.yOffset = 0;\\n switch (combiningClass) {\\n case \\\"Double_Above\\\":\\n case \\\"Double_Below\\\":\\n position.xOffset += baseBox.minX - markBox.width / 2 - markBox.minX;\\n break;\\n case \\\"Attached_Below_Left\\\":\\n case \\\"Below_Left\\\":\\n case \\\"Above_Left\\\":\\n position.xOffset += baseBox.minX - markBox.minX;\\n break;\\n case \\\"Attached_Above_Right\\\":\\n case \\\"Below_Right\\\":\\n case \\\"Above_Right\\\":\\n position.xOffset += baseBox.maxX - markBox.width - markBox.minX;\\n break;\\n default:\\n position.xOffset += baseBox.minX + (baseBox.width - markBox.width) / 2 - markBox.minX;\\n }\\n switch (combiningClass) {\\n case \\\"Double_Below\\\":\\n case \\\"Below_Left\\\":\\n case \\\"Below\\\":\\n case \\\"Below_Right\\\":\\n case \\\"Attached_Below_Left\\\":\\n case \\\"Attached_Below\\\":\\n if (combiningClass === \\\"Attached_Below_Left\\\" || combiningClass === \\\"Attached_Below\\\") baseBox.minY += yGap;\\n position.yOffset = -baseBox.minY - markBox.maxY;\\n baseBox.minY += markBox.height;\\n break;\\n case \\\"Double_Above\\\":\\n case \\\"Above_Left\\\":\\n case \\\"Above\\\":\\n case \\\"Above_Right\\\":\\n case \\\"Attached_Above\\\":\\n case \\\"Attached_Above_Right\\\":\\n if (combiningClass === \\\"Attached_Above\\\" || combiningClass === \\\"Attached_Above_Right\\\") baseBox.maxY += yGap;\\n position.yOffset = baseBox.maxY - markBox.minY;\\n baseBox.maxY += markBox.height;\\n break;\\n }\\n position.xAdvance = position.yAdvance = 0;\\n position.xOffset += xOffset;\\n position.yOffset += yOffset;\\n } else {\\n xOffset -= position.xAdvance;\\n yOffset -= position.yAdvance;\\n }\\n }\\n return;\\n }\\n getCombiningClass(codePoint) {\\n let combiningClass = (0, $747425b437e121da$export$c03b919c6651ed55)(codePoint);\\n if ((codePoint & -256) === 3584) {\\n if (combiningClass === \\\"Not_Reordered\\\") switch (codePoint) {\\n case 3633:\\n case 3636:\\n case 3637:\\n case 3638:\\n case 3639:\\n case 3655:\\n case 3660:\\n case 3645:\\n case 3662:\\n return \\\"Above_Right\\\";\\n case 3761:\\n case 3764:\\n case 3765:\\n case 3766:\\n case 3767:\\n case 3771:\\n case 3788:\\n case 3789:\\n return \\\"Above\\\";\\n case 3772:\\n return \\\"Below\\\";\\n }\\n else if (codePoint === 3642) return \\\"Below_Right\\\";\\n }\\n switch (combiningClass) {\\n // Hebrew\\n case \\\"CCC10\\\":\\n case \\\"CCC11\\\":\\n case \\\"CCC12\\\":\\n case \\\"CCC13\\\":\\n case \\\"CCC14\\\":\\n case \\\"CCC15\\\":\\n case \\\"CCC16\\\":\\n case \\\"CCC17\\\":\\n case \\\"CCC18\\\":\\n case \\\"CCC20\\\":\\n case \\\"CCC22\\\":\\n return \\\"Below\\\";\\n case \\\"CCC23\\\":\\n return \\\"Attached_Above\\\";\\n case \\\"CCC24\\\":\\n return \\\"Above_Right\\\";\\n case \\\"CCC25\\\":\\n case \\\"CCC19\\\":\\n return \\\"Above_Left\\\";\\n case \\\"CCC26\\\":\\n return \\\"Above\\\";\\n case \\\"CCC21\\\":\\n break;\\n // Arabic and Syriac\\n case \\\"CCC27\\\":\\n case \\\"CCC28\\\":\\n case \\\"CCC30\\\":\\n case \\\"CCC31\\\":\\n case \\\"CCC33\\\":\\n case \\\"CCC34\\\":\\n case \\\"CCC35\\\":\\n case \\\"CCC36\\\":\\n return \\\"Above\\\";\\n case \\\"CCC29\\\":\\n case \\\"CCC32\\\":\\n return \\\"Below\\\";\\n // Thai\\n case \\\"CCC103\\\":\\n return \\\"Below_Right\\\";\\n case \\\"CCC107\\\":\\n return \\\"Above_Right\\\";\\n // Lao\\n case \\\"CCC118\\\":\\n return \\\"Below\\\";\\n case \\\"CCC122\\\":\\n return \\\"Above\\\";\\n // Tibetan\\n case \\\"CCC129\\\":\\n case \\\"CCC132\\\":\\n return \\\"Below\\\";\\n case \\\"CCC130\\\":\\n return \\\"Above\\\";\\n }\\n return combiningClass;\\n }\\n constructor(font) {\\n this.font = font;\\n }\\n };\\n $f34600ab9d7f70d8$export$2e2bcd8739ae039 = class _$f34600ab9d7f70d8$export$2e2bcd8739ae039 {\\n /**\\n * The width of the bounding box\\n * @type {number}\\n */\\n get width() {\\n return this.maxX - this.minX;\\n }\\n /**\\n * The height of the bounding box\\n * @type {number}\\n */\\n get height() {\\n return this.maxY - this.minY;\\n }\\n addPoint(x, y) {\\n if (Math.abs(x) !== Infinity) {\\n if (x < this.minX) this.minX = x;\\n if (x > this.maxX) this.maxX = x;\\n }\\n if (Math.abs(y) !== Infinity) {\\n if (y < this.minY) this.minY = y;\\n if (y > this.maxY) this.maxY = y;\\n }\\n }\\n copy() {\\n return new _$f34600ab9d7f70d8$export$2e2bcd8739ae039(this.minX, this.minY, this.maxX, this.maxY);\\n }\\n constructor(minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity) {\\n this.minX = minX;\\n this.minY = minY;\\n this.maxX = maxX;\\n this.maxY = maxY;\\n }\\n };\\n $130d1a642ebcd2b7$var$UNICODE_SCRIPTS = {\\n Caucasian_Albanian: \\\"aghb\\\",\\n Arabic: \\\"arab\\\",\\n Imperial_Aramaic: \\\"armi\\\",\\n Armenian: \\\"armn\\\",\\n Avestan: \\\"avst\\\",\\n Balinese: \\\"bali\\\",\\n Bamum: \\\"bamu\\\",\\n Bassa_Vah: \\\"bass\\\",\\n Batak: \\\"batk\\\",\\n Bengali: [\\n \\\"bng2\\\",\\n \\\"beng\\\"\\n ],\\n Bopomofo: \\\"bopo\\\",\\n Brahmi: \\\"brah\\\",\\n Braille: \\\"brai\\\",\\n Buginese: \\\"bugi\\\",\\n Buhid: \\\"buhd\\\",\\n Chakma: \\\"cakm\\\",\\n Canadian_Aboriginal: \\\"cans\\\",\\n Carian: \\\"cari\\\",\\n Cham: \\\"cham\\\",\\n Cherokee: \\\"cher\\\",\\n Coptic: \\\"copt\\\",\\n Cypriot: \\\"cprt\\\",\\n Cyrillic: \\\"cyrl\\\",\\n Devanagari: [\\n \\\"dev2\\\",\\n \\\"deva\\\"\\n ],\\n Deseret: \\\"dsrt\\\",\\n Duployan: \\\"dupl\\\",\\n Egyptian_Hieroglyphs: \\\"egyp\\\",\\n Elbasan: \\\"elba\\\",\\n Ethiopic: \\\"ethi\\\",\\n Georgian: \\\"geor\\\",\\n Glagolitic: \\\"glag\\\",\\n Gothic: \\\"goth\\\",\\n Grantha: \\\"gran\\\",\\n Greek: \\\"grek\\\",\\n Gujarati: [\\n \\\"gjr2\\\",\\n \\\"gujr\\\"\\n ],\\n Gurmukhi: [\\n \\\"gur2\\\",\\n \\\"guru\\\"\\n ],\\n Hangul: \\\"hang\\\",\\n Han: \\\"hani\\\",\\n Hanunoo: \\\"hano\\\",\\n Hebrew: \\\"hebr\\\",\\n Hiragana: \\\"hira\\\",\\n Pahawh_Hmong: \\\"hmng\\\",\\n Katakana_Or_Hiragana: \\\"hrkt\\\",\\n Old_Italic: \\\"ital\\\",\\n Javanese: \\\"java\\\",\\n Kayah_Li: \\\"kali\\\",\\n Katakana: \\\"kana\\\",\\n Kharoshthi: \\\"khar\\\",\\n Khmer: \\\"khmr\\\",\\n Khojki: \\\"khoj\\\",\\n Kannada: [\\n \\\"knd2\\\",\\n \\\"knda\\\"\\n ],\\n Kaithi: \\\"kthi\\\",\\n Tai_Tham: \\\"lana\\\",\\n Lao: \\\"lao \\\",\\n Latin: \\\"latn\\\",\\n Lepcha: \\\"lepc\\\",\\n Limbu: \\\"limb\\\",\\n Linear_A: \\\"lina\\\",\\n Linear_B: \\\"linb\\\",\\n Lisu: \\\"lisu\\\",\\n Lycian: \\\"lyci\\\",\\n Lydian: \\\"lydi\\\",\\n Mahajani: \\\"mahj\\\",\\n Mandaic: \\\"mand\\\",\\n Manichaean: \\\"mani\\\",\\n Mende_Kikakui: \\\"mend\\\",\\n Meroitic_Cursive: \\\"merc\\\",\\n Meroitic_Hieroglyphs: \\\"mero\\\",\\n Malayalam: [\\n \\\"mlm2\\\",\\n \\\"mlym\\\"\\n ],\\n Modi: \\\"modi\\\",\\n Mongolian: \\\"mong\\\",\\n Mro: \\\"mroo\\\",\\n Meetei_Mayek: \\\"mtei\\\",\\n Myanmar: [\\n \\\"mym2\\\",\\n \\\"mymr\\\"\\n ],\\n Old_North_Arabian: \\\"narb\\\",\\n Nabataean: \\\"nbat\\\",\\n Nko: \\\"nko \\\",\\n Ogham: \\\"ogam\\\",\\n Ol_Chiki: \\\"olck\\\",\\n Old_Turkic: \\\"orkh\\\",\\n Oriya: [\\n \\\"ory2\\\",\\n \\\"orya\\\"\\n ],\\n Osmanya: \\\"osma\\\",\\n Palmyrene: \\\"palm\\\",\\n Pau_Cin_Hau: \\\"pauc\\\",\\n Old_Permic: \\\"perm\\\",\\n Phags_Pa: \\\"phag\\\",\\n Inscriptional_Pahlavi: \\\"phli\\\",\\n Psalter_Pahlavi: \\\"phlp\\\",\\n Phoenician: \\\"phnx\\\",\\n Miao: \\\"plrd\\\",\\n Inscriptional_Parthian: \\\"prti\\\",\\n Rejang: \\\"rjng\\\",\\n Runic: \\\"runr\\\",\\n Samaritan: \\\"samr\\\",\\n Old_South_Arabian: \\\"sarb\\\",\\n Saurashtra: \\\"saur\\\",\\n Shavian: \\\"shaw\\\",\\n Sharada: \\\"shrd\\\",\\n Siddham: \\\"sidd\\\",\\n Khudawadi: \\\"sind\\\",\\n Sinhala: \\\"sinh\\\",\\n Sora_Sompeng: \\\"sora\\\",\\n Sundanese: \\\"sund\\\",\\n Syloti_Nagri: \\\"sylo\\\",\\n Syriac: \\\"syrc\\\",\\n Tagbanwa: \\\"tagb\\\",\\n Takri: \\\"takr\\\",\\n Tai_Le: \\\"tale\\\",\\n New_Tai_Lue: \\\"talu\\\",\\n Tamil: [\\n \\\"tml2\\\",\\n \\\"taml\\\"\\n ],\\n Tai_Viet: \\\"tavt\\\",\\n Telugu: [\\n \\\"tel2\\\",\\n \\\"telu\\\"\\n ],\\n Tifinagh: \\\"tfng\\\",\\n Tagalog: \\\"tglg\\\",\\n Thaana: \\\"thaa\\\",\\n Thai: \\\"thai\\\",\\n Tibetan: \\\"tibt\\\",\\n Tirhuta: \\\"tirh\\\",\\n Ugaritic: \\\"ugar\\\",\\n Vai: \\\"vai \\\",\\n Warang_Citi: \\\"wara\\\",\\n Old_Persian: \\\"xpeo\\\",\\n Cuneiform: \\\"xsux\\\",\\n Yi: \\\"yi \\\",\\n Inherited: \\\"zinh\\\",\\n Common: \\\"zyyy\\\",\\n Unknown: \\\"zzzz\\\"\\n };\\n $130d1a642ebcd2b7$var$OPENTYPE_SCRIPTS = {};\\n for (let script in $130d1a642ebcd2b7$var$UNICODE_SCRIPTS) {\\n let tag = $130d1a642ebcd2b7$var$UNICODE_SCRIPTS[script];\\n if (Array.isArray(tag)) for (let t of tag) $130d1a642ebcd2b7$var$OPENTYPE_SCRIPTS[t] = script;\\n else $130d1a642ebcd2b7$var$OPENTYPE_SCRIPTS[tag] = script;\\n }\\n $130d1a642ebcd2b7$var$RTL = {\\n arab: true,\\n hebr: true,\\n syrc: true,\\n thaa: true,\\n cprt: true,\\n khar: true,\\n phnx: true,\\n \\\"nko \\\": true,\\n lydi: true,\\n avst: true,\\n armi: true,\\n phli: true,\\n prti: true,\\n sarb: true,\\n orkh: true,\\n samr: true,\\n mand: true,\\n merc: true,\\n mero: true,\\n // Unicode 7.0 (not listed on http://www.microsoft.com/typography/otspec/scripttags.htm)\\n mani: true,\\n mend: true,\\n nbat: true,\\n narb: true,\\n palm: true,\\n phlp: true\\n // Psalter Pahlavi\\n };\\n $be07b3e97a42687a$export$2e2bcd8739ae039 = class {\\n /**\\n * The total advance width of the run.\\n * @type {number}\\n */\\n get advanceWidth() {\\n let width = 0;\\n for (let position of this.positions) width += position.xAdvance;\\n return width;\\n }\\n /**\\n * The total advance height of the run.\\n * @type {number}\\n */\\n get advanceHeight() {\\n let height = 0;\\n for (let position of this.positions) height += position.yAdvance;\\n return height;\\n }\\n /**\\n * The bounding box containing all glyphs in the run.\\n * @type {BBox}\\n */\\n get bbox() {\\n let bbox = new (0, $f34600ab9d7f70d8$export$2e2bcd8739ae039)();\\n let x = 0;\\n let y = 0;\\n for (let index = 0; index < this.glyphs.length; index++) {\\n let glyph = this.glyphs[index];\\n let p = this.positions[index];\\n let b = glyph.bbox;\\n bbox.addPoint(b.minX + x + p.xOffset, b.minY + y + p.yOffset);\\n bbox.addPoint(b.maxX + x + p.xOffset, b.maxY + y + p.yOffset);\\n x += p.xAdvance;\\n y += p.yAdvance;\\n }\\n return bbox;\\n }\\n constructor(glyphs, features, script, language, direction) {\\n this.glyphs = glyphs;\\n this.positions = null;\\n this.script = script;\\n this.language = language || null;\\n this.direction = direction || $130d1a642ebcd2b7$export$9fddb9d0dd7d8a54(script);\\n this.features = {};\\n if (Array.isArray(features)) for (let tag of features) this.features[tag] = true;\\n else if (typeof features === \\\"object\\\") this.features = features;\\n }\\n };\\n $1ac75d9a55b67f01$export$2e2bcd8739ae039 = class {\\n constructor(xAdvance = 0, yAdvance = 0, xOffset = 0, yOffset = 0) {\\n this.xAdvance = xAdvance;\\n this.yAdvance = yAdvance;\\n this.xOffset = xOffset;\\n this.yOffset = yOffset;\\n }\\n };\\n $3b6302b64eccc32c$var$features = {\\n allTypographicFeatures: {\\n code: 0,\\n exclusive: false,\\n allTypeFeatures: 0\\n },\\n ligatures: {\\n code: 1,\\n exclusive: false,\\n requiredLigatures: 0,\\n commonLigatures: 2,\\n rareLigatures: 4,\\n // logos: 6\\n rebusPictures: 8,\\n diphthongLigatures: 10,\\n squaredLigatures: 12,\\n abbrevSquaredLigatures: 14,\\n symbolLigatures: 16,\\n contextualLigatures: 18,\\n historicalLigatures: 20\\n },\\n cursiveConnection: {\\n code: 2,\\n exclusive: true,\\n unconnected: 0,\\n partiallyConnected: 1,\\n cursive: 2\\n },\\n letterCase: {\\n code: 3,\\n exclusive: true\\n },\\n // upperAndLowerCase: 0 # deprecated\\n // allCaps: 1 # deprecated\\n // allLowerCase: 2 # deprecated\\n // smallCaps: 3 # deprecated\\n // initialCaps: 4 # deprecated\\n // initialCapsAndSmallCaps: 5 # deprecated\\n verticalSubstitution: {\\n code: 4,\\n exclusive: false,\\n substituteVerticalForms: 0\\n },\\n linguisticRearrangement: {\\n code: 5,\\n exclusive: false,\\n linguisticRearrangement: 0\\n },\\n numberSpacing: {\\n code: 6,\\n exclusive: true,\\n monospacedNumbers: 0,\\n proportionalNumbers: 1,\\n thirdWidthNumbers: 2,\\n quarterWidthNumbers: 3\\n },\\n smartSwash: {\\n code: 8,\\n exclusive: false,\\n wordInitialSwashes: 0,\\n wordFinalSwashes: 2,\\n // lineInitialSwashes: 4\\n // lineFinalSwashes: 6\\n nonFinalSwashes: 8\\n },\\n diacritics: {\\n code: 9,\\n exclusive: true,\\n showDiacritics: 0,\\n hideDiacritics: 1,\\n decomposeDiacritics: 2\\n },\\n verticalPosition: {\\n code: 10,\\n exclusive: true,\\n normalPosition: 0,\\n superiors: 1,\\n inferiors: 2,\\n ordinals: 3,\\n scientificInferiors: 4\\n },\\n fractions: {\\n code: 11,\\n exclusive: true,\\n noFractions: 0,\\n verticalFractions: 1,\\n diagonalFractions: 2\\n },\\n overlappingCharacters: {\\n code: 13,\\n exclusive: false,\\n preventOverlap: 0\\n },\\n typographicExtras: {\\n code: 14,\\n exclusive: false,\\n // hyphensToEmDash: 0\\n // hyphenToEnDash: 2\\n slashedZero: 4\\n },\\n // formInterrobang: 6\\n // smartQuotes: 8\\n // periodsToEllipsis: 10\\n mathematicalExtras: {\\n code: 15,\\n exclusive: false,\\n // hyphenToMinus: 0\\n // asteristoMultiply: 2\\n // slashToDivide: 4\\n // inequalityLigatures: 6\\n // exponents: 8\\n mathematicalGreek: 10\\n },\\n ornamentSets: {\\n code: 16,\\n exclusive: true,\\n noOrnaments: 0,\\n dingbats: 1,\\n piCharacters: 2,\\n fleurons: 3,\\n decorativeBorders: 4,\\n internationalSymbols: 5,\\n mathSymbols: 6\\n },\\n characterAlternatives: {\\n code: 17,\\n exclusive: true,\\n noAlternates: 0\\n },\\n // user defined options\\n designComplexity: {\\n code: 18,\\n exclusive: true,\\n designLevel1: 0,\\n designLevel2: 1,\\n designLevel3: 2,\\n designLevel4: 3,\\n designLevel5: 4\\n },\\n styleOptions: {\\n code: 19,\\n exclusive: true,\\n noStyleOptions: 0,\\n displayText: 1,\\n engravedText: 2,\\n illuminatedCaps: 3,\\n titlingCaps: 4,\\n tallCaps: 5\\n },\\n characterShape: {\\n code: 20,\\n exclusive: true,\\n traditionalCharacters: 0,\\n simplifiedCharacters: 1,\\n JIS1978Characters: 2,\\n JIS1983Characters: 3,\\n JIS1990Characters: 4,\\n traditionalAltOne: 5,\\n traditionalAltTwo: 6,\\n traditionalAltThree: 7,\\n traditionalAltFour: 8,\\n traditionalAltFive: 9,\\n expertCharacters: 10,\\n JIS2004Characters: 11,\\n hojoCharacters: 12,\\n NLCCharacters: 13,\\n traditionalNamesCharacters: 14\\n },\\n numberCase: {\\n code: 21,\\n exclusive: true,\\n lowerCaseNumbers: 0,\\n upperCaseNumbers: 1\\n },\\n textSpacing: {\\n code: 22,\\n exclusive: true,\\n proportionalText: 0,\\n monospacedText: 1,\\n halfWidthText: 2,\\n thirdWidthText: 3,\\n quarterWidthText: 4,\\n altProportionalText: 5,\\n altHalfWidthText: 6\\n },\\n transliteration: {\\n code: 23,\\n exclusive: true,\\n noTransliteration: 0\\n },\\n // hanjaToHangul: 1\\n // hiraganaToKatakana: 2\\n // katakanaToHiragana: 3\\n // kanaToRomanization: 4\\n // romanizationToHiragana: 5\\n // romanizationToKatakana: 6\\n // hanjaToHangulAltOne: 7\\n // hanjaToHangulAltTwo: 8\\n // hanjaToHangulAltThree: 9\\n annotation: {\\n code: 24,\\n exclusive: true,\\n noAnnotation: 0,\\n boxAnnotation: 1,\\n roundedBoxAnnotation: 2,\\n circleAnnotation: 3,\\n invertedCircleAnnotation: 4,\\n parenthesisAnnotation: 5,\\n periodAnnotation: 6,\\n romanNumeralAnnotation: 7,\\n diamondAnnotation: 8,\\n invertedBoxAnnotation: 9,\\n invertedRoundedBoxAnnotation: 10\\n },\\n kanaSpacing: {\\n code: 25,\\n exclusive: true,\\n fullWidthKana: 0,\\n proportionalKana: 1\\n },\\n ideographicSpacing: {\\n code: 26,\\n exclusive: true,\\n fullWidthIdeographs: 0,\\n proportionalIdeographs: 1,\\n halfWidthIdeographs: 2\\n },\\n unicodeDecomposition: {\\n code: 27,\\n exclusive: false,\\n canonicalComposition: 0,\\n compatibilityComposition: 2,\\n transcodingComposition: 4\\n },\\n rubyKana: {\\n code: 28,\\n exclusive: false,\\n // noRubyKana: 0 # deprecated - use rubyKanaOff instead\\n // rubyKana: 1 # deprecated - use rubyKanaOn instead\\n rubyKana: 2\\n },\\n CJKSymbolAlternatives: {\\n code: 29,\\n exclusive: true,\\n noCJKSymbolAlternatives: 0,\\n CJKSymbolAltOne: 1,\\n CJKSymbolAltTwo: 2,\\n CJKSymbolAltThree: 3,\\n CJKSymbolAltFour: 4,\\n CJKSymbolAltFive: 5\\n },\\n ideographicAlternatives: {\\n code: 30,\\n exclusive: true,\\n noIdeographicAlternatives: 0,\\n ideographicAltOne: 1,\\n ideographicAltTwo: 2,\\n ideographicAltThree: 3,\\n ideographicAltFour: 4,\\n ideographicAltFive: 5\\n },\\n CJKVerticalRomanPlacement: {\\n code: 31,\\n exclusive: true,\\n CJKVerticalRomanCentered: 0,\\n CJKVerticalRomanHBaseline: 1\\n },\\n italicCJKRoman: {\\n code: 32,\\n exclusive: false,\\n // noCJKItalicRoman: 0 # deprecated - use CJKItalicRomanOff instead\\n // CJKItalicRoman: 1 # deprecated - use CJKItalicRomanOn instead\\n CJKItalicRoman: 2\\n },\\n caseSensitiveLayout: {\\n code: 33,\\n exclusive: false,\\n caseSensitiveLayout: 0,\\n caseSensitiveSpacing: 2\\n },\\n alternateKana: {\\n code: 34,\\n exclusive: false,\\n alternateHorizKana: 0,\\n alternateVertKana: 2\\n },\\n stylisticAlternatives: {\\n code: 35,\\n exclusive: false,\\n noStylisticAlternates: 0,\\n stylisticAltOne: 2,\\n stylisticAltTwo: 4,\\n stylisticAltThree: 6,\\n stylisticAltFour: 8,\\n stylisticAltFive: 10,\\n stylisticAltSix: 12,\\n stylisticAltSeven: 14,\\n stylisticAltEight: 16,\\n stylisticAltNine: 18,\\n stylisticAltTen: 20,\\n stylisticAltEleven: 22,\\n stylisticAltTwelve: 24,\\n stylisticAltThirteen: 26,\\n stylisticAltFourteen: 28,\\n stylisticAltFifteen: 30,\\n stylisticAltSixteen: 32,\\n stylisticAltSeventeen: 34,\\n stylisticAltEighteen: 36,\\n stylisticAltNineteen: 38,\\n stylisticAltTwenty: 40\\n },\\n contextualAlternates: {\\n code: 36,\\n exclusive: false,\\n contextualAlternates: 0,\\n swashAlternates: 2,\\n contextualSwashAlternates: 4\\n },\\n lowerCase: {\\n code: 37,\\n exclusive: true,\\n defaultLowerCase: 0,\\n lowerCaseSmallCaps: 1,\\n lowerCasePetiteCaps: 2\\n },\\n upperCase: {\\n code: 38,\\n exclusive: true,\\n defaultUpperCase: 0,\\n upperCaseSmallCaps: 1,\\n upperCasePetiteCaps: 2\\n },\\n languageTag: {\\n code: 39,\\n exclusive: true\\n },\\n CJKRomanSpacing: {\\n code: 103,\\n exclusive: true,\\n halfWidthCJKRoman: 0,\\n proportionalCJKRoman: 1,\\n defaultCJKRoman: 2,\\n fullWidthCJKRoman: 3\\n }\\n };\\n $3b6302b64eccc32c$var$feature = (name, selector) => [\\n $3b6302b64eccc32c$var$features[name].code,\\n $3b6302b64eccc32c$var$features[name][selector]\\n ];\\n $3b6302b64eccc32c$var$OTMapping = {\\n rlig: $3b6302b64eccc32c$var$feature(\\\"ligatures\\\", \\\"requiredLigatures\\\"),\\n clig: $3b6302b64eccc32c$var$feature(\\\"ligatures\\\", \\\"contextualLigatures\\\"),\\n dlig: $3b6302b64eccc32c$var$feature(\\\"ligatures\\\", \\\"rareLigatures\\\"),\\n hlig: $3b6302b64eccc32c$var$feature(\\\"ligatures\\\", \\\"historicalLigatures\\\"),\\n liga: $3b6302b64eccc32c$var$feature(\\\"ligatures\\\", \\\"commonLigatures\\\"),\\n hist: $3b6302b64eccc32c$var$feature(\\\"ligatures\\\", \\\"historicalLigatures\\\"),\\n smcp: $3b6302b64eccc32c$var$feature(\\\"lowerCase\\\", \\\"lowerCaseSmallCaps\\\"),\\n pcap: $3b6302b64eccc32c$var$feature(\\\"lowerCase\\\", \\\"lowerCasePetiteCaps\\\"),\\n frac: $3b6302b64eccc32c$var$feature(\\\"fractions\\\", \\\"diagonalFractions\\\"),\\n dnom: $3b6302b64eccc32c$var$feature(\\\"fractions\\\", \\\"diagonalFractions\\\"),\\n numr: $3b6302b64eccc32c$var$feature(\\\"fractions\\\", \\\"diagonalFractions\\\"),\\n afrc: $3b6302b64eccc32c$var$feature(\\\"fractions\\\", \\\"verticalFractions\\\"),\\n // aalt\\n // abvf, abvm, abvs, akhn, blwf, blwm, blws, cfar, cjct, cpsp, falt, isol, jalt, ljmo, mset?\\n // ltra, ltrm, nukt, pref, pres, pstf, psts, rand, rkrf, rphf, rtla, rtlm, size, tjmo, tnum?\\n // unic, vatu, vhal, vjmo, vpal, vrt2\\n // dist -> trak table?\\n // kern, vkrn -> kern table\\n // lfbd + opbd + rtbd -> opbd table?\\n // mark, mkmk -> acnt table?\\n // locl -> languageTag + ltag table\\n case: $3b6302b64eccc32c$var$feature(\\\"caseSensitiveLayout\\\", \\\"caseSensitiveLayout\\\"),\\n ccmp: $3b6302b64eccc32c$var$feature(\\\"unicodeDecomposition\\\", \\\"canonicalComposition\\\"),\\n cpct: $3b6302b64eccc32c$var$feature(\\\"CJKVerticalRomanPlacement\\\", \\\"CJKVerticalRomanCentered\\\"),\\n valt: $3b6302b64eccc32c$var$feature(\\\"CJKVerticalRomanPlacement\\\", \\\"CJKVerticalRomanCentered\\\"),\\n swsh: $3b6302b64eccc32c$var$feature(\\\"contextualAlternates\\\", \\\"swashAlternates\\\"),\\n cswh: $3b6302b64eccc32c$var$feature(\\\"contextualAlternates\\\", \\\"contextualSwashAlternates\\\"),\\n curs: $3b6302b64eccc32c$var$feature(\\\"cursiveConnection\\\", \\\"cursive\\\"),\\n c2pc: $3b6302b64eccc32c$var$feature(\\\"upperCase\\\", \\\"upperCasePetiteCaps\\\"),\\n c2sc: $3b6302b64eccc32c$var$feature(\\\"upperCase\\\", \\\"upperCaseSmallCaps\\\"),\\n init: $3b6302b64eccc32c$var$feature(\\\"smartSwash\\\", \\\"wordInitialSwashes\\\"),\\n fin2: $3b6302b64eccc32c$var$feature(\\\"smartSwash\\\", \\\"wordFinalSwashes\\\"),\\n medi: $3b6302b64eccc32c$var$feature(\\\"smartSwash\\\", \\\"nonFinalSwashes\\\"),\\n med2: $3b6302b64eccc32c$var$feature(\\\"smartSwash\\\", \\\"nonFinalSwashes\\\"),\\n fin3: $3b6302b64eccc32c$var$feature(\\\"smartSwash\\\", \\\"wordFinalSwashes\\\"),\\n fina: $3b6302b64eccc32c$var$feature(\\\"smartSwash\\\", \\\"wordFinalSwashes\\\"),\\n pkna: $3b6302b64eccc32c$var$feature(\\\"kanaSpacing\\\", \\\"proportionalKana\\\"),\\n half: $3b6302b64eccc32c$var$feature(\\\"textSpacing\\\", \\\"halfWidthText\\\"),\\n halt: $3b6302b64eccc32c$var$feature(\\\"textSpacing\\\", \\\"altHalfWidthText\\\"),\\n hkna: $3b6302b64eccc32c$var$feature(\\\"alternateKana\\\", \\\"alternateHorizKana\\\"),\\n vkna: $3b6302b64eccc32c$var$feature(\\\"alternateKana\\\", \\\"alternateVertKana\\\"),\\n // hngl: feature 'transliteration', 'hanjaToHangulSelector' # deprecated\\n ital: $3b6302b64eccc32c$var$feature(\\\"italicCJKRoman\\\", \\\"CJKItalicRoman\\\"),\\n lnum: $3b6302b64eccc32c$var$feature(\\\"numberCase\\\", \\\"upperCaseNumbers\\\"),\\n onum: $3b6302b64eccc32c$var$feature(\\\"numberCase\\\", \\\"lowerCaseNumbers\\\"),\\n mgrk: $3b6302b64eccc32c$var$feature(\\\"mathematicalExtras\\\", \\\"mathematicalGreek\\\"),\\n // nalt: not enough info. what type of annotation?\\n // ornm: ditto, which ornament style?\\n calt: $3b6302b64eccc32c$var$feature(\\\"contextualAlternates\\\", \\\"contextualAlternates\\\"),\\n vrt2: $3b6302b64eccc32c$var$feature(\\\"verticalSubstitution\\\", \\\"substituteVerticalForms\\\"),\\n vert: $3b6302b64eccc32c$var$feature(\\\"verticalSubstitution\\\", \\\"substituteVerticalForms\\\"),\\n tnum: $3b6302b64eccc32c$var$feature(\\\"numberSpacing\\\", \\\"monospacedNumbers\\\"),\\n pnum: $3b6302b64eccc32c$var$feature(\\\"numberSpacing\\\", \\\"proportionalNumbers\\\"),\\n sups: $3b6302b64eccc32c$var$feature(\\\"verticalPosition\\\", \\\"superiors\\\"),\\n subs: $3b6302b64eccc32c$var$feature(\\\"verticalPosition\\\", \\\"inferiors\\\"),\\n ordn: $3b6302b64eccc32c$var$feature(\\\"verticalPosition\\\", \\\"ordinals\\\"),\\n pwid: $3b6302b64eccc32c$var$feature(\\\"textSpacing\\\", \\\"proportionalText\\\"),\\n hwid: $3b6302b64eccc32c$var$feature(\\\"textSpacing\\\", \\\"halfWidthText\\\"),\\n qwid: $3b6302b64eccc32c$var$feature(\\\"textSpacing\\\", \\\"quarterWidthText\\\"),\\n twid: $3b6302b64eccc32c$var$feature(\\\"textSpacing\\\", \\\"thirdWidthText\\\"),\\n fwid: $3b6302b64eccc32c$var$feature(\\\"textSpacing\\\", \\\"proportionalText\\\"),\\n palt: $3b6302b64eccc32c$var$feature(\\\"textSpacing\\\", \\\"altProportionalText\\\"),\\n trad: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"traditionalCharacters\\\"),\\n smpl: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"simplifiedCharacters\\\"),\\n jp78: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"JIS1978Characters\\\"),\\n jp83: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"JIS1983Characters\\\"),\\n jp90: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"JIS1990Characters\\\"),\\n jp04: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"JIS2004Characters\\\"),\\n expt: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"expertCharacters\\\"),\\n hojo: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"hojoCharacters\\\"),\\n nlck: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"NLCCharacters\\\"),\\n tnam: $3b6302b64eccc32c$var$feature(\\\"characterShape\\\", \\\"traditionalNamesCharacters\\\"),\\n ruby: $3b6302b64eccc32c$var$feature(\\\"rubyKana\\\", \\\"rubyKana\\\"),\\n titl: $3b6302b64eccc32c$var$feature(\\\"styleOptions\\\", \\\"titlingCaps\\\"),\\n zero: $3b6302b64eccc32c$var$feature(\\\"typographicExtras\\\", \\\"slashedZero\\\"),\\n ss01: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltOne\\\"),\\n ss02: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltTwo\\\"),\\n ss03: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltThree\\\"),\\n ss04: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltFour\\\"),\\n ss05: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltFive\\\"),\\n ss06: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltSix\\\"),\\n ss07: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltSeven\\\"),\\n ss08: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltEight\\\"),\\n ss09: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltNine\\\"),\\n ss10: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltTen\\\"),\\n ss11: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltEleven\\\"),\\n ss12: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltTwelve\\\"),\\n ss13: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltThirteen\\\"),\\n ss14: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltFourteen\\\"),\\n ss15: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltFifteen\\\"),\\n ss16: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltSixteen\\\"),\\n ss17: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltSeventeen\\\"),\\n ss18: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltEighteen\\\"),\\n ss19: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltNineteen\\\"),\\n ss20: $3b6302b64eccc32c$var$feature(\\\"stylisticAlternatives\\\", \\\"stylisticAltTwenty\\\")\\n };\\n for (let i = 1; i <= 99; i++) $3b6302b64eccc32c$var$OTMapping[`cv${`00${i}`.slice(-2)}`] = [\\n $3b6302b64eccc32c$var$features.characterAlternatives.code,\\n i\\n ];\\n $3b6302b64eccc32c$var$AATMapping = {};\\n for (let ot in $3b6302b64eccc32c$var$OTMapping) {\\n let aat = $3b6302b64eccc32c$var$OTMapping[ot];\\n if ($3b6302b64eccc32c$var$AATMapping[aat[0]] == null) $3b6302b64eccc32c$var$AATMapping[aat[0]] = {};\\n $3b6302b64eccc32c$var$AATMapping[aat[0]][aat[1]] = ot;\\n }\\n $ff5ce077dae0f144$export$2e2bcd8739ae039 = class {\\n lookup(glyph) {\\n switch (this.table.version) {\\n case 0:\\n return this.table.values.getItem(glyph);\\n case 2:\\n case 4: {\\n let min = 0;\\n let max = this.table.binarySearchHeader.nUnits - 1;\\n while (min <= max) {\\n var mid = min + max >> 1;\\n var seg = this.table.segments[mid];\\n if (seg.firstGlyph === 65535) return null;\\n if (glyph < seg.firstGlyph) max = mid - 1;\\n else if (glyph > seg.lastGlyph) min = mid + 1;\\n else {\\n if (this.table.version === 2) return seg.value;\\n else return seg.values[glyph - seg.firstGlyph];\\n }\\n }\\n return null;\\n }\\n case 6: {\\n let min = 0;\\n let max = this.table.binarySearchHeader.nUnits - 1;\\n while (min <= max) {\\n var mid = min + max >> 1;\\n var seg = this.table.segments[mid];\\n if (seg.glyph === 65535) return null;\\n if (glyph < seg.glyph) max = mid - 1;\\n else if (glyph > seg.glyph) min = mid + 1;\\n else return seg.value;\\n }\\n return null;\\n }\\n case 8:\\n return this.table.values[glyph - this.table.firstGlyph];\\n default:\\n throw new Error(`Unknown lookup table format: ${this.table.version}`);\\n }\\n }\\n glyphsForValue(classValue) {\\n let res = [];\\n switch (this.table.version) {\\n case 2:\\n case 4:\\n for (let segment of this.table.segments) if (this.table.version === 2 && segment.value === classValue) res.push(...(0, $12727730ddfc8bfe$export$d02631cccf789723)(segment.firstGlyph, segment.lastGlyph + 1));\\n else {\\n for (let index = 0; index < segment.values.length; index++) if (segment.values[index] === classValue) res.push(segment.firstGlyph + index);\\n }\\n break;\\n case 6:\\n for (let segment of this.table.segments) if (segment.value === classValue) res.push(segment.glyph);\\n break;\\n case 8:\\n for (let i = 0; i < this.table.values.length; i++) if (this.table.values[i] === classValue) res.push(this.table.firstGlyph + i);\\n break;\\n default:\\n throw new Error(`Unknown lookup table format: ${this.table.version}`);\\n }\\n return res;\\n }\\n constructor(table) {\\n this.table = table;\\n }\\n };\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $ff5ce077dae0f144$export$2e2bcd8739ae039.prototype, \\\"glyphsForValue\\\", null);\\n $50c7aac9316f2948$var$START_OF_TEXT_STATE = 0;\\n $50c7aac9316f2948$var$END_OF_TEXT_CLASS = 0;\\n $50c7aac9316f2948$var$OUT_OF_BOUNDS_CLASS = 1;\\n $50c7aac9316f2948$var$DELETED_GLYPH_CLASS = 2;\\n $50c7aac9316f2948$var$DONT_ADVANCE = 16384;\\n $50c7aac9316f2948$export$2e2bcd8739ae039 = class {\\n process(glyphs, reverse, processEntry) {\\n let currentState = $50c7aac9316f2948$var$START_OF_TEXT_STATE;\\n let index = reverse ? glyphs.length - 1 : 0;\\n let dir = reverse ? -1 : 1;\\n while (dir === 1 && index <= glyphs.length || dir === -1 && index >= -1) {\\n let glyph = null;\\n let classCode = $50c7aac9316f2948$var$OUT_OF_BOUNDS_CLASS;\\n let shouldAdvance = true;\\n if (index === glyphs.length || index === -1) classCode = $50c7aac9316f2948$var$END_OF_TEXT_CLASS;\\n else {\\n glyph = glyphs[index];\\n if (glyph.id === 65535) classCode = $50c7aac9316f2948$var$DELETED_GLYPH_CLASS;\\n else {\\n classCode = this.lookupTable.lookup(glyph.id);\\n if (classCode == null) classCode = $50c7aac9316f2948$var$OUT_OF_BOUNDS_CLASS;\\n }\\n }\\n let row = this.stateTable.stateArray.getItem(currentState);\\n let entryIndex = row[classCode];\\n let entry = this.stateTable.entryTable.getItem(entryIndex);\\n if (classCode !== $50c7aac9316f2948$var$END_OF_TEXT_CLASS && classCode !== $50c7aac9316f2948$var$DELETED_GLYPH_CLASS) {\\n processEntry(glyph, entry, index);\\n shouldAdvance = !(entry.flags & $50c7aac9316f2948$var$DONT_ADVANCE);\\n }\\n currentState = entry.newState;\\n if (shouldAdvance) index += dir;\\n }\\n return glyphs;\\n }\\n /**\\n * Performs a depth-first traversal of the glyph strings\\n * represented by the state machine.\\n */\\n traverse(opts, state = 0, visited = /* @__PURE__ */ new Set()) {\\n if (visited.has(state)) return;\\n visited.add(state);\\n let { nClasses, stateArray, entryTable } = this.stateTable;\\n let row = stateArray.getItem(state);\\n for (let classCode = 4; classCode < nClasses; classCode++) {\\n let entryIndex = row[classCode];\\n let entry = entryTable.getItem(entryIndex);\\n for (let glyph of this.lookupTable.glyphsForValue(classCode)) {\\n if (opts.enter) opts.enter(glyph, entry);\\n if (entry.newState !== 0) this.traverse(opts, entry.newState, visited);\\n if (opts.exit) opts.exit(glyph, entry);\\n }\\n }\\n }\\n constructor(stateTable) {\\n this.stateTable = stateTable;\\n this.lookupTable = new (0, $ff5ce077dae0f144$export$2e2bcd8739ae039)(stateTable.classTable);\\n }\\n };\\n $55f71433a605c87d$var$MARK_FIRST = 32768;\\n $55f71433a605c87d$var$MARK_LAST = 8192;\\n $55f71433a605c87d$var$VERB = 15;\\n $55f71433a605c87d$var$SET_MARK = 32768;\\n $55f71433a605c87d$var$SET_COMPONENT = 32768;\\n $55f71433a605c87d$var$PERFORM_ACTION = 8192;\\n $55f71433a605c87d$var$LAST_MASK = 2147483648;\\n $55f71433a605c87d$var$STORE_MASK = 1073741824;\\n $55f71433a605c87d$var$OFFSET_MASK = 1073741823;\\n $55f71433a605c87d$var$REVERSE_DIRECTION = 4194304;\\n $55f71433a605c87d$var$CURRENT_INSERT_BEFORE = 2048;\\n $55f71433a605c87d$var$MARKED_INSERT_BEFORE = 1024;\\n $55f71433a605c87d$var$CURRENT_INSERT_COUNT = 992;\\n $55f71433a605c87d$var$MARKED_INSERT_COUNT = 31;\\n $55f71433a605c87d$export$2e2bcd8739ae039 = class {\\n // Processes an array of glyphs and applies the specified features\\n // Features should be in the form of {featureType:{featureSetting:boolean}}\\n process(glyphs, features = {}) {\\n for (let chain of this.morx.chains) {\\n let flags = chain.defaultFlags;\\n for (let feature of chain.features) {\\n let f;\\n if (f = features[feature.featureType]) {\\n if (f[feature.featureSetting]) {\\n flags &= feature.disableFlags;\\n flags |= feature.enableFlags;\\n } else if (f[feature.featureSetting] === false) {\\n flags |= ~feature.disableFlags;\\n flags &= ~feature.enableFlags;\\n }\\n }\\n }\\n for (let subtable of chain.subtables) if (subtable.subFeatureFlags & flags) this.processSubtable(subtable, glyphs);\\n }\\n let index = glyphs.length - 1;\\n while (index >= 0) {\\n if (glyphs[index].id === 65535) glyphs.splice(index, 1);\\n index--;\\n }\\n return glyphs;\\n }\\n processSubtable(subtable, glyphs) {\\n this.subtable = subtable;\\n this.glyphs = glyphs;\\n if (this.subtable.type === 4) {\\n this.processNoncontextualSubstitutions(this.subtable, this.glyphs);\\n return;\\n }\\n this.ligatureStack = [];\\n this.markedGlyph = null;\\n this.firstGlyph = null;\\n this.lastGlyph = null;\\n this.markedIndex = null;\\n let stateMachine = this.getStateMachine(subtable);\\n let process2 = this.getProcessor();\\n let reverse = !!(this.subtable.coverage & $55f71433a605c87d$var$REVERSE_DIRECTION);\\n return stateMachine.process(this.glyphs, reverse, process2);\\n }\\n getStateMachine(subtable) {\\n return new (0, $50c7aac9316f2948$export$2e2bcd8739ae039)(subtable.table.stateTable);\\n }\\n getProcessor() {\\n switch (this.subtable.type) {\\n case 0:\\n return this.processIndicRearragement;\\n case 1:\\n return this.processContextualSubstitution;\\n case 2:\\n return this.processLigature;\\n case 4:\\n return this.processNoncontextualSubstitutions;\\n case 5:\\n return this.processGlyphInsertion;\\n default:\\n throw new Error(`Invalid morx subtable type: ${this.subtable.type}`);\\n }\\n }\\n processIndicRearragement(glyph, entry, index) {\\n if (entry.flags & $55f71433a605c87d$var$MARK_FIRST) this.firstGlyph = index;\\n if (entry.flags & $55f71433a605c87d$var$MARK_LAST) this.lastGlyph = index;\\n $55f71433a605c87d$var$reorderGlyphs(this.glyphs, entry.flags & $55f71433a605c87d$var$VERB, this.firstGlyph, this.lastGlyph);\\n }\\n processContextualSubstitution(glyph, entry, index) {\\n let subsitutions = this.subtable.table.substitutionTable.items;\\n if (entry.markIndex !== 65535) {\\n let lookup = subsitutions.getItem(entry.markIndex);\\n let lookupTable = new (0, $ff5ce077dae0f144$export$2e2bcd8739ae039)(lookup);\\n glyph = this.glyphs[this.markedGlyph];\\n var gid = lookupTable.lookup(glyph.id);\\n if (gid) this.glyphs[this.markedGlyph] = this.font.getGlyph(gid, glyph.codePoints);\\n }\\n if (entry.currentIndex !== 65535) {\\n let lookup = subsitutions.getItem(entry.currentIndex);\\n let lookupTable = new (0, $ff5ce077dae0f144$export$2e2bcd8739ae039)(lookup);\\n glyph = this.glyphs[index];\\n var gid = lookupTable.lookup(glyph.id);\\n if (gid) this.glyphs[index] = this.font.getGlyph(gid, glyph.codePoints);\\n }\\n if (entry.flags & $55f71433a605c87d$var$SET_MARK) this.markedGlyph = index;\\n }\\n processLigature(glyph, entry, index) {\\n if (entry.flags & $55f71433a605c87d$var$SET_COMPONENT) this.ligatureStack.push(index);\\n if (entry.flags & $55f71433a605c87d$var$PERFORM_ACTION) {\\n let actions = this.subtable.table.ligatureActions;\\n let components = this.subtable.table.components;\\n let ligatureList = this.subtable.table.ligatureList;\\n let actionIndex = entry.action;\\n let last = false;\\n let ligatureIndex = 0;\\n let codePoints = [];\\n let ligatureGlyphs = [];\\n while (!last) {\\n let componentGlyph = this.ligatureStack.pop();\\n codePoints.unshift(...this.glyphs[componentGlyph].codePoints);\\n let action = actions.getItem(actionIndex++);\\n last = !!(action & $55f71433a605c87d$var$LAST_MASK);\\n let store = !!(action & $55f71433a605c87d$var$STORE_MASK);\\n let offset = (action & $55f71433a605c87d$var$OFFSET_MASK) << 2 >> 2;\\n offset += this.glyphs[componentGlyph].id;\\n let component = components.getItem(offset);\\n ligatureIndex += component;\\n if (last || store) {\\n let ligatureEntry = ligatureList.getItem(ligatureIndex);\\n this.glyphs[componentGlyph] = this.font.getGlyph(ligatureEntry, codePoints);\\n ligatureGlyphs.push(componentGlyph);\\n ligatureIndex = 0;\\n codePoints = [];\\n } else this.glyphs[componentGlyph] = this.font.getGlyph(65535);\\n }\\n this.ligatureStack.push(...ligatureGlyphs);\\n }\\n }\\n processNoncontextualSubstitutions(subtable, glyphs, index) {\\n let lookupTable = new (0, $ff5ce077dae0f144$export$2e2bcd8739ae039)(subtable.table.lookupTable);\\n for (index = 0; index < glyphs.length; index++) {\\n let glyph = glyphs[index];\\n if (glyph.id !== 65535) {\\n let gid = lookupTable.lookup(glyph.id);\\n if (gid) glyphs[index] = this.font.getGlyph(gid, glyph.codePoints);\\n }\\n }\\n }\\n _insertGlyphs(glyphIndex, insertionActionIndex, count, isBefore) {\\n let insertions = [];\\n while (count--) {\\n let gid = this.subtable.table.insertionActions.getItem(insertionActionIndex++);\\n insertions.push(this.font.getGlyph(gid));\\n }\\n if (!isBefore) glyphIndex++;\\n this.glyphs.splice(glyphIndex, 0, ...insertions);\\n }\\n processGlyphInsertion(glyph, entry, index) {\\n if (entry.flags & $55f71433a605c87d$var$SET_MARK) this.markedIndex = index;\\n if (entry.markedInsertIndex !== 65535) {\\n let count = (entry.flags & $55f71433a605c87d$var$MARKED_INSERT_COUNT) >>> 5;\\n let isBefore = !!(entry.flags & $55f71433a605c87d$var$MARKED_INSERT_BEFORE);\\n this._insertGlyphs(this.markedIndex, entry.markedInsertIndex, count, isBefore);\\n }\\n if (entry.currentInsertIndex !== 65535) {\\n let count = (entry.flags & $55f71433a605c87d$var$CURRENT_INSERT_COUNT) >>> 5;\\n let isBefore = !!(entry.flags & $55f71433a605c87d$var$CURRENT_INSERT_BEFORE);\\n this._insertGlyphs(index, entry.currentInsertIndex, count, isBefore);\\n }\\n }\\n getSupportedFeatures() {\\n let features = [];\\n for (let chain of this.morx.chains) for (let feature of chain.features) features.push([\\n feature.featureType,\\n feature.featureSetting\\n ]);\\n return features;\\n }\\n generateInputs(gid) {\\n if (!this.inputCache) this.generateInputCache();\\n return this.inputCache[gid] || [];\\n }\\n generateInputCache() {\\n this.inputCache = {};\\n for (let chain of this.morx.chains) {\\n let flags = chain.defaultFlags;\\n for (let subtable of chain.subtables) if (subtable.subFeatureFlags & flags) this.generateInputsForSubtable(subtable);\\n }\\n }\\n generateInputsForSubtable(subtable) {\\n if (subtable.type !== 2) return;\\n let reverse = !!(subtable.coverage & $55f71433a605c87d$var$REVERSE_DIRECTION);\\n if (reverse) throw new Error(\\\"Reverse subtable, not supported.\\\");\\n this.subtable = subtable;\\n this.ligatureStack = [];\\n let stateMachine = this.getStateMachine(subtable);\\n let process2 = this.getProcessor();\\n let input = [];\\n let stack = [];\\n this.glyphs = [];\\n stateMachine.traverse({\\n enter: (glyph, entry) => {\\n let glyphs = this.glyphs;\\n stack.push({\\n glyphs: glyphs.slice(),\\n ligatureStack: this.ligatureStack.slice()\\n });\\n let g = this.font.getGlyph(glyph);\\n input.push(g);\\n glyphs.push(input[input.length - 1]);\\n process2(glyphs[glyphs.length - 1], entry, glyphs.length - 1);\\n let count = 0;\\n let found = 0;\\n for (let i = 0; i < glyphs.length && count <= 1; i++) if (glyphs[i].id !== 65535) {\\n count++;\\n found = glyphs[i].id;\\n }\\n if (count === 1) {\\n let result = input.map((g2) => g2.id);\\n let cache2 = this.inputCache[found];\\n if (cache2) cache2.push(result);\\n else this.inputCache[found] = [\\n result\\n ];\\n }\\n },\\n exit: () => {\\n ({ glyphs: this.glyphs, ligatureStack: this.ligatureStack } = stack.pop());\\n input.pop();\\n }\\n });\\n }\\n constructor(font) {\\n this.processIndicRearragement = this.processIndicRearragement.bind(this);\\n this.processContextualSubstitution = this.processContextualSubstitution.bind(this);\\n this.processLigature = this.processLigature.bind(this);\\n this.processNoncontextualSubstitutions = this.processNoncontextualSubstitutions.bind(this);\\n this.processGlyphInsertion = this.processGlyphInsertion.bind(this);\\n this.font = font;\\n this.morx = font.morx;\\n this.inputCache = null;\\n }\\n };\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $55f71433a605c87d$export$2e2bcd8739ae039.prototype, \\\"getStateMachine\\\", null);\\n $ba6dd74203be8728$export$2e2bcd8739ae039 = class {\\n substitute(glyphRun) {\\n if (glyphRun.direction === \\\"rtl\\\") glyphRun.glyphs.reverse();\\n this.morxProcessor.process(glyphRun.glyphs, $3b6302b64eccc32c$export$b813f7d2a1677c16(glyphRun.features));\\n }\\n getAvailableFeatures(script, language) {\\n return $3b6302b64eccc32c$export$bd6df347a4f391c4(this.morxProcessor.getSupportedFeatures());\\n }\\n stringsForGlyph(gid) {\\n let glyphStrings = this.morxProcessor.generateInputs(gid);\\n let result = /* @__PURE__ */ new Set();\\n for (let glyphs of glyphStrings) this._addStrings(glyphs, 0, result, \\\"\\\");\\n return result;\\n }\\n _addStrings(glyphs, index, strings, string) {\\n let codePoints = this.font._cmapProcessor.codePointsForGlyph(glyphs[index]);\\n for (let codePoint of codePoints) {\\n let s = string + String.fromCodePoint(codePoint);\\n if (index < glyphs.length - 1) this._addStrings(glyphs, index + 1, strings, s);\\n else strings.add(s);\\n }\\n }\\n constructor(font) {\\n this.font = font;\\n this.morxProcessor = new (0, $55f71433a605c87d$export$2e2bcd8739ae039)(font);\\n this.fallbackPosition = false;\\n }\\n };\\n $94d7a73bd2edfc9a$export$2e2bcd8739ae039 = class {\\n /**\\n * Adds the given features to the last stage.\\n * Ignores features that have already been applied.\\n */\\n _addFeatures(features, global) {\\n let stageIndex = this.stages.length - 1;\\n let stage = this.stages[stageIndex];\\n for (let feature of features) if (this.allFeatures[feature] == null) {\\n stage.push(feature);\\n this.allFeatures[feature] = stageIndex;\\n if (global) this.globalFeatures[feature] = true;\\n }\\n }\\n /**\\n * Add features to the last stage\\n */\\n add(arg, global = true) {\\n if (this.stages.length === 0) this.stages.push([]);\\n if (typeof arg === \\\"string\\\") arg = [\\n arg\\n ];\\n if (Array.isArray(arg)) this._addFeatures(arg, global);\\n else if (typeof arg === \\\"object\\\") {\\n this._addFeatures(arg.global || [], true);\\n this._addFeatures(arg.local || [], false);\\n } else throw new Error(\\\"Unsupported argument to ShapingPlan#add\\\");\\n }\\n /**\\n * Add a new stage\\n */\\n addStage(arg, global) {\\n if (typeof arg === \\\"function\\\") this.stages.push(arg, []);\\n else {\\n this.stages.push([]);\\n this.add(arg, global);\\n }\\n }\\n setFeatureOverrides(features) {\\n if (Array.isArray(features)) this.add(features);\\n else if (typeof features === \\\"object\\\") for (let tag in features) {\\n if (features[tag]) this.add(tag);\\n else if (this.allFeatures[tag] != null) {\\n let stage = this.stages[this.allFeatures[tag]];\\n stage.splice(stage.indexOf(tag), 1);\\n delete this.allFeatures[tag];\\n delete this.globalFeatures[tag];\\n }\\n }\\n }\\n /**\\n * Assigns the global features to the given glyphs\\n */\\n assignGlobalFeatures(glyphs) {\\n for (let glyph of glyphs) for (let feature in this.globalFeatures) glyph.features[feature] = true;\\n }\\n /**\\n * Executes the planned stages using the given OTProcessor\\n */\\n process(processor, glyphs, positions) {\\n for (let stage of this.stages) {\\n if (typeof stage === \\\"function\\\") {\\n if (!positions) stage(this.font, glyphs, this);\\n } else if (stage.length > 0) processor.applyFeatures(stage, glyphs, positions);\\n }\\n }\\n constructor(font, script, direction) {\\n this.font = font;\\n this.script = script;\\n this.direction = direction;\\n this.stages = [];\\n this.globalFeatures = {};\\n this.allFeatures = {};\\n }\\n };\\n $649970d87335b30f$var$VARIATION_FEATURES = [\\n \\\"rvrn\\\"\\n ];\\n $649970d87335b30f$var$COMMON_FEATURES = [\\n \\\"ccmp\\\",\\n \\\"locl\\\",\\n \\\"rlig\\\",\\n \\\"mark\\\",\\n \\\"mkmk\\\"\\n ];\\n $649970d87335b30f$var$FRACTIONAL_FEATURES = [\\n \\\"frac\\\",\\n \\\"numr\\\",\\n \\\"dnom\\\"\\n ];\\n $649970d87335b30f$var$HORIZONTAL_FEATURES = [\\n \\\"calt\\\",\\n \\\"clig\\\",\\n \\\"liga\\\",\\n \\\"rclt\\\",\\n \\\"curs\\\",\\n \\\"kern\\\"\\n ];\\n $649970d87335b30f$var$DIRECTIONAL_FEATURES = {\\n ltr: [\\n \\\"ltra\\\",\\n \\\"ltrm\\\"\\n ],\\n rtl: [\\n \\\"rtla\\\",\\n \\\"rtlm\\\"\\n ]\\n };\\n $649970d87335b30f$export$2e2bcd8739ae039 = class {\\n static plan(plan, glyphs, features) {\\n this.planPreprocessing(plan);\\n this.planFeatures(plan);\\n this.planPostprocessing(plan, features);\\n plan.assignGlobalFeatures(glyphs);\\n this.assignFeatures(plan, glyphs);\\n }\\n static planPreprocessing(plan) {\\n plan.add({\\n global: [\\n ...$649970d87335b30f$var$VARIATION_FEATURES,\\n ...$649970d87335b30f$var$DIRECTIONAL_FEATURES[plan.direction]\\n ],\\n local: $649970d87335b30f$var$FRACTIONAL_FEATURES\\n });\\n }\\n static planFeatures(plan) {\\n }\\n static planPostprocessing(plan, userFeatures) {\\n plan.add([\\n ...$649970d87335b30f$var$COMMON_FEATURES,\\n ...$649970d87335b30f$var$HORIZONTAL_FEATURES\\n ]);\\n plan.setFeatureOverrides(userFeatures);\\n }\\n static assignFeatures(plan, glyphs) {\\n for (let i = 0; i < glyphs.length; i++) {\\n let glyph = glyphs[i];\\n if (glyph.codePoints[0] === 8260) {\\n let start = i;\\n let end = i + 1;\\n while (start > 0 && (0, $747425b437e121da$export$727d9dbc4fbb948f)(glyphs[start - 1].codePoints[0])) {\\n glyphs[start - 1].features.numr = true;\\n glyphs[start - 1].features.frac = true;\\n start--;\\n }\\n while (end < glyphs.length && (0, $747425b437e121da$export$727d9dbc4fbb948f)(glyphs[end].codePoints[0])) {\\n glyphs[end].features.dnom = true;\\n glyphs[end].features.frac = true;\\n end++;\\n }\\n glyph.features.frac = true;\\n i = end - 1;\\n }\\n }\\n }\\n };\\n (0, _define_property)($649970d87335b30f$export$2e2bcd8739ae039, \\\"zeroMarkWidths\\\", \\\"AFTER_GPOS\\\");\\n $764eb544bbe1ccf0$var$trie = new (0, import_unicode_trie2.default)((0, $12727730ddfc8bfe$export$94fdf11bafc8de6b)(\\\"APABAAAAAAAAOAAAAf0BAv7tmi1MxDAUx7vtvjhAgcDgkEgEAnmXEBIMCYaEcygEiqBQ4FAkCE4ikUgMiiBJSAgSiUQSDMn9L9eSl6bddddug9t7yS/trevre+3r27pcNxZiG+yCfdCVv/9LeQxOwRm4AJegD27ALbgD9+ABPJF+z+BN/h7yDj5k/VOWX6SdmU5+wLWknggxDxaS8u0qiiX4uiz9XamQ3wzDMAzDMAzDMAzDVI/h959V/v7BMAzDMAzDMLlyNTNiMSdewVxbiA44B4/guz1qW58VYlMI0WsJ0W+N6kXw0spvPtdwhtkwnGM6uLaV4Xyzg3v3PM9DPfQ/sOg4xPWjipy31P8LTqbU304c/cLCUmWJLNB2Uz2U1KTeRKNmKHVMfbJC+/0loTZRH/W5cvEvBJPMbREkWt3FD1NcqXZBSpuE2Ad0PBehPtNrPtIEdYP+hiRt/V1jIiE69X4NT/uVZI3PUHE9bm5M7ePGdZWy951v7Nn6j8v1WWKP3mt6ttnsigx6VN7Vc0VomSSGqW2mGNP1muZPl7LfjNUaKNFtDGVf2fvE9O7VlBS5j333c5p/eeoOqcs1R/hIqDWLJ7TTlksirVT1SI7l8k4Yp+g3jafGcrU1RM6l9th80XOpnlN97bDNY4i4s61B0Si/ipa0uHMl6zqEjlFfCZm/TM8KmzQDjmuTAQ==\\\"));\\n $764eb544bbe1ccf0$var$FEATURES = [\\n \\\"isol\\\",\\n \\\"fina\\\",\\n \\\"fin2\\\",\\n \\\"fin3\\\",\\n \\\"medi\\\",\\n \\\"med2\\\",\\n \\\"init\\\"\\n ];\\n $764eb544bbe1ccf0$var$ShapingClasses = {\\n Non_Joining: 0,\\n Left_Joining: 1,\\n Right_Joining: 2,\\n Dual_Joining: 3,\\n Join_Causing: 3,\\n ALAPH: 4,\\n \\\"DALATH RISH\\\": 5,\\n Transparent: 6\\n };\\n $764eb544bbe1ccf0$var$ISOL = \\\"isol\\\";\\n $764eb544bbe1ccf0$var$FINA = \\\"fina\\\";\\n $764eb544bbe1ccf0$var$FIN2 = \\\"fin2\\\";\\n $764eb544bbe1ccf0$var$FIN3 = \\\"fin3\\\";\\n $764eb544bbe1ccf0$var$MEDI = \\\"medi\\\";\\n $764eb544bbe1ccf0$var$MED2 = \\\"med2\\\";\\n $764eb544bbe1ccf0$var$INIT = \\\"init\\\";\\n $764eb544bbe1ccf0$var$NONE = null;\\n $764eb544bbe1ccf0$var$STATE_TABLE = [\\n // Non_Joining, Left_Joining, Right_Joining, Dual_Joining, ALAPH, DALATH RISH\\n // State 0: prev was U, not willing to join.\\n [\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$NONE,\\n 0\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 1\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 1\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 6\\n ]\\n ],\\n // State 1: prev was R or ISOL/ALAPH, not willing to join.\\n [\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$NONE,\\n 0\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 1\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$FIN2,\\n 5\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 6\\n ]\\n ],\\n // State 2: prev was D/L in ISOL form, willing to join.\\n [\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$NONE,\\n 0\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$INIT,\\n $764eb544bbe1ccf0$var$FINA,\\n 1\\n ],\\n [\\n $764eb544bbe1ccf0$var$INIT,\\n $764eb544bbe1ccf0$var$FINA,\\n 3\\n ],\\n [\\n $764eb544bbe1ccf0$var$INIT,\\n $764eb544bbe1ccf0$var$FINA,\\n 4\\n ],\\n [\\n $764eb544bbe1ccf0$var$INIT,\\n $764eb544bbe1ccf0$var$FINA,\\n 6\\n ]\\n ],\\n // State 3: prev was D in FINA form, willing to join.\\n [\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$NONE,\\n 0\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$MEDI,\\n $764eb544bbe1ccf0$var$FINA,\\n 1\\n ],\\n [\\n $764eb544bbe1ccf0$var$MEDI,\\n $764eb544bbe1ccf0$var$FINA,\\n 3\\n ],\\n [\\n $764eb544bbe1ccf0$var$MEDI,\\n $764eb544bbe1ccf0$var$FINA,\\n 4\\n ],\\n [\\n $764eb544bbe1ccf0$var$MEDI,\\n $764eb544bbe1ccf0$var$FINA,\\n 6\\n ]\\n ],\\n // State 4: prev was FINA ALAPH, not willing to join.\\n [\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$NONE,\\n 0\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$MED2,\\n $764eb544bbe1ccf0$var$ISOL,\\n 1\\n ],\\n [\\n $764eb544bbe1ccf0$var$MED2,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$MED2,\\n $764eb544bbe1ccf0$var$FIN2,\\n 5\\n ],\\n [\\n $764eb544bbe1ccf0$var$MED2,\\n $764eb544bbe1ccf0$var$ISOL,\\n 6\\n ]\\n ],\\n // State 5: prev was FIN2/FIN3 ALAPH, not willing to join.\\n [\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$NONE,\\n 0\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$ISOL,\\n $764eb544bbe1ccf0$var$ISOL,\\n 1\\n ],\\n [\\n $764eb544bbe1ccf0$var$ISOL,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$ISOL,\\n $764eb544bbe1ccf0$var$FIN2,\\n 5\\n ],\\n [\\n $764eb544bbe1ccf0$var$ISOL,\\n $764eb544bbe1ccf0$var$ISOL,\\n 6\\n ]\\n ],\\n // State 6: prev was DALATH/RISH, not willing to join.\\n [\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$NONE,\\n 0\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 1\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 2\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$FIN3,\\n 5\\n ],\\n [\\n $764eb544bbe1ccf0$var$NONE,\\n $764eb544bbe1ccf0$var$ISOL,\\n 6\\n ]\\n ]\\n ];\\n $764eb544bbe1ccf0$export$2e2bcd8739ae039 = class extends (0, $649970d87335b30f$export$2e2bcd8739ae039) {\\n static planFeatures(plan) {\\n plan.add([\\n \\\"ccmp\\\",\\n \\\"locl\\\"\\n ]);\\n for (let i = 0; i < $764eb544bbe1ccf0$var$FEATURES.length; i++) {\\n let feature = $764eb544bbe1ccf0$var$FEATURES[i];\\n plan.addStage(feature, false);\\n }\\n plan.addStage(\\\"mset\\\");\\n }\\n static assignFeatures(plan, glyphs) {\\n super.assignFeatures(plan, glyphs);\\n let prev = -1;\\n let state = 0;\\n let actions = [];\\n for (let i = 0; i < glyphs.length; i++) {\\n let curAction, prevAction;\\n var glyph = glyphs[i];\\n let type = $764eb544bbe1ccf0$var$getShapingClass(glyph.codePoints[0]);\\n if (type === $764eb544bbe1ccf0$var$ShapingClasses.Transparent) {\\n actions[i] = $764eb544bbe1ccf0$var$NONE;\\n continue;\\n }\\n [prevAction, curAction, state] = $764eb544bbe1ccf0$var$STATE_TABLE[state][type];\\n if (prevAction !== $764eb544bbe1ccf0$var$NONE && prev !== -1) actions[prev] = prevAction;\\n actions[i] = curAction;\\n prev = i;\\n }\\n for (let index = 0; index < glyphs.length; index++) {\\n let feature;\\n var glyph = glyphs[index];\\n if (feature = actions[index]) glyph.features[feature] = true;\\n }\\n }\\n };\\n $85d408632270248b$export$2e2bcd8739ae039 = class {\\n reset(options = {}, index = 0) {\\n this.options = options;\\n this.flags = options.flags || {};\\n this.markAttachmentType = options.markAttachmentType || 0;\\n this.index = index;\\n }\\n get cur() {\\n return this.glyphs[this.index] || null;\\n }\\n shouldIgnore(glyph) {\\n return this.flags.ignoreMarks && glyph.isMark || this.flags.ignoreBaseGlyphs && glyph.isBase || this.flags.ignoreLigatures && glyph.isLigature || this.markAttachmentType && glyph.isMark && glyph.markAttachmentType !== this.markAttachmentType;\\n }\\n move(dir) {\\n this.index += dir;\\n while (0 <= this.index && this.index < this.glyphs.length && this.shouldIgnore(this.glyphs[this.index])) this.index += dir;\\n if (0 > this.index || this.index >= this.glyphs.length) return null;\\n return this.glyphs[this.index];\\n }\\n next() {\\n return this.move(1);\\n }\\n prev() {\\n return this.move(-1);\\n }\\n peek(count = 1) {\\n let idx = this.index;\\n let res = this.increment(count);\\n this.index = idx;\\n return res;\\n }\\n peekIndex(count = 1) {\\n let idx = this.index;\\n this.increment(count);\\n let res = this.index;\\n this.index = idx;\\n return res;\\n }\\n increment(count = 1) {\\n let dir = count < 0 ? -1 : 1;\\n count = Math.abs(count);\\n while (count--) this.move(dir);\\n return this.glyphs[this.index];\\n }\\n constructor(glyphs, options) {\\n this.glyphs = glyphs;\\n this.reset(options);\\n }\\n };\\n $a83b9c36aaa94fd3$var$DEFAULT_SCRIPTS = [\\n \\\"DFLT\\\",\\n \\\"dflt\\\",\\n \\\"latn\\\"\\n ];\\n $a83b9c36aaa94fd3$export$2e2bcd8739ae039 = class {\\n findScript(script) {\\n if (this.table.scriptList == null) return null;\\n if (!Array.isArray(script)) script = [\\n script\\n ];\\n for (let s of script) for (let entry of this.table.scriptList) {\\n if (entry.tag === s) return entry;\\n }\\n return null;\\n }\\n selectScript(script, language, direction) {\\n let changed = false;\\n let entry;\\n if (!this.script || script !== this.scriptTag) {\\n entry = this.findScript(script);\\n if (!entry) entry = this.findScript($a83b9c36aaa94fd3$var$DEFAULT_SCRIPTS);\\n if (!entry) return this.scriptTag;\\n this.scriptTag = entry.tag;\\n this.script = entry.script;\\n this.language = null;\\n this.languageTag = null;\\n changed = true;\\n }\\n if (!direction || direction !== this.direction) this.direction = direction || $130d1a642ebcd2b7$export$9fddb9d0dd7d8a54(script);\\n if (language && language.length < 4) language += \\\" \\\".repeat(4 - language.length);\\n if (!language || language !== this.languageTag) {\\n this.language = null;\\n for (let lang of this.script.langSysRecords) if (lang.tag === language) {\\n this.language = lang.langSys;\\n this.languageTag = lang.tag;\\n break;\\n }\\n if (!this.language) {\\n this.language = this.script.defaultLangSys;\\n this.languageTag = null;\\n }\\n changed = true;\\n }\\n if (changed) {\\n this.features = {};\\n if (this.language) for (let featureIndex of this.language.featureIndexes) {\\n let record = this.table.featureList[featureIndex];\\n let substituteFeature = this.substituteFeatureForVariations(featureIndex);\\n this.features[record.tag] = substituteFeature || record.feature;\\n }\\n }\\n return this.scriptTag;\\n }\\n lookupsForFeatures(userFeatures = [], exclude) {\\n let lookups = [];\\n for (let tag of userFeatures) {\\n let feature = this.features[tag];\\n if (!feature) continue;\\n for (let lookupIndex of feature.lookupListIndexes) {\\n if (exclude && exclude.indexOf(lookupIndex) !== -1) continue;\\n lookups.push({\\n feature: tag,\\n index: lookupIndex,\\n lookup: this.table.lookupList.get(lookupIndex)\\n });\\n }\\n }\\n lookups.sort((a, b) => a.index - b.index);\\n return lookups;\\n }\\n substituteFeatureForVariations(featureIndex) {\\n if (this.variationsIndex === -1) return null;\\n let record = this.table.featureVariations.featureVariationRecords[this.variationsIndex];\\n let substitutions = record.featureTableSubstitution.substitutions;\\n for (let substitution of substitutions) {\\n if (substitution.featureIndex === featureIndex) return substitution.alternateFeatureTable;\\n }\\n return null;\\n }\\n findVariationsIndex(coords) {\\n let variations = this.table.featureVariations;\\n if (!variations) return -1;\\n let records = variations.featureVariationRecords;\\n for (let i = 0; i < records.length; i++) {\\n let conditions = records[i].conditionSet.conditionTable;\\n if (this.variationConditionsMatch(conditions, coords)) return i;\\n }\\n return -1;\\n }\\n variationConditionsMatch(conditions, coords) {\\n return conditions.every((condition) => {\\n let coord = condition.axisIndex < coords.length ? coords[condition.axisIndex] : 0;\\n return condition.filterRangeMinValue <= coord && coord <= condition.filterRangeMaxValue;\\n });\\n }\\n applyFeatures(userFeatures, glyphs, advances) {\\n let lookups = this.lookupsForFeatures(userFeatures);\\n this.applyLookups(lookups, glyphs, advances);\\n }\\n applyLookups(lookups, glyphs, positions) {\\n this.glyphs = glyphs;\\n this.positions = positions;\\n this.glyphIterator = new (0, $85d408632270248b$export$2e2bcd8739ae039)(glyphs);\\n for (let { feature, lookup } of lookups) {\\n this.currentFeature = feature;\\n this.glyphIterator.reset(lookup.flags);\\n while (this.glyphIterator.index < glyphs.length) {\\n if (!(feature in this.glyphIterator.cur.features)) {\\n this.glyphIterator.next();\\n continue;\\n }\\n for (let table of lookup.subTables) {\\n let res = this.applyLookup(lookup.lookupType, table);\\n if (res) break;\\n }\\n this.glyphIterator.next();\\n }\\n }\\n }\\n applyLookup(lookup, table) {\\n throw new Error(\\\"applyLookup must be implemented by subclasses\\\");\\n }\\n applyLookupList(lookupRecords) {\\n let options = this.glyphIterator.options;\\n let glyphIndex = this.glyphIterator.index;\\n for (let lookupRecord of lookupRecords) {\\n this.glyphIterator.reset(options, glyphIndex);\\n this.glyphIterator.increment(lookupRecord.sequenceIndex);\\n let lookup = this.table.lookupList.get(lookupRecord.lookupListIndex);\\n this.glyphIterator.reset(lookup.flags, this.glyphIterator.index);\\n for (let table of lookup.subTables) {\\n if (this.applyLookup(lookup.lookupType, table)) break;\\n }\\n }\\n this.glyphIterator.reset(options, glyphIndex);\\n return true;\\n }\\n coverageIndex(coverage, glyph) {\\n if (glyph == null) glyph = this.glyphIterator.cur.id;\\n switch (coverage.version) {\\n case 1:\\n return coverage.glyphs.indexOf(glyph);\\n case 2:\\n for (let range of coverage.rangeRecords) {\\n if (range.start <= glyph && glyph <= range.end) return range.startCoverageIndex + glyph - range.start;\\n }\\n break;\\n }\\n return -1;\\n }\\n match(sequenceIndex, sequence, fn, matched) {\\n let pos = this.glyphIterator.index;\\n let glyph = this.glyphIterator.increment(sequenceIndex);\\n let idx = 0;\\n while (idx < sequence.length && glyph && fn(sequence[idx], glyph)) {\\n if (matched) matched.push(this.glyphIterator.index);\\n idx++;\\n glyph = this.glyphIterator.next();\\n }\\n this.glyphIterator.index = pos;\\n if (idx < sequence.length) return false;\\n return matched || true;\\n }\\n sequenceMatches(sequenceIndex, sequence) {\\n return this.match(sequenceIndex, sequence, (component, glyph) => component === glyph.id);\\n }\\n sequenceMatchIndices(sequenceIndex, sequence) {\\n return this.match(sequenceIndex, sequence, (component, glyph) => {\\n if (!(this.currentFeature in glyph.features)) return false;\\n return component === glyph.id;\\n }, []);\\n }\\n coverageSequenceMatches(sequenceIndex, sequence) {\\n return this.match(sequenceIndex, sequence, (coverage, glyph) => this.coverageIndex(coverage, glyph.id) >= 0);\\n }\\n getClassID(glyph, classDef) {\\n switch (classDef.version) {\\n case 1:\\n let i = glyph - classDef.startGlyph;\\n if (i >= 0 && i < classDef.classValueArray.length) return classDef.classValueArray[i];\\n break;\\n case 2:\\n for (let range of classDef.classRangeRecord) {\\n if (range.start <= glyph && glyph <= range.end) return range.class;\\n }\\n break;\\n }\\n return 0;\\n }\\n classSequenceMatches(sequenceIndex, sequence, classDef) {\\n return this.match(sequenceIndex, sequence, (classID, glyph) => classID === this.getClassID(glyph.id, classDef));\\n }\\n applyContext(table) {\\n let index, set;\\n switch (table.version) {\\n case 1:\\n index = this.coverageIndex(table.coverage);\\n if (index === -1) return false;\\n set = table.ruleSets[index];\\n for (let rule of set) {\\n if (this.sequenceMatches(1, rule.input)) return this.applyLookupList(rule.lookupRecords);\\n }\\n break;\\n case 2:\\n if (this.coverageIndex(table.coverage) === -1) return false;\\n index = this.getClassID(this.glyphIterator.cur.id, table.classDef);\\n if (index === -1) return false;\\n set = table.classSet[index];\\n for (let rule of set) {\\n if (this.classSequenceMatches(1, rule.classes, table.classDef)) return this.applyLookupList(rule.lookupRecords);\\n }\\n break;\\n case 3:\\n if (this.coverageSequenceMatches(0, table.coverages)) return this.applyLookupList(table.lookupRecords);\\n break;\\n }\\n return false;\\n }\\n applyChainingContext(table) {\\n let index;\\n switch (table.version) {\\n case 1:\\n index = this.coverageIndex(table.coverage);\\n if (index === -1) return false;\\n let set = table.chainRuleSets[index];\\n for (let rule of set) {\\n if (this.sequenceMatches(-rule.backtrack.length, rule.backtrack) && this.sequenceMatches(1, rule.input) && this.sequenceMatches(1 + rule.input.length, rule.lookahead)) return this.applyLookupList(rule.lookupRecords);\\n }\\n break;\\n case 2:\\n if (this.coverageIndex(table.coverage) === -1) return false;\\n index = this.getClassID(this.glyphIterator.cur.id, table.inputClassDef);\\n let rules = table.chainClassSet[index];\\n if (!rules) return false;\\n for (let rule of rules) {\\n if (this.classSequenceMatches(-rule.backtrack.length, rule.backtrack, table.backtrackClassDef) && this.classSequenceMatches(1, rule.input, table.inputClassDef) && this.classSequenceMatches(1 + rule.input.length, rule.lookahead, table.lookaheadClassDef)) return this.applyLookupList(rule.lookupRecords);\\n }\\n break;\\n case 3:\\n if (this.coverageSequenceMatches(-table.backtrackGlyphCount, table.backtrackCoverage) && this.coverageSequenceMatches(0, table.inputCoverage) && this.coverageSequenceMatches(table.inputGlyphCount, table.lookaheadCoverage)) return this.applyLookupList(table.lookupRecords);\\n break;\\n }\\n return false;\\n }\\n constructor(font, table) {\\n this.font = font;\\n this.table = table;\\n this.script = null;\\n this.scriptTag = null;\\n this.language = null;\\n this.languageTag = null;\\n this.features = {};\\n this.lookups = {};\\n this.variationsIndex = font._variationProcessor ? this.findVariationsIndex(font._variationProcessor.normalizedCoords) : -1;\\n this.selectScript();\\n this.glyphs = [];\\n this.positions = [];\\n this.ligatureID = 1;\\n this.currentFeature = null;\\n }\\n };\\n $10e7b257e1a9a756$export$2e2bcd8739ae039 = class _$10e7b257e1a9a756$export$2e2bcd8739ae039 {\\n get id() {\\n return this._id;\\n }\\n set id(id) {\\n this._id = id;\\n this.substituted = true;\\n let GDEF = this._font.GDEF;\\n if (GDEF && GDEF.glyphClassDef) {\\n let classID = (0, $a83b9c36aaa94fd3$export$2e2bcd8739ae039).prototype.getClassID(id, GDEF.glyphClassDef);\\n this.isBase = classID === 1;\\n this.isLigature = classID === 2;\\n this.isMark = classID === 3;\\n this.markAttachmentType = GDEF.markAttachClassDef ? (0, $a83b9c36aaa94fd3$export$2e2bcd8739ae039).prototype.getClassID(id, GDEF.markAttachClassDef) : 0;\\n } else {\\n this.isMark = this.codePoints.length > 0 && this.codePoints.every((0, $747425b437e121da$export$e33ad6871e762338));\\n this.isBase = !this.isMark;\\n this.isLigature = this.codePoints.length > 1;\\n this.markAttachmentType = 0;\\n }\\n }\\n copy() {\\n return new _$10e7b257e1a9a756$export$2e2bcd8739ae039(this._font, this.id, this.codePoints, this.features);\\n }\\n constructor(font, id, codePoints = [], features) {\\n this._font = font;\\n this.codePoints = codePoints;\\n this.id = id;\\n this.features = {};\\n if (Array.isArray(features)) for (let i = 0; i < features.length; i++) {\\n let feature = features[i];\\n this.features[feature] = true;\\n }\\n else if (typeof features === \\\"object\\\") Object.assign(this.features, features);\\n this.ligatureID = null;\\n this.ligatureComponent = null;\\n this.isLigated = false;\\n this.cursiveAttachment = null;\\n this.markAttachment = null;\\n this.shaperInfo = null;\\n this.substituted = false;\\n this.isMultiplied = false;\\n }\\n };\\n $e1c6bbc8cb416f8c$export$2e2bcd8739ae039 = class extends (0, $649970d87335b30f$export$2e2bcd8739ae039) {\\n static planFeatures(plan) {\\n plan.add([\\n \\\"ljmo\\\",\\n \\\"vjmo\\\",\\n \\\"tjmo\\\"\\n ], false);\\n }\\n static assignFeatures(plan, glyphs) {\\n let state = 0;\\n let i = 0;\\n while (i < glyphs.length) {\\n let action;\\n let glyph = glyphs[i];\\n let code = glyph.codePoints[0];\\n let type = $e1c6bbc8cb416f8c$var$getType(code);\\n [action, state] = $e1c6bbc8cb416f8c$var$STATE_TABLE[state][type];\\n switch (action) {\\n case $e1c6bbc8cb416f8c$var$DECOMPOSE:\\n if (!plan.font.hasGlyphForCodePoint(code)) i = $e1c6bbc8cb416f8c$var$decompose(glyphs, i, plan.font);\\n break;\\n case $e1c6bbc8cb416f8c$var$COMPOSE:\\n i = $e1c6bbc8cb416f8c$var$compose(glyphs, i, plan.font);\\n break;\\n case $e1c6bbc8cb416f8c$var$TONE_MARK:\\n $e1c6bbc8cb416f8c$var$reorderToneMark(glyphs, i, plan.font);\\n break;\\n case $e1c6bbc8cb416f8c$var$INVALID:\\n i = $e1c6bbc8cb416f8c$var$insertDottedCircle(glyphs, i, plan.font);\\n break;\\n }\\n i++;\\n }\\n }\\n };\\n (0, _define_property)($e1c6bbc8cb416f8c$export$2e2bcd8739ae039, \\\"zeroMarkWidths\\\", \\\"NONE\\\");\\n $e1c6bbc8cb416f8c$var$HANGUL_BASE = 44032;\\n $e1c6bbc8cb416f8c$var$HANGUL_END = 55204;\\n $e1c6bbc8cb416f8c$var$HANGUL_COUNT = $e1c6bbc8cb416f8c$var$HANGUL_END - $e1c6bbc8cb416f8c$var$HANGUL_BASE + 1;\\n $e1c6bbc8cb416f8c$var$L_BASE = 4352;\\n $e1c6bbc8cb416f8c$var$V_BASE = 4449;\\n $e1c6bbc8cb416f8c$var$T_BASE = 4519;\\n $e1c6bbc8cb416f8c$var$L_COUNT = 19;\\n $e1c6bbc8cb416f8c$var$V_COUNT = 21;\\n $e1c6bbc8cb416f8c$var$T_COUNT = 28;\\n $e1c6bbc8cb416f8c$var$L_END = $e1c6bbc8cb416f8c$var$L_BASE + $e1c6bbc8cb416f8c$var$L_COUNT - 1;\\n $e1c6bbc8cb416f8c$var$V_END = $e1c6bbc8cb416f8c$var$V_BASE + $e1c6bbc8cb416f8c$var$V_COUNT - 1;\\n $e1c6bbc8cb416f8c$var$T_END = $e1c6bbc8cb416f8c$var$T_BASE + $e1c6bbc8cb416f8c$var$T_COUNT - 1;\\n $e1c6bbc8cb416f8c$var$DOTTED_CIRCLE = 9676;\\n $e1c6bbc8cb416f8c$var$isL = (code) => 4352 <= code && code <= 4447 || 43360 <= code && code <= 43388;\\n $e1c6bbc8cb416f8c$var$isV = (code) => 4448 <= code && code <= 4519 || 55216 <= code && code <= 55238;\\n $e1c6bbc8cb416f8c$var$isT = (code) => 4520 <= code && code <= 4607 || 55243 <= code && code <= 55291;\\n $e1c6bbc8cb416f8c$var$isTone = (code) => 12334 <= code && code <= 12335;\\n $e1c6bbc8cb416f8c$var$isLVT = (code) => $e1c6bbc8cb416f8c$var$HANGUL_BASE <= code && code <= $e1c6bbc8cb416f8c$var$HANGUL_END;\\n $e1c6bbc8cb416f8c$var$isLV = (code) => code - $e1c6bbc8cb416f8c$var$HANGUL_BASE < $e1c6bbc8cb416f8c$var$HANGUL_COUNT && (code - $e1c6bbc8cb416f8c$var$HANGUL_BASE) % $e1c6bbc8cb416f8c$var$T_COUNT === 0;\\n $e1c6bbc8cb416f8c$var$isCombiningL = (code) => $e1c6bbc8cb416f8c$var$L_BASE <= code && code <= $e1c6bbc8cb416f8c$var$L_END;\\n $e1c6bbc8cb416f8c$var$isCombiningV = (code) => $e1c6bbc8cb416f8c$var$V_BASE <= code && code <= $e1c6bbc8cb416f8c$var$V_END;\\n $e1c6bbc8cb416f8c$var$isCombiningT = (code) => $e1c6bbc8cb416f8c$var$T_BASE + 1 && 1 <= code && code <= $e1c6bbc8cb416f8c$var$T_END;\\n $e1c6bbc8cb416f8c$var$X = 0;\\n $e1c6bbc8cb416f8c$var$L = 1;\\n $e1c6bbc8cb416f8c$var$V = 2;\\n $e1c6bbc8cb416f8c$var$T = 3;\\n $e1c6bbc8cb416f8c$var$LV = 4;\\n $e1c6bbc8cb416f8c$var$LVT = 5;\\n $e1c6bbc8cb416f8c$var$M = 6;\\n $e1c6bbc8cb416f8c$var$NO_ACTION = 0;\\n $e1c6bbc8cb416f8c$var$DECOMPOSE = 1;\\n $e1c6bbc8cb416f8c$var$COMPOSE = 2;\\n $e1c6bbc8cb416f8c$var$TONE_MARK = 4;\\n $e1c6bbc8cb416f8c$var$INVALID = 5;\\n $e1c6bbc8cb416f8c$var$STATE_TABLE = [\\n // X L V T LV LVT M\\n // State 0: start state\\n [\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 1\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$DECOMPOSE,\\n 2\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$DECOMPOSE,\\n 3\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$INVALID,\\n 0\\n ]\\n ],\\n // State 1: <L>\\n [\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 1\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$COMPOSE,\\n 2\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$DECOMPOSE,\\n 2\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$DECOMPOSE,\\n 3\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$INVALID,\\n 0\\n ]\\n ],\\n // State 2: <L,V> or <LV>\\n [\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 1\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$COMPOSE,\\n 3\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$DECOMPOSE,\\n 2\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$DECOMPOSE,\\n 3\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$TONE_MARK,\\n 0\\n ]\\n ],\\n // State 3: <L,V,T> or <LVT>\\n [\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 1\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$NO_ACTION,\\n 0\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$DECOMPOSE,\\n 2\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$DECOMPOSE,\\n 3\\n ],\\n [\\n $e1c6bbc8cb416f8c$var$TONE_MARK,\\n 0\\n ]\\n ]\\n ];\\n $4b0735ca6c692ea5$exports = {};\\n $4b0735ca6c692ea5$exports = JSON.parse('{\\\"stateTable\\\":[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,2,3,4,5,6,7,8,9,0,10,11,11,12,13,14,15,16,17],[0,0,0,18,19,20,21,22,23,0,24,0,0,25,26,0,0,27,0],[0,0,0,28,29,30,31,32,33,0,34,0,0,35,36,0,0,37,0],[0,0,0,38,5,7,7,8,9,0,10,0,0,0,13,0,0,16,0],[0,39,0,0,0,40,41,0,9,0,10,0,0,0,42,0,39,0,0],[0,0,0,0,43,44,44,8,9,0,0,0,0,12,43,0,0,0,0],[0,0,0,0,43,44,44,8,9,0,0,0,0,0,43,0,0,0,0],[0,0,0,45,46,47,48,49,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,50,0,0,51,0,10,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,52,0,0,0,0,0,0,0,0],[0,0,0,53,54,55,56,57,58,0,59,0,0,60,61,0,0,62,0],[0,0,0,4,5,7,7,8,9,0,10,0,0,0,13,0,0,16,0],[0,63,64,0,0,40,41,0,9,0,10,0,0,0,42,0,63,0,0],[0,2,3,4,5,6,7,8,9,0,10,11,11,12,13,0,2,16,0],[0,0,0,18,65,20,21,22,23,0,24,0,0,25,26,0,0,27,0],[0,0,0,0,66,67,67,8,9,0,10,0,0,0,68,0,0,0,0],[0,0,0,69,0,70,70,0,71,0,72,0,0,0,0,0,0,0,0],[0,0,0,73,19,74,74,22,23,0,24,0,0,0,26,0,0,27,0],[0,75,0,0,0,76,77,0,23,0,24,0,0,0,78,0,75,0,0],[0,0,0,0,79,80,80,22,23,0,0,0,0,25,79,0,0,0,0],[0,0,0,18,19,20,74,22,23,0,24,0,0,25,26,0,0,27,0],[0,0,0,81,82,83,84,85,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,86,0,0,87,0,24,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0,0,0,0],[0,0,0,18,19,74,74,22,23,0,24,0,0,0,26,0,0,27,0],[0,89,90,0,0,76,77,0,23,0,24,0,0,0,78,0,89,0,0],[0,0,0,0,91,92,92,22,23,0,24,0,0,0,93,0,0,0,0],[0,0,0,94,29,95,31,32,33,0,34,0,0,0,36,0,0,37,0],[0,96,0,0,0,97,98,0,33,0,34,0,0,0,99,0,96,0,0],[0,0,0,0,100,101,101,32,33,0,0,0,0,35,100,0,0,0,0],[0,0,0,0,100,101,101,32,33,0,0,0,0,0,100,0,0,0,0],[0,0,0,102,103,104,105,106,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,107,0,0,108,0,34,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,109,0,0,0,0,0,0,0,0],[0,0,0,28,29,95,31,32,33,0,34,0,0,0,36,0,0,37,0],[0,110,111,0,0,97,98,0,33,0,34,0,0,0,99,0,110,0,0],[0,0,0,0,112,113,113,32,33,0,34,0,0,0,114,0,0,0,0],[0,0,0,0,5,7,7,8,9,0,10,0,0,0,13,0,0,16,0],[0,0,0,115,116,117,118,8,9,0,10,0,0,119,120,0,0,16,0],[0,0,0,0,0,121,121,0,9,0,10,0,0,0,42,0,0,0,0],[0,39,0,122,0,123,123,8,9,0,10,0,0,0,42,0,39,0,0],[0,124,64,0,0,0,0,0,0,0,0,0,0,0,0,0,124,0,0],[0,39,0,0,0,121,125,0,9,0,10,0,0,0,42,0,39,0,0],[0,0,0,0,0,126,126,8,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,46,47,48,49,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,47,47,49,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,127,127,49,9,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,128,127,127,49,9,0,0,0,0,0,0,0,0,0,0],[0,0,0,129,130,131,132,133,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0],[0,0,0,0,0,50,0,0,0,0,10,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,134,0,0,0,0,0,0,0,0],[0,0,0,135,54,56,56,57,58,0,59,0,0,0,61,0,0,62,0],[0,136,0,0,0,137,138,0,58,0,59,0,0,0,139,0,136,0,0],[0,0,0,0,140,141,141,57,58,0,0,0,0,60,140,0,0,0,0],[0,0,0,0,140,141,141,57,58,0,0,0,0,0,140,0,0,0,0],[0,0,0,142,143,144,145,146,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,147,0,0,148,0,59,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,149,0,0,0,0,0,0,0,0],[0,0,0,53,54,56,56,57,58,0,59,0,0,0,61,0,0,62,0],[0,150,151,0,0,137,138,0,58,0,59,0,0,0,139,0,150,0,0],[0,0,0,0,152,153,153,57,58,0,59,0,0,0,154,0,0,0,0],[0,0,0,155,116,156,157,8,9,0,10,0,0,158,120,0,0,16,0],[0,0,0,0,0,121,121,0,9,0,10,0,0,0,0,0,0,0,0],[0,75,3,4,5,159,160,8,161,0,162,0,11,12,163,0,75,16,0],[0,0,0,0,0,40,164,0,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,165,44,44,8,9,0,0,0,0,0,165,0,0,0,0],[0,124,64,0,0,40,164,0,9,0,10,0,0,0,42,0,124,0,0],[0,0,0,0,0,70,70,0,71,0,72,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,71,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,166,0,0,167,0,72,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,168,0,0,0,0,0,0,0,0],[0,0,0,0,19,74,74,22,23,0,24,0,0,0,26,0,0,27,0],[0,0,0,0,79,80,80,22,23,0,0,0,0,0,79,0,0,0,0],[0,0,0,169,170,171,172,22,23,0,24,0,0,173,174,0,0,27,0],[0,0,0,0,0,175,175,0,23,0,24,0,0,0,78,0,0,0,0],[0,75,0,176,0,177,177,22,23,0,24,0,0,0,78,0,75,0,0],[0,178,90,0,0,0,0,0,0,0,0,0,0,0,0,0,178,0,0],[0,75,0,0,0,175,179,0,23,0,24,0,0,0,78,0,75,0,0],[0,0,0,0,0,180,180,22,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,82,83,84,85,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,83,83,85,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,181,181,85,23,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,182,181,181,85,23,0,0,0,0,0,0,0,0,0,0],[0,0,0,183,184,185,186,187,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0],[0,0,0,0,0,86,0,0,0,0,24,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,188,0,0,0,0,0,0,0,0],[0,0,0,189,170,190,191,22,23,0,24,0,0,192,174,0,0,27,0],[0,0,0,0,0,175,175,0,23,0,24,0,0,0,0,0,0,0,0],[0,0,0,0,0,76,193,0,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,194,80,80,22,23,0,0,0,0,0,194,0,0,0,0],[0,178,90,0,0,76,193,0,23,0,24,0,0,0,78,0,178,0,0],[0,0,0,0,29,95,31,32,33,0,34,0,0,0,36,0,0,37,0],[0,0,0,0,100,101,101,32,33,0,0,0,0,0,100,0,0,0,0],[0,0,0,195,196,197,198,32,33,0,34,0,0,199,200,0,0,37,0],[0,0,0,0,0,201,201,0,33,0,34,0,0,0,99,0,0,0,0],[0,96,0,202,0,203,203,32,33,0,34,0,0,0,99,0,96,0,0],[0,204,111,0,0,0,0,0,0,0,0,0,0,0,0,0,204,0,0],[0,96,0,0,0,201,205,0,33,0,34,0,0,0,99,0,96,0,0],[0,0,0,0,0,206,206,32,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,103,104,105,106,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,104,104,106,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,207,207,106,33,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,208,207,207,106,33,0,0,0,0,0,0,0,0,0,0],[0,0,0,209,210,211,212,213,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,34,0,0,0,0,0,0,0,0],[0,0,0,0,0,107,0,0,0,0,34,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,214,0,0,0,0,0,0,0,0],[0,0,0,215,196,216,217,32,33,0,34,0,0,218,200,0,0,37,0],[0,0,0,0,0,201,201,0,33,0,34,0,0,0,0,0,0,0,0],[0,0,0,0,0,97,219,0,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,220,101,101,32,33,0,0,0,0,0,220,0,0,0,0],[0,204,111,0,0,97,219,0,33,0,34,0,0,0,99,0,204,0,0],[0,0,0,221,116,222,222,8,9,0,10,0,0,0,120,0,0,16,0],[0,223,0,0,0,40,224,0,9,0,10,0,0,0,42,0,223,0,0],[0,0,0,0,225,44,44,8,9,0,0,0,0,119,225,0,0,0,0],[0,0,0,115,116,117,222,8,9,0,10,0,0,119,120,0,0,16,0],[0,0,0,115,116,222,222,8,9,0,10,0,0,0,120,0,0,16,0],[0,226,64,0,0,40,224,0,9,0,10,0,0,0,42,0,226,0,0],[0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0],[0,39,0,0,0,121,121,0,9,0,10,0,0,0,42,0,39,0,0],[0,0,0,0,0,44,44,8,9,0,0,0,0,0,0,0,0,0,0],[0,0,0,227,0,228,229,0,9,0,10,0,0,230,0,0,0,0,0],[0,39,0,122,0,121,121,0,9,0,10,0,0,0,42,0,39,0,0],[0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,231,231,49,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,232,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,130,131,132,133,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,131,131,133,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,233,233,133,9,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,234,233,233,133,9,0,0,0,0,0,0,0,0,0,0],[0,0,0,235,236,237,238,239,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,54,56,56,57,58,0,59,0,0,0,61,0,0,62,0],[0,0,0,240,241,242,243,57,58,0,59,0,0,244,245,0,0,62,0],[0,0,0,0,0,246,246,0,58,0,59,0,0,0,139,0,0,0,0],[0,136,0,247,0,248,248,57,58,0,59,0,0,0,139,0,136,0,0],[0,249,151,0,0,0,0,0,0,0,0,0,0,0,0,0,249,0,0],[0,136,0,0,0,246,250,0,58,0,59,0,0,0,139,0,136,0,0],[0,0,0,0,0,251,251,57,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,143,144,145,146,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,144,144,146,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,252,252,146,58,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,253,252,252,146,58,0,0,0,0,0,0,0,0,0,0],[0,0,0,254,255,256,257,258,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,59,0,0,0,0,0,0,0,0],[0,0,0,0,0,147,0,0,0,0,59,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,259,0,0,0,0,0,0,0,0],[0,0,0,260,241,261,262,57,58,0,59,0,0,263,245,0,0,62,0],[0,0,0,0,0,246,246,0,58,0,59,0,0,0,0,0,0,0,0],[0,0,0,0,0,137,264,0,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,265,141,141,57,58,0,0,0,0,0,265,0,0,0,0],[0,249,151,0,0,137,264,0,58,0,59,0,0,0,139,0,249,0,0],[0,0,0,221,116,222,222,8,9,0,10,0,0,0,120,0,0,16,0],[0,0,0,0,225,44,44,8,9,0,0,0,0,158,225,0,0,0,0],[0,0,0,155,116,156,222,8,9,0,10,0,0,158,120,0,0,16,0],[0,0,0,155,116,222,222,8,9,0,10,0,0,0,120,0,0,16,0],[0,0,0,0,43,266,266,8,161,0,24,0,0,12,267,0,0,0,0],[0,75,0,176,43,268,268,269,161,0,24,0,0,0,267,0,75,0,0],[0,0,0,0,0,270,0,0,271,0,162,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,272,0,0,0,0,0,0,0,0],[0,273,274,0,0,40,41,0,9,0,10,0,0,0,42,0,273,0,0],[0,0,0,40,0,123,123,8,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,121,275,0,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,72,0,0,0,0,0,0,0,0],[0,0,0,0,0,166,0,0,0,0,72,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,276,0,0,0,0,0,0,0,0],[0,0,0,277,170,278,278,22,23,0,24,0,0,0,174,0,0,27,0],[0,279,0,0,0,76,280,0,23,0,24,0,0,0,78,0,279,0,0],[0,0,0,0,281,80,80,22,23,0,0,0,0,173,281,0,0,0,0],[0,0,0,169,170,171,278,22,23,0,24,0,0,173,174,0,0,27,0],[0,0,0,169,170,278,278,22,23,0,24,0,0,0,174,0,0,27,0],[0,282,90,0,0,76,280,0,23,0,24,0,0,0,78,0,282,0,0],[0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0],[0,75,0,0,0,175,175,0,23,0,24,0,0,0,78,0,75,0,0],[0,0,0,0,0,80,80,22,23,0,0,0,0,0,0,0,0,0,0],[0,0,0,283,0,284,285,0,23,0,24,0,0,286,0,0,0,0,0],[0,75,0,176,0,175,175,0,23,0,24,0,0,0,78,0,75,0,0],[0,0,0,0,0,0,0,22,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,287,287,85,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,288,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,184,185,186,187,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,185,185,187,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,289,289,187,23,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,290,289,289,187,23,0,0,0,0,0,0,0,0,0,0],[0,0,0,291,292,293,294,295,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,277,170,278,278,22,23,0,24,0,0,0,174,0,0,27,0],[0,0,0,0,281,80,80,22,23,0,0,0,0,192,281,0,0,0,0],[0,0,0,189,170,190,278,22,23,0,24,0,0,192,174,0,0,27,0],[0,0,0,189,170,278,278,22,23,0,24,0,0,0,174,0,0,27,0],[0,0,0,76,0,177,177,22,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,175,296,0,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,297,196,298,298,32,33,0,34,0,0,0,200,0,0,37,0],[0,299,0,0,0,97,300,0,33,0,34,0,0,0,99,0,299,0,0],[0,0,0,0,301,101,101,32,33,0,0,0,0,199,301,0,0,0,0],[0,0,0,195,196,197,298,32,33,0,34,0,0,199,200,0,0,37,0],[0,0,0,195,196,298,298,32,33,0,34,0,0,0,200,0,0,37,0],[0,302,111,0,0,97,300,0,33,0,34,0,0,0,99,0,302,0,0],[0,0,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0],[0,96,0,0,0,201,201,0,33,0,34,0,0,0,99,0,96,0,0],[0,0,0,0,0,101,101,32,33,0,0,0,0,0,0,0,0,0,0],[0,0,0,303,0,304,305,0,33,0,34,0,0,306,0,0,0,0,0],[0,96,0,202,0,201,201,0,33,0,34,0,0,0,99,0,96,0,0],[0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,307,307,106,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,308,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,210,211,212,213,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,211,211,213,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,309,309,213,33,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,310,309,309,213,33,0,0,0,0,0,0,0,0,0,0],[0,0,0,311,312,313,314,315,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,297,196,298,298,32,33,0,34,0,0,0,200,0,0,37,0],[0,0,0,0,301,101,101,32,33,0,0,0,0,218,301,0,0,0,0],[0,0,0,215,196,216,298,32,33,0,34,0,0,218,200,0,0,37,0],[0,0,0,215,196,298,298,32,33,0,34,0,0,0,200,0,0,37,0],[0,0,0,97,0,203,203,32,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,201,316,0,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,116,222,222,8,9,0,10,0,0,0,120,0,0,16,0],[0,0,0,0,225,44,44,8,9,0,0,0,0,0,225,0,0,0,0],[0,0,0,317,318,319,320,8,9,0,10,0,0,321,322,0,0,16,0],[0,223,0,323,0,123,123,8,9,0,10,0,0,0,42,0,223,0,0],[0,223,0,0,0,121,324,0,9,0,10,0,0,0,42,0,223,0,0],[0,0,0,325,318,326,327,8,9,0,10,0,0,328,322,0,0,16,0],[0,0,0,64,0,121,121,0,9,0,10,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,9,0,0,0,0,230,0,0,0,0,0],[0,0,0,227,0,228,121,0,9,0,10,0,0,230,0,0,0,0,0],[0,0,0,227,0,121,121,0,9,0,10,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,0,0],[0,0,0,0,0,329,329,133,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,330,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,236,237,238,239,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,237,237,239,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,331,331,239,9,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,332,331,331,239,9,0,0,0,0,0,0,0,0,0,0],[0,0,0,333,40,121,334,0,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,335,241,336,336,57,58,0,59,0,0,0,245,0,0,62,0],[0,337,0,0,0,137,338,0,58,0,59,0,0,0,139,0,337,0,0],[0,0,0,0,339,141,141,57,58,0,0,0,0,244,339,0,0,0,0],[0,0,0,240,241,242,336,57,58,0,59,0,0,244,245,0,0,62,0],[0,0,0,240,241,336,336,57,58,0,59,0,0,0,245,0,0,62,0],[0,340,151,0,0,137,338,0,58,0,59,0,0,0,139,0,340,0,0],[0,0,0,0,0,0,0,0,58,0,0,0,0,0,0,0,0,0,0],[0,136,0,0,0,246,246,0,58,0,59,0,0,0,139,0,136,0,0],[0,0,0,0,0,141,141,57,58,0,0,0,0,0,0,0,0,0,0],[0,0,0,341,0,342,343,0,58,0,59,0,0,344,0,0,0,0,0],[0,136,0,247,0,246,246,0,58,0,59,0,0,0,139,0,136,0,0],[0,0,0,0,0,0,0,57,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,345,345,146,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,346,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,255,256,257,258,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,256,256,258,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,347,347,258,58,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,348,347,347,258,58,0,0,0,0,0,0,0,0,0,0],[0,0,0,349,350,351,352,353,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,335,241,336,336,57,58,0,59,0,0,0,245,0,0,62,0],[0,0,0,0,339,141,141,57,58,0,0,0,0,263,339,0,0,0,0],[0,0,0,260,241,261,336,57,58,0,59,0,0,263,245,0,0,62,0],[0,0,0,260,241,336,336,57,58,0,59,0,0,0,245,0,0,62,0],[0,0,0,137,0,248,248,57,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,246,354,0,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,126,126,8,23,0,0,0,0,0,0,0,0,0,0],[0,355,90,0,0,121,125,0,9,0,10,0,0,0,42,0,355,0,0],[0,0,0,0,0,356,356,269,23,0,0,0,0,0,0,0,0,0,0],[0,0,0,357,358,359,360,361,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,162,0,0,0,0,0,0,0,0],[0,0,0,0,0,270,0,0,0,0,162,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,363,0,0,0,0,0,0,0,0],[0,0,0,364,116,365,366,8,161,0,162,0,0,367,120,0,0,16,0],[0,0,0,0,0,368,368,0,161,0,162,0,0,0,0,0,0,0,0],[0,0,0,40,0,121,121,0,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,170,278,278,22,23,0,24,0,0,0,174,0,0,27,0],[0,0,0,0,281,80,80,22,23,0,0,0,0,0,281,0,0,0,0],[0,0,0,369,370,371,372,22,23,0,24,0,0,373,374,0,0,27,0],[0,279,0,375,0,177,177,22,23,0,24,0,0,0,78,0,279,0,0],[0,279,0,0,0,175,376,0,23,0,24,0,0,0,78,0,279,0,0],[0,0,0,377,370,378,379,22,23,0,24,0,0,380,374,0,0,27,0],[0,0,0,90,0,175,175,0,23,0,24,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,23,0,0,0,0,286,0,0,0,0,0],[0,0,0,283,0,284,175,0,23,0,24,0,0,286,0,0,0,0,0],[0,0,0,283,0,175,175,0,23,0,24,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,85,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,82,0,0],[0,0,0,0,0,381,381,187,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,382,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,292,293,294,295,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,293,293,295,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,0,383,383,295,23,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,384,383,383,295,23,0,0,0,0,0,0,0,0,0,0],[0,0,0,385,76,175,386,0,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,76,0,175,175,0,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,196,298,298,32,33,0,34,0,0,0,200,0,0,37,0],[0,0,0,0,301,101,101,32,33,0,0,0,0,0,301,0,0,0,0],[0,0,0,387,388,389,390,32,33,0,34,0,0,391,392,0,0,37,0],[0,299,0,393,0,203,203,32,33,0,34,0,0,0,99,0,299,0,0],[0,299,0,0,0,201,394,0,33,0,34,0,0,0,99,0,299,0,0],[0,0,0,395,388,396,397,32,33,0,34,0,0,398,392,0,0,37,0],[0,0,0,111,0,201,201,0,33,0,34,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,33,0,0,0,0,306,0,0,0,0,0],[0,0,0,303,0,304,201,0,33,0,34,0,0,306,0,0,0,0,0],[0,0,0,303,0,201,201,0,33,0,34,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,106,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,0,0],[0,0,0,0,0,399,399,213,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,400,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,312,313,314,315,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,313,313,315,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,0,401,401,315,33,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,402,401,401,315,33,0,0,0,0,0,0,0,0,0,0],[0,0,0,403,97,201,404,0,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,97,0,201,201,0,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,405,318,406,406,8,9,0,10,0,0,0,322,0,0,16,0],[0,407,0,0,0,40,408,0,9,0,10,0,0,0,42,0,407,0,0],[0,0,0,0,409,44,44,8,9,0,0,0,0,321,409,0,0,0,0],[0,0,0,317,318,319,406,8,9,0,10,0,0,321,322,0,0,16,0],[0,0,0,317,318,406,406,8,9,0,10,0,0,0,322,0,0,16,0],[0,410,64,0,0,40,408,0,9,0,10,0,0,0,42,0,410,0,0],[0,223,0,0,0,121,121,0,9,0,10,0,0,0,42,0,223,0,0],[0,223,0,323,0,121,121,0,9,0,10,0,0,0,42,0,223,0,0],[0,0,0,405,318,406,406,8,9,0,10,0,0,0,322,0,0,16,0],[0,0,0,0,409,44,44,8,9,0,0,0,0,328,409,0,0,0,0],[0,0,0,325,318,326,406,8,9,0,10,0,0,328,322,0,0,16,0],[0,0,0,325,318,406,406,8,9,0,10,0,0,0,322,0,0,16,0],[0,0,0,0,0,0,0,133,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130,0,0],[0,0,0,0,0,411,411,239,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,40,121,334,0,9,0,10,0,0,0,42,0,0,0,0],[0,0,0,0,413,0,0,0,9,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,241,336,336,57,58,0,59,0,0,0,245,0,0,62,0],[0,0,0,0,339,141,141,57,58,0,0,0,0,0,339,0,0,0,0],[0,0,0,414,415,416,417,57,58,0,59,0,0,418,419,0,0,62,0],[0,337,0,420,0,248,248,57,58,0,59,0,0,0,139,0,337,0,0],[0,337,0,0,0,246,421,0,58,0,59,0,0,0,139,0,337,0,0],[0,0,0,422,415,423,424,57,58,0,59,0,0,425,419,0,0,62,0],[0,0,0,151,0,246,246,0,58,0,59,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,58,0,0,0,0,344,0,0,0,0,0],[0,0,0,341,0,342,246,0,58,0,59,0,0,344,0,0,0,0,0],[0,0,0,341,0,246,246,0,58,0,59,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,146,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,143,0,0],[0,0,0,0,0,426,426,258,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,427,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,350,351,352,353,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,351,351,353,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,0,428,428,353,58,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,429,428,428,353,58,0,0,0,0,0,0,0,0,0,0],[0,0,0,430,137,246,431,0,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,137,0,246,246,0,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,432,116,433,434,8,161,0,162,0,0,435,120,0,0,16,0],[0,0,0,0,0,180,180,269,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,358,359,360,361,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,0,0,359,359,361,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,0,0,436,436,361,161,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,437,436,436,361,161,0,0,0,0,0,0,0,0,0,0],[0,0,0,438,439,440,441,442,161,0,162,0,0,0,362,0,0,0,0],[0,443,274,0,0,0,0,0,0,0,0,0,0,0,0,0,443,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,444,116,445,445,8,161,0,162,0,0,0,120,0,0,16,0],[0,0,0,0,225,44,44,8,161,0,0,0,0,367,225,0,0,0,0],[0,0,0,364,116,365,445,8,161,0,162,0,0,367,120,0,0,16,0],[0,0,0,364,116,445,445,8,161,0,162,0,0,0,120,0,0,16,0],[0,0,0,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0],[0,0,0,446,370,447,447,22,23,0,24,0,0,0,374,0,0,27,0],[0,448,0,0,0,76,449,0,23,0,24,0,0,0,78,0,448,0,0],[0,0,0,0,450,80,80,22,23,0,0,0,0,373,450,0,0,0,0],[0,0,0,369,370,371,447,22,23,0,24,0,0,373,374,0,0,27,0],[0,0,0,369,370,447,447,22,23,0,24,0,0,0,374,0,0,27,0],[0,451,90,0,0,76,449,0,23,0,24,0,0,0,78,0,451,0,0],[0,279,0,0,0,175,175,0,23,0,24,0,0,0,78,0,279,0,0],[0,279,0,375,0,175,175,0,23,0,24,0,0,0,78,0,279,0,0],[0,0,0,446,370,447,447,22,23,0,24,0,0,0,374,0,0,27,0],[0,0,0,0,450,80,80,22,23,0,0,0,0,380,450,0,0,0,0],[0,0,0,377,370,378,447,22,23,0,24,0,0,380,374,0,0,27,0],[0,0,0,377,370,447,447,22,23,0,24,0,0,0,374,0,0,27,0],[0,0,0,0,0,0,0,187,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,0,0],[0,0,0,0,0,452,452,295,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,453,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,76,175,386,0,23,0,24,0,0,0,78,0,0,0,0],[0,0,0,0,454,0,0,0,23,0,0,0,0,0,0,0,0,0,0],[0,0,0,455,388,456,456,32,33,0,34,0,0,0,392,0,0,37,0],[0,457,0,0,0,97,458,0,33,0,34,0,0,0,99,0,457,0,0],[0,0,0,0,459,101,101,32,33,0,0,0,0,391,459,0,0,0,0],[0,0,0,387,388,389,456,32,33,0,34,0,0,391,392,0,0,37,0],[0,0,0,387,388,456,456,32,33,0,34,0,0,0,392,0,0,37,0],[0,460,111,0,0,97,458,0,33,0,34,0,0,0,99,0,460,0,0],[0,299,0,0,0,201,201,0,33,0,34,0,0,0,99,0,299,0,0],[0,299,0,393,0,201,201,0,33,0,34,0,0,0,99,0,299,0,0],[0,0,0,455,388,456,456,32,33,0,34,0,0,0,392,0,0,37,0],[0,0,0,0,459,101,101,32,33,0,0,0,0,398,459,0,0,0,0],[0,0,0,395,388,396,456,32,33,0,34,0,0,398,392,0,0,37,0],[0,0,0,395,388,456,456,32,33,0,34,0,0,0,392,0,0,37,0],[0,0,0,0,0,0,0,213,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,210,0,0],[0,0,0,0,0,461,461,315,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,462,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,97,201,404,0,33,0,34,0,0,0,99,0,0,0,0],[0,0,0,0,463,0,0,0,33,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,318,406,406,8,9,0,10,0,0,0,322,0,0,16,0],[0,0,0,0,409,44,44,8,9,0,0,0,0,0,409,0,0,0,0],[0,0,0,464,465,466,467,8,9,0,10,0,0,468,469,0,0,16,0],[0,407,0,470,0,123,123,8,9,0,10,0,0,0,42,0,407,0,0],[0,407,0,0,0,121,471,0,9,0,10,0,0,0,42,0,407,0,0],[0,0,0,472,465,473,474,8,9,0,10,0,0,475,469,0,0,16,0],[0,0,0,0,0,0,0,239,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,236,0,0],[0,0,0,0,0,0,476,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,477,415,478,478,57,58,0,59,0,0,0,419,0,0,62,0],[0,479,0,0,0,137,480,0,58,0,59,0,0,0,139,0,479,0,0],[0,0,0,0,481,141,141,57,58,0,0,0,0,418,481,0,0,0,0],[0,0,0,414,415,416,478,57,58,0,59,0,0,418,419,0,0,62,0],[0,0,0,414,415,478,478,57,58,0,59,0,0,0,419,0,0,62,0],[0,482,151,0,0,137,480,0,58,0,59,0,0,0,139,0,482,0,0],[0,337,0,0,0,246,246,0,58,0,59,0,0,0,139,0,337,0,0],[0,337,0,420,0,246,246,0,58,0,59,0,0,0,139,0,337,0,0],[0,0,0,477,415,478,478,57,58,0,59,0,0,0,419,0,0,62,0],[0,0,0,0,481,141,141,57,58,0,0,0,0,425,481,0,0,0,0],[0,0,0,422,415,423,478,57,58,0,59,0,0,425,419,0,0,62,0],[0,0,0,422,415,478,478,57,58,0,59,0,0,0,419,0,0,62,0],[0,0,0,0,0,0,0,258,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0],[0,0,0,0,0,483,483,353,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,484,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,137,246,431,0,58,0,59,0,0,0,139,0,0,0,0],[0,0,0,0,485,0,0,0,58,0,0,0,0,0,0,0,0,0,0],[0,0,0,444,116,445,445,8,161,0,162,0,0,0,120,0,0,16,0],[0,0,0,0,225,44,44,8,161,0,0,0,0,435,225,0,0,0,0],[0,0,0,432,116,433,445,8,161,0,162,0,0,435,120,0,0,16,0],[0,0,0,432,116,445,445,8,161,0,162,0,0,0,120,0,0,16,0],[0,0,0,0,0,486,486,361,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,487,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,439,440,441,442,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,0,0,440,440,442,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,0,0,488,488,442,161,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,489,488,488,442,161,0,0,0,0,0,0,0,0,0,0],[0,0,0,490,491,492,493,494,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,495,0,496,497,0,161,0,162,0,0,498,0,0,0,0,0],[0,0,0,0,116,445,445,8,161,0,162,0,0,0,120,0,0,16,0],[0,0,0,0,225,44,44,8,161,0,0,0,0,0,225,0,0,0,0],[0,0,0,0,370,447,447,22,23,0,24,0,0,0,374,0,0,27,0],[0,0,0,0,450,80,80,22,23,0,0,0,0,0,450,0,0,0,0],[0,0,0,499,500,501,502,22,23,0,24,0,0,503,504,0,0,27,0],[0,448,0,505,0,177,177,22,23,0,24,0,0,0,78,0,448,0,0],[0,448,0,0,0,175,506,0,23,0,24,0,0,0,78,0,448,0,0],[0,0,0,507,500,508,509,22,23,0,24,0,0,510,504,0,0,27,0],[0,0,0,0,0,0,0,295,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,292,0,0],[0,0,0,0,0,0,511,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,388,456,456,32,33,0,34,0,0,0,392,0,0,37,0],[0,0,0,0,459,101,101,32,33,0,0,0,0,0,459,0,0,0,0],[0,0,0,512,513,514,515,32,33,0,34,0,0,516,517,0,0,37,0],[0,457,0,518,0,203,203,32,33,0,34,0,0,0,99,0,457,0,0],[0,457,0,0,0,201,519,0,33,0,34,0,0,0,99,0,457,0,0],[0,0,0,520,513,521,522,32,33,0,34,0,0,523,517,0,0,37,0],[0,0,0,0,0,0,0,315,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,312,0,0],[0,0,0,0,0,0,524,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,525,465,526,526,8,9,0,10,0,0,0,469,0,0,16,0],[0,527,0,0,0,40,528,0,9,0,10,0,0,0,42,0,527,0,0],[0,0,0,0,529,44,44,8,9,0,0,0,0,468,529,0,0,0,0],[0,0,0,464,465,466,526,8,9,0,10,0,0,468,469,0,0,16,0],[0,0,0,464,465,526,526,8,9,0,10,0,0,0,469,0,0,16,0],[0,530,64,0,0,40,528,0,9,0,10,0,0,0,42,0,530,0,0],[0,407,0,0,0,121,121,0,9,0,10,0,0,0,42,0,407,0,0],[0,407,0,470,0,121,121,0,9,0,10,0,0,0,42,0,407,0,0],[0,0,0,525,465,526,526,8,9,0,10,0,0,0,469,0,0,16,0],[0,0,0,0,529,44,44,8,9,0,0,0,0,475,529,0,0,0,0],[0,0,0,472,465,473,526,8,9,0,10,0,0,475,469,0,0,16,0],[0,0,0,472,465,526,526,8,9,0,10,0,0,0,469,0,0,16,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,0,0],[0,0,0,0,415,478,478,57,58,0,59,0,0,0,419,0,0,62,0],[0,0,0,0,481,141,141,57,58,0,0,0,0,0,481,0,0,0,0],[0,0,0,531,532,533,534,57,58,0,59,0,0,535,536,0,0,62,0],[0,479,0,537,0,248,248,57,58,0,59,0,0,0,139,0,479,0,0],[0,479,0,0,0,246,538,0,58,0,59,0,0,0,139,0,479,0,0],[0,0,0,539,532,540,541,57,58,0,59,0,0,542,536,0,0,62,0],[0,0,0,0,0,0,0,353,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,350,0,0],[0,0,0,0,0,0,543,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,361,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,358,0,0],[0,0,0,0,0,544,544,442,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,545,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,491,492,493,494,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,0,0,492,492,494,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,0,0,546,546,494,161,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,547,546,546,494,161,0,0,0,0,0,0,0,0,0,0],[0,0,0,548,549,368,550,0,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,274,0,368,368,0,161,0,162,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,161,0,0,0,0,498,0,0,0,0,0],[0,0,0,495,0,496,368,0,161,0,162,0,0,498,0,0,0,0,0],[0,0,0,495,0,368,368,0,161,0,162,0,0,0,0,0,0,0,0],[0,0,0,551,500,552,552,22,23,0,24,0,0,0,504,0,0,27,0],[0,553,0,0,0,76,554,0,23,0,24,0,0,0,78,0,553,0,0],[0,0,0,0,555,80,80,22,23,0,0,0,0,503,555,0,0,0,0],[0,0,0,499,500,501,552,22,23,0,24,0,0,503,504,0,0,27,0],[0,0,0,499,500,552,552,22,23,0,24,0,0,0,504,0,0,27,0],[0,556,90,0,0,76,554,0,23,0,24,0,0,0,78,0,556,0,0],[0,448,0,0,0,175,175,0,23,0,24,0,0,0,78,0,448,0,0],[0,448,0,505,0,175,175,0,23,0,24,0,0,0,78,0,448,0,0],[0,0,0,551,500,552,552,22,23,0,24,0,0,0,504,0,0,27,0],[0,0,0,0,555,80,80,22,23,0,0,0,0,510,555,0,0,0,0],[0,0,0,507,500,508,552,22,23,0,24,0,0,510,504,0,0,27,0],[0,0,0,507,500,552,552,22,23,0,24,0,0,0,504,0,0,27,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,0,0],[0,0,0,557,513,558,558,32,33,0,34,0,0,0,517,0,0,37,0],[0,559,0,0,0,97,560,0,33,0,34,0,0,0,99,0,559,0,0],[0,0,0,0,561,101,101,32,33,0,0,0,0,516,561,0,0,0,0],[0,0,0,512,513,514,558,32,33,0,34,0,0,516,517,0,0,37,0],[0,0,0,512,513,558,558,32,33,0,34,0,0,0,517,0,0,37,0],[0,562,111,0,0,97,560,0,33,0,34,0,0,0,99,0,562,0,0],[0,457,0,0,0,201,201,0,33,0,34,0,0,0,99,0,457,0,0],[0,457,0,518,0,201,201,0,33,0,34,0,0,0,99,0,457,0,0],[0,0,0,557,513,558,558,32,33,0,34,0,0,0,517,0,0,37,0],[0,0,0,0,561,101,101,32,33,0,0,0,0,523,561,0,0,0,0],[0,0,0,520,513,521,558,32,33,0,34,0,0,523,517,0,0,37,0],[0,0,0,520,513,558,558,32,33,0,34,0,0,0,517,0,0,37,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,0,0],[0,0,0,0,465,526,526,8,9,0,10,0,0,0,469,0,0,16,0],[0,0,0,0,529,44,44,8,9,0,0,0,0,0,529,0,0,0,0],[0,0,0,563,66,564,565,8,9,0,10,0,0,566,68,0,0,16,0],[0,527,0,567,0,123,123,8,9,0,10,0,0,0,42,0,527,0,0],[0,527,0,0,0,121,568,0,9,0,10,0,0,0,42,0,527,0,0],[0,0,0,569,66,570,571,8,9,0,10,0,0,572,68,0,0,16,0],[0,0,0,573,532,574,574,57,58,0,59,0,0,0,536,0,0,62,0],[0,575,0,0,0,137,576,0,58,0,59,0,0,0,139,0,575,0,0],[0,0,0,0,577,141,141,57,58,0,0,0,0,535,577,0,0,0,0],[0,0,0,531,532,533,574,57,58,0,59,0,0,535,536,0,0,62,0],[0,0,0,531,532,574,574,57,58,0,59,0,0,0,536,0,0,62,0],[0,578,151,0,0,137,576,0,58,0,59,0,0,0,139,0,578,0,0],[0,479,0,0,0,246,246,0,58,0,59,0,0,0,139,0,479,0,0],[0,479,0,537,0,246,246,0,58,0,59,0,0,0,139,0,479,0,0],[0,0,0,573,532,574,574,57,58,0,59,0,0,0,536,0,0,62,0],[0,0,0,0,577,141,141,57,58,0,0,0,0,542,577,0,0,0,0],[0,0,0,539,532,540,574,57,58,0,59,0,0,542,536,0,0,62,0],[0,0,0,539,532,574,574,57,58,0,59,0,0,0,536,0,0,62,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,137,0,0],[0,0,0,0,0,0,0,442,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,439,0,0],[0,0,0,0,0,579,579,494,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,580,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,549,368,550,0,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,0,0,368,368,0,161,0,162,0,0,0,362,0,0,0,0],[0,0,0,0,581,0,0,0,161,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,500,552,552,22,23,0,24,0,0,0,504,0,0,27,0],[0,0,0,0,555,80,80,22,23,0,0,0,0,0,555,0,0,0,0],[0,0,0,582,91,583,584,22,23,0,24,0,0,585,93,0,0,27,0],[0,553,0,586,0,177,177,22,23,0,24,0,0,0,78,0,553,0,0],[0,553,0,0,0,175,587,0,23,0,24,0,0,0,78,0,553,0,0],[0,0,0,588,91,589,590,22,23,0,24,0,0,591,93,0,0,27,0],[0,0,0,0,513,558,558,32,33,0,34,0,0,0,517,0,0,37,0],[0,0,0,0,561,101,101,32,33,0,0,0,0,0,561,0,0,0,0],[0,0,0,592,112,593,594,32,33,0,34,0,0,595,114,0,0,37,0],[0,559,0,596,0,203,203,32,33,0,34,0,0,0,99,0,559,0,0],[0,559,0,0,0,201,597,0,33,0,34,0,0,0,99,0,559,0,0],[0,0,0,598,112,599,600,32,33,0,34,0,0,601,114,0,0,37,0],[0,0,0,602,66,67,67,8,9,0,10,0,0,0,68,0,0,16,0],[0,0,0,0,165,44,44,8,9,0,0,0,0,566,165,0,0,0,0],[0,0,0,563,66,564,67,8,9,0,10,0,0,566,68,0,0,16,0],[0,0,0,563,66,67,67,8,9,0,10,0,0,0,68,0,0,16,0],[0,527,0,0,0,121,121,0,9,0,10,0,0,0,42,0,527,0,0],[0,527,0,567,0,121,121,0,9,0,10,0,0,0,42,0,527,0,0],[0,0,0,602,66,67,67,8,9,0,10,0,0,0,68,0,0,16,0],[0,0,0,0,165,44,44,8,9,0,0,0,0,572,165,0,0,0,0],[0,0,0,569,66,570,67,8,9,0,10,0,0,572,68,0,0,16,0],[0,0,0,569,66,67,67,8,9,0,10,0,0,0,68,0,0,16,0],[0,0,0,0,532,574,574,57,58,0,59,0,0,0,536,0,0,62,0],[0,0,0,0,577,141,141,57,58,0,0,0,0,0,577,0,0,0,0],[0,0,0,603,152,604,605,57,58,0,59,0,0,606,154,0,0,62,0],[0,575,0,607,0,248,248,57,58,0,59,0,0,0,139,0,575,0,0],[0,575,0,0,0,246,608,0,58,0,59,0,0,0,139,0,575,0,0],[0,0,0,609,152,610,611,57,58,0,59,0,0,612,154,0,0,62,0],[0,0,0,0,0,0,0,494,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,491,0,0],[0,0,0,0,0,0,613,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,614,91,92,92,22,23,0,24,0,0,0,93,0,0,27,0],[0,0,0,0,194,80,80,22,23,0,0,0,0,585,194,0,0,0,0],[0,0,0,582,91,583,92,22,23,0,24,0,0,585,93,0,0,27,0],[0,0,0,582,91,92,92,22,23,0,24,0,0,0,93,0,0,27,0],[0,553,0,0,0,175,175,0,23,0,24,0,0,0,78,0,553,0,0],[0,553,0,586,0,175,175,0,23,0,24,0,0,0,78,0,553,0,0],[0,0,0,614,91,92,92,22,23,0,24,0,0,0,93,0,0,27,0],[0,0,0,0,194,80,80,22,23,0,0,0,0,591,194,0,0,0,0],[0,0,0,588,91,589,92,22,23,0,24,0,0,591,93,0,0,27,0],[0,0,0,588,91,92,92,22,23,0,24,0,0,0,93,0,0,27,0],[0,0,0,615,112,113,113,32,33,0,34,0,0,0,114,0,0,37,0],[0,0,0,0,220,101,101,32,33,0,0,0,0,595,220,0,0,0,0],[0,0,0,592,112,593,113,32,33,0,34,0,0,595,114,0,0,37,0],[0,0,0,592,112,113,113,32,33,0,34,0,0,0,114,0,0,37,0],[0,559,0,0,0,201,201,0,33,0,34,0,0,0,99,0,559,0,0],[0,559,0,596,0,201,201,0,33,0,34,0,0,0,99,0,559,0,0],[0,0,0,615,112,113,113,32,33,0,34,0,0,0,114,0,0,37,0],[0,0,0,0,220,101,101,32,33,0,0,0,0,601,220,0,0,0,0],[0,0,0,598,112,599,113,32,33,0,34,0,0,601,114,0,0,37,0],[0,0,0,598,112,113,113,32,33,0,34,0,0,0,114,0,0,37,0],[0,0,0,0,66,67,67,8,9,0,10,0,0,0,68,0,0,16,0],[0,0,0,616,152,153,153,57,58,0,59,0,0,0,154,0,0,62,0],[0,0,0,0,265,141,141,57,58,0,0,0,0,606,265,0,0,0,0],[0,0,0,603,152,604,153,57,58,0,59,0,0,606,154,0,0,62,0],[0,0,0,603,152,153,153,57,58,0,59,0,0,0,154,0,0,62,0],[0,575,0,0,0,246,246,0,58,0,59,0,0,0,139,0,575,0,0],[0,575,0,607,0,246,246,0,58,0,59,0,0,0,139,0,575,0,0],[0,0,0,616,152,153,153,57,58,0,59,0,0,0,154,0,0,62,0],[0,0,0,0,265,141,141,57,58,0,0,0,0,612,265,0,0,0,0],[0,0,0,609,152,610,153,57,58,0,59,0,0,612,154,0,0,62,0],[0,0,0,609,152,153,153,57,58,0,59,0,0,0,154,0,0,62,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,549,0,0],[0,0,0,0,91,92,92,22,23,0,24,0,0,0,93,0,0,27,0],[0,0,0,0,112,113,113,32,33,0,34,0,0,0,114,0,0,37,0],[0,0,0,0,152,153,153,57,58,0,59,0,0,0,154,0,0,62,0]],\\\"accepting\\\":[false,true,true,true,true,true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,false,true,false,true,true,false,false,true,true,true,true,true,true,false,false,true,true,true,true,true,true,true,true,true,true,false,true,true,false,true,true,true,false,true,true,true,false,true,false,true,true,false,false,true,true,true,true,true,true,true,false,true,true,false,true,true,true,false,true,false,true,true,false,false,true,true,true,true,true,true,true,false,true,true,true,false,true,true,true,false,true,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,true,false,true,false,true,true,false,false,true,true,true,true,true,true,true,false,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,false,true,false,true,true,false,false,false,true,true,false,false,true,true,true,false,true,true,true,true,true,true,false,true,true,true,false,true,false,true,true,false,false,false,true,true,false,false,true,true,true,false,true,true,true,true,true,false,true,true,true,true,true,false,true,true,false,false,false,false,true,true,false,false,true,true,true,false,true,true,true,false,true,false,true,true,false,false,false,true,true,false,false,true,true,true,false,true,true,true,true,false,true,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,false,true,true,false,false,false,false,true,true,false,false,true,true,true,false,true,true,true,true,true,false,true,true,false,false,false,false,true,true,false,false,true,true,true,true,false,true,true,true,true,true,true,false,true,true,false,false,false,false,true,false,true,false,true,true,true,true,true,false,true,true,false,false,false,false,true,true,false,false,true,true,true,false,true,true,false,false,true,false,true,true,false,true,true,false,true,true,false,true,true,true,true,true,true,false,true,true,false,false,false,false,true,false,true,true,false,true,true,true,true,true,true,false,true,true,false,false,false,false,true,false,true,false,true,true,true,true,false,false,false,true,true,false,true,true,true,true,true,true,false,true,true,false,false,false,false,true,false,true,false,true,true,false,false,true,true,false,false,true,true,true,false,true,false,true,true,true,true,false,false,false,true,false,true,true,true,true,false,false,false,true,true,false,true,true,true,true,true,true,false,true,true,false,true,false,true,true,true,true,false,false,false,false,false,false,false,true,true,false,false,true,true,false,true,true,true,true,false,true,true,true,true,true,true,false,true,true,false,true,true,false,true,true,true,true,true,true,false,true,true,false,true,false,true,true,true,true,true,true,false,true,true,true,true,true,true,false,true,true,false,false,false,false,false,true,true,false,true,false,true,true,true,true,true,false,true,true,true,true,true,false,true,true,true,true,true,false,true,true,true,false,true,true,true,true,false,false,false,true,false,true,true,true,true,true,false,true,true,true,false,true,true,true,true,true,false,true,true,true,true,false,true,true,true,true,true,false,true,true,false,true,true,true],\\\"tags\\\":[[],[\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\"],[\\\"broken_cluster\\\"],[\\\"symbol_cluster\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"symbol_cluster\\\"],[],[\\\"symbol_cluster\\\"],[\\\"symbol_cluster\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"symbol_cluster\\\"],[\\\"symbol_cluster\\\"],[\\\"symbol_cluster\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[],[],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[],[\\\"broken_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"broken_cluster\\\"],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"symbol_cluster\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[],[],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[],[],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[],[],[],[\\\"broken_cluster\\\"],[],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[],[],[],[\\\"consonant_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[],[],[],[\\\"vowel_syllable\\\"],[],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[],[],[\\\"standalone_cluster\\\"],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[],[],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[],[],[],[],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[],[],[],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[\\\"consonant_syllable\\\",\\\"broken_cluster\\\"],[],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[],[],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[],[\\\"consonant_syllable\\\"],[\\\"consonant_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[],[\\\"vowel_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"broken_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"standalone_cluster\\\"],[\\\"standalone_cluster\\\"],[],[\\\"consonant_syllable\\\"],[\\\"vowel_syllable\\\"],[\\\"standalone_cluster\\\"]]}');\\n $aa333a9607471296$exports = {};\\n $aa333a9607471296$exports = JSON.parse('{\\\"categories\\\":[\\\"O\\\",\\\"IND\\\",\\\"S\\\",\\\"GB\\\",\\\"B\\\",\\\"FM\\\",\\\"CGJ\\\",\\\"VMAbv\\\",\\\"VMPst\\\",\\\"VAbv\\\",\\\"VPst\\\",\\\"CMBlw\\\",\\\"VPre\\\",\\\"VBlw\\\",\\\"H\\\",\\\"VMBlw\\\",\\\"CMAbv\\\",\\\"MBlw\\\",\\\"CS\\\",\\\"R\\\",\\\"SUB\\\",\\\"MPst\\\",\\\"MPre\\\",\\\"FAbv\\\",\\\"FPst\\\",\\\"FBlw\\\",\\\"null\\\",\\\"SMAbv\\\",\\\"SMBlw\\\",\\\"VMPre\\\",\\\"ZWNJ\\\",\\\"ZWJ\\\",\\\"WJ\\\",\\\"M\\\",\\\"VS\\\",\\\"N\\\",\\\"HN\\\",\\\"MAbv\\\"],\\\"decompositions\\\":{\\\"2507\\\":[2503,2494],\\\"2508\\\":[2503,2519],\\\"2888\\\":[2887,2902],\\\"2891\\\":[2887,2878],\\\"2892\\\":[2887,2903],\\\"3018\\\":[3014,3006],\\\"3019\\\":[3015,3006],\\\"3020\\\":[3014,3031],\\\"3144\\\":[3142,3158],\\\"3264\\\":[3263,3285],\\\"3271\\\":[3270,3285],\\\"3272\\\":[3270,3286],\\\"3274\\\":[3270,3266],\\\"3275\\\":[3270,3266,3285],\\\"3402\\\":[3398,3390],\\\"3403\\\":[3399,3390],\\\"3404\\\":[3398,3415],\\\"3546\\\":[3545,3530],\\\"3548\\\":[3545,3535],\\\"3549\\\":[3545,3535,3530],\\\"3550\\\":[3545,3551],\\\"3635\\\":[3661,3634],\\\"3763\\\":[3789,3762],\\\"3955\\\":[3953,3954],\\\"3957\\\":[3953,3956],\\\"3958\\\":[4018,3968],\\\"3959\\\":[4018,3953,3968],\\\"3960\\\":[4019,3968],\\\"3961\\\":[4019,3953,3968],\\\"3969\\\":[3953,3968],\\\"6971\\\":[6970,6965],\\\"6973\\\":[6972,6965],\\\"6976\\\":[6974,6965],\\\"6977\\\":[6975,6965],\\\"6979\\\":[6978,6965],\\\"69934\\\":[69937,69927],\\\"69935\\\":[69938,69927],\\\"70475\\\":[70471,70462],\\\"70476\\\":[70471,70487],\\\"70843\\\":[70841,70842],\\\"70844\\\":[70841,70832],\\\"70846\\\":[70841,70845],\\\"71098\\\":[71096,71087],\\\"71099\\\":[71097,71087]},\\\"stateTable\\\":[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[2,2,3,4,4,5,0,6,7,8,9,10,11,12,13,14,15,16,0,17,18,11,19,20,21,22,0,0,0,23,0,0,2,0,0,24,0,25],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,28,0,0,0,0,0,27,0,0,0],[0,0,0,0,0,29,0,30,31,32,33,34,35,36,37,38,39,40,0,0,41,35,42,43,44,45,0,0,0,46,0,0,0,0,39,0,0,47],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,6,7,0,0,0,0,0,0,14,0,0,0,0,0,0,0,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,6,7,8,9,0,0,12,0,14,0,0,0,0,0,0,0,20,21,22,0,0,0,23,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,6,7,0,9,0,0,0,0,14,0,0,0,0,0,0,0,20,21,22,0,0,0,23,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,6,7,8,9,10,11,12,13,14,0,16,0,0,18,11,19,20,21,22,0,0,0,23,0,0,0,0,0,0,0,25],[0,0,0,0,0,5,0,6,7,8,9,0,11,12,0,14,0,0,0,0,0,0,0,20,21,22,0,0,0,23,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,6,7,0,9,0,0,12,0,14,0,0,0,0,0,0,0,20,21,22,0,0,0,23,0,0,0,0,0,0,0,0],[0,0,0,0,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,0,7,0,0,0,0,0,0,14,0,0,0,0,0,0,0,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,6,7,8,9,10,11,12,13,14,15,16,0,0,18,11,19,20,21,22,0,0,0,23,0,0,0,0,0,0,0,25],[0,0,0,0,0,5,0,6,7,8,9,0,11,12,0,14,0,0,0,0,0,11,0,20,21,22,0,0,0,23,0,0,0,0,0,0,0,0],[0,0,0,4,4,5,0,6,7,8,9,10,11,12,13,14,15,16,0,0,18,11,19,20,21,22,0,0,0,23,0,0,0,0,0,0,0,25],[0,0,0,0,0,5,0,6,7,8,9,48,11,12,13,14,48,16,0,0,18,11,19,20,21,22,0,0,0,23,0,0,0,0,49,0,0,25],[0,0,0,0,0,5,0,6,7,8,9,0,11,12,0,14,0,16,0,0,0,11,0,20,21,22,0,0,0,23,0,0,0,0,0,0,0,25],[0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,22,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,6,7,0,0,0,0,0,0,14,0,0,0,0,0,0,0,20,21,22,0,0,0,23,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,0,51,0],[0,0,0,0,0,5,0,6,7,8,9,0,11,12,0,14,0,16,0,0,0,11,0,20,21,22,0,0,0,23,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,28,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,30,31,0,0,0,0,0,0,38,0,0,0,0,0,0,0,43,44,45,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,0,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,44,45,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,30,31,32,33,0,0,36,0,38,0,0,0,0,0,0,0,43,44,45,0,0,0,46,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,30,31,0,33,0,0,0,0,38,0,0,0,0,0,0,0,43,44,45,0,0,0,46,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,30,31,32,33,34,35,36,37,38,0,40,0,0,41,35,42,43,44,45,0,0,0,46,0,0,0,0,0,0,0,47],[0,0,0,0,0,29,0,30,31,32,33,0,35,36,0,38,0,0,0,0,0,0,0,43,44,45,0,0,0,46,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,30,31,0,33,0,0,36,0,38,0,0,0,0,0,0,0,43,44,45,0,0,0,46,0,0,0,0,0,0,0,0],[0,0,0,0,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,0,31,0,0,0,0,0,0,38,0,0,0,0,0,0,0,43,44,45,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,30,31,32,33,34,35,36,37,38,39,40,0,0,41,35,42,43,44,45,0,0,0,46,0,0,0,0,0,0,0,47],[0,0,0,0,0,29,0,30,31,32,33,0,35,36,0,38,0,0,0,0,0,35,0,43,44,45,0,0,0,46,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,30,31,32,33,52,35,36,37,38,52,40,0,0,41,35,42,43,44,45,0,0,0,46,0,0,0,0,53,0,0,47],[0,0,0,0,0,29,0,30,31,32,33,0,35,36,0,38,0,40,0,0,0,35,0,43,44,45,0,0,0,46,0,0,0,0,0,0,0,47],[0,0,0,0,0,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,44,45,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44,45,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,30,31,0,0,0,0,0,0,38,0,0,0,0,0,0,0,43,44,45,0,0,0,46,0,0,0,0,0,0,0,0],[0,0,0,0,0,29,0,30,31,32,33,0,35,36,0,38,0,40,0,0,0,35,0,43,44,45,0,0,0,46,0,0,0,0,0,0,0,0],[0,0,0,0,0,5,0,6,7,8,9,48,11,12,13,14,0,16,0,0,18,11,19,20,21,22,0,0,0,23,0,0,0,0,0,0,0,25],[0,0,0,0,0,5,0,6,7,8,9,48,11,12,13,14,48,16,0,0,18,11,19,20,21,22,0,0,0,23,0,0,0,0,0,0,0,25],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0],[0,0,0,0,0,29,0,30,31,32,33,52,35,36,37,38,0,40,0,0,41,35,42,43,44,45,0,0,0,46,0,0,0,0,0,0,0,47],[0,0,0,0,0,29,0,30,31,32,33,52,35,36,37,38,52,40,0,0,41,35,42,43,44,45,0,0,0,46,0,0,0,0,0,0,0,47],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,0,51,0]],\\\"accepting\\\":[false,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],\\\"tags\\\":[[],[\\\"broken_cluster\\\"],[\\\"independent_cluster\\\"],[\\\"symbol_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"numeral_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"independent_cluster\\\"],[\\\"symbol_cluster\\\"],[\\\"symbol_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"virama_terminated_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"broken_cluster\\\"],[\\\"numeral_cluster\\\"],[\\\"number_joiner_terminated_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"standard_cluster\\\"],[\\\"numeral_cluster\\\"]]}');\\n $90a9d3398ee54fe5$export$a513ea61a7bee91c = {\\n X: 1,\\n C: 2,\\n V: 4,\\n N: 8,\\n H: 16,\\n ZWNJ: 32,\\n ZWJ: 64,\\n M: 128,\\n SM: 256,\\n VD: 512,\\n A: 1024,\\n Placeholder: 2048,\\n Dotted_Circle: 4096,\\n RS: 8192,\\n Coeng: 16384,\\n Repha: 32768,\\n Ra: 65536,\\n CM: 131072,\\n Symbol: 262144\\n // Avagraha, etc that take marks (SM,A,VD).\\n };\\n $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0 = {\\n Start: 1,\\n Ra_To_Become_Reph: 2,\\n Pre_M: 4,\\n Pre_C: 8,\\n Base_C: 16,\\n After_Main: 32,\\n Above_C: 64,\\n Before_Sub: 128,\\n Below_C: 256,\\n After_Sub: 512,\\n Before_Post: 1024,\\n Post_C: 2048,\\n After_Post: 4096,\\n Final_C: 8192,\\n SMVD: 16384,\\n End: 32768\\n };\\n $90a9d3398ee54fe5$export$8519deaa7de2b07 = $90a9d3398ee54fe5$export$a513ea61a7bee91c.C | $90a9d3398ee54fe5$export$a513ea61a7bee91c.Ra | $90a9d3398ee54fe5$export$a513ea61a7bee91c.CM | $90a9d3398ee54fe5$export$a513ea61a7bee91c.V | $90a9d3398ee54fe5$export$a513ea61a7bee91c.Placeholder | $90a9d3398ee54fe5$export$a513ea61a7bee91c.Dotted_Circle;\\n $90a9d3398ee54fe5$export$bbcd928767338e0d = $90a9d3398ee54fe5$export$a513ea61a7bee91c.ZWJ | $90a9d3398ee54fe5$export$a513ea61a7bee91c.ZWNJ;\\n $90a9d3398ee54fe5$export$ca9599b2a300afc = $90a9d3398ee54fe5$export$a513ea61a7bee91c.H | $90a9d3398ee54fe5$export$a513ea61a7bee91c.Coeng;\\n $90a9d3398ee54fe5$export$e99d119da76a0fc5 = {\\n Default: {\\n hasOldSpec: false,\\n virama: 0,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.Before_Post,\\n rephMode: \\\"Implicit\\\",\\n blwfMode: \\\"Pre_And_Post\\\"\\n },\\n Devanagari: {\\n hasOldSpec: true,\\n virama: 2381,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.Before_Post,\\n rephMode: \\\"Implicit\\\",\\n blwfMode: \\\"Pre_And_Post\\\"\\n },\\n Bengali: {\\n hasOldSpec: true,\\n virama: 2509,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.After_Sub,\\n rephMode: \\\"Implicit\\\",\\n blwfMode: \\\"Pre_And_Post\\\"\\n },\\n Gurmukhi: {\\n hasOldSpec: true,\\n virama: 2637,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.Before_Sub,\\n rephMode: \\\"Implicit\\\",\\n blwfMode: \\\"Pre_And_Post\\\"\\n },\\n Gujarati: {\\n hasOldSpec: true,\\n virama: 2765,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.Before_Post,\\n rephMode: \\\"Implicit\\\",\\n blwfMode: \\\"Pre_And_Post\\\"\\n },\\n Oriya: {\\n hasOldSpec: true,\\n virama: 2893,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.After_Main,\\n rephMode: \\\"Implicit\\\",\\n blwfMode: \\\"Pre_And_Post\\\"\\n },\\n Tamil: {\\n hasOldSpec: true,\\n virama: 3021,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.After_Post,\\n rephMode: \\\"Implicit\\\",\\n blwfMode: \\\"Pre_And_Post\\\"\\n },\\n Telugu: {\\n hasOldSpec: true,\\n virama: 3149,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.After_Post,\\n rephMode: \\\"Explicit\\\",\\n blwfMode: \\\"Post_Only\\\"\\n },\\n Kannada: {\\n hasOldSpec: true,\\n virama: 3277,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.After_Post,\\n rephMode: \\\"Implicit\\\",\\n blwfMode: \\\"Post_Only\\\"\\n },\\n Malayalam: {\\n hasOldSpec: true,\\n virama: 3405,\\n basePos: \\\"Last\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.After_Main,\\n rephMode: \\\"Log_Repha\\\",\\n blwfMode: \\\"Pre_And_Post\\\"\\n },\\n // Handled by UniversalShaper\\n // Sinhala: {\\n // hasOldSpec: false,\\n // virama: 0x0DCA,\\n // basePos: 'Last_Sinhala',\\n // rephPos: POSITIONS.After_Main,\\n // rephMode: 'Explicit',\\n // blwfMode: 'Pre_And_Post'\\n // },\\n Khmer: {\\n hasOldSpec: false,\\n virama: 6098,\\n basePos: \\\"First\\\",\\n rephPos: $90a9d3398ee54fe5$export$1a1f61c9c4dd9df0.Ra_To_Become_Reph,\\n rephMode: \\\"Vis_Repha\\\",\\n blwfMode: \\\"Pre_And_Post\\\"\\n }\\n };\\n $90a9d3398ee54fe5$export$f647c9cfdd77d95a = {\\n // Khmer\\n 6078: [\\n 6081,\\n 6078\\n ],\\n 6079: [\\n 6081,\\n 6079\\n ],\\n 6080: [\\n 6081,\\n 6080\\n ],\\n 6084: [\\n 6081,\\n 6084\\n ],\\n 6085: [\\n 6081,\\n 6085\\n ]\\n };\\n ({ decompositions: $7826f90f6f0cecc9$var$decompositions } = (0, /* @__PURE__ */ $parcel$interopDefault2($aa333a9607471296$exports)));\\n $7826f90f6f0cecc9$var$trie = new (0, import_unicode_trie2.default)((0, $12727730ddfc8bfe$export$94fdf11bafc8de6b)(\\\"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\\\"));\\n $7826f90f6f0cecc9$var$stateMachine = new (0, import_dfa.default)((0, /* @__PURE__ */ $parcel$interopDefault2($4b0735ca6c692ea5$exports)));\\n $7826f90f6f0cecc9$export$2e2bcd8739ae039 = class extends (0, $649970d87335b30f$export$2e2bcd8739ae039) {\\n static planFeatures(plan) {\\n plan.addStage($7826f90f6f0cecc9$var$setupSyllables);\\n plan.addStage([\\n \\\"locl\\\",\\n \\\"ccmp\\\"\\n ]);\\n plan.addStage($7826f90f6f0cecc9$var$initialReordering);\\n plan.addStage(\\\"nukt\\\");\\n plan.addStage(\\\"akhn\\\");\\n plan.addStage(\\\"rphf\\\", false);\\n plan.addStage(\\\"rkrf\\\");\\n plan.addStage(\\\"pref\\\", false);\\n plan.addStage(\\\"blwf\\\", false);\\n plan.addStage(\\\"abvf\\\", false);\\n plan.addStage(\\\"half\\\", false);\\n plan.addStage(\\\"pstf\\\", false);\\n plan.addStage(\\\"vatu\\\");\\n plan.addStage(\\\"cjct\\\");\\n plan.addStage(\\\"cfar\\\", false);\\n plan.addStage($7826f90f6f0cecc9$var$finalReordering);\\n plan.addStage({\\n local: [\\n \\\"init\\\"\\n ],\\n global: [\\n \\\"pres\\\",\\n \\\"abvs\\\",\\n \\\"blws\\\",\\n \\\"psts\\\",\\n \\\"haln\\\",\\n \\\"dist\\\",\\n \\\"abvm\\\",\\n \\\"blwm\\\",\\n \\\"calt\\\",\\n \\\"clig\\\"\\n ]\\n });\\n plan.unicodeScript = $130d1a642ebcd2b7$export$ce50e82f12a827a4(plan.script);\\n plan.indicConfig = (0, $90a9d3398ee54fe5$export$e99d119da76a0fc5)[plan.unicodeScript] || (0, $90a9d3398ee54fe5$export$e99d119da76a0fc5).Default;\\n plan.isOldSpec = plan.indicConfig.hasOldSpec && plan.script[plan.script.length - 1] !== \\\"2\\\";\\n }\\n static assignFeatures(plan, glyphs) {\\n for (let i = glyphs.length - 1; i >= 0; i--) {\\n let codepoint = glyphs[i].codePoints[0];\\n let d = (0, $90a9d3398ee54fe5$export$f647c9cfdd77d95a)[codepoint] || $7826f90f6f0cecc9$var$decompositions[codepoint];\\n if (d) {\\n let decomposed = d.map((c) => {\\n let g = plan.font.glyphForCodePoint(c);\\n return new (0, $10e7b257e1a9a756$export$2e2bcd8739ae039)(plan.font, g.id, [\\n c\\n ], glyphs[i].features);\\n });\\n glyphs.splice(i, 1, ...decomposed);\\n }\\n }\\n }\\n };\\n (0, _define_property)($7826f90f6f0cecc9$export$2e2bcd8739ae039, \\\"zeroMarkWidths\\\", \\\"NONE\\\");\\n $7826f90f6f0cecc9$var$IndicInfo = class {\\n constructor(category, position, syllableType, syllable) {\\n this.category = category;\\n this.position = position;\\n this.syllableType = syllableType;\\n this.syllable = syllable;\\n }\\n };\\n ({ categories: $7ab494fe977143c6$var$categories, decompositions: $7ab494fe977143c6$var$decompositions } = (0, /* @__PURE__ */ $parcel$interopDefault2($aa333a9607471296$exports)));\\n $7ab494fe977143c6$var$trie = new (0, import_unicode_trie2.default)((0, $12727730ddfc8bfe$export$94fdf11bafc8de6b)(\\\"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\\\"));\\n $7ab494fe977143c6$var$stateMachine = new (0, import_dfa.default)((0, /* @__PURE__ */ $parcel$interopDefault2($aa333a9607471296$exports)));\\n $7ab494fe977143c6$export$2e2bcd8739ae039 = class extends (0, $649970d87335b30f$export$2e2bcd8739ae039) {\\n static planFeatures(plan) {\\n plan.addStage($7ab494fe977143c6$var$setupSyllables);\\n plan.addStage([\\n \\\"locl\\\",\\n \\\"ccmp\\\",\\n \\\"nukt\\\",\\n \\\"akhn\\\"\\n ]);\\n plan.addStage($7ab494fe977143c6$var$clearSubstitutionFlags);\\n plan.addStage([\\n \\\"rphf\\\"\\n ], false);\\n plan.addStage($7ab494fe977143c6$var$recordRphf);\\n plan.addStage($7ab494fe977143c6$var$clearSubstitutionFlags);\\n plan.addStage([\\n \\\"pref\\\"\\n ]);\\n plan.addStage($7ab494fe977143c6$var$recordPref);\\n plan.addStage([\\n \\\"rkrf\\\",\\n \\\"abvf\\\",\\n \\\"blwf\\\",\\n \\\"half\\\",\\n \\\"pstf\\\",\\n \\\"vatu\\\",\\n \\\"cjct\\\"\\n ]);\\n plan.addStage($7ab494fe977143c6$var$reorder);\\n plan.addStage([\\n \\\"abvs\\\",\\n \\\"blws\\\",\\n \\\"pres\\\",\\n \\\"psts\\\",\\n \\\"dist\\\",\\n \\\"abvm\\\",\\n \\\"blwm\\\"\\n ]);\\n }\\n static assignFeatures(plan, glyphs) {\\n for (let i = glyphs.length - 1; i >= 0; i--) {\\n let codepoint = glyphs[i].codePoints[0];\\n if ($7ab494fe977143c6$var$decompositions[codepoint]) {\\n let decomposed = $7ab494fe977143c6$var$decompositions[codepoint].map((c) => {\\n let g = plan.font.glyphForCodePoint(c);\\n return new (0, $10e7b257e1a9a756$export$2e2bcd8739ae039)(plan.font, g.id, [\\n c\\n ], glyphs[i].features);\\n });\\n glyphs.splice(i, 1, ...decomposed);\\n }\\n }\\n }\\n };\\n (0, _define_property)($7ab494fe977143c6$export$2e2bcd8739ae039, \\\"zeroMarkWidths\\\", \\\"BEFORE_GPOS\\\");\\n $7ab494fe977143c6$var$USEInfo = class {\\n constructor(category, syllableType, syllable) {\\n this.category = category;\\n this.syllableType = syllableType;\\n this.syllable = syllable;\\n }\\n };\\n $102b6fe50f1d50b4$var$SHAPERS = {\\n arab: (0, $764eb544bbe1ccf0$export$2e2bcd8739ae039),\\n mong: (0, $764eb544bbe1ccf0$export$2e2bcd8739ae039),\\n syrc: (0, $764eb544bbe1ccf0$export$2e2bcd8739ae039),\\n \\\"nko \\\": (0, $764eb544bbe1ccf0$export$2e2bcd8739ae039),\\n phag: (0, $764eb544bbe1ccf0$export$2e2bcd8739ae039),\\n mand: (0, $764eb544bbe1ccf0$export$2e2bcd8739ae039),\\n mani: (0, $764eb544bbe1ccf0$export$2e2bcd8739ae039),\\n phlp: (0, $764eb544bbe1ccf0$export$2e2bcd8739ae039),\\n hang: (0, $e1c6bbc8cb416f8c$export$2e2bcd8739ae039),\\n bng2: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n beng: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n dev2: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n deva: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n gjr2: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n gujr: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n guru: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n gur2: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n knda: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n knd2: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n mlm2: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n mlym: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n ory2: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n orya: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n taml: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n tml2: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n telu: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n tel2: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n khmr: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n bali: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n batk: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n brah: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n bugi: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n buhd: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n cakm: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n cham: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n dupl: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n egyp: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n gran: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n hano: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n java: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n kthi: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n kali: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n khar: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n khoj: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n sind: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n lepc: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n limb: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n mahj: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n // mand: UniversalShaper, // Mandaic\\n // mani: UniversalShaper, // Manichaean\\n mtei: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n modi: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n // mong: UniversalShaper, // Mongolian\\n // 'nko ': UniversalShaper, // N’Ko\\n hmng: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n // phag: UniversalShaper, // Phags-pa\\n // phlp: UniversalShaper, // Psalter Pahlavi\\n rjng: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n saur: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n shrd: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n sidd: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n sinh: (0, $7826f90f6f0cecc9$export$2e2bcd8739ae039),\\n sund: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n sylo: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n tglg: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n tagb: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n tale: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n lana: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n tavt: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n takr: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n tibt: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n tfng: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n tirh: (0, $7ab494fe977143c6$export$2e2bcd8739ae039),\\n latn: (0, $649970d87335b30f$export$2e2bcd8739ae039),\\n DFLT: (0, $649970d87335b30f$export$2e2bcd8739ae039)\\n };\\n $0a876c45f1f7c41c$export$2e2bcd8739ae039 = class extends (0, $a83b9c36aaa94fd3$export$2e2bcd8739ae039) {\\n applyLookup(lookupType, table) {\\n switch (lookupType) {\\n case 1: {\\n let index = this.coverageIndex(table.coverage);\\n if (index === -1) return false;\\n let glyph = this.glyphIterator.cur;\\n switch (table.version) {\\n case 1:\\n glyph.id = glyph.id + table.deltaGlyphID & 65535;\\n break;\\n case 2:\\n glyph.id = table.substitute.get(index);\\n break;\\n }\\n return true;\\n }\\n case 2: {\\n let index = this.coverageIndex(table.coverage);\\n if (index !== -1) {\\n let sequence = table.sequences.get(index);\\n if (sequence.length === 0) {\\n this.glyphs.splice(this.glyphIterator.index, 1);\\n return true;\\n }\\n this.glyphIterator.cur.id = sequence[0];\\n this.glyphIterator.cur.ligatureComponent = 0;\\n let features = this.glyphIterator.cur.features;\\n let curGlyph = this.glyphIterator.cur;\\n let replacement = sequence.slice(1).map((gid, i) => {\\n let glyph = new (0, $10e7b257e1a9a756$export$2e2bcd8739ae039)(this.font, gid, void 0, features);\\n glyph.shaperInfo = curGlyph.shaperInfo;\\n glyph.isLigated = curGlyph.isLigated;\\n glyph.ligatureComponent = i + 1;\\n glyph.substituted = true;\\n glyph.isMultiplied = true;\\n return glyph;\\n });\\n this.glyphs.splice(this.glyphIterator.index + 1, 0, ...replacement);\\n return true;\\n }\\n return false;\\n }\\n case 3: {\\n let index = this.coverageIndex(table.coverage);\\n if (index !== -1) {\\n let USER_INDEX = 0;\\n this.glyphIterator.cur.id = table.alternateSet.get(index)[USER_INDEX];\\n return true;\\n }\\n return false;\\n }\\n case 4: {\\n let index = this.coverageIndex(table.coverage);\\n if (index === -1) return false;\\n for (let ligature of table.ligatureSets.get(index)) {\\n let matched = this.sequenceMatchIndices(1, ligature.components);\\n if (!matched) continue;\\n let curGlyph = this.glyphIterator.cur;\\n let characters = curGlyph.codePoints.slice();\\n for (let index2 of matched) characters.push(...this.glyphs[index2].codePoints);\\n let ligatureGlyph = new (0, $10e7b257e1a9a756$export$2e2bcd8739ae039)(this.font, ligature.glyph, characters, curGlyph.features);\\n ligatureGlyph.shaperInfo = curGlyph.shaperInfo;\\n ligatureGlyph.isLigated = true;\\n ligatureGlyph.substituted = true;\\n let isMarkLigature = curGlyph.isMark;\\n for (let i = 0; i < matched.length && isMarkLigature; i++) isMarkLigature = this.glyphs[matched[i]].isMark;\\n ligatureGlyph.ligatureID = isMarkLigature ? null : this.ligatureID++;\\n let lastLigID = curGlyph.ligatureID;\\n let lastNumComps = curGlyph.codePoints.length;\\n let curComps = lastNumComps;\\n let idx = this.glyphIterator.index + 1;\\n for (let matchIndex of matched) {\\n if (isMarkLigature) idx = matchIndex;\\n else while (idx < matchIndex) {\\n var ligatureComponent = curComps - lastNumComps + Math.min(this.glyphs[idx].ligatureComponent || 1, lastNumComps);\\n this.glyphs[idx].ligatureID = ligatureGlyph.ligatureID;\\n this.glyphs[idx].ligatureComponent = ligatureComponent;\\n idx++;\\n }\\n lastLigID = this.glyphs[idx].ligatureID;\\n lastNumComps = this.glyphs[idx].codePoints.length;\\n curComps += lastNumComps;\\n idx++;\\n }\\n if (lastLigID && !isMarkLigature) for (let i = idx; i < this.glyphs.length; i++) {\\n if (this.glyphs[i].ligatureID === lastLigID) {\\n var ligatureComponent = curComps - lastNumComps + Math.min(this.glyphs[i].ligatureComponent || 1, lastNumComps);\\n this.glyphs[i].ligatureComponent = ligatureComponent;\\n } else break;\\n }\\n for (let i = matched.length - 1; i >= 0; i--) this.glyphs.splice(matched[i], 1);\\n this.glyphs[this.glyphIterator.index] = ligatureGlyph;\\n return true;\\n }\\n return false;\\n }\\n case 5:\\n return this.applyContext(table);\\n case 6:\\n return this.applyChainingContext(table);\\n case 7:\\n return this.applyLookup(table.lookupType, table.extension);\\n default:\\n throw new Error(`GSUB lookupType ${lookupType} is not supported`);\\n }\\n }\\n };\\n $c96c93587d49c14d$export$2e2bcd8739ae039 = class extends (0, $a83b9c36aaa94fd3$export$2e2bcd8739ae039) {\\n applyPositionValue(sequenceIndex, value) {\\n let position = this.positions[this.glyphIterator.peekIndex(sequenceIndex)];\\n if (value.xAdvance != null) position.xAdvance += value.xAdvance;\\n if (value.yAdvance != null) position.yAdvance += value.yAdvance;\\n if (value.xPlacement != null) position.xOffset += value.xPlacement;\\n if (value.yPlacement != null) position.yOffset += value.yPlacement;\\n let variationProcessor = this.font._variationProcessor;\\n let variationStore = this.font.GDEF && this.font.GDEF.itemVariationStore;\\n if (variationProcessor && variationStore) {\\n if (value.xPlaDevice) position.xOffset += variationProcessor.getDelta(variationStore, value.xPlaDevice.a, value.xPlaDevice.b);\\n if (value.yPlaDevice) position.yOffset += variationProcessor.getDelta(variationStore, value.yPlaDevice.a, value.yPlaDevice.b);\\n if (value.xAdvDevice) position.xAdvance += variationProcessor.getDelta(variationStore, value.xAdvDevice.a, value.xAdvDevice.b);\\n if (value.yAdvDevice) position.yAdvance += variationProcessor.getDelta(variationStore, value.yAdvDevice.a, value.yAdvDevice.b);\\n }\\n }\\n applyLookup(lookupType, table) {\\n switch (lookupType) {\\n case 1: {\\n let index = this.coverageIndex(table.coverage);\\n if (index === -1) return false;\\n switch (table.version) {\\n case 1:\\n this.applyPositionValue(0, table.value);\\n break;\\n case 2:\\n this.applyPositionValue(0, table.values.get(index));\\n break;\\n }\\n return true;\\n }\\n case 2: {\\n let nextGlyph = this.glyphIterator.peek();\\n if (!nextGlyph) return false;\\n let index = this.coverageIndex(table.coverage);\\n if (index === -1) return false;\\n switch (table.version) {\\n case 1:\\n let set = table.pairSets.get(index);\\n for (let pair2 of set) if (pair2.secondGlyph === nextGlyph.id) {\\n this.applyPositionValue(0, pair2.value1);\\n this.applyPositionValue(1, pair2.value2);\\n return true;\\n }\\n return false;\\n case 2:\\n let class1 = this.getClassID(this.glyphIterator.cur.id, table.classDef1);\\n let class2 = this.getClassID(nextGlyph.id, table.classDef2);\\n if (class1 === -1 || class2 === -1) return false;\\n var pair = table.classRecords.get(class1).get(class2);\\n this.applyPositionValue(0, pair.value1);\\n this.applyPositionValue(1, pair.value2);\\n return true;\\n }\\n }\\n case 3: {\\n let nextIndex = this.glyphIterator.peekIndex();\\n let nextGlyph = this.glyphs[nextIndex];\\n if (!nextGlyph) return false;\\n let curRecord = table.entryExitRecords[this.coverageIndex(table.coverage)];\\n if (!curRecord || !curRecord.exitAnchor) return false;\\n let nextRecord = table.entryExitRecords[this.coverageIndex(table.coverage, nextGlyph.id)];\\n if (!nextRecord || !nextRecord.entryAnchor) return false;\\n let entry = this.getAnchor(nextRecord.entryAnchor);\\n let exit = this.getAnchor(curRecord.exitAnchor);\\n let cur = this.positions[this.glyphIterator.index];\\n let next = this.positions[nextIndex];\\n let d;\\n switch (this.direction) {\\n case \\\"ltr\\\":\\n cur.xAdvance = exit.x + cur.xOffset;\\n d = entry.x + next.xOffset;\\n next.xAdvance -= d;\\n next.xOffset -= d;\\n break;\\n case \\\"rtl\\\":\\n d = exit.x + cur.xOffset;\\n cur.xAdvance -= d;\\n cur.xOffset -= d;\\n next.xAdvance = entry.x + next.xOffset;\\n break;\\n }\\n if (this.glyphIterator.flags.rightToLeft) {\\n this.glyphIterator.cur.cursiveAttachment = nextIndex;\\n cur.yOffset = entry.y - exit.y;\\n } else {\\n nextGlyph.cursiveAttachment = this.glyphIterator.index;\\n cur.yOffset = exit.y - entry.y;\\n }\\n return true;\\n }\\n case 4: {\\n let markIndex = this.coverageIndex(table.markCoverage);\\n if (markIndex === -1) return false;\\n let baseGlyphIndex = this.glyphIterator.index;\\n while (--baseGlyphIndex >= 0 && (this.glyphs[baseGlyphIndex].isMark || this.glyphs[baseGlyphIndex].ligatureComponent > 0)) ;\\n if (baseGlyphIndex < 0) return false;\\n let baseIndex = this.coverageIndex(table.baseCoverage, this.glyphs[baseGlyphIndex].id);\\n if (baseIndex === -1) return false;\\n let markRecord = table.markArray[markIndex];\\n let baseAnchor = table.baseArray[baseIndex][markRecord.class];\\n this.applyAnchor(markRecord, baseAnchor, baseGlyphIndex);\\n return true;\\n }\\n case 5: {\\n let markIndex = this.coverageIndex(table.markCoverage);\\n if (markIndex === -1) return false;\\n let baseGlyphIndex = this.glyphIterator.index;\\n while (--baseGlyphIndex >= 0 && this.glyphs[baseGlyphIndex].isMark) ;\\n if (baseGlyphIndex < 0) return false;\\n let ligIndex = this.coverageIndex(table.ligatureCoverage, this.glyphs[baseGlyphIndex].id);\\n if (ligIndex === -1) return false;\\n let ligAttach = table.ligatureArray[ligIndex];\\n let markGlyph = this.glyphIterator.cur;\\n let ligGlyph = this.glyphs[baseGlyphIndex];\\n let compIndex = ligGlyph.ligatureID && ligGlyph.ligatureID === markGlyph.ligatureID && markGlyph.ligatureComponent > 0 ? Math.min(markGlyph.ligatureComponent, ligGlyph.codePoints.length) - 1 : ligGlyph.codePoints.length - 1;\\n let markRecord = table.markArray[markIndex];\\n let baseAnchor = ligAttach[compIndex][markRecord.class];\\n this.applyAnchor(markRecord, baseAnchor, baseGlyphIndex);\\n return true;\\n }\\n case 6: {\\n let mark1Index = this.coverageIndex(table.mark1Coverage);\\n if (mark1Index === -1) return false;\\n let prevIndex = this.glyphIterator.peekIndex(-1);\\n let prev = this.glyphs[prevIndex];\\n if (!prev || !prev.isMark) return false;\\n let cur = this.glyphIterator.cur;\\n let good = false;\\n if (cur.ligatureID === prev.ligatureID) {\\n if (!cur.ligatureID) good = true;\\n else if (cur.ligatureComponent === prev.ligatureComponent) good = true;\\n } else if (cur.ligatureID && !cur.ligatureComponent || prev.ligatureID && !prev.ligatureComponent) good = true;\\n if (!good) return false;\\n let mark2Index = this.coverageIndex(table.mark2Coverage, prev.id);\\n if (mark2Index === -1) return false;\\n let markRecord = table.mark1Array[mark1Index];\\n let baseAnchor = table.mark2Array[mark2Index][markRecord.class];\\n this.applyAnchor(markRecord, baseAnchor, prevIndex);\\n return true;\\n }\\n case 7:\\n return this.applyContext(table);\\n case 8:\\n return this.applyChainingContext(table);\\n case 9:\\n return this.applyLookup(table.lookupType, table.extension);\\n default:\\n throw new Error(`Unsupported GPOS table: ${lookupType}`);\\n }\\n }\\n applyAnchor(markRecord, baseAnchor, baseGlyphIndex) {\\n let baseCoords = this.getAnchor(baseAnchor);\\n let markCoords = this.getAnchor(markRecord.markAnchor);\\n let basePos = this.positions[baseGlyphIndex];\\n let markPos = this.positions[this.glyphIterator.index];\\n markPos.xOffset = baseCoords.x - markCoords.x;\\n markPos.yOffset = baseCoords.y - markCoords.y;\\n this.glyphIterator.cur.markAttachment = baseGlyphIndex;\\n }\\n getAnchor(anchor) {\\n let x = anchor.xCoordinate;\\n let y = anchor.yCoordinate;\\n let variationProcessor = this.font._variationProcessor;\\n let variationStore = this.font.GDEF && this.font.GDEF.itemVariationStore;\\n if (variationProcessor && variationStore) {\\n if (anchor.xDeviceTable) x += variationProcessor.getDelta(variationStore, anchor.xDeviceTable.a, anchor.xDeviceTable.b);\\n if (anchor.yDeviceTable) y += variationProcessor.getDelta(variationStore, anchor.yDeviceTable.a, anchor.yDeviceTable.b);\\n }\\n return {\\n x,\\n y\\n };\\n }\\n applyFeatures(userFeatures, glyphs, advances) {\\n super.applyFeatures(userFeatures, glyphs, advances);\\n for (var i = 0; i < this.glyphs.length; i++) this.fixCursiveAttachment(i);\\n this.fixMarkAttachment();\\n }\\n fixCursiveAttachment(i) {\\n let glyph = this.glyphs[i];\\n if (glyph.cursiveAttachment != null) {\\n let j = glyph.cursiveAttachment;\\n glyph.cursiveAttachment = null;\\n this.fixCursiveAttachment(j);\\n this.positions[i].yOffset += this.positions[j].yOffset;\\n }\\n }\\n fixMarkAttachment() {\\n for (let i = 0; i < this.glyphs.length; i++) {\\n let glyph = this.glyphs[i];\\n if (glyph.markAttachment != null) {\\n let j = glyph.markAttachment;\\n this.positions[i].xOffset += this.positions[j].xOffset;\\n this.positions[i].yOffset += this.positions[j].yOffset;\\n if (this.direction === \\\"ltr\\\") for (let k = j; k < i; k++) {\\n this.positions[i].xOffset -= this.positions[k].xAdvance;\\n this.positions[i].yOffset -= this.positions[k].yAdvance;\\n }\\n else for (let k = j + 1; k < i + 1; k++) {\\n this.positions[i].xOffset += this.positions[k].xAdvance;\\n this.positions[i].yOffset += this.positions[k].yAdvance;\\n }\\n }\\n }\\n }\\n };\\n $a62492810de27e3d$export$2e2bcd8739ae039 = class {\\n setup(glyphRun) {\\n this.glyphInfos = glyphRun.glyphs.map((glyph) => new (0, $10e7b257e1a9a756$export$2e2bcd8739ae039)(this.font, glyph.id, [\\n ...glyph.codePoints\\n ]));\\n let script = null;\\n if (this.GPOSProcessor) script = this.GPOSProcessor.selectScript(glyphRun.script, glyphRun.language, glyphRun.direction);\\n if (this.GSUBProcessor) script = this.GSUBProcessor.selectScript(glyphRun.script, glyphRun.language, glyphRun.direction);\\n this.shaper = $102b6fe50f1d50b4$export$7877a478dd30fd3d(script);\\n this.plan = new (0, $94d7a73bd2edfc9a$export$2e2bcd8739ae039)(this.font, script, glyphRun.direction);\\n this.shaper.plan(this.plan, this.glyphInfos, glyphRun.features);\\n for (let key in this.plan.allFeatures) glyphRun.features[key] = true;\\n }\\n substitute(glyphRun) {\\n if (this.GSUBProcessor) {\\n this.plan.process(this.GSUBProcessor, this.glyphInfos);\\n glyphRun.glyphs = this.glyphInfos.map((glyphInfo) => this.font.getGlyph(glyphInfo.id, glyphInfo.codePoints));\\n }\\n }\\n position(glyphRun) {\\n if (this.shaper.zeroMarkWidths === \\\"BEFORE_GPOS\\\") this.zeroMarkAdvances(glyphRun.positions);\\n if (this.GPOSProcessor) this.plan.process(this.GPOSProcessor, this.glyphInfos, glyphRun.positions);\\n if (this.shaper.zeroMarkWidths === \\\"AFTER_GPOS\\\") this.zeroMarkAdvances(glyphRun.positions);\\n if (glyphRun.direction === \\\"rtl\\\") {\\n glyphRun.glyphs.reverse();\\n glyphRun.positions.reverse();\\n }\\n return this.GPOSProcessor && this.GPOSProcessor.features;\\n }\\n zeroMarkAdvances(positions) {\\n for (let i = 0; i < this.glyphInfos.length; i++) if (this.glyphInfos[i].isMark) {\\n positions[i].xAdvance = 0;\\n positions[i].yAdvance = 0;\\n }\\n }\\n cleanup() {\\n this.glyphInfos = null;\\n this.plan = null;\\n this.shaper = null;\\n }\\n getAvailableFeatures(script, language) {\\n let features = [];\\n if (this.GSUBProcessor) {\\n this.GSUBProcessor.selectScript(script, language);\\n features.push(...Object.keys(this.GSUBProcessor.features));\\n }\\n if (this.GPOSProcessor) {\\n this.GPOSProcessor.selectScript(script, language);\\n features.push(...Object.keys(this.GPOSProcessor.features));\\n }\\n return features;\\n }\\n constructor(font) {\\n this.font = font;\\n this.glyphInfos = null;\\n this.plan = null;\\n this.GSUBProcessor = null;\\n this.GPOSProcessor = null;\\n this.fallbackPosition = true;\\n if (font.GSUB) this.GSUBProcessor = new (0, $0a876c45f1f7c41c$export$2e2bcd8739ae039)(font, font.GSUB);\\n if (font.GPOS) this.GPOSProcessor = new (0, $c96c93587d49c14d$export$2e2bcd8739ae039)(font, font.GPOS);\\n }\\n };\\n $4c0a7fa5df7a9ab1$export$2e2bcd8739ae039 = class {\\n layout(string, features, script, language, direction) {\\n if (typeof features === \\\"string\\\") {\\n direction = language;\\n language = script;\\n script = features;\\n features = [];\\n }\\n if (typeof string === \\\"string\\\") {\\n if (script == null) script = $130d1a642ebcd2b7$export$e5cb25e204fb8450(string);\\n var glyphs = this.font.glyphsForString(string);\\n } else {\\n if (script == null) {\\n let codePoints = [];\\n for (let glyph of string) codePoints.push(...glyph.codePoints);\\n script = $130d1a642ebcd2b7$export$16fab0757cfc223d(codePoints);\\n }\\n var glyphs = string;\\n }\\n let glyphRun = new (0, $be07b3e97a42687a$export$2e2bcd8739ae039)(glyphs, features, script, language, direction);\\n if (glyphs.length === 0) {\\n glyphRun.positions = [];\\n return glyphRun;\\n }\\n if (this.engine && this.engine.setup) this.engine.setup(glyphRun);\\n this.substitute(glyphRun);\\n this.position(glyphRun);\\n this.hideDefaultIgnorables(glyphRun.glyphs, glyphRun.positions);\\n if (this.engine && this.engine.cleanup) this.engine.cleanup();\\n return glyphRun;\\n }\\n substitute(glyphRun) {\\n if (this.engine && this.engine.substitute) this.engine.substitute(glyphRun);\\n }\\n position(glyphRun) {\\n glyphRun.positions = glyphRun.glyphs.map((glyph) => new (0, $1ac75d9a55b67f01$export$2e2bcd8739ae039)(glyph.advanceWidth));\\n let positioned = null;\\n if (this.engine && this.engine.position) positioned = this.engine.position(glyphRun);\\n if (!positioned && (!this.engine || this.engine.fallbackPosition)) {\\n if (!this.unicodeLayoutEngine) this.unicodeLayoutEngine = new (0, $0a4bdfeb6dfd6f5e$export$2e2bcd8739ae039)(this.font);\\n this.unicodeLayoutEngine.positionGlyphs(glyphRun.glyphs, glyphRun.positions);\\n }\\n if ((!positioned || !positioned.kern) && glyphRun.features.kern !== false && this.font.kern) {\\n if (!this.kernProcessor) this.kernProcessor = new (0, $0bba3a9db57637f3$export$2e2bcd8739ae039)(this.font);\\n this.kernProcessor.process(glyphRun.glyphs, glyphRun.positions);\\n glyphRun.features.kern = true;\\n }\\n }\\n hideDefaultIgnorables(glyphs, positions) {\\n let space = this.font.glyphForCodePoint(32);\\n for (let i = 0; i < glyphs.length; i++) if (this.isDefaultIgnorable(glyphs[i].codePoints[0])) {\\n glyphs[i] = space;\\n positions[i].xAdvance = 0;\\n positions[i].yAdvance = 0;\\n }\\n }\\n isDefaultIgnorable(ch) {\\n let plane = ch >> 16;\\n if (plane === 0)\\n switch (ch >> 8) {\\n case 0:\\n return ch === 173;\\n case 3:\\n return ch === 847;\\n case 6:\\n return ch === 1564;\\n case 23:\\n return 6068 <= ch && ch <= 6069;\\n case 24:\\n return 6155 <= ch && ch <= 6158;\\n case 32:\\n return 8203 <= ch && ch <= 8207 || 8234 <= ch && ch <= 8238 || 8288 <= ch && ch <= 8303;\\n case 254:\\n return 65024 <= ch && ch <= 65039 || ch === 65279;\\n case 255:\\n return 65520 <= ch && ch <= 65528;\\n default:\\n return false;\\n }\\n else\\n switch (plane) {\\n case 1:\\n return 113824 <= ch && ch <= 113827 || 119155 <= ch && ch <= 119162;\\n case 14:\\n return 917504 <= ch && ch <= 921599;\\n default:\\n return false;\\n }\\n }\\n getAvailableFeatures(script, language) {\\n let features = [];\\n if (this.engine) features.push(...this.engine.getAvailableFeatures(script, language));\\n if (this.font.kern && features.indexOf(\\\"kern\\\") === -1) features.push(\\\"kern\\\");\\n return features;\\n }\\n stringsForGlyph(gid) {\\n let result = /* @__PURE__ */ new Set();\\n let codePoints = this.font._cmapProcessor.codePointsForGlyph(gid);\\n for (let codePoint of codePoints) result.add(String.fromCodePoint(codePoint));\\n if (this.engine && this.engine.stringsForGlyph) for (let string of this.engine.stringsForGlyph(gid)) result.add(string);\\n return Array.from(result);\\n }\\n constructor(font) {\\n this.font = font;\\n this.unicodeLayoutEngine = null;\\n this.kernProcessor = null;\\n if (this.font.morx) this.engine = new (0, $ba6dd74203be8728$export$2e2bcd8739ae039)(this.font);\\n else if (this.font.GSUB || this.font.GPOS) this.engine = new (0, $a62492810de27e3d$export$2e2bcd8739ae039)(this.font);\\n }\\n };\\n $f43aec954cdfdf21$var$SVG_COMMANDS = {\\n moveTo: \\\"M\\\",\\n lineTo: \\\"L\\\",\\n quadraticCurveTo: \\\"Q\\\",\\n bezierCurveTo: \\\"C\\\",\\n closePath: \\\"Z\\\"\\n };\\n $f43aec954cdfdf21$export$2e2bcd8739ae039 = class _$f43aec954cdfdf21$export$2e2bcd8739ae039 {\\n /**\\n * Compiles the path to a JavaScript function that can be applied with\\n * a graphics context in order to render the path.\\n * @return {string}\\n */\\n toFunction() {\\n return (ctx) => {\\n this.commands.forEach((c) => {\\n return ctx[c.command].apply(ctx, c.args);\\n });\\n };\\n }\\n /**\\n * Converts the path to an SVG path data string\\n * @return {string}\\n */\\n toSVG() {\\n let cmds = this.commands.map((c) => {\\n let args = c.args.map((arg) => Math.round(arg * 100) / 100);\\n return `${$f43aec954cdfdf21$var$SVG_COMMANDS[c.command]}${args.join(\\\" \\\")}`;\\n });\\n return cmds.join(\\\"\\\");\\n }\\n /**\\n * Gets the \\\"control box\\\" of a path.\\n * This is like the bounding box, but it includes all points including\\n * control points of bezier segments and is much faster to compute than\\n * the real bounding box.\\n * @type {BBox}\\n */\\n get cbox() {\\n if (!this._cbox) {\\n let cbox = new (0, $f34600ab9d7f70d8$export$2e2bcd8739ae039)();\\n for (let command of this.commands) for (let i = 0; i < command.args.length; i += 2) cbox.addPoint(command.args[i], command.args[i + 1]);\\n this._cbox = Object.freeze(cbox);\\n }\\n return this._cbox;\\n }\\n /**\\n * Gets the exact bounding box of the path by evaluating curve segments.\\n * Slower to compute than the control box, but more accurate.\\n * @type {BBox}\\n */\\n get bbox() {\\n if (this._bbox) return this._bbox;\\n let bbox = new (0, $f34600ab9d7f70d8$export$2e2bcd8739ae039)();\\n let cx = 0, cy = 0;\\n let f = (t) => Math.pow(1 - t, 3) * p0[i] + 3 * Math.pow(1 - t, 2) * t * p1[i] + 3 * (1 - t) * Math.pow(t, 2) * p2[i] + Math.pow(t, 3) * p3[i];\\n for (let c of this.commands) switch (c.command) {\\n case \\\"moveTo\\\":\\n case \\\"lineTo\\\":\\n let [x, y] = c.args;\\n bbox.addPoint(x, y);\\n cx = x;\\n cy = y;\\n break;\\n case \\\"quadraticCurveTo\\\":\\n case \\\"bezierCurveTo\\\":\\n if (c.command === \\\"quadraticCurveTo\\\") {\\n var [qp1x, qp1y, p3x, p3y] = c.args;\\n var cp1x = cx + 2 / 3 * (qp1x - cx);\\n var cp1y = cy + 2 / 3 * (qp1y - cy);\\n var cp2x = p3x + 2 / 3 * (qp1x - p3x);\\n var cp2y = p3y + 2 / 3 * (qp1y - p3y);\\n } else var [cp1x, cp1y, cp2x, cp2y, p3x, p3y] = c.args;\\n bbox.addPoint(p3x, p3y);\\n var p0 = [\\n cx,\\n cy\\n ];\\n var p1 = [\\n cp1x,\\n cp1y\\n ];\\n var p2 = [\\n cp2x,\\n cp2y\\n ];\\n var p3 = [\\n p3x,\\n p3y\\n ];\\n for (var i = 0; i <= 1; i++) {\\n let b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];\\n let a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];\\n c = 3 * p1[i] - 3 * p0[i];\\n if (a === 0) {\\n if (b === 0) continue;\\n let t = -c / b;\\n if (0 < t && t < 1) {\\n if (i === 0) bbox.addPoint(f(t), bbox.maxY);\\n else if (i === 1) bbox.addPoint(bbox.maxX, f(t));\\n }\\n continue;\\n }\\n let b2ac = Math.pow(b, 2) - 4 * c * a;\\n if (b2ac < 0) continue;\\n let t1 = (-b + Math.sqrt(b2ac)) / (2 * a);\\n if (0 < t1 && t1 < 1) {\\n if (i === 0) bbox.addPoint(f(t1), bbox.maxY);\\n else if (i === 1) bbox.addPoint(bbox.maxX, f(t1));\\n }\\n let t2 = (-b - Math.sqrt(b2ac)) / (2 * a);\\n if (0 < t2 && t2 < 1) {\\n if (i === 0) bbox.addPoint(f(t2), bbox.maxY);\\n else if (i === 1) bbox.addPoint(bbox.maxX, f(t2));\\n }\\n }\\n cx = p3x;\\n cy = p3y;\\n break;\\n }\\n return this._bbox = Object.freeze(bbox);\\n }\\n /**\\n * Applies a mapping function to each point in the path.\\n * @param {function} fn\\n * @return {Path}\\n */\\n mapPoints(fn) {\\n let path = new _$f43aec954cdfdf21$export$2e2bcd8739ae039();\\n for (let c of this.commands) {\\n let args = [];\\n for (let i = 0; i < c.args.length; i += 2) {\\n let [x, y] = fn(c.args[i], c.args[i + 1]);\\n args.push(x, y);\\n }\\n path[c.command](...args);\\n }\\n return path;\\n }\\n /**\\n * Transforms the path by the given matrix.\\n */\\n transform(m0, m1, m2, m3, m4, m5) {\\n return this.mapPoints((x, y) => {\\n const tx = m0 * x + m2 * y + m4;\\n const ty = m1 * x + m3 * y + m5;\\n return [\\n tx,\\n ty\\n ];\\n });\\n }\\n /**\\n * Translates the path by the given offset.\\n */\\n translate(x, y) {\\n return this.transform(1, 0, 0, 1, x, y);\\n }\\n /**\\n * Rotates the path by the given angle (in radians).\\n */\\n rotate(angle) {\\n let cos = Math.cos(angle);\\n let sin = Math.sin(angle);\\n return this.transform(cos, sin, -sin, cos, 0, 0);\\n }\\n /**\\n * Scales the path.\\n */\\n scale(scaleX, scaleY = scaleX) {\\n return this.transform(scaleX, 0, 0, scaleY, 0, 0);\\n }\\n constructor() {\\n this.commands = [];\\n this._bbox = null;\\n this._cbox = null;\\n }\\n };\\n for (let command of [\\n \\\"moveTo\\\",\\n \\\"lineTo\\\",\\n \\\"quadraticCurveTo\\\",\\n \\\"bezierCurveTo\\\",\\n \\\"closePath\\\"\\n ]) $f43aec954cdfdf21$export$2e2bcd8739ae039.prototype[command] = function(...args) {\\n this._bbox = this._cbox = null;\\n this.commands.push({\\n command,\\n args\\n });\\n return this;\\n };\\n $7713b9b7b438dff8$export$2e2bcd8739ae039 = [\\n \\\".notdef\\\",\\n \\\".null\\\",\\n \\\"nonmarkingreturn\\\",\\n \\\"space\\\",\\n \\\"exclam\\\",\\n \\\"quotedbl\\\",\\n \\\"numbersign\\\",\\n \\\"dollar\\\",\\n \\\"percent\\\",\\n \\\"ampersand\\\",\\n \\\"quotesingle\\\",\\n \\\"parenleft\\\",\\n \\\"parenright\\\",\\n \\\"asterisk\\\",\\n \\\"plus\\\",\\n \\\"comma\\\",\\n \\\"hyphen\\\",\\n \\\"period\\\",\\n \\\"slash\\\",\\n \\\"zero\\\",\\n \\\"one\\\",\\n \\\"two\\\",\\n \\\"three\\\",\\n \\\"four\\\",\\n \\\"five\\\",\\n \\\"six\\\",\\n \\\"seven\\\",\\n \\\"eight\\\",\\n \\\"nine\\\",\\n \\\"colon\\\",\\n \\\"semicolon\\\",\\n \\\"less\\\",\\n \\\"equal\\\",\\n \\\"greater\\\",\\n \\\"question\\\",\\n \\\"at\\\",\\n \\\"A\\\",\\n \\\"B\\\",\\n \\\"C\\\",\\n \\\"D\\\",\\n \\\"E\\\",\\n \\\"F\\\",\\n \\\"G\\\",\\n \\\"H\\\",\\n \\\"I\\\",\\n \\\"J\\\",\\n \\\"K\\\",\\n \\\"L\\\",\\n \\\"M\\\",\\n \\\"N\\\",\\n \\\"O\\\",\\n \\\"P\\\",\\n \\\"Q\\\",\\n \\\"R\\\",\\n \\\"S\\\",\\n \\\"T\\\",\\n \\\"U\\\",\\n \\\"V\\\",\\n \\\"W\\\",\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\",\\n \\\"bracketleft\\\",\\n \\\"backslash\\\",\\n \\\"bracketright\\\",\\n \\\"asciicircum\\\",\\n \\\"underscore\\\",\\n \\\"grave\\\",\\n \\\"a\\\",\\n \\\"b\\\",\\n \\\"c\\\",\\n \\\"d\\\",\\n \\\"e\\\",\\n \\\"f\\\",\\n \\\"g\\\",\\n \\\"h\\\",\\n \\\"i\\\",\\n \\\"j\\\",\\n \\\"k\\\",\\n \\\"l\\\",\\n \\\"m\\\",\\n \\\"n\\\",\\n \\\"o\\\",\\n \\\"p\\\",\\n \\\"q\\\",\\n \\\"r\\\",\\n \\\"s\\\",\\n \\\"t\\\",\\n \\\"u\\\",\\n \\\"v\\\",\\n \\\"w\\\",\\n \\\"x\\\",\\n \\\"y\\\",\\n \\\"z\\\",\\n \\\"braceleft\\\",\\n \\\"bar\\\",\\n \\\"braceright\\\",\\n \\\"asciitilde\\\",\\n \\\"Adieresis\\\",\\n \\\"Aring\\\",\\n \\\"Ccedilla\\\",\\n \\\"Eacute\\\",\\n \\\"Ntilde\\\",\\n \\\"Odieresis\\\",\\n \\\"Udieresis\\\",\\n \\\"aacute\\\",\\n \\\"agrave\\\",\\n \\\"acircumflex\\\",\\n \\\"adieresis\\\",\\n \\\"atilde\\\",\\n \\\"aring\\\",\\n \\\"ccedilla\\\",\\n \\\"eacute\\\",\\n \\\"egrave\\\",\\n \\\"ecircumflex\\\",\\n \\\"edieresis\\\",\\n \\\"iacute\\\",\\n \\\"igrave\\\",\\n \\\"icircumflex\\\",\\n \\\"idieresis\\\",\\n \\\"ntilde\\\",\\n \\\"oacute\\\",\\n \\\"ograve\\\",\\n \\\"ocircumflex\\\",\\n \\\"odieresis\\\",\\n \\\"otilde\\\",\\n \\\"uacute\\\",\\n \\\"ugrave\\\",\\n \\\"ucircumflex\\\",\\n \\\"udieresis\\\",\\n \\\"dagger\\\",\\n \\\"degree\\\",\\n \\\"cent\\\",\\n \\\"sterling\\\",\\n \\\"section\\\",\\n \\\"bullet\\\",\\n \\\"paragraph\\\",\\n \\\"germandbls\\\",\\n \\\"registered\\\",\\n \\\"copyright\\\",\\n \\\"trademark\\\",\\n \\\"acute\\\",\\n \\\"dieresis\\\",\\n \\\"notequal\\\",\\n \\\"AE\\\",\\n \\\"Oslash\\\",\\n \\\"infinity\\\",\\n \\\"plusminus\\\",\\n \\\"lessequal\\\",\\n \\\"greaterequal\\\",\\n \\\"yen\\\",\\n \\\"mu\\\",\\n \\\"partialdiff\\\",\\n \\\"summation\\\",\\n \\\"product\\\",\\n \\\"pi\\\",\\n \\\"integral\\\",\\n \\\"ordfeminine\\\",\\n \\\"ordmasculine\\\",\\n \\\"Omega\\\",\\n \\\"ae\\\",\\n \\\"oslash\\\",\\n \\\"questiondown\\\",\\n \\\"exclamdown\\\",\\n \\\"logicalnot\\\",\\n \\\"radical\\\",\\n \\\"florin\\\",\\n \\\"approxequal\\\",\\n \\\"Delta\\\",\\n \\\"guillemotleft\\\",\\n \\\"guillemotright\\\",\\n \\\"ellipsis\\\",\\n \\\"nonbreakingspace\\\",\\n \\\"Agrave\\\",\\n \\\"Atilde\\\",\\n \\\"Otilde\\\",\\n \\\"OE\\\",\\n \\\"oe\\\",\\n \\\"endash\\\",\\n \\\"emdash\\\",\\n \\\"quotedblleft\\\",\\n \\\"quotedblright\\\",\\n \\\"quoteleft\\\",\\n \\\"quoteright\\\",\\n \\\"divide\\\",\\n \\\"lozenge\\\",\\n \\\"ydieresis\\\",\\n \\\"Ydieresis\\\",\\n \\\"fraction\\\",\\n \\\"currency\\\",\\n \\\"guilsinglleft\\\",\\n \\\"guilsinglright\\\",\\n \\\"fi\\\",\\n \\\"fl\\\",\\n \\\"daggerdbl\\\",\\n \\\"periodcentered\\\",\\n \\\"quotesinglbase\\\",\\n \\\"quotedblbase\\\",\\n \\\"perthousand\\\",\\n \\\"Acircumflex\\\",\\n \\\"Ecircumflex\\\",\\n \\\"Aacute\\\",\\n \\\"Edieresis\\\",\\n \\\"Egrave\\\",\\n \\\"Iacute\\\",\\n \\\"Icircumflex\\\",\\n \\\"Idieresis\\\",\\n \\\"Igrave\\\",\\n \\\"Oacute\\\",\\n \\\"Ocircumflex\\\",\\n \\\"apple\\\",\\n \\\"Ograve\\\",\\n \\\"Uacute\\\",\\n \\\"Ucircumflex\\\",\\n \\\"Ugrave\\\",\\n \\\"dotlessi\\\",\\n \\\"circumflex\\\",\\n \\\"tilde\\\",\\n \\\"macron\\\",\\n \\\"breve\\\",\\n \\\"dotaccent\\\",\\n \\\"ring\\\",\\n \\\"cedilla\\\",\\n \\\"hungarumlaut\\\",\\n \\\"ogonek\\\",\\n \\\"caron\\\",\\n \\\"Lslash\\\",\\n \\\"lslash\\\",\\n \\\"Scaron\\\",\\n \\\"scaron\\\",\\n \\\"Zcaron\\\",\\n \\\"zcaron\\\",\\n \\\"brokenbar\\\",\\n \\\"Eth\\\",\\n \\\"eth\\\",\\n \\\"Yacute\\\",\\n \\\"yacute\\\",\\n \\\"Thorn\\\",\\n \\\"thorn\\\",\\n \\\"minus\\\",\\n \\\"multiply\\\",\\n \\\"onesuperior\\\",\\n \\\"twosuperior\\\",\\n \\\"threesuperior\\\",\\n \\\"onehalf\\\",\\n \\\"onequarter\\\",\\n \\\"threequarters\\\",\\n \\\"franc\\\",\\n \\\"Gbreve\\\",\\n \\\"gbreve\\\",\\n \\\"Idotaccent\\\",\\n \\\"Scedilla\\\",\\n \\\"scedilla\\\",\\n \\\"Cacute\\\",\\n \\\"cacute\\\",\\n \\\"Ccaron\\\",\\n \\\"ccaron\\\",\\n \\\"dcroat\\\"\\n ];\\n $f92906be28e61769$export$2e2bcd8739ae039 = class {\\n _getPath() {\\n return new (0, $f43aec954cdfdf21$export$2e2bcd8739ae039)();\\n }\\n _getCBox() {\\n return this.path.cbox;\\n }\\n _getBBox() {\\n return this.path.bbox;\\n }\\n _getTableMetrics(table) {\\n if (this.id < table.metrics.length) return table.metrics.get(this.id);\\n let metric = table.metrics.get(table.metrics.length - 1);\\n let res = {\\n advance: metric ? metric.advance : 0,\\n bearing: table.bearings.get(this.id - table.metrics.length) || 0\\n };\\n return res;\\n }\\n _getMetrics(cbox) {\\n if (this._metrics) return this._metrics;\\n let { advance: advanceWidth, bearing: leftBearing } = this._getTableMetrics(this._font.hmtx);\\n if (this._font.vmtx) var { advance: advanceHeight, bearing: topBearing } = this._getTableMetrics(this._font.vmtx);\\n else {\\n let os2;\\n if (typeof cbox === \\\"undefined\\\" || cbox === null) ({ cbox } = this);\\n if ((os2 = this._font[\\\"OS/2\\\"]) && os2.version > 0) {\\n var advanceHeight = Math.abs(os2.typoAscender - os2.typoDescender);\\n var topBearing = os2.typoAscender - cbox.maxY;\\n } else {\\n let { hhea } = this._font;\\n var advanceHeight = Math.abs(hhea.ascent - hhea.descent);\\n var topBearing = hhea.ascent - cbox.maxY;\\n }\\n }\\n if (this._font._variationProcessor && this._font.HVAR) advanceWidth += this._font._variationProcessor.getAdvanceAdjustment(this.id, this._font.HVAR);\\n return this._metrics = {\\n advanceWidth,\\n advanceHeight,\\n leftBearing,\\n topBearing\\n };\\n }\\n /**\\n * The glyph’s control box.\\n * This is often the same as the bounding box, but is faster to compute.\\n * Because of the way bezier curves are defined, some of the control points\\n * can be outside of the bounding box. Where `bbox` takes this into account,\\n * `cbox` does not. Thus, cbox is less accurate, but faster to compute.\\n * See [here](http://www.freetype.org/freetype2/docs/glyphs/glyphs-6.html#section-2)\\n * for a more detailed description.\\n *\\n * @type {BBox}\\n */\\n get cbox() {\\n return this._getCBox();\\n }\\n /**\\n * The glyph’s bounding box, i.e. the rectangle that encloses the\\n * glyph outline as tightly as possible.\\n * @type {BBox}\\n */\\n get bbox() {\\n return this._getBBox();\\n }\\n /**\\n * A vector Path object representing the glyph outline.\\n * @type {Path}\\n */\\n get path() {\\n return this._getPath();\\n }\\n /**\\n * Returns a path scaled to the given font size.\\n * @param {number} size\\n * @return {Path}\\n */\\n getScaledPath(size) {\\n let scale = 1 / this._font.unitsPerEm * size;\\n return this.path.scale(scale);\\n }\\n /**\\n * The glyph's advance width.\\n * @type {number}\\n */\\n get advanceWidth() {\\n return this._getMetrics().advanceWidth;\\n }\\n /**\\n * The glyph's advance height.\\n * @type {number}\\n */\\n get advanceHeight() {\\n return this._getMetrics().advanceHeight;\\n }\\n get ligatureCaretPositions() {\\n }\\n _getName() {\\n let { post } = this._font;\\n if (!post) return null;\\n switch (post.version) {\\n case 1:\\n return (0, $7713b9b7b438dff8$export$2e2bcd8739ae039)[this.id];\\n case 2:\\n let id = post.glyphNameIndex[this.id];\\n if (id < (0, $7713b9b7b438dff8$export$2e2bcd8739ae039).length) return (0, $7713b9b7b438dff8$export$2e2bcd8739ae039)[id];\\n return post.names[id - (0, $7713b9b7b438dff8$export$2e2bcd8739ae039).length];\\n case 2.5:\\n return (0, $7713b9b7b438dff8$export$2e2bcd8739ae039)[this.id + post.offsets[this.id]];\\n case 4:\\n return String.fromCharCode(post.map[this.id]);\\n }\\n }\\n /**\\n * The glyph's name\\n * @type {string}\\n */\\n get name() {\\n return this._getName();\\n }\\n /**\\n * Renders the glyph to the given graphics context, at the specified font size.\\n * @param {CanvasRenderingContext2d} ctx\\n * @param {number} size\\n */\\n render(ctx, size) {\\n ctx.save();\\n let scale = 1 / this._font.head.unitsPerEm * size;\\n ctx.scale(scale, scale);\\n let fn = this.path.toFunction();\\n fn(ctx);\\n ctx.fill();\\n ctx.restore();\\n }\\n constructor(id, codePoints, font) {\\n this.id = id;\\n this.codePoints = codePoints;\\n this._font = font;\\n this.isMark = this.codePoints.length > 0 && this.codePoints.every((0, $747425b437e121da$export$e33ad6871e762338));\\n this.isLigature = this.codePoints.length > 1;\\n }\\n };\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $f92906be28e61769$export$2e2bcd8739ae039.prototype, \\\"cbox\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $f92906be28e61769$export$2e2bcd8739ae039.prototype, \\\"bbox\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $f92906be28e61769$export$2e2bcd8739ae039.prototype, \\\"path\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $f92906be28e61769$export$2e2bcd8739ae039.prototype, \\\"advanceWidth\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $f92906be28e61769$export$2e2bcd8739ae039.prototype, \\\"advanceHeight\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $f92906be28e61769$export$2e2bcd8739ae039.prototype, \\\"name\\\", null);\\n $69aac16029968692$var$GlyfHeader = new Struct({\\n numberOfContours: int16,\\n xMin: int16,\\n yMin: int16,\\n xMax: int16,\\n yMax: int16\\n });\\n $69aac16029968692$var$ON_CURVE = 1;\\n $69aac16029968692$var$X_SHORT_VECTOR = 2;\\n $69aac16029968692$var$Y_SHORT_VECTOR = 4;\\n $69aac16029968692$var$REPEAT = 8;\\n $69aac16029968692$var$SAME_X = 16;\\n $69aac16029968692$var$SAME_Y = 32;\\n $69aac16029968692$var$ARG_1_AND_2_ARE_WORDS = 1;\\n $69aac16029968692$var$WE_HAVE_A_SCALE = 8;\\n $69aac16029968692$var$MORE_COMPONENTS = 32;\\n $69aac16029968692$var$WE_HAVE_AN_X_AND_Y_SCALE = 64;\\n $69aac16029968692$var$WE_HAVE_A_TWO_BY_TWO = 128;\\n $69aac16029968692$var$WE_HAVE_INSTRUCTIONS = 256;\\n $69aac16029968692$export$baf26146a414f24a = class _$69aac16029968692$export$baf26146a414f24a {\\n copy() {\\n return new _$69aac16029968692$export$baf26146a414f24a(this.onCurve, this.endContour, this.x, this.y);\\n }\\n constructor(onCurve, endContour, x = 0, y = 0) {\\n this.onCurve = onCurve;\\n this.endContour = endContour;\\n this.x = x;\\n this.y = y;\\n }\\n };\\n $69aac16029968692$var$Component = class {\\n constructor(glyphID, dx, dy) {\\n this.glyphID = glyphID;\\n this.dx = dx;\\n this.dy = dy;\\n this.pos = 0;\\n this.scaleX = this.scaleY = 1;\\n this.scale01 = this.scale10 = 0;\\n }\\n };\\n $69aac16029968692$export$2e2bcd8739ae039 = class extends (0, $f92906be28e61769$export$2e2bcd8739ae039) {\\n // Parses just the glyph header and returns the bounding box\\n _getCBox(internal) {\\n if (this._font._variationProcessor && !internal) return this.path.cbox;\\n let stream = this._font._getTableStream(\\\"glyf\\\");\\n stream.pos += this._font.loca.offsets[this.id];\\n let glyph = $69aac16029968692$var$GlyfHeader.decode(stream);\\n let cbox = new (0, $f34600ab9d7f70d8$export$2e2bcd8739ae039)(glyph.xMin, glyph.yMin, glyph.xMax, glyph.yMax);\\n return Object.freeze(cbox);\\n }\\n // Parses a single glyph coordinate\\n _parseGlyphCoord(stream, prev, short, same) {\\n if (short) {\\n var val = stream.readUInt8();\\n if (!same) val = -val;\\n val += prev;\\n } else if (same) var val = prev;\\n else var val = prev + stream.readInt16BE();\\n return val;\\n }\\n // Decodes the glyph data into points for simple glyphs,\\n // or components for composite glyphs\\n _decode() {\\n let glyfPos = this._font.loca.offsets[this.id];\\n let nextPos = this._font.loca.offsets[this.id + 1];\\n if (glyfPos === nextPos) return null;\\n let stream = this._font._getTableStream(\\\"glyf\\\");\\n stream.pos += glyfPos;\\n let startPos = stream.pos;\\n let glyph = $69aac16029968692$var$GlyfHeader.decode(stream);\\n if (glyph.numberOfContours > 0) this._decodeSimple(glyph, stream);\\n else if (glyph.numberOfContours < 0) this._decodeComposite(glyph, stream, startPos);\\n return glyph;\\n }\\n _decodeSimple(glyph, stream) {\\n glyph.points = [];\\n let endPtsOfContours = new ArrayT(uint16, glyph.numberOfContours).decode(stream);\\n glyph.instructions = new ArrayT(uint8, uint16).decode(stream);\\n let flags = [];\\n let numCoords = endPtsOfContours[endPtsOfContours.length - 1] + 1;\\n while (flags.length < numCoords) {\\n var flag = stream.readUInt8();\\n flags.push(flag);\\n if (flag & $69aac16029968692$var$REPEAT) {\\n let count = stream.readUInt8();\\n for (let j = 0; j < count; j++) flags.push(flag);\\n }\\n }\\n for (var i = 0; i < flags.length; i++) {\\n var flag = flags[i];\\n let point = new $69aac16029968692$export$baf26146a414f24a(!!(flag & $69aac16029968692$var$ON_CURVE), endPtsOfContours.indexOf(i) >= 0, 0, 0);\\n glyph.points.push(point);\\n }\\n let px = 0;\\n for (var i = 0; i < flags.length; i++) {\\n var flag = flags[i];\\n glyph.points[i].x = px = this._parseGlyphCoord(stream, px, flag & $69aac16029968692$var$X_SHORT_VECTOR, flag & $69aac16029968692$var$SAME_X);\\n }\\n let py = 0;\\n for (var i = 0; i < flags.length; i++) {\\n var flag = flags[i];\\n glyph.points[i].y = py = this._parseGlyphCoord(stream, py, flag & $69aac16029968692$var$Y_SHORT_VECTOR, flag & $69aac16029968692$var$SAME_Y);\\n }\\n if (this._font._variationProcessor) {\\n let points = glyph.points.slice();\\n points.push(...this._getPhantomPoints(glyph));\\n this._font._variationProcessor.transformPoints(this.id, points);\\n glyph.phantomPoints = points.slice(-4);\\n }\\n return;\\n }\\n _decodeComposite(glyph, stream, offset = 0) {\\n glyph.components = [];\\n let haveInstructions = false;\\n let flags = $69aac16029968692$var$MORE_COMPONENTS;\\n while (flags & $69aac16029968692$var$MORE_COMPONENTS) {\\n flags = stream.readUInt16BE();\\n let gPos = stream.pos - offset;\\n let glyphID = stream.readUInt16BE();\\n if (!haveInstructions) haveInstructions = (flags & $69aac16029968692$var$WE_HAVE_INSTRUCTIONS) !== 0;\\n if (flags & $69aac16029968692$var$ARG_1_AND_2_ARE_WORDS) {\\n var dx = stream.readInt16BE();\\n var dy = stream.readInt16BE();\\n } else {\\n var dx = stream.readInt8();\\n var dy = stream.readInt8();\\n }\\n var component = new $69aac16029968692$var$Component(glyphID, dx, dy);\\n component.pos = gPos;\\n if (flags & $69aac16029968692$var$WE_HAVE_A_SCALE)\\n component.scaleX = component.scaleY = (stream.readUInt8() << 24 | stream.readUInt8() << 16) / 1073741824;\\n else if (flags & $69aac16029968692$var$WE_HAVE_AN_X_AND_Y_SCALE) {\\n component.scaleX = (stream.readUInt8() << 24 | stream.readUInt8() << 16) / 1073741824;\\n component.scaleY = (stream.readUInt8() << 24 | stream.readUInt8() << 16) / 1073741824;\\n } else if (flags & $69aac16029968692$var$WE_HAVE_A_TWO_BY_TWO) {\\n component.scaleX = (stream.readUInt8() << 24 | stream.readUInt8() << 16) / 1073741824;\\n component.scale01 = (stream.readUInt8() << 24 | stream.readUInt8() << 16) / 1073741824;\\n component.scale10 = (stream.readUInt8() << 24 | stream.readUInt8() << 16) / 1073741824;\\n component.scaleY = (stream.readUInt8() << 24 | stream.readUInt8() << 16) / 1073741824;\\n }\\n glyph.components.push(component);\\n }\\n if (this._font._variationProcessor) {\\n let points = [];\\n for (let j = 0; j < glyph.components.length; j++) {\\n var component = glyph.components[j];\\n points.push(new $69aac16029968692$export$baf26146a414f24a(true, true, component.dx, component.dy));\\n }\\n points.push(...this._getPhantomPoints(glyph));\\n this._font._variationProcessor.transformPoints(this.id, points);\\n glyph.phantomPoints = points.splice(-4, 4);\\n for (let i = 0; i < points.length; i++) {\\n let point = points[i];\\n glyph.components[i].dx = point.x;\\n glyph.components[i].dy = point.y;\\n }\\n }\\n return haveInstructions;\\n }\\n _getPhantomPoints(glyph) {\\n let cbox = this._getCBox(true);\\n if (this._metrics == null) this._metrics = (0, $f92906be28e61769$export$2e2bcd8739ae039).prototype._getMetrics.call(this, cbox);\\n let { advanceWidth, advanceHeight, leftBearing, topBearing } = this._metrics;\\n return [\\n new $69aac16029968692$export$baf26146a414f24a(false, true, glyph.xMin - leftBearing, 0),\\n new $69aac16029968692$export$baf26146a414f24a(false, true, glyph.xMin - leftBearing + advanceWidth, 0),\\n new $69aac16029968692$export$baf26146a414f24a(false, true, 0, glyph.yMax + topBearing),\\n new $69aac16029968692$export$baf26146a414f24a(false, true, 0, glyph.yMax + topBearing + advanceHeight)\\n ];\\n }\\n // Decodes font data, resolves composite glyphs, and returns an array of contours\\n _getContours() {\\n let glyph = this._decode();\\n if (!glyph) return [];\\n let points = [];\\n if (glyph.numberOfContours < 0)\\n for (let component of glyph.components) {\\n let contours2 = this._font.getGlyph(component.glyphID)._getContours();\\n for (let i = 0; i < contours2.length; i++) {\\n let contour = contours2[i];\\n for (let j = 0; j < contour.length; j++) {\\n let point2 = contour[j];\\n let x = point2.x * component.scaleX + point2.y * component.scale01 + component.dx;\\n let y = point2.y * component.scaleY + point2.x * component.scale10 + component.dy;\\n points.push(new $69aac16029968692$export$baf26146a414f24a(point2.onCurve, point2.endContour, x, y));\\n }\\n }\\n }\\n else points = glyph.points || [];\\n if (glyph.phantomPoints && !this._font.directory.tables.HVAR) {\\n this._metrics.advanceWidth = glyph.phantomPoints[1].x - glyph.phantomPoints[0].x;\\n this._metrics.advanceHeight = glyph.phantomPoints[3].y - glyph.phantomPoints[2].y;\\n this._metrics.leftBearing = glyph.xMin - glyph.phantomPoints[0].x;\\n this._metrics.topBearing = glyph.phantomPoints[2].y - glyph.yMax;\\n }\\n let contours = [];\\n let cur = [];\\n for (let k = 0; k < points.length; k++) {\\n var point = points[k];\\n cur.push(point);\\n if (point.endContour) {\\n contours.push(cur);\\n cur = [];\\n }\\n }\\n return contours;\\n }\\n _getMetrics() {\\n if (this._metrics) return this._metrics;\\n let cbox = this._getCBox(true);\\n super._getMetrics(cbox);\\n if (this._font._variationProcessor && !this._font.HVAR)\\n this.path;\\n return this._metrics;\\n }\\n // Converts contours to a Path object that can be rendered\\n _getPath() {\\n let contours = this._getContours();\\n let path = new (0, $f43aec954cdfdf21$export$2e2bcd8739ae039)();\\n for (let i = 0; i < contours.length; i++) {\\n let contour = contours[i];\\n let firstPt = contour[0];\\n let lastPt = contour[contour.length - 1];\\n let start = 0;\\n if (firstPt.onCurve) {\\n var curvePt = null;\\n start = 1;\\n } else {\\n if (lastPt.onCurve)\\n firstPt = lastPt;\\n else\\n firstPt = new $69aac16029968692$export$baf26146a414f24a(false, false, (firstPt.x + lastPt.x) / 2, (firstPt.y + lastPt.y) / 2);\\n var curvePt = firstPt;\\n }\\n path.moveTo(firstPt.x, firstPt.y);\\n for (let j = start; j < contour.length; j++) {\\n let pt = contour[j];\\n let prevPt = j === 0 ? firstPt : contour[j - 1];\\n if (prevPt.onCurve && pt.onCurve) path.lineTo(pt.x, pt.y);\\n else if (prevPt.onCurve && !pt.onCurve) var curvePt = pt;\\n else if (!prevPt.onCurve && !pt.onCurve) {\\n let midX = (prevPt.x + pt.x) / 2;\\n let midY = (prevPt.y + pt.y) / 2;\\n path.quadraticCurveTo(prevPt.x, prevPt.y, midX, midY);\\n var curvePt = pt;\\n } else if (!prevPt.onCurve && pt.onCurve) {\\n path.quadraticCurveTo(curvePt.x, curvePt.y, pt.x, pt.y);\\n var curvePt = null;\\n } else throw new Error(\\\"Unknown TTF path state\\\");\\n }\\n if (curvePt) path.quadraticCurveTo(curvePt.x, curvePt.y, firstPt.x, firstPt.y);\\n path.closePath();\\n }\\n return path;\\n }\\n constructor(...args) {\\n super(...args);\\n (0, _define_property)(this, \\\"type\\\", \\\"TTF\\\");\\n }\\n };\\n $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e61769$export$2e2bcd8739ae039) {\\n _getName() {\\n if (this._font.CFF2) return super._getName();\\n return this._font[\\\"CFF \\\"].getGlyphName(this.id);\\n }\\n bias(s) {\\n if (s.length < 1240) return 107;\\n else if (s.length < 33900) return 1131;\\n else return 32768;\\n }\\n _getPath() {\\n let cff = this._font.CFF2 || this._font[\\\"CFF \\\"];\\n let { stream } = cff;\\n let str = cff.topDict.CharStrings[this.id];\\n let end = str.offset + str.length;\\n stream.pos = str.offset;\\n let path = new (0, $f43aec954cdfdf21$export$2e2bcd8739ae039)();\\n let stack = [];\\n let trans = [];\\n let width = null;\\n let nStems = 0;\\n let x = 0, y = 0;\\n let usedGsubrs;\\n let usedSubrs;\\n let open = false;\\n this._usedGsubrs = usedGsubrs = {};\\n this._usedSubrs = usedSubrs = {};\\n let gsubrs = cff.globalSubrIndex || [];\\n let gsubrsBias = this.bias(gsubrs);\\n let privateDict = cff.privateDictForGlyph(this.id) || {};\\n let subrs = privateDict.Subrs || [];\\n let subrsBias = this.bias(subrs);\\n let vstore = cff.topDict.vstore && cff.topDict.vstore.itemVariationStore;\\n let vsindex = privateDict.vsindex;\\n let variationProcessor = this._font._variationProcessor;\\n function checkWidth() {\\n if (width == null) width = stack.shift() + privateDict.nominalWidthX;\\n }\\n function parseStems() {\\n if (stack.length % 2 !== 0) checkWidth();\\n nStems += stack.length >> 1;\\n return stack.length = 0;\\n }\\n function moveTo(x2, y2) {\\n if (open) path.closePath();\\n path.moveTo(x2, y2);\\n open = true;\\n }\\n let parse = function() {\\n while (stream.pos < end) {\\n let op = stream.readUInt8();\\n if (op < 32) {\\n let index, subr, phase;\\n let c1x, c1y, c2x, c2y, c3x, c3y;\\n let c4x, c4y, c5x, c5y, c6x, c6y;\\n let pts;\\n switch (op) {\\n case 1:\\n case 3:\\n case 18:\\n case 23:\\n parseStems();\\n break;\\n case 4:\\n if (stack.length > 1) checkWidth();\\n y += stack.shift();\\n moveTo(x, y);\\n break;\\n case 5:\\n while (stack.length >= 2) {\\n x += stack.shift();\\n y += stack.shift();\\n path.lineTo(x, y);\\n }\\n break;\\n case 6:\\n case 7:\\n phase = op === 6;\\n while (stack.length >= 1) {\\n if (phase) x += stack.shift();\\n else y += stack.shift();\\n path.lineTo(x, y);\\n phase = !phase;\\n }\\n break;\\n case 8:\\n while (stack.length > 0) {\\n c1x = x + stack.shift();\\n c1y = y + stack.shift();\\n c2x = c1x + stack.shift();\\n c2y = c1y + stack.shift();\\n x = c2x + stack.shift();\\n y = c2y + stack.shift();\\n path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);\\n }\\n break;\\n case 10:\\n index = stack.pop() + subrsBias;\\n subr = subrs[index];\\n if (subr) {\\n usedSubrs[index] = true;\\n let p = stream.pos;\\n let e = end;\\n stream.pos = subr.offset;\\n end = subr.offset + subr.length;\\n parse();\\n stream.pos = p;\\n end = e;\\n }\\n break;\\n case 11:\\n if (cff.version >= 2) break;\\n return;\\n case 14:\\n if (cff.version >= 2) break;\\n if (stack.length > 0) checkWidth();\\n if (open) {\\n path.closePath();\\n open = false;\\n }\\n break;\\n case 15:\\n if (cff.version < 2) throw new Error(\\\"vsindex operator not supported in CFF v1\\\");\\n vsindex = stack.pop();\\n break;\\n case 16: {\\n if (cff.version < 2) throw new Error(\\\"blend operator not supported in CFF v1\\\");\\n if (!variationProcessor) throw new Error(\\\"blend operator in non-variation font\\\");\\n let blendVector = variationProcessor.getBlendVector(vstore, vsindex);\\n let numBlends = stack.pop();\\n let numOperands = numBlends * blendVector.length;\\n let delta = stack.length - numOperands;\\n let base = delta - numBlends;\\n for (let i = 0; i < numBlends; i++) {\\n let sum = stack[base + i];\\n for (let j = 0; j < blendVector.length; j++) sum += blendVector[j] * stack[delta++];\\n stack[base + i] = sum;\\n }\\n while (numOperands--) stack.pop();\\n break;\\n }\\n case 19:\\n case 20:\\n parseStems();\\n stream.pos += nStems + 7 >> 3;\\n break;\\n case 21:\\n if (stack.length > 2) checkWidth();\\n x += stack.shift();\\n y += stack.shift();\\n moveTo(x, y);\\n break;\\n case 22:\\n if (stack.length > 1) checkWidth();\\n x += stack.shift();\\n moveTo(x, y);\\n break;\\n case 24:\\n while (stack.length >= 8) {\\n c1x = x + stack.shift();\\n c1y = y + stack.shift();\\n c2x = c1x + stack.shift();\\n c2y = c1y + stack.shift();\\n x = c2x + stack.shift();\\n y = c2y + stack.shift();\\n path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);\\n }\\n x += stack.shift();\\n y += stack.shift();\\n path.lineTo(x, y);\\n break;\\n case 25:\\n while (stack.length >= 8) {\\n x += stack.shift();\\n y += stack.shift();\\n path.lineTo(x, y);\\n }\\n c1x = x + stack.shift();\\n c1y = y + stack.shift();\\n c2x = c1x + stack.shift();\\n c2y = c1y + stack.shift();\\n x = c2x + stack.shift();\\n y = c2y + stack.shift();\\n path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);\\n break;\\n case 26:\\n if (stack.length % 2) x += stack.shift();\\n while (stack.length >= 4) {\\n c1x = x;\\n c1y = y + stack.shift();\\n c2x = c1x + stack.shift();\\n c2y = c1y + stack.shift();\\n x = c2x;\\n y = c2y + stack.shift();\\n path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);\\n }\\n break;\\n case 27:\\n if (stack.length % 2) y += stack.shift();\\n while (stack.length >= 4) {\\n c1x = x + stack.shift();\\n c1y = y;\\n c2x = c1x + stack.shift();\\n c2y = c1y + stack.shift();\\n x = c2x + stack.shift();\\n y = c2y;\\n path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);\\n }\\n break;\\n case 28:\\n stack.push(stream.readInt16BE());\\n break;\\n case 29:\\n index = stack.pop() + gsubrsBias;\\n subr = gsubrs[index];\\n if (subr) {\\n usedGsubrs[index] = true;\\n let p = stream.pos;\\n let e = end;\\n stream.pos = subr.offset;\\n end = subr.offset + subr.length;\\n parse();\\n stream.pos = p;\\n end = e;\\n }\\n break;\\n case 30:\\n case 31:\\n phase = op === 31;\\n while (stack.length >= 4) {\\n if (phase) {\\n c1x = x + stack.shift();\\n c1y = y;\\n c2x = c1x + stack.shift();\\n c2y = c1y + stack.shift();\\n y = c2y + stack.shift();\\n x = c2x + (stack.length === 1 ? stack.shift() : 0);\\n } else {\\n c1x = x;\\n c1y = y + stack.shift();\\n c2x = c1x + stack.shift();\\n c2y = c1y + stack.shift();\\n x = c2x + stack.shift();\\n y = c2y + (stack.length === 1 ? stack.shift() : 0);\\n }\\n path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);\\n phase = !phase;\\n }\\n break;\\n case 12:\\n op = stream.readUInt8();\\n switch (op) {\\n case 3:\\n let a = stack.pop();\\n let b = stack.pop();\\n stack.push(a && b ? 1 : 0);\\n break;\\n case 4:\\n a = stack.pop();\\n b = stack.pop();\\n stack.push(a || b ? 1 : 0);\\n break;\\n case 5:\\n a = stack.pop();\\n stack.push(a ? 0 : 1);\\n break;\\n case 9:\\n a = stack.pop();\\n stack.push(Math.abs(a));\\n break;\\n case 10:\\n a = stack.pop();\\n b = stack.pop();\\n stack.push(a + b);\\n break;\\n case 11:\\n a = stack.pop();\\n b = stack.pop();\\n stack.push(a - b);\\n break;\\n case 12:\\n a = stack.pop();\\n b = stack.pop();\\n stack.push(a / b);\\n break;\\n case 14:\\n a = stack.pop();\\n stack.push(-a);\\n break;\\n case 15:\\n a = stack.pop();\\n b = stack.pop();\\n stack.push(a === b ? 1 : 0);\\n break;\\n case 18:\\n stack.pop();\\n break;\\n case 20:\\n let val = stack.pop();\\n let idx = stack.pop();\\n trans[idx] = val;\\n break;\\n case 21:\\n idx = stack.pop();\\n stack.push(trans[idx] || 0);\\n break;\\n case 22:\\n let s1 = stack.pop();\\n let s2 = stack.pop();\\n let v1 = stack.pop();\\n let v2 = stack.pop();\\n stack.push(v1 <= v2 ? s1 : s2);\\n break;\\n case 23:\\n stack.push(Math.random());\\n break;\\n case 24:\\n a = stack.pop();\\n b = stack.pop();\\n stack.push(a * b);\\n break;\\n case 26:\\n a = stack.pop();\\n stack.push(Math.sqrt(a));\\n break;\\n case 27:\\n a = stack.pop();\\n stack.push(a, a);\\n break;\\n case 28:\\n a = stack.pop();\\n b = stack.pop();\\n stack.push(b, a);\\n break;\\n case 29:\\n idx = stack.pop();\\n if (idx < 0) idx = 0;\\n else if (idx > stack.length - 1) idx = stack.length - 1;\\n stack.push(stack[idx]);\\n break;\\n case 30:\\n let n = stack.pop();\\n let j = stack.pop();\\n if (j >= 0) while (j > 0) {\\n var t = stack[n - 1];\\n for (let i = n - 2; i >= 0; i--) stack[i + 1] = stack[i];\\n stack[0] = t;\\n j--;\\n }\\n else while (j < 0) {\\n var t = stack[0];\\n for (let i = 0; i <= n; i++) stack[i] = stack[i + 1];\\n stack[n - 1] = t;\\n j++;\\n }\\n break;\\n case 34:\\n c1x = x + stack.shift();\\n c1y = y;\\n c2x = c1x + stack.shift();\\n c2y = c1y + stack.shift();\\n c3x = c2x + stack.shift();\\n c3y = c2y;\\n c4x = c3x + stack.shift();\\n c4y = c3y;\\n c5x = c4x + stack.shift();\\n c5y = c4y;\\n c6x = c5x + stack.shift();\\n c6y = c5y;\\n x = c6x;\\n y = c6y;\\n path.bezierCurveTo(c1x, c1y, c2x, c2y, c3x, c3y);\\n path.bezierCurveTo(c4x, c4y, c5x, c5y, c6x, c6y);\\n break;\\n case 35:\\n pts = [];\\n for (let i = 0; i <= 5; i++) {\\n x += stack.shift();\\n y += stack.shift();\\n pts.push(x, y);\\n }\\n path.bezierCurveTo(...pts.slice(0, 6));\\n path.bezierCurveTo(...pts.slice(6));\\n stack.shift();\\n break;\\n case 36:\\n c1x = x + stack.shift();\\n c1y = y + stack.shift();\\n c2x = c1x + stack.shift();\\n c2y = c1y + stack.shift();\\n c3x = c2x + stack.shift();\\n c3y = c2y;\\n c4x = c3x + stack.shift();\\n c4y = c3y;\\n c5x = c4x + stack.shift();\\n c5y = c4y + stack.shift();\\n c6x = c5x + stack.shift();\\n c6y = c5y;\\n x = c6x;\\n y = c6y;\\n path.bezierCurveTo(c1x, c1y, c2x, c2y, c3x, c3y);\\n path.bezierCurveTo(c4x, c4y, c5x, c5y, c6x, c6y);\\n break;\\n case 37:\\n let startx = x;\\n let starty = y;\\n pts = [];\\n for (let i = 0; i <= 4; i++) {\\n x += stack.shift();\\n y += stack.shift();\\n pts.push(x, y);\\n }\\n if (Math.abs(x - startx) > Math.abs(y - starty)) {\\n x += stack.shift();\\n y = starty;\\n } else {\\n x = startx;\\n y += stack.shift();\\n }\\n pts.push(x, y);\\n path.bezierCurveTo(...pts.slice(0, 6));\\n path.bezierCurveTo(...pts.slice(6));\\n break;\\n default:\\n throw new Error(`Unknown op: 12 ${op}`);\\n }\\n break;\\n default:\\n throw new Error(`Unknown op: ${op}`);\\n }\\n } else if (op < 247) stack.push(op - 139);\\n else if (op < 251) {\\n var b1 = stream.readUInt8();\\n stack.push((op - 247) * 256 + b1 + 108);\\n } else if (op < 255) {\\n var b1 = stream.readUInt8();\\n stack.push(-(op - 251) * 256 - b1 - 108);\\n } else stack.push(stream.readInt32BE() / 65536);\\n }\\n };\\n parse();\\n if (open) path.closePath();\\n return path;\\n }\\n constructor(...args) {\\n super(...args);\\n (0, _define_property)(this, \\\"type\\\", \\\"CFF\\\");\\n }\\n };\\n $25d8f049c222084c$var$SBIXImage = new Struct({\\n originX: uint16,\\n originY: uint16,\\n type: new StringT(4),\\n data: new BufferT((t) => t.parent.buflen - t._currentOffset)\\n });\\n $25d8f049c222084c$export$2e2bcd8739ae039 = class extends (0, $69aac16029968692$export$2e2bcd8739ae039) {\\n /**\\n * Returns an object representing a glyph image at the given point size.\\n * The object has a data property with a Buffer containing the actual image data,\\n * along with the image type, and origin.\\n *\\n * @param {number} size\\n * @return {object}\\n */\\n getImageForSize(size) {\\n for (let i = 0; i < this._font.sbix.imageTables.length; i++) {\\n var table = this._font.sbix.imageTables[i];\\n if (table.ppem >= size) break;\\n }\\n let offsets = table.imageOffsets;\\n let start = offsets[this.id];\\n let end = offsets[this.id + 1];\\n if (start === end) return null;\\n this._font.stream.pos = start;\\n return $25d8f049c222084c$var$SBIXImage.decode(this._font.stream, {\\n buflen: end - start\\n });\\n }\\n render(ctx, size) {\\n let img = this.getImageForSize(size);\\n if (img != null) {\\n let scale = size / this._font.unitsPerEm;\\n ctx.image(img.data, {\\n height: size,\\n x: img.originX,\\n y: (this.bbox.minY - img.originY) * scale\\n });\\n }\\n if (this._font.sbix.flags.renderOutlines) super.render(ctx, size);\\n }\\n constructor(...args) {\\n super(...args);\\n (0, _define_property)(this, \\\"type\\\", \\\"SBIX\\\");\\n }\\n };\\n $0d411f0165859681$var$COLRLayer = class {\\n constructor(glyph, color) {\\n this.glyph = glyph;\\n this.color = color;\\n }\\n };\\n $0d411f0165859681$export$2e2bcd8739ae039 = class extends (0, $f92906be28e61769$export$2e2bcd8739ae039) {\\n _getBBox() {\\n let bbox = new (0, $f34600ab9d7f70d8$export$2e2bcd8739ae039)();\\n for (let i = 0; i < this.layers.length; i++) {\\n let layer = this.layers[i];\\n let b = layer.glyph.bbox;\\n bbox.addPoint(b.minX, b.minY);\\n bbox.addPoint(b.maxX, b.maxY);\\n }\\n return bbox;\\n }\\n /**\\n * Returns an array of objects containing the glyph and color for\\n * each layer in the composite color glyph.\\n * @type {object[]}\\n */\\n get layers() {\\n let cpal = this._font.CPAL;\\n let colr = this._font.COLR;\\n let low = 0;\\n let high = colr.baseGlyphRecord.length - 1;\\n while (low <= high) {\\n let mid = low + high >> 1;\\n var rec = colr.baseGlyphRecord[mid];\\n if (this.id < rec.gid) high = mid - 1;\\n else if (this.id > rec.gid) low = mid + 1;\\n else {\\n var baseLayer = rec;\\n break;\\n }\\n }\\n if (baseLayer == null) {\\n var g = this._font._getBaseGlyph(this.id);\\n var color = {\\n red: 0,\\n green: 0,\\n blue: 0,\\n alpha: 255\\n };\\n return [\\n new $0d411f0165859681$var$COLRLayer(g, color)\\n ];\\n }\\n let layers = [];\\n for (let i = baseLayer.firstLayerIndex; i < baseLayer.firstLayerIndex + baseLayer.numLayers; i++) {\\n var rec = colr.layerRecords[i];\\n var color = cpal.colorRecords[rec.paletteIndex];\\n var g = this._font._getBaseGlyph(rec.gid);\\n layers.push(new $0d411f0165859681$var$COLRLayer(g, color));\\n }\\n return layers;\\n }\\n render(ctx, size) {\\n for (let { glyph, color } of this.layers) {\\n ctx.fillColor([\\n color.red,\\n color.green,\\n color.blue\\n ], color.alpha / 255 * 100);\\n glyph.render(ctx, size);\\n }\\n return;\\n }\\n constructor(...args) {\\n super(...args);\\n (0, _define_property)(this, \\\"type\\\", \\\"COLR\\\");\\n }\\n };\\n $0bb840cac04e911b$var$TUPLES_SHARE_POINT_NUMBERS = 32768;\\n $0bb840cac04e911b$var$TUPLE_COUNT_MASK = 4095;\\n $0bb840cac04e911b$var$EMBEDDED_TUPLE_COORD = 32768;\\n $0bb840cac04e911b$var$INTERMEDIATE_TUPLE = 16384;\\n $0bb840cac04e911b$var$PRIVATE_POINT_NUMBERS = 8192;\\n $0bb840cac04e911b$var$TUPLE_INDEX_MASK = 4095;\\n $0bb840cac04e911b$var$POINTS_ARE_WORDS = 128;\\n $0bb840cac04e911b$var$POINT_RUN_COUNT_MASK = 127;\\n $0bb840cac04e911b$var$DELTAS_ARE_ZERO = 128;\\n $0bb840cac04e911b$var$DELTAS_ARE_WORDS = 64;\\n $0bb840cac04e911b$var$DELTA_RUN_COUNT_MASK = 63;\\n $0bb840cac04e911b$export$2e2bcd8739ae039 = class {\\n normalizeCoords(coords) {\\n let normalized = [];\\n for (var i = 0; i < this.font.fvar.axis.length; i++) {\\n let axis = this.font.fvar.axis[i];\\n if (coords[i] < axis.defaultValue) normalized.push((coords[i] - axis.defaultValue + Number.EPSILON) / (axis.defaultValue - axis.minValue + Number.EPSILON));\\n else normalized.push((coords[i] - axis.defaultValue + Number.EPSILON) / (axis.maxValue - axis.defaultValue + Number.EPSILON));\\n }\\n if (this.font.avar) for (var i = 0; i < this.font.avar.segment.length; i++) {\\n let segment = this.font.avar.segment[i];\\n for (let j = 0; j < segment.correspondence.length; j++) {\\n let pair = segment.correspondence[j];\\n if (j >= 1 && normalized[i] < pair.fromCoord) {\\n let prev = segment.correspondence[j - 1];\\n normalized[i] = ((normalized[i] - prev.fromCoord) * (pair.toCoord - prev.toCoord) + Number.EPSILON) / (pair.fromCoord - prev.fromCoord + Number.EPSILON) + prev.toCoord;\\n break;\\n }\\n }\\n }\\n return normalized;\\n }\\n transformPoints(gid, glyphPoints) {\\n if (!this.font.fvar || !this.font.gvar) return;\\n let { gvar } = this.font;\\n if (gid >= gvar.glyphCount) return;\\n let offset = gvar.offsets[gid];\\n if (offset === gvar.offsets[gid + 1]) return;\\n let { stream } = this.font;\\n stream.pos = offset;\\n if (stream.pos >= stream.length) return;\\n let tupleCount = stream.readUInt16BE();\\n let offsetToData = offset + stream.readUInt16BE();\\n if (tupleCount & $0bb840cac04e911b$var$TUPLES_SHARE_POINT_NUMBERS) {\\n var here = stream.pos;\\n stream.pos = offsetToData;\\n var sharedPoints = this.decodePoints();\\n offsetToData = stream.pos;\\n stream.pos = here;\\n }\\n let origPoints = glyphPoints.map((pt) => pt.copy());\\n tupleCount &= $0bb840cac04e911b$var$TUPLE_COUNT_MASK;\\n for (let i = 0; i < tupleCount; i++) {\\n let tupleDataSize = stream.readUInt16BE();\\n let tupleIndex = stream.readUInt16BE();\\n if (tupleIndex & $0bb840cac04e911b$var$EMBEDDED_TUPLE_COORD) {\\n var tupleCoords = [];\\n for (let a = 0; a < gvar.axisCount; a++) tupleCoords.push(stream.readInt16BE() / 16384);\\n } else {\\n if ((tupleIndex & $0bb840cac04e911b$var$TUPLE_INDEX_MASK) >= gvar.globalCoordCount) throw new Error(\\\"Invalid gvar table\\\");\\n var tupleCoords = gvar.globalCoords[tupleIndex & $0bb840cac04e911b$var$TUPLE_INDEX_MASK];\\n }\\n if (tupleIndex & $0bb840cac04e911b$var$INTERMEDIATE_TUPLE) {\\n var startCoords = [];\\n for (let a = 0; a < gvar.axisCount; a++) startCoords.push(stream.readInt16BE() / 16384);\\n var endCoords = [];\\n for (let a = 0; a < gvar.axisCount; a++) endCoords.push(stream.readInt16BE() / 16384);\\n }\\n let factor = this.tupleFactor(tupleIndex, tupleCoords, startCoords, endCoords);\\n if (factor === 0) {\\n offsetToData += tupleDataSize;\\n continue;\\n }\\n var here = stream.pos;\\n stream.pos = offsetToData;\\n if (tupleIndex & $0bb840cac04e911b$var$PRIVATE_POINT_NUMBERS) var points = this.decodePoints();\\n else var points = sharedPoints;\\n let nPoints = points.length === 0 ? glyphPoints.length : points.length;\\n let xDeltas = this.decodeDeltas(nPoints);\\n let yDeltas = this.decodeDeltas(nPoints);\\n if (points.length === 0) for (let i2 = 0; i2 < glyphPoints.length; i2++) {\\n var point = glyphPoints[i2];\\n point.x += Math.round(xDeltas[i2] * factor);\\n point.y += Math.round(yDeltas[i2] * factor);\\n }\\n else {\\n let outPoints = origPoints.map((pt) => pt.copy());\\n let hasDelta = glyphPoints.map(() => false);\\n for (let i2 = 0; i2 < points.length; i2++) {\\n let idx = points[i2];\\n if (idx < glyphPoints.length) {\\n let point2 = outPoints[idx];\\n hasDelta[idx] = true;\\n point2.x += xDeltas[i2] * factor;\\n point2.y += yDeltas[i2] * factor;\\n }\\n }\\n this.interpolateMissingDeltas(outPoints, origPoints, hasDelta);\\n for (let i2 = 0; i2 < glyphPoints.length; i2++) {\\n let deltaX = outPoints[i2].x - origPoints[i2].x;\\n let deltaY = outPoints[i2].y - origPoints[i2].y;\\n glyphPoints[i2].x = Math.round(glyphPoints[i2].x + deltaX);\\n glyphPoints[i2].y = Math.round(glyphPoints[i2].y + deltaY);\\n }\\n }\\n offsetToData += tupleDataSize;\\n stream.pos = here;\\n }\\n }\\n decodePoints() {\\n let stream = this.font.stream;\\n let count = stream.readUInt8();\\n if (count & $0bb840cac04e911b$var$POINTS_ARE_WORDS) count = (count & $0bb840cac04e911b$var$POINT_RUN_COUNT_MASK) << 8 | stream.readUInt8();\\n let points = new Uint16Array(count);\\n let i = 0;\\n let point = 0;\\n while (i < count) {\\n let run = stream.readUInt8();\\n let runCount = (run & $0bb840cac04e911b$var$POINT_RUN_COUNT_MASK) + 1;\\n let fn = run & $0bb840cac04e911b$var$POINTS_ARE_WORDS ? stream.readUInt16 : stream.readUInt8;\\n for (let j = 0; j < runCount && i < count; j++) {\\n point += fn.call(stream);\\n points[i++] = point;\\n }\\n }\\n return points;\\n }\\n decodeDeltas(count) {\\n let stream = this.font.stream;\\n let i = 0;\\n let deltas = new Int16Array(count);\\n while (i < count) {\\n let run = stream.readUInt8();\\n let runCount = (run & $0bb840cac04e911b$var$DELTA_RUN_COUNT_MASK) + 1;\\n if (run & $0bb840cac04e911b$var$DELTAS_ARE_ZERO) i += runCount;\\n else {\\n let fn = run & $0bb840cac04e911b$var$DELTAS_ARE_WORDS ? stream.readInt16BE : stream.readInt8;\\n for (let j = 0; j < runCount && i < count; j++) deltas[i++] = fn.call(stream);\\n }\\n }\\n return deltas;\\n }\\n tupleFactor(tupleIndex, tupleCoords, startCoords, endCoords) {\\n let normalized = this.normalizedCoords;\\n let { gvar } = this.font;\\n let factor = 1;\\n for (let i = 0; i < gvar.axisCount; i++) {\\n if (tupleCoords[i] === 0) continue;\\n if (normalized[i] === 0) return 0;\\n if ((tupleIndex & $0bb840cac04e911b$var$INTERMEDIATE_TUPLE) === 0) {\\n if (normalized[i] < Math.min(0, tupleCoords[i]) || normalized[i] > Math.max(0, tupleCoords[i])) return 0;\\n factor = (factor * normalized[i] + Number.EPSILON) / (tupleCoords[i] + Number.EPSILON);\\n } else {\\n if (normalized[i] < startCoords[i] || normalized[i] > endCoords[i]) return 0;\\n else if (normalized[i] < tupleCoords[i]) factor = factor * (normalized[i] - startCoords[i] + Number.EPSILON) / (tupleCoords[i] - startCoords[i] + Number.EPSILON);\\n else factor = factor * (endCoords[i] - normalized[i] + Number.EPSILON) / (endCoords[i] - tupleCoords[i] + Number.EPSILON);\\n }\\n }\\n return factor;\\n }\\n // Interpolates points without delta values.\\n // Needed for the Ø and Q glyphs in Skia.\\n // Algorithm from Freetype.\\n interpolateMissingDeltas(points, inPoints, hasDelta) {\\n if (points.length === 0) return;\\n let point = 0;\\n while (point < points.length) {\\n let firstPoint = point;\\n let endPoint = point;\\n let pt = points[endPoint];\\n while (!pt.endContour) pt = points[++endPoint];\\n while (point <= endPoint && !hasDelta[point]) point++;\\n if (point > endPoint) continue;\\n let firstDelta = point;\\n let curDelta = point;\\n point++;\\n while (point <= endPoint) {\\n if (hasDelta[point]) {\\n this.deltaInterpolate(curDelta + 1, point - 1, curDelta, point, inPoints, points);\\n curDelta = point;\\n }\\n point++;\\n }\\n if (curDelta === firstDelta) this.deltaShift(firstPoint, endPoint, curDelta, inPoints, points);\\n else {\\n this.deltaInterpolate(curDelta + 1, endPoint, curDelta, firstDelta, inPoints, points);\\n if (firstDelta > 0) this.deltaInterpolate(firstPoint, firstDelta - 1, curDelta, firstDelta, inPoints, points);\\n }\\n point = endPoint + 1;\\n }\\n }\\n deltaInterpolate(p1, p2, ref1, ref2, inPoints, outPoints) {\\n if (p1 > p2) return;\\n let iterable = [\\n \\\"x\\\",\\n \\\"y\\\"\\n ];\\n for (let i = 0; i < iterable.length; i++) {\\n let k = iterable[i];\\n if (inPoints[ref1][k] > inPoints[ref2][k]) {\\n var p = ref1;\\n ref1 = ref2;\\n ref2 = p;\\n }\\n let in1 = inPoints[ref1][k];\\n let in2 = inPoints[ref2][k];\\n let out1 = outPoints[ref1][k];\\n let out2 = outPoints[ref2][k];\\n if (in1 !== in2 || out1 === out2) {\\n let scale = in1 === in2 ? 0 : (out2 - out1) / (in2 - in1);\\n for (let p3 = p1; p3 <= p2; p3++) {\\n let out = inPoints[p3][k];\\n if (out <= in1) out += out1 - in1;\\n else if (out >= in2) out += out2 - in2;\\n else out = out1 + (out - in1) * scale;\\n outPoints[p3][k] = out;\\n }\\n }\\n }\\n }\\n deltaShift(p1, p2, ref, inPoints, outPoints) {\\n let deltaX = outPoints[ref].x - inPoints[ref].x;\\n let deltaY = outPoints[ref].y - inPoints[ref].y;\\n if (deltaX === 0 && deltaY === 0) return;\\n for (let p = p1; p <= p2; p++) if (p !== ref) {\\n outPoints[p].x += deltaX;\\n outPoints[p].y += deltaY;\\n }\\n }\\n getAdvanceAdjustment(gid, table) {\\n let outerIndex, innerIndex;\\n if (table.advanceWidthMapping) {\\n let idx = gid;\\n if (idx >= table.advanceWidthMapping.mapCount) idx = table.advanceWidthMapping.mapCount - 1;\\n let entryFormat = table.advanceWidthMapping.entryFormat;\\n ({ outerIndex, innerIndex } = table.advanceWidthMapping.mapData[idx]);\\n } else {\\n outerIndex = 0;\\n innerIndex = gid;\\n }\\n return this.getDelta(table.itemVariationStore, outerIndex, innerIndex);\\n }\\n // See pseudo code from `Font Variations Overview'\\n // in the OpenType specification.\\n getDelta(itemStore, outerIndex, innerIndex) {\\n if (outerIndex >= itemStore.itemVariationData.length) return 0;\\n let varData = itemStore.itemVariationData[outerIndex];\\n if (innerIndex >= varData.deltaSets.length) return 0;\\n let deltaSet = varData.deltaSets[innerIndex];\\n let blendVector = this.getBlendVector(itemStore, outerIndex);\\n let netAdjustment = 0;\\n for (let master = 0; master < varData.regionIndexCount; master++) netAdjustment += deltaSet.deltas[master] * blendVector[master];\\n return netAdjustment;\\n }\\n getBlendVector(itemStore, outerIndex) {\\n let varData = itemStore.itemVariationData[outerIndex];\\n if (this.blendVectors.has(varData)) return this.blendVectors.get(varData);\\n let normalizedCoords = this.normalizedCoords;\\n let blendVector = [];\\n for (let master = 0; master < varData.regionIndexCount; master++) {\\n let scalar = 1;\\n let regionIndex = varData.regionIndexes[master];\\n let axes = itemStore.variationRegionList.variationRegions[regionIndex];\\n for (let j = 0; j < axes.length; j++) {\\n let axis = axes[j];\\n let axisScalar;\\n if (axis.startCoord > axis.peakCoord || axis.peakCoord > axis.endCoord) axisScalar = 1;\\n else if (axis.startCoord < 0 && axis.endCoord > 0 && axis.peakCoord !== 0) axisScalar = 1;\\n else if (axis.peakCoord === 0) axisScalar = 1;\\n else if (normalizedCoords[j] < axis.startCoord || normalizedCoords[j] > axis.endCoord) axisScalar = 0;\\n else {\\n if (normalizedCoords[j] === axis.peakCoord) axisScalar = 1;\\n else if (normalizedCoords[j] < axis.peakCoord) axisScalar = (normalizedCoords[j] - axis.startCoord + Number.EPSILON) / (axis.peakCoord - axis.startCoord + Number.EPSILON);\\n else axisScalar = (axis.endCoord - normalizedCoords[j] + Number.EPSILON) / (axis.endCoord - axis.peakCoord + Number.EPSILON);\\n }\\n scalar *= axisScalar;\\n }\\n blendVector[master] = scalar;\\n }\\n this.blendVectors.set(varData, blendVector);\\n return blendVector;\\n }\\n constructor(font, coords) {\\n this.font = font;\\n this.normalizedCoords = this.normalizeCoords(coords);\\n this.blendVectors = /* @__PURE__ */ new Map();\\n }\\n };\\n $5cc7476da92df375$var$resolved = Promise.resolve();\\n $5cc7476da92df375$export$2e2bcd8739ae039 = class {\\n includeGlyph(glyph) {\\n if (typeof glyph === \\\"object\\\") glyph = glyph.id;\\n if (this.mapping[glyph] == null) {\\n this.glyphs.push(glyph);\\n this.mapping[glyph] = this.glyphs.length - 1;\\n }\\n return this.mapping[glyph];\\n }\\n constructor(font) {\\n this.font = font;\\n this.glyphs = [];\\n this.mapping = {};\\n this.includeGlyph(0);\\n }\\n };\\n $807e58506be70005$var$ON_CURVE = 1;\\n $807e58506be70005$var$X_SHORT_VECTOR = 2;\\n $807e58506be70005$var$Y_SHORT_VECTOR = 4;\\n $807e58506be70005$var$REPEAT = 8;\\n $807e58506be70005$var$SAME_X = 16;\\n $807e58506be70005$var$SAME_Y = 32;\\n $807e58506be70005$var$Point = class {\\n static size(val) {\\n return val >= 0 && val <= 255 ? 1 : 2;\\n }\\n static encode(stream, value) {\\n if (value >= 0 && value <= 255) stream.writeUInt8(value);\\n else stream.writeInt16BE(value);\\n }\\n };\\n $807e58506be70005$var$Glyf = new Struct({\\n numberOfContours: int16,\\n xMin: int16,\\n yMin: int16,\\n xMax: int16,\\n yMax: int16,\\n endPtsOfContours: new ArrayT(uint16, \\\"numberOfContours\\\"),\\n instructions: new ArrayT(uint8, uint16),\\n flags: new ArrayT(uint8, 0),\\n xPoints: new ArrayT($807e58506be70005$var$Point, 0),\\n yPoints: new ArrayT($807e58506be70005$var$Point, 0)\\n });\\n $807e58506be70005$export$2e2bcd8739ae039 = class {\\n encodeSimple(path, instructions = []) {\\n let endPtsOfContours = [];\\n let xPoints = [];\\n let yPoints = [];\\n let flags = [];\\n let same = 0;\\n let lastX = 0, lastY = 0, lastFlag = 0;\\n let pointCount = 0;\\n for (let i = 0; i < path.commands.length; i++) {\\n let c = path.commands[i];\\n for (let j = 0; j < c.args.length; j += 2) {\\n let x = c.args[j];\\n let y = c.args[j + 1];\\n let flag = 0;\\n if (c.command === \\\"quadraticCurveTo\\\" && j === 2) {\\n let next = path.commands[i + 1];\\n if (next && next.command === \\\"quadraticCurveTo\\\") {\\n let midX = (lastX + next.args[0]) / 2;\\n let midY = (lastY + next.args[1]) / 2;\\n if (x === midX && y === midY) continue;\\n }\\n }\\n if (!(c.command === \\\"quadraticCurveTo\\\" && j === 0)) flag |= $807e58506be70005$var$ON_CURVE;\\n flag = this._encodePoint(x, lastX, xPoints, flag, $807e58506be70005$var$X_SHORT_VECTOR, $807e58506be70005$var$SAME_X);\\n flag = this._encodePoint(y, lastY, yPoints, flag, $807e58506be70005$var$Y_SHORT_VECTOR, $807e58506be70005$var$SAME_Y);\\n if (flag === lastFlag && same < 255) {\\n flags[flags.length - 1] |= $807e58506be70005$var$REPEAT;\\n same++;\\n } else {\\n if (same > 0) {\\n flags.push(same);\\n same = 0;\\n }\\n flags.push(flag);\\n lastFlag = flag;\\n }\\n lastX = x;\\n lastY = y;\\n pointCount++;\\n }\\n if (c.command === \\\"closePath\\\") endPtsOfContours.push(pointCount - 1);\\n }\\n if (path.commands.length > 1 && path.commands[path.commands.length - 1].command !== \\\"closePath\\\") endPtsOfContours.push(pointCount - 1);\\n let bbox = path.bbox;\\n let glyf = {\\n numberOfContours: endPtsOfContours.length,\\n xMin: bbox.minX,\\n yMin: bbox.minY,\\n xMax: bbox.maxX,\\n yMax: bbox.maxY,\\n endPtsOfContours,\\n instructions,\\n flags,\\n xPoints,\\n yPoints\\n };\\n let size = $807e58506be70005$var$Glyf.size(glyf);\\n let tail = 4 - size % 4;\\n let stream = new EncodeStream(size + tail);\\n $807e58506be70005$var$Glyf.encode(stream, glyf);\\n if (tail !== 0) stream.fill(0, tail);\\n return stream.buffer;\\n }\\n _encodePoint(value, last, points, flag, shortFlag, sameFlag) {\\n let diff = value - last;\\n if (value === last) flag |= sameFlag;\\n else {\\n if (-255 <= diff && diff <= 255) {\\n flag |= shortFlag;\\n if (diff < 0) diff = -diff;\\n else flag |= sameFlag;\\n }\\n points.push(diff);\\n }\\n return flag;\\n }\\n };\\n $4abbb6a5dbdc441a$export$2e2bcd8739ae039 = class extends (0, $5cc7476da92df375$export$2e2bcd8739ae039) {\\n _addGlyph(gid) {\\n let glyph = this.font.getGlyph(gid);\\n let glyf = glyph._decode();\\n let curOffset = this.font.loca.offsets[gid];\\n let nextOffset = this.font.loca.offsets[gid + 1];\\n let stream = this.font._getTableStream(\\\"glyf\\\");\\n stream.pos += curOffset;\\n let buffer = stream.readBuffer(nextOffset - curOffset);\\n if (glyf && glyf.numberOfContours < 0) {\\n buffer = new Uint8Array(buffer);\\n let view = new DataView(buffer.buffer);\\n for (let component of glyf.components) {\\n gid = this.includeGlyph(component.glyphID);\\n view.setUint16(component.pos, gid);\\n }\\n } else if (glyf && this.font._variationProcessor)\\n buffer = this.glyphEncoder.encodeSimple(glyph.path, glyf.instructions);\\n this.glyf.push(buffer);\\n this.loca.offsets.push(this.offset);\\n this.hmtx.metrics.push({\\n advance: glyph.advanceWidth,\\n bearing: glyph._getMetrics().leftBearing\\n });\\n this.offset += buffer.length;\\n return this.glyf.length - 1;\\n }\\n encode() {\\n this.glyf = [];\\n this.offset = 0;\\n this.loca = {\\n offsets: [],\\n version: this.font.loca.version\\n };\\n this.hmtx = {\\n metrics: [],\\n bearings: []\\n };\\n let i = 0;\\n while (i < this.glyphs.length) this._addGlyph(this.glyphs[i++]);\\n let maxp = (0, import_clone.default)(this.font.maxp);\\n maxp.numGlyphs = this.glyf.length;\\n this.loca.offsets.push(this.offset);\\n let head = (0, import_clone.default)(this.font.head);\\n head.indexToLocFormat = this.loca.version;\\n let hhea = (0, import_clone.default)(this.font.hhea);\\n hhea.numberOfMetrics = this.hmtx.metrics.length;\\n return (0, $816c07a04b6dba87$export$2e2bcd8739ae039).toBuffer({\\n tables: {\\n head,\\n hhea,\\n loca: this.loca,\\n maxp,\\n \\\"cvt \\\": this.font[\\\"cvt \\\"],\\n prep: this.font.prep,\\n glyf: this.glyf,\\n hmtx: this.hmtx,\\n fpgm: this.font.fpgm\\n }\\n });\\n }\\n constructor(font) {\\n super(font);\\n this.glyphEncoder = new (0, $807e58506be70005$export$2e2bcd8739ae039)();\\n }\\n };\\n $001d739428a71d5a$export$2e2bcd8739ae039 = class extends (0, $5cc7476da92df375$export$2e2bcd8739ae039) {\\n subsetCharstrings() {\\n this.charstrings = [];\\n let gsubrs = {};\\n for (let gid of this.glyphs) {\\n this.charstrings.push(this.cff.getCharString(gid));\\n let glyph = this.font.getGlyph(gid);\\n let path = glyph.path;\\n for (let subr in glyph._usedGsubrs) gsubrs[subr] = true;\\n }\\n this.gsubrs = this.subsetSubrs(this.cff.globalSubrIndex, gsubrs);\\n }\\n subsetSubrs(subrs, used) {\\n let res = [];\\n for (let i = 0; i < subrs.length; i++) {\\n let subr = subrs[i];\\n if (used[i]) {\\n this.cff.stream.pos = subr.offset;\\n res.push(this.cff.stream.readBuffer(subr.length));\\n } else res.push(new Uint8Array([\\n 11\\n ]));\\n }\\n return res;\\n }\\n subsetFontdict(topDict) {\\n topDict.FDArray = [];\\n topDict.FDSelect = {\\n version: 0,\\n fds: []\\n };\\n let used_fds = {};\\n let used_subrs = [];\\n let fd_select = {};\\n for (let gid of this.glyphs) {\\n let fd = this.cff.fdForGlyph(gid);\\n if (fd == null) continue;\\n if (!used_fds[fd]) {\\n topDict.FDArray.push(Object.assign({}, this.cff.topDict.FDArray[fd]));\\n used_subrs.push({});\\n fd_select[fd] = topDict.FDArray.length - 1;\\n }\\n used_fds[fd] = true;\\n topDict.FDSelect.fds.push(fd_select[fd]);\\n let glyph = this.font.getGlyph(gid);\\n let path = glyph.path;\\n for (let subr in glyph._usedSubrs) used_subrs[fd_select[fd]][subr] = true;\\n }\\n for (let i = 0; i < topDict.FDArray.length; i++) {\\n let dict = topDict.FDArray[i];\\n delete dict.FontName;\\n if (dict.Private && dict.Private.Subrs) {\\n dict.Private = Object.assign({}, dict.Private);\\n dict.Private.Subrs = this.subsetSubrs(dict.Private.Subrs, used_subrs[i]);\\n }\\n }\\n return;\\n }\\n createCIDFontdict(topDict) {\\n let used_subrs = {};\\n for (let gid of this.glyphs) {\\n let glyph = this.font.getGlyph(gid);\\n let path = glyph.path;\\n for (let subr in glyph._usedSubrs) used_subrs[subr] = true;\\n }\\n let privateDict = Object.assign({}, this.cff.topDict.Private);\\n if (this.cff.topDict.Private && this.cff.topDict.Private.Subrs) privateDict.Subrs = this.subsetSubrs(this.cff.topDict.Private.Subrs, used_subrs);\\n topDict.FDArray = [\\n {\\n Private: privateDict\\n }\\n ];\\n return topDict.FDSelect = {\\n version: 3,\\n nRanges: 1,\\n ranges: [\\n {\\n first: 0,\\n fd: 0\\n }\\n ],\\n sentinel: this.charstrings.length\\n };\\n }\\n addString(string) {\\n if (!string) return null;\\n if (!this.strings) this.strings = [];\\n this.strings.push(string);\\n return (0, $229224aec43783c5$export$2e2bcd8739ae039).length + this.strings.length - 1;\\n }\\n encode() {\\n this.subsetCharstrings();\\n let charset = {\\n version: this.charstrings.length > 255 ? 2 : 1,\\n ranges: [\\n {\\n first: 1,\\n nLeft: this.charstrings.length - 2\\n }\\n ]\\n };\\n let topDict = Object.assign({}, this.cff.topDict);\\n topDict.Private = null;\\n topDict.charset = charset;\\n topDict.Encoding = null;\\n topDict.CharStrings = this.charstrings;\\n for (let key of [\\n \\\"version\\\",\\n \\\"Notice\\\",\\n \\\"Copyright\\\",\\n \\\"FullName\\\",\\n \\\"FamilyName\\\",\\n \\\"Weight\\\",\\n \\\"PostScript\\\",\\n \\\"BaseFontName\\\",\\n \\\"FontName\\\"\\n ]) topDict[key] = this.addString(this.cff.string(topDict[key]));\\n topDict.ROS = [\\n this.addString(\\\"Adobe\\\"),\\n this.addString(\\\"Identity\\\"),\\n 0\\n ];\\n topDict.CIDCount = this.charstrings.length;\\n if (this.cff.isCIDFont) this.subsetFontdict(topDict);\\n else this.createCIDFontdict(topDict);\\n let top = {\\n version: 1,\\n hdrSize: this.cff.hdrSize,\\n offSize: 4,\\n header: this.cff.header,\\n nameIndex: [\\n this.cff.postscriptName\\n ],\\n topDictIndex: [\\n topDict\\n ],\\n stringIndex: this.strings,\\n globalSubrIndex: this.gsubrs\\n };\\n return (0, $b84fd3dd9d8eddb2$export$2e2bcd8739ae039).toBuffer(top);\\n }\\n constructor(font) {\\n super(font);\\n this.cff = this.font[\\\"CFF \\\"];\\n if (!this.cff) throw new Error(\\\"Not a CFF Font\\\");\\n }\\n };\\n $4c1709dee528ea76$export$2e2bcd8739ae039 = class _$4c1709dee528ea76$export$2e2bcd8739ae039 {\\n static probe(buffer) {\\n let format = (0, $12727730ddfc8bfe$export$3d28c1996ced1f14).decode(buffer.slice(0, 4));\\n return format === \\\"true\\\" || format === \\\"OTTO\\\" || format === String.fromCharCode(0, 1, 0, 0);\\n }\\n setDefaultLanguage(lang = null) {\\n this.defaultLanguage = lang;\\n }\\n _getTable(table) {\\n if (!(table.tag in this._tables)) try {\\n this._tables[table.tag] = this._decodeTable(table);\\n } catch (e) {\\n if ($d636bc798e7178db$export$bd5c5d8b8dcafd78) {\\n console.error(`Error decoding table ${table.tag}`);\\n console.error(e.stack);\\n }\\n }\\n return this._tables[table.tag];\\n }\\n _getTableStream(tag) {\\n let table = this.directory.tables[tag];\\n if (table) {\\n this.stream.pos = table.offset;\\n return this.stream;\\n }\\n return null;\\n }\\n _decodeDirectory() {\\n return this.directory = (0, $816c07a04b6dba87$export$2e2bcd8739ae039).decode(this.stream, {\\n _startOffset: 0\\n });\\n }\\n _decodeTable(table) {\\n let pos = this.stream.pos;\\n let stream = this._getTableStream(table.tag);\\n let result = (0, $c3395722bea751e2$export$2e2bcd8739ae039)[table.tag].decode(stream, this, table.length);\\n this.stream.pos = pos;\\n return result;\\n }\\n /**\\n * Gets a string from the font's `name` table\\n * `lang` is a BCP-47 language code.\\n * @return {string}\\n */\\n getName(key, lang = this.defaultLanguage || $d636bc798e7178db$export$42940898df819940) {\\n let record = this.name && this.name.records[key];\\n if (record)\\n return record[lang] || record[this.defaultLanguage] || record[$d636bc798e7178db$export$42940898df819940] || record[\\\"en\\\"] || record[Object.keys(record)[0]] || null;\\n return null;\\n }\\n /**\\n * The unique PostScript name for this font, e.g. \\\"Helvetica-Bold\\\"\\n * @type {string}\\n */\\n get postscriptName() {\\n return this.getName(\\\"postscriptName\\\");\\n }\\n /**\\n * The font's full name, e.g. \\\"Helvetica Bold\\\"\\n * @type {string}\\n */\\n get fullName() {\\n return this.getName(\\\"fullName\\\");\\n }\\n /**\\n * The font's family name, e.g. \\\"Helvetica\\\"\\n * @type {string}\\n */\\n get familyName() {\\n return this.getName(\\\"fontFamily\\\");\\n }\\n /**\\n * The font's sub-family, e.g. \\\"Bold\\\".\\n * @type {string}\\n */\\n get subfamilyName() {\\n return this.getName(\\\"fontSubfamily\\\");\\n }\\n /**\\n * The font's copyright information\\n * @type {string}\\n */\\n get copyright() {\\n return this.getName(\\\"copyright\\\");\\n }\\n /**\\n * The font's version number\\n * @type {string}\\n */\\n get version() {\\n return this.getName(\\\"version\\\");\\n }\\n /**\\n * The font’s [ascender](https://en.wikipedia.org/wiki/Ascender_(typography))\\n * @type {number}\\n */\\n get ascent() {\\n return this.hhea.ascent;\\n }\\n /**\\n * The font’s [descender](https://en.wikipedia.org/wiki/Descender)\\n * @type {number}\\n */\\n get descent() {\\n return this.hhea.descent;\\n }\\n /**\\n * The amount of space that should be included between lines\\n * @type {number}\\n */\\n get lineGap() {\\n return this.hhea.lineGap;\\n }\\n /**\\n * The offset from the normal underline position that should be used\\n * @type {number}\\n */\\n get underlinePosition() {\\n return this.post.underlinePosition;\\n }\\n /**\\n * The weight of the underline that should be used\\n * @type {number}\\n */\\n get underlineThickness() {\\n return this.post.underlineThickness;\\n }\\n /**\\n * If this is an italic font, the angle the cursor should be drawn at to match the font design\\n * @type {number}\\n */\\n get italicAngle() {\\n return this.post.italicAngle;\\n }\\n /**\\n * The height of capital letters above the baseline.\\n * See [here](https://en.wikipedia.org/wiki/Cap_height) for more details.\\n * @type {number}\\n */\\n get capHeight() {\\n let os2 = this[\\\"OS/2\\\"];\\n return os2 ? os2.capHeight : this.ascent;\\n }\\n /**\\n * The height of lower case letters in the font.\\n * See [here](https://en.wikipedia.org/wiki/X-height) for more details.\\n * @type {number}\\n */\\n get xHeight() {\\n let os2 = this[\\\"OS/2\\\"];\\n return os2 ? os2.xHeight : 0;\\n }\\n /**\\n * The number of glyphs in the font.\\n * @type {number}\\n */\\n get numGlyphs() {\\n return this.maxp.numGlyphs;\\n }\\n /**\\n * The size of the font’s internal coordinate grid\\n * @type {number}\\n */\\n get unitsPerEm() {\\n return this.head.unitsPerEm;\\n }\\n /**\\n * The font’s bounding box, i.e. the box that encloses all glyphs in the font.\\n * @type {BBox}\\n */\\n get bbox() {\\n return Object.freeze(new (0, $f34600ab9d7f70d8$export$2e2bcd8739ae039)(this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax));\\n }\\n get _cmapProcessor() {\\n return new (0, $f08dd41ef10b694c$export$2e2bcd8739ae039)(this.cmap);\\n }\\n /**\\n * An array of all of the unicode code points supported by the font.\\n * @type {number[]}\\n */\\n get characterSet() {\\n return this._cmapProcessor.getCharacterSet();\\n }\\n /**\\n * Returns whether there is glyph in the font for the given unicode code point.\\n *\\n * @param {number} codePoint\\n * @return {boolean}\\n */\\n hasGlyphForCodePoint(codePoint) {\\n return !!this._cmapProcessor.lookup(codePoint);\\n }\\n /**\\n * Maps a single unicode code point to a Glyph object.\\n * Does not perform any advanced substitutions (there is no context to do so).\\n *\\n * @param {number} codePoint\\n * @return {Glyph}\\n */\\n glyphForCodePoint(codePoint) {\\n return this.getGlyph(this._cmapProcessor.lookup(codePoint), [\\n codePoint\\n ]);\\n }\\n /**\\n * Returns an array of Glyph objects for the given string.\\n * This is only a one-to-one mapping from characters to glyphs.\\n * For most uses, you should use font.layout (described below), which\\n * provides a much more advanced mapping supporting AAT and OpenType shaping.\\n *\\n * @param {string} string\\n * @return {Glyph[]}\\n */\\n glyphsForString(string) {\\n let glyphs = [];\\n let len = string.length;\\n let idx = 0;\\n let last = -1;\\n let state = -1;\\n while (idx <= len) {\\n let code = 0;\\n let nextState = 0;\\n if (idx < len) {\\n code = string.charCodeAt(idx++);\\n if (55296 <= code && code <= 56319 && idx < len) {\\n let next = string.charCodeAt(idx);\\n if (56320 <= next && next <= 57343) {\\n idx++;\\n code = ((code & 1023) << 10) + (next & 1023) + 65536;\\n }\\n }\\n nextState = 65024 <= code && code <= 65039 || 917760 <= code && code <= 917999 ? 1 : 0;\\n } else idx++;\\n if (state === 0 && nextState === 1)\\n glyphs.push(this.getGlyph(this._cmapProcessor.lookup(last, code), [\\n last,\\n code\\n ]));\\n else if (state === 0 && nextState === 0)\\n glyphs.push(this.glyphForCodePoint(last));\\n last = code;\\n state = nextState;\\n }\\n return glyphs;\\n }\\n get _layoutEngine() {\\n return new (0, $4c0a7fa5df7a9ab1$export$2e2bcd8739ae039)(this);\\n }\\n /**\\n * Returns a GlyphRun object, which includes an array of Glyphs and GlyphPositions for the given string.\\n *\\n * @param {string} string\\n * @param {string[]} [userFeatures]\\n * @param {string} [script]\\n * @param {string} [language]\\n * @param {string} [direction]\\n * @return {GlyphRun}\\n */\\n layout(string, userFeatures, script, language, direction) {\\n return this._layoutEngine.layout(string, userFeatures, script, language, direction);\\n }\\n /**\\n * Returns an array of strings that map to the given glyph id.\\n * @param {number} gid - glyph id\\n */\\n stringsForGlyph(gid) {\\n return this._layoutEngine.stringsForGlyph(gid);\\n }\\n /**\\n * An array of all [OpenType feature tags](https://www.microsoft.com/typography/otspec/featuretags.htm)\\n * (or mapped AAT tags) supported by the font.\\n * The features parameter is an array of OpenType feature tags to be applied in addition to the default set.\\n * If this is an AAT font, the OpenType feature tags are mapped to AAT features.\\n *\\n * @type {string[]}\\n */\\n get availableFeatures() {\\n return this._layoutEngine.getAvailableFeatures();\\n }\\n getAvailableFeatures(script, language) {\\n return this._layoutEngine.getAvailableFeatures(script, language);\\n }\\n _getBaseGlyph(glyph, characters = []) {\\n if (!this._glyphs[glyph]) {\\n if (this.directory.tables.glyf) this._glyphs[glyph] = new (0, $69aac16029968692$export$2e2bcd8739ae039)(glyph, characters, this);\\n else if (this.directory.tables[\\\"CFF \\\"] || this.directory.tables.CFF2) this._glyphs[glyph] = new (0, $62cc5109c6101893$export$2e2bcd8739ae039)(glyph, characters, this);\\n }\\n return this._glyphs[glyph] || null;\\n }\\n /**\\n * Returns a glyph object for the given glyph id.\\n * You can pass the array of code points this glyph represents for\\n * your use later, and it will be stored in the glyph object.\\n *\\n * @param {number} glyph\\n * @param {number[]} characters\\n * @return {Glyph}\\n */\\n getGlyph(glyph, characters = []) {\\n if (!this._glyphs[glyph]) {\\n if (this.directory.tables.sbix) this._glyphs[glyph] = new (0, $25d8f049c222084c$export$2e2bcd8739ae039)(glyph, characters, this);\\n else if (this.directory.tables.COLR && this.directory.tables.CPAL) this._glyphs[glyph] = new (0, $0d411f0165859681$export$2e2bcd8739ae039)(glyph, characters, this);\\n else this._getBaseGlyph(glyph, characters);\\n }\\n return this._glyphs[glyph] || null;\\n }\\n /**\\n * Returns a Subset for this font.\\n * @return {Subset}\\n */\\n createSubset() {\\n if (this.directory.tables[\\\"CFF \\\"]) return new (0, $001d739428a71d5a$export$2e2bcd8739ae039)(this);\\n return new (0, $4abbb6a5dbdc441a$export$2e2bcd8739ae039)(this);\\n }\\n /**\\n * Returns an object describing the available variation axes\\n * that this font supports. Keys are setting tags, and values\\n * contain the axis name, range, and default value.\\n *\\n * @type {object}\\n */\\n get variationAxes() {\\n let res = {};\\n if (!this.fvar) return res;\\n for (let axis of this.fvar.axis) res[axis.axisTag.trim()] = {\\n name: axis.name.en,\\n min: axis.minValue,\\n default: axis.defaultValue,\\n max: axis.maxValue\\n };\\n return res;\\n }\\n /**\\n * Returns an object describing the named variation instances\\n * that the font designer has specified. Keys are variation names\\n * and values are the variation settings for this instance.\\n *\\n * @type {object}\\n */\\n get namedVariations() {\\n let res = {};\\n if (!this.fvar) return res;\\n for (let instance of this.fvar.instance) {\\n let settings = {};\\n for (let i = 0; i < this.fvar.axis.length; i++) {\\n let axis = this.fvar.axis[i];\\n settings[axis.axisTag.trim()] = instance.coord[i];\\n }\\n res[instance.name.en] = settings;\\n }\\n return res;\\n }\\n /**\\n * Returns a new font with the given variation settings applied.\\n * Settings can either be an instance name, or an object containing\\n * variation tags as specified by the `variationAxes` property.\\n *\\n * @param {object} settings\\n * @return {TTFFont}\\n */\\n getVariation(settings) {\\n if (!(this.directory.tables.fvar && (this.directory.tables.gvar && this.directory.tables.glyf || this.directory.tables.CFF2))) throw new Error(\\\"Variations require a font with the fvar, gvar and glyf, or CFF2 tables.\\\");\\n if (typeof settings === \\\"string\\\") settings = this.namedVariations[settings];\\n if (typeof settings !== \\\"object\\\") throw new Error(\\\"Variation settings must be either a variation name or settings object.\\\");\\n let coords = this.fvar.axis.map((axis, i) => {\\n let axisTag = axis.axisTag.trim();\\n if (axisTag in settings) return Math.max(axis.minValue, Math.min(axis.maxValue, settings[axisTag]));\\n else return axis.defaultValue;\\n });\\n let stream = new DecodeStream(this.stream.buffer);\\n stream.pos = this._directoryPos;\\n let font = new _$4c1709dee528ea76$export$2e2bcd8739ae039(stream, coords);\\n font._tables = this._tables;\\n return font;\\n }\\n get _variationProcessor() {\\n if (!this.fvar) return null;\\n let variationCoords = this.variationCoords;\\n if (!variationCoords && !this.CFF2) return null;\\n if (!variationCoords) variationCoords = this.fvar.axis.map((axis) => axis.defaultValue);\\n return new (0, $0bb840cac04e911b$export$2e2bcd8739ae039)(this, variationCoords);\\n }\\n // Standardized format plugin API\\n getFont(name) {\\n return this.getVariation(name);\\n }\\n constructor(stream, variationCoords = null) {\\n (0, _define_property)(this, \\\"type\\\", \\\"TTF\\\");\\n this.defaultLanguage = null;\\n this.stream = stream;\\n this.variationCoords = variationCoords;\\n this._directoryPos = this.stream.pos;\\n this._tables = {};\\n this._glyphs = {};\\n this._decodeDirectory();\\n for (let tag in this.directory.tables) {\\n let table = this.directory.tables[tag];\\n if ((0, $c3395722bea751e2$export$2e2bcd8739ae039)[tag] && table.length > 0) Object.defineProperty(this, tag, {\\n get: this._getTable.bind(this, table)\\n });\\n }\\n }\\n };\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $4c1709dee528ea76$export$2e2bcd8739ae039.prototype, \\\"bbox\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $4c1709dee528ea76$export$2e2bcd8739ae039.prototype, \\\"_cmapProcessor\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $4c1709dee528ea76$export$2e2bcd8739ae039.prototype, \\\"characterSet\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $4c1709dee528ea76$export$2e2bcd8739ae039.prototype, \\\"_layoutEngine\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $4c1709dee528ea76$export$2e2bcd8739ae039.prototype, \\\"variationAxes\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $4c1709dee528ea76$export$2e2bcd8739ae039.prototype, \\\"namedVariations\\\", null);\\n (0, __decorate)([\\n (0, $e71565f2ce09cb6b$export$69a3209f1a06c04d)\\n ], $4c1709dee528ea76$export$2e2bcd8739ae039.prototype, \\\"_variationProcessor\\\", null);\\n $c1726355ecc5b889$var$WOFFDirectoryEntry = new Struct({\\n tag: new StringT(4),\\n offset: new Pointer(uint32, \\\"void\\\", {\\n type: \\\"global\\\"\\n }),\\n compLength: uint32,\\n length: uint32,\\n origChecksum: uint32\\n });\\n $c1726355ecc5b889$var$WOFFDirectory = new Struct({\\n tag: new StringT(4),\\n flavor: uint32,\\n length: uint32,\\n numTables: uint16,\\n reserved: new Reserved(uint16),\\n totalSfntSize: uint32,\\n majorVersion: uint16,\\n minorVersion: uint16,\\n metaOffset: uint32,\\n metaLength: uint32,\\n metaOrigLength: uint32,\\n privOffset: uint32,\\n privLength: uint32,\\n tables: new ArrayT($c1726355ecc5b889$var$WOFFDirectoryEntry, \\\"numTables\\\")\\n });\\n $c1726355ecc5b889$var$WOFFDirectory.process = function() {\\n let tables = {};\\n for (let table of this.tables) tables[table.tag] = table;\\n this.tables = tables;\\n };\\n $c1726355ecc5b889$export$2e2bcd8739ae039 = $c1726355ecc5b889$var$WOFFDirectory;\\n $760785214b9fc52c$export$2e2bcd8739ae039 = class extends (0, $4c1709dee528ea76$export$2e2bcd8739ae039) {\\n static probe(buffer) {\\n return (0, $12727730ddfc8bfe$export$3d28c1996ced1f14).decode(buffer.slice(0, 4)) === \\\"wOFF\\\";\\n }\\n _decodeDirectory() {\\n this.directory = (0, $c1726355ecc5b889$export$2e2bcd8739ae039).decode(this.stream, {\\n _startOffset: 0\\n });\\n }\\n _getTableStream(tag) {\\n let table = this.directory.tables[tag];\\n if (table) {\\n this.stream.pos = table.offset;\\n if (table.compLength < table.length) {\\n this.stream.pos += 2;\\n let outBuffer = new Uint8Array(table.length);\\n let buf = (0, import_tiny_inflate.default)(this.stream.readBuffer(table.compLength - 2), outBuffer);\\n return new DecodeStream(buf);\\n } else return this.stream;\\n }\\n return null;\\n }\\n constructor(...args) {\\n super(...args);\\n (0, _define_property)(this, \\\"type\\\", \\\"WOFF\\\");\\n }\\n };\\n $8046190c9f1ad19e$export$2e2bcd8739ae039 = class extends (0, $69aac16029968692$export$2e2bcd8739ae039) {\\n _decode() {\\n return this._font._transformedGlyphs[this.id];\\n }\\n _getCBox() {\\n return this.path.bbox;\\n }\\n constructor(...args) {\\n super(...args);\\n (0, _define_property)(this, \\\"type\\\", \\\"WOFF2\\\");\\n }\\n };\\n $c28ec7bbb3b8de3a$var$Base128 = {\\n decode(stream) {\\n let result = 0;\\n let iterable = [\\n 0,\\n 1,\\n 2,\\n 3,\\n 4\\n ];\\n for (let j = 0; j < iterable.length; j++) {\\n let i = iterable[j];\\n let code = stream.readUInt8();\\n if (result & 3758096384) throw new Error(\\\"Overflow\\\");\\n result = result << 7 | code & 127;\\n if ((code & 128) === 0) return result;\\n }\\n throw new Error(\\\"Bad base 128 number\\\");\\n }\\n };\\n $c28ec7bbb3b8de3a$var$knownTags = [\\n \\\"cmap\\\",\\n \\\"head\\\",\\n \\\"hhea\\\",\\n \\\"hmtx\\\",\\n \\\"maxp\\\",\\n \\\"name\\\",\\n \\\"OS/2\\\",\\n \\\"post\\\",\\n \\\"cvt \\\",\\n \\\"fpgm\\\",\\n \\\"glyf\\\",\\n \\\"loca\\\",\\n \\\"prep\\\",\\n \\\"CFF \\\",\\n \\\"VORG\\\",\\n \\\"EBDT\\\",\\n \\\"EBLC\\\",\\n \\\"gasp\\\",\\n \\\"hdmx\\\",\\n \\\"kern\\\",\\n \\\"LTSH\\\",\\n \\\"PCLT\\\",\\n \\\"VDMX\\\",\\n \\\"vhea\\\",\\n \\\"vmtx\\\",\\n \\\"BASE\\\",\\n \\\"GDEF\\\",\\n \\\"GPOS\\\",\\n \\\"GSUB\\\",\\n \\\"EBSC\\\",\\n \\\"JSTF\\\",\\n \\\"MATH\\\",\\n \\\"CBDT\\\",\\n \\\"CBLC\\\",\\n \\\"COLR\\\",\\n \\\"CPAL\\\",\\n \\\"SVG \\\",\\n \\\"sbix\\\",\\n \\\"acnt\\\",\\n \\\"avar\\\",\\n \\\"bdat\\\",\\n \\\"bloc\\\",\\n \\\"bsln\\\",\\n \\\"cvar\\\",\\n \\\"fdsc\\\",\\n \\\"feat\\\",\\n \\\"fmtx\\\",\\n \\\"fvar\\\",\\n \\\"gvar\\\",\\n \\\"hsty\\\",\\n \\\"just\\\",\\n \\\"lcar\\\",\\n \\\"mort\\\",\\n \\\"morx\\\",\\n \\\"opbd\\\",\\n \\\"prop\\\",\\n \\\"trak\\\",\\n \\\"Zapf\\\",\\n \\\"Silf\\\",\\n \\\"Glat\\\",\\n \\\"Gloc\\\",\\n \\\"Feat\\\",\\n \\\"Sill\\\"\\n ];\\n $c28ec7bbb3b8de3a$var$WOFF2DirectoryEntry = new Struct({\\n flags: uint8,\\n customTag: new Optional(new StringT(4), (t) => (t.flags & 63) === 63),\\n tag: (t) => t.customTag || $c28ec7bbb3b8de3a$var$knownTags[t.flags & 63],\\n length: $c28ec7bbb3b8de3a$var$Base128,\\n transformVersion: (t) => t.flags >>> 6 & 3,\\n transformed: (t) => t.tag === \\\"glyf\\\" || t.tag === \\\"loca\\\" ? t.transformVersion === 0 : t.transformVersion !== 0,\\n transformLength: new Optional($c28ec7bbb3b8de3a$var$Base128, (t) => t.transformed)\\n });\\n $c28ec7bbb3b8de3a$var$WOFF2Directory = new Struct({\\n tag: new StringT(4),\\n flavor: uint32,\\n length: uint32,\\n numTables: uint16,\\n reserved: new Reserved(uint16),\\n totalSfntSize: uint32,\\n totalCompressedSize: uint32,\\n majorVersion: uint16,\\n minorVersion: uint16,\\n metaOffset: uint32,\\n metaLength: uint32,\\n metaOrigLength: uint32,\\n privOffset: uint32,\\n privLength: uint32,\\n tables: new ArrayT($c28ec7bbb3b8de3a$var$WOFF2DirectoryEntry, \\\"numTables\\\")\\n });\\n $c28ec7bbb3b8de3a$var$WOFF2Directory.process = function() {\\n let tables = {};\\n for (let i = 0; i < this.tables.length; i++) {\\n let table = this.tables[i];\\n tables[table.tag] = table;\\n }\\n return this.tables = tables;\\n };\\n $c28ec7bbb3b8de3a$export$2e2bcd8739ae039 = $c28ec7bbb3b8de3a$var$WOFF2Directory;\\n $21ee218f84ac7f32$export$2e2bcd8739ae039 = class extends (0, $4c1709dee528ea76$export$2e2bcd8739ae039) {\\n static probe(buffer) {\\n return (0, $12727730ddfc8bfe$export$3d28c1996ced1f14).decode(buffer.slice(0, 4)) === \\\"wOF2\\\";\\n }\\n _decodeDirectory() {\\n this.directory = (0, $c28ec7bbb3b8de3a$export$2e2bcd8739ae039).decode(this.stream);\\n this._dataPos = this.stream.pos;\\n }\\n _decompress() {\\n if (!this._decompressed) {\\n this.stream.pos = this._dataPos;\\n let buffer = this.stream.readBuffer(this.directory.totalCompressedSize);\\n let decompressedSize = 0;\\n for (let tag in this.directory.tables) {\\n let entry = this.directory.tables[tag];\\n entry.offset = decompressedSize;\\n decompressedSize += entry.transformLength != null ? entry.transformLength : entry.length;\\n }\\n let decompressed = (0, import_decompress.default)(buffer, decompressedSize);\\n if (!decompressed) throw new Error(\\\"Error decoding compressed data in WOFF2\\\");\\n this.stream = new DecodeStream(decompressed);\\n this._decompressed = true;\\n }\\n }\\n _decodeTable(table) {\\n this._decompress();\\n return super._decodeTable(table);\\n }\\n // Override this method to get a glyph and return our\\n // custom subclass if there is a glyf table.\\n _getBaseGlyph(glyph, characters = []) {\\n if (!this._glyphs[glyph]) {\\n if (this.directory.tables.glyf && this.directory.tables.glyf.transformed) {\\n if (!this._transformedGlyphs) this._transformGlyfTable();\\n return this._glyphs[glyph] = new (0, $8046190c9f1ad19e$export$2e2bcd8739ae039)(glyph, characters, this);\\n } else return super._getBaseGlyph(glyph, characters);\\n }\\n }\\n _transformGlyfTable() {\\n this._decompress();\\n this.stream.pos = this.directory.tables.glyf.offset;\\n let table = $21ee218f84ac7f32$var$GlyfTable.decode(this.stream);\\n let glyphs = [];\\n for (let index = 0; index < table.numGlyphs; index++) {\\n let glyph = {};\\n let nContours = table.nContours.readInt16BE();\\n glyph.numberOfContours = nContours;\\n if (nContours > 0) {\\n let nPoints = [];\\n let totalPoints = 0;\\n for (let i = 0; i < nContours; i++) {\\n let r = $21ee218f84ac7f32$var$read255UInt16(table.nPoints);\\n totalPoints += r;\\n nPoints.push(totalPoints);\\n }\\n glyph.points = $21ee218f84ac7f32$var$decodeTriplet(table.flags, table.glyphs, totalPoints);\\n for (let i = 0; i < nContours; i++) glyph.points[nPoints[i] - 1].endContour = true;\\n var instructionSize = $21ee218f84ac7f32$var$read255UInt16(table.glyphs);\\n } else if (nContours < 0) {\\n let haveInstructions = (0, $69aac16029968692$export$2e2bcd8739ae039).prototype._decodeComposite.call({\\n _font: this\\n }, glyph, table.composites);\\n if (haveInstructions) var instructionSize = $21ee218f84ac7f32$var$read255UInt16(table.glyphs);\\n }\\n glyphs.push(glyph);\\n }\\n this._transformedGlyphs = glyphs;\\n }\\n constructor(...args) {\\n super(...args);\\n (0, _define_property)(this, \\\"type\\\", \\\"WOFF2\\\");\\n }\\n };\\n $21ee218f84ac7f32$var$Substream = class {\\n decode(stream, parent) {\\n return new DecodeStream(this._buf.decode(stream, parent));\\n }\\n constructor(length) {\\n this.length = length;\\n this._buf = new BufferT(length);\\n }\\n };\\n $21ee218f84ac7f32$var$GlyfTable = new Struct({\\n version: uint32,\\n numGlyphs: uint16,\\n indexFormat: uint16,\\n nContourStreamSize: uint32,\\n nPointsStreamSize: uint32,\\n flagStreamSize: uint32,\\n glyphStreamSize: uint32,\\n compositeStreamSize: uint32,\\n bboxStreamSize: uint32,\\n instructionStreamSize: uint32,\\n nContours: new $21ee218f84ac7f32$var$Substream(\\\"nContourStreamSize\\\"),\\n nPoints: new $21ee218f84ac7f32$var$Substream(\\\"nPointsStreamSize\\\"),\\n flags: new $21ee218f84ac7f32$var$Substream(\\\"flagStreamSize\\\"),\\n glyphs: new $21ee218f84ac7f32$var$Substream(\\\"glyphStreamSize\\\"),\\n composites: new $21ee218f84ac7f32$var$Substream(\\\"compositeStreamSize\\\"),\\n bboxes: new $21ee218f84ac7f32$var$Substream(\\\"bboxStreamSize\\\"),\\n instructions: new $21ee218f84ac7f32$var$Substream(\\\"instructionStreamSize\\\")\\n });\\n $21ee218f84ac7f32$var$WORD_CODE = 253;\\n $21ee218f84ac7f32$var$ONE_MORE_BYTE_CODE2 = 254;\\n $21ee218f84ac7f32$var$ONE_MORE_BYTE_CODE1 = 255;\\n $21ee218f84ac7f32$var$LOWEST_U_CODE = 253;\\n $cd5853a56c68fec7$var$TTCHeader = new VersionedStruct(uint32, {\\n 65536: {\\n numFonts: uint32,\\n offsets: new ArrayT(uint32, \\\"numFonts\\\")\\n },\\n 131072: {\\n numFonts: uint32,\\n offsets: new ArrayT(uint32, \\\"numFonts\\\"),\\n dsigTag: uint32,\\n dsigLength: uint32,\\n dsigOffset: uint32\\n }\\n });\\n $cd5853a56c68fec7$export$2e2bcd8739ae039 = class {\\n static probe(buffer) {\\n return (0, $12727730ddfc8bfe$export$3d28c1996ced1f14).decode(buffer.slice(0, 4)) === \\\"ttcf\\\";\\n }\\n getFont(name) {\\n for (let offset of this.header.offsets) {\\n let stream = new DecodeStream(this.stream.buffer);\\n stream.pos = offset;\\n let font = new (0, $4c1709dee528ea76$export$2e2bcd8739ae039)(stream);\\n if (font.postscriptName === name || font.postscriptName instanceof Uint8Array && name instanceof Uint8Array && font.postscriptName.every((v, i) => name[i] === v)) return font;\\n }\\n return null;\\n }\\n get fonts() {\\n let fonts = [];\\n for (let offset of this.header.offsets) {\\n let stream = new DecodeStream(this.stream.buffer);\\n stream.pos = offset;\\n fonts.push(new (0, $4c1709dee528ea76$export$2e2bcd8739ae039)(stream));\\n }\\n return fonts;\\n }\\n constructor(stream) {\\n (0, _define_property)(this, \\\"type\\\", \\\"TTC\\\");\\n this.stream = stream;\\n if (stream.readString(4) !== \\\"ttcf\\\") throw new Error(\\\"Not a TrueType collection\\\");\\n this.header = $cd5853a56c68fec7$var$TTCHeader.decode(stream);\\n }\\n };\\n $05f49f930186144e$var$DFontName = new StringT(uint8);\\n $05f49f930186144e$var$DFontData = new Struct({\\n len: uint32,\\n buf: new BufferT(\\\"len\\\")\\n });\\n $05f49f930186144e$var$Ref = new Struct({\\n id: uint16,\\n nameOffset: int16,\\n attr: uint8,\\n dataOffset: uint24,\\n handle: uint32\\n });\\n $05f49f930186144e$var$Type = new Struct({\\n name: new StringT(4),\\n maxTypeIndex: uint16,\\n refList: new Pointer(uint16, new ArrayT($05f49f930186144e$var$Ref, (t) => t.maxTypeIndex + 1), {\\n type: \\\"parent\\\"\\n })\\n });\\n $05f49f930186144e$var$TypeList = new Struct({\\n length: uint16,\\n types: new ArrayT($05f49f930186144e$var$Type, (t) => t.length + 1)\\n });\\n $05f49f930186144e$var$DFontMap = new Struct({\\n reserved: new Reserved(uint8, 24),\\n typeList: new Pointer(uint16, $05f49f930186144e$var$TypeList),\\n nameListOffset: new Pointer(uint16, \\\"void\\\")\\n });\\n $05f49f930186144e$var$DFontHeader = new Struct({\\n dataOffset: uint32,\\n map: new Pointer(uint32, $05f49f930186144e$var$DFontMap),\\n dataLength: uint32,\\n mapLength: uint32\\n });\\n $05f49f930186144e$export$2e2bcd8739ae039 = class {\\n static probe(buffer) {\\n let stream = new DecodeStream(buffer);\\n try {\\n var header = $05f49f930186144e$var$DFontHeader.decode(stream);\\n } catch (e) {\\n return false;\\n }\\n for (let type of header.map.typeList.types) {\\n if (type.name === \\\"sfnt\\\") return true;\\n }\\n return false;\\n }\\n getFont(name) {\\n if (!this.sfnt) return null;\\n for (let ref of this.sfnt.refList) {\\n let pos = this.header.dataOffset + ref.dataOffset + 4;\\n let stream = new DecodeStream(this.stream.buffer.slice(pos));\\n let font = new (0, $4c1709dee528ea76$export$2e2bcd8739ae039)(stream);\\n if (font.postscriptName === name || font.postscriptName instanceof Uint8Array && name instanceof Uint8Array && font.postscriptName.every((v, i) => name[i] === v)) return font;\\n }\\n return null;\\n }\\n get fonts() {\\n let fonts = [];\\n for (let ref of this.sfnt.refList) {\\n let pos = this.header.dataOffset + ref.dataOffset + 4;\\n let stream = new DecodeStream(this.stream.buffer.slice(pos));\\n fonts.push(new (0, $4c1709dee528ea76$export$2e2bcd8739ae039)(stream));\\n }\\n return fonts;\\n }\\n constructor(stream) {\\n (0, _define_property)(this, \\\"type\\\", \\\"DFont\\\");\\n this.stream = stream;\\n this.header = $05f49f930186144e$var$DFontHeader.decode(this.stream);\\n for (let type of this.header.map.typeList.types) {\\n for (let ref of type.refList) if (ref.nameOffset >= 0) {\\n this.stream.pos = ref.nameOffset + this.header.map.nameListOffset;\\n ref.name = $05f49f930186144e$var$DFontName.decode(this.stream);\\n } else ref.name = null;\\n if (type.name === \\\"sfnt\\\") this.sfnt = type;\\n }\\n }\\n };\\n (0, $d636bc798e7178db$export$36b2f24e97d43be)((0, $4c1709dee528ea76$export$2e2bcd8739ae039));\\n (0, $d636bc798e7178db$export$36b2f24e97d43be)((0, $760785214b9fc52c$export$2e2bcd8739ae039));\\n (0, $d636bc798e7178db$export$36b2f24e97d43be)((0, $21ee218f84ac7f32$export$2e2bcd8739ae039));\\n (0, $d636bc798e7178db$export$36b2f24e97d43be)((0, $cd5853a56c68fec7$export$2e2bcd8739ae039));\\n (0, $d636bc798e7178db$export$36b2f24e97d43be)((0, $05f49f930186144e$export$2e2bcd8739ae039));\\n }\\n });\\n\\n // src/fonts/google-fonts.ts\\n var TSHIRT_FONTS = [\\n // Bold/Display Fonts - Perfect for statements and headlines (49 fonts)\\n {\\n name: \\\"Bebas Neue\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Modern condensed display\\\"\\n },\\n {\\n name: \\\"Bevan\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold slab serif display\\\"\\n },\\n {\\n name: \\\"Bigshot One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold elegant display\\\"\\n },\\n {\\n name: \\\"Anton\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Super bold display font\\\"\\n },\\n {\\n name: \\\"Oswald\\\",\\n category: \\\"display\\\",\\n weights: [200, 300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Condensed sans-serif\\\"\\n },\\n {\\n name: \\\"Archivo Black\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Heavy weight display\\\"\\n },\\n {\\n name: \\\"Alfa Slab One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold slab serif, varsity style\\\"\\n },\\n {\\n name: \\\"Bowlby One SC\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Blocky display, sports style\\\"\\n },\\n {\\n name: \\\"Black Ops One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Military/stencil style\\\"\\n },\\n {\\n name: \\\"Abril Fatface\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold high-contrast display\\\"\\n },\\n {\\n name: \\\"Bangers\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Comic book style\\\"\\n },\\n {\\n name: \\\"Titan One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Heavy impactful display\\\"\\n },\\n {\\n name: \\\"Lilita One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Rounded display font\\\"\\n },\\n {\\n name: \\\"Fugaz One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold geometric display\\\"\\n },\\n {\\n name: \\\"Russo One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold sans display\\\"\\n },\\n {\\n name: \\\"Passion One\\\",\\n category: \\\"display\\\",\\n weights: [400, 700, 900],\\n googleFont: true,\\n description: \\\"Condensed bold display\\\"\\n },\\n {\\n name: \\\"Righteous\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"1980s-style display\\\"\\n },\\n {\\n name: \\\"Bungee\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold urban/street style\\\"\\n },\\n {\\n name: \\\"Barlow Condensed\\\",\\n category: \\\"display\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Condensed sans display\\\"\\n },\\n {\\n name: \\\"Staatliches\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold condensed display\\\"\\n },\\n {\\n name: \\\"Rubik Mono One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Blocky monoline display\\\"\\n },\\n {\\n name: \\\"Ultra\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Ultra bold serif\\\"\\n },\\n {\\n name: \\\"Audiowide\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Tech/futuristic display\\\"\\n },\\n {\\n name: \\\"Changa One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Rounded bold display\\\"\\n },\\n {\\n name: \\\"Lobster\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold script display\\\"\\n },\\n {\\n name: \\\"Coda\\\",\\n category: \\\"display\\\",\\n weights: [400, 800],\\n googleFont: true,\\n description: \\\"Bold humanist sans\\\"\\n },\\n {\\n name: \\\"Teko\\\",\\n category: \\\"display\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Narrow sans display\\\"\\n },\\n {\\n name: \\\"Fredoka One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Rounded bold display\\\"\\n },\\n {\\n name: \\\"Caprasimo\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Retro rounded display\\\"\\n },\\n {\\n name: \\\"Fjalla One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold condensed sans\\\"\\n },\\n {\\n name: \\\"Secular One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Hebrew-inspired display\\\"\\n },\\n {\\n name: \\\"Saira\\\",\\n category: \\\"display\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Semi-condensed sans display\\\"\\n },\\n {\\n name: \\\"Barlow Semi Condensed\\\",\\n category: \\\"display\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Semi-condensed low-contrast\\\"\\n },\\n {\\n name: \\\"Exo\\\",\\n category: \\\"display\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Geometric technological display\\\"\\n },\\n {\\n name: \\\"Saira Condensed\\\",\\n category: \\\"display\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Condensed display font\\\"\\n },\\n {\\n name: \\\"Fredoka\\\",\\n category: \\\"display\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Rounded friendly display\\\"\\n },\\n {\\n name: \\\"Comfortaa\\\",\\n category: \\\"display\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Rounded geometric display\\\"\\n },\\n {\\n name: \\\"Questrial\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Simple sans-serif display\\\"\\n },\\n {\\n name: \\\"Lexend\\\",\\n category: \\\"display\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Variable sans for readability\\\"\\n },\\n {\\n name: \\\"Darker Grotesque\\\",\\n category: \\\"display\\\",\\n weights: [300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Contemporary grotesque sans\\\"\\n },\\n {\\n name: \\\"Bakbak One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Heavy condensed display\\\"\\n },\\n {\\n name: \\\"Turret Road\\\",\\n category: \\\"display\\\",\\n weights: [200, 300, 400, 500, 700, 800],\\n googleFont: true,\\n description: \\\"Geometric display font\\\"\\n },\\n {\\n name: \\\"Zilla Slab Highlight\\\",\\n category: \\\"display\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Highlighted slab serif\\\"\\n },\\n {\\n name: \\\"Bree Serif\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Upright italic slab\\\"\\n },\\n {\\n name: \\\"Overpass\\\",\\n category: \\\"display\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Highway-inspired sans\\\"\\n },\\n {\\n name: \\\"Archivo\\\",\\n category: \\\"display\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Grotesque sans-serif\\\"\\n },\\n {\\n name: \\\"Chakra Petch\\\",\\n category: \\\"display\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Futuristic Thai-inspired\\\"\\n },\\n {\\n name: \\\"Concert One\\\",\\n category: \\\"display\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Rounded grotesque display\\\"\\n },\\n // Sans Serif - Modern and clean (44 fonts)\\n {\\n name: \\\"Roboto\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 300, 400, 500, 700, 900],\\n googleFont: true,\\n description: \\\"Clean, modern sans-serif\\\"\\n },\\n {\\n name: \\\"Montserrat\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Geometric sans-serif\\\"\\n },\\n {\\n name: \\\"Open Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [300, 400, 500, 600, 700, 800],\\n googleFont: true,\\n description: \\\"Highly readable\\\"\\n },\\n {\\n name: \\\"Poppins\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Geometric with personality\\\"\\n },\\n {\\n name: \\\"Work Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Contemporary sans-serif\\\"\\n },\\n {\\n name: \\\"Raleway\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Elegant sans-serif\\\"\\n },\\n {\\n name: \\\"Lato\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 300, 400, 700, 900],\\n googleFont: true,\\n description: \\\"Warm sans-serif\\\"\\n },\\n {\\n name: \\\"Nunito\\\",\\n category: \\\"sans-serif\\\",\\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Rounded sans-serif\\\"\\n },\\n {\\n name: \\\"Outfit\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Modern geometric sans\\\"\\n },\\n {\\n name: \\\"Inter\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Clean interface font\\\"\\n },\\n {\\n name: \\\"Quicksand\\\",\\n category: \\\"sans-serif\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Friendly rounded sans\\\"\\n },\\n {\\n name: \\\"Rubik\\\",\\n category: \\\"sans-serif\\\",\\n weights: [300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Slightly rounded sans\\\"\\n },\\n {\\n name: \\\"Barlow\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Low-contrast sans\\\"\\n },\\n {\\n name: \\\"Josefin Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Geometric vintage sans\\\"\\n },\\n {\\n name: \\\"Exo 2\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Contemporary geometric\\\"\\n },\\n {\\n name: \\\"Kanit\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Modern loopless Thai\\\"\\n },\\n {\\n name: \\\"Hind\\\",\\n category: \\\"sans-serif\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Clean humanist sans\\\"\\n },\\n {\\n name: \\\"Alata\\\",\\n category: \\\"sans-serif\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Geometric sans\\\"\\n },\\n {\\n name: \\\"Urbanist\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Geometric low-contrast\\\"\\n },\\n {\\n name: \\\"Manrope\\\",\\n category: \\\"sans-serif\\\",\\n weights: [200, 300, 400, 500, 600, 700, 800],\\n googleFont: true,\\n description: \\\"Modern geometric sans\\\"\\n },\\n {\\n name: \\\"Be Vietnam Pro\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Modern Vietnamese-optimized sans\\\"\\n },\\n {\\n name: \\\"Belanosima\\\",\\n category: \\\"sans-serif\\\",\\n weights: [400, 600, 700],\\n googleFont: true,\\n description: \\\"Contemporary sans-serif\\\"\\n },\\n {\\n name: \\\"DM Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Low-contrast geometric sans\\\"\\n },\\n {\\n name: \\\"Source Sans 3\\\",\\n category: \\\"sans-serif\\\",\\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Adobe sans-serif family\\\"\\n },\\n {\\n name: \\\"Source Sans Pro\\\",\\n category: \\\"sans-serif\\\",\\n weights: [200, 300, 400, 600, 700, 900],\\n googleFont: true,\\n description: \\\"Adobe sans-serif (legacy)\\\"\\n },\\n {\\n name: \\\"IBM Plex Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"IBM corporate sans\\\"\\n },\\n {\\n name: \\\"Karla\\\",\\n category: \\\"sans-serif\\\",\\n weights: [200, 300, 400, 500, 600, 700, 800],\\n googleFont: true,\\n description: \\\"Grotesque sans-serif\\\"\\n },\\n {\\n name: \\\"PT Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Russian universal sans\\\"\\n },\\n {\\n name: \\\"Fira Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Mozilla humanist sans\\\"\\n },\\n {\\n name: \\\"Space Grotesk\\\",\\n category: \\\"sans-serif\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Proportional space age sans\\\"\\n },\\n {\\n name: \\\"Syne\\\",\\n category: \\\"sans-serif\\\",\\n weights: [400, 500, 600, 700, 800],\\n googleFont: true,\\n description: \\\"Geometric variable sans\\\"\\n },\\n {\\n name: \\\"Libre Franklin\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Interpretation of Franklin Gothic\\\"\\n },\\n {\\n name: \\\"Alegreya Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 300, 400, 500, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Humanist sans companion\\\"\\n },\\n {\\n name: \\\"Archivo Narrow\\\",\\n category: \\\"sans-serif\\\",\\n weights: [400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Narrow grotesque sans\\\"\\n },\\n {\\n name: \\\"Chivo\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Grotesque sans-serif\\\"\\n },\\n {\\n name: \\\"Neuton\\\",\\n category: \\\"sans-serif\\\",\\n weights: [200, 300, 400, 700, 800],\\n googleFont: true,\\n description: \\\"Serif-adjacent sans\\\"\\n },\\n {\\n name: \\\"Prompt\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Loopless Thai sans\\\"\\n },\\n {\\n name: \\\"Noto Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Google universal sans\\\"\\n },\\n {\\n name: \\\"Nunito Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [200, 300, 400, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Rounded sans-serif\\\"\\n },\\n {\\n name: \\\"Proza Libre\\\",\\n category: \\\"sans-serif\\\",\\n weights: [400, 500, 600, 700, 800],\\n googleFont: true,\\n description: \\\"Humanist sans-serif\\\"\\n },\\n {\\n name: \\\"Cabin\\\",\\n category: \\\"sans-serif\\\",\\n weights: [400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Humanist sans inspired by Edward Johnston\\\"\\n },\\n {\\n name: \\\"Signika\\\",\\n category: \\\"sans-serif\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Sans-serif for signage\\\"\\n },\\n {\\n name: \\\"Public Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Strong neutral sans\\\"\\n },\\n {\\n name: \\\"Plus Jakarta Sans\\\",\\n category: \\\"sans-serif\\\",\\n weights: [200, 300, 400, 500, 600, 700, 800],\\n googleFont: true,\\n description: \\\"Geometric neo-grotesque\\\"\\n },\\n {\\n name: \\\"Red Hat Display\\\",\\n category: \\\"sans-serif\\\",\\n weights: [300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Display variant of Red Hat sans\\\"\\n },\\n // Script/Handwritten - Personal and creative (26 fonts)\\n {\\n name: \\\"Pacifico\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Retro surf script\\\"\\n },\\n {\\n name: \\\"Dancing Script\\\",\\n category: \\\"script\\\",\\n weights: [400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Elegant handwriting\\\"\\n },\\n {\\n name: \\\"Satisfy\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Casual handwritten\\\"\\n },\\n {\\n name: \\\"Permanent Marker\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold marker style\\\"\\n },\\n {\\n name: \\\"Caveat\\\",\\n category: \\\"script\\\",\\n weights: [400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Modern handwritten\\\"\\n },\\n {\\n name: \\\"Shadows Into Light\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Friendly handwriting\\\"\\n },\\n {\\n name: \\\"Kaushan Script\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold script\\\"\\n },\\n {\\n name: \\\"Amatic SC\\\",\\n category: \\\"script\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Hand-drawn style\\\"\\n },\\n {\\n name: \\\"Indie Flower\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Casual handwriting\\\"\\n },\\n {\\n name: \\\"Cookie\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Brush script\\\"\\n },\\n {\\n name: \\\"Sacramento\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Elegant script\\\"\\n },\\n {\\n name: \\\"Allura\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Formal script\\\"\\n },\\n {\\n name: \\\"Great Vibes\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Elegant calligraphy\\\"\\n },\\n {\\n name: \\\"Yellowtail\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Flat-nib script\\\"\\n },\\n {\\n name: \\\"Courgette\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Casual upright script\\\"\\n },\\n {\\n name: \\\"Beth Ellen\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Handwritten marker style\\\"\\n },\\n {\\n name: \\\"Covered By Your Grace\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Casual handwritten\\\"\\n },\\n {\\n name: \\\"Nothing You Could Do\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Hand-drawn lettering\\\"\\n },\\n {\\n name: \\\"Homemade Apple\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Thin marker handwriting\\\"\\n },\\n {\\n name: \\\"Reenie Beanie\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Casual handwritten note style\\\"\\n },\\n {\\n name: \\\"Patrick Hand\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Handwriting font\\\"\\n },\\n {\\n name: \\\"Architects Daughter\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Architect-style handwriting\\\"\\n },\\n {\\n name: \\\"Handlee\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Casual handwriting\\\"\\n },\\n {\\n name: \\\"Zeyada\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bouncy handwritten script\\\"\\n },\\n {\\n name: \\\"Gloria Hallelujah\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Comic-style handwriting\\\"\\n },\\n {\\n name: \\\"Bad Script\\\",\\n category: \\\"script\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Casual Cyrillic script\\\"\\n },\\n // Serif - Classic and elegant (28 fonts)\\n {\\n name: \\\"Playfair Display\\\",\\n category: \\\"serif\\\",\\n weights: [400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"High-contrast elegant\\\"\\n },\\n {\\n name: \\\"Merriweather\\\",\\n category: \\\"serif\\\",\\n weights: [300, 400, 700, 900],\\n googleFont: true,\\n description: \\\"Readable serif\\\"\\n },\\n {\\n name: \\\"Lora\\\",\\n category: \\\"serif\\\",\\n weights: [400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Contemporary serif\\\"\\n },\\n {\\n name: \\\"Crimson Text\\\",\\n category: \\\"serif\\\",\\n weights: [400, 600, 700],\\n googleFont: true,\\n description: \\\"Classic book typography\\\"\\n },\\n {\\n name: \\\"PT Serif\\\",\\n category: \\\"serif\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Transitional serif\\\"\\n },\\n {\\n name: \\\"Libre Baskerville\\\",\\n category: \\\"serif\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Classic serif\\\"\\n },\\n {\\n name: \\\"Bitter\\\",\\n category: \\\"serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Contemporary slab serif\\\"\\n },\\n {\\n name: \\\"Cormorant Garamond\\\",\\n category: \\\"serif\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Display serif\\\"\\n },\\n {\\n name: \\\"Cinzel\\\",\\n category: \\\"serif\\\",\\n weights: [400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Classical serif capitals\\\"\\n },\\n {\\n name: \\\"Zilla Slab\\\",\\n category: \\\"serif\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Contemporary slab serif\\\"\\n },\\n {\\n name: \\\"Cardo\\\",\\n category: \\\"serif\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Large text serif\\\"\\n },\\n {\\n name: \\\"Spectral\\\",\\n category: \\\"serif\\\",\\n weights: [200, 300, 400, 500, 600, 700, 800],\\n googleFont: true,\\n description: \\\"Efficient serif\\\"\\n },\\n {\\n name: \\\"Literata\\\",\\n category: \\\"serif\\\",\\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Modern serif\\\"\\n },\\n {\\n name: \\\"Cantata One\\\",\\n category: \\\"serif\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Humanist slab serif\\\"\\n },\\n {\\n name: \\\"Bellefair\\\",\\n category: \\\"serif\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Elegant high-contrast serif\\\"\\n },\\n {\\n name: \\\"Source Serif Pro\\\",\\n category: \\\"serif\\\",\\n weights: [200, 300, 400, 600, 700, 900],\\n googleFont: true,\\n description: \\\"Adobe serif family\\\"\\n },\\n {\\n name: \\\"Cormorant\\\",\\n category: \\\"serif\\\",\\n weights: [300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Display serif typeface\\\"\\n },\\n {\\n name: \\\"Eczar\\\",\\n category: \\\"serif\\\",\\n weights: [400, 500, 600, 700, 800],\\n googleFont: true,\\n description: \\\"Hybrid serif for screen\\\"\\n },\\n {\\n name: \\\"Alegreya\\\",\\n category: \\\"serif\\\",\\n weights: [400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Humanist serif\\\"\\n },\\n {\\n name: \\\"Fraunces\\\",\\n category: \\\"serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Variable display serif\\\"\\n },\\n {\\n name: \\\"Inknut Antiqua\\\",\\n category: \\\"serif\\\",\\n weights: [300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Display serif\\\"\\n },\\n {\\n name: \\\"BioRhyme\\\",\\n category: \\\"serif\\\",\\n weights: [200, 300, 400, 700, 800],\\n googleFont: true,\\n description: \\\"Rounded slab serif\\\"\\n },\\n {\\n name: \\\"Slabo 27px\\\",\\n category: \\\"serif\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Display serif at 27px\\\"\\n },\\n {\\n name: \\\"Slabo 13px\\\",\\n category: \\\"serif\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Text serif at 13px\\\"\\n },\\n {\\n name: \\\"Crimson Pro\\\",\\n category: \\\"serif\\\",\\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Modern oldstyle serif\\\"\\n },\\n {\\n name: \\\"Noto Serif\\\",\\n category: \\\"serif\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Google universal serif\\\"\\n },\\n {\\n name: \\\"EB Garamond\\\",\\n category: \\\"serif\\\",\\n weights: [400, 500, 600, 700, 800],\\n googleFont: true,\\n description: \\\"Classical Garamond revival\\\"\\n },\\n {\\n name: \\\"Vollkorn\\\",\\n category: \\\"serif\\\",\\n weights: [400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Quiet, moderate serif\\\"\\n },\\n {\\n name: \\\"Young Serif\\\",\\n category: \\\"serif\\\",\\n weights: [400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Modern retro serif\\\"\\n },\\n // Vintage/Retro - Nostalgic and stylish (49 fonts)\\n // Art Deco & 1920s-30s Style\\n {\\n name: \\\"Monoton\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Art deco display\\\"\\n },\\n {\\n name: \\\"Limelight\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Art deco geometric sans\\\"\\n },\\n {\\n name: \\\"Poiret One\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Art deco constructivist\\\"\\n },\\n {\\n name: \\\"Italiana\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Art deco calligraphic\\\"\\n },\\n {\\n name: \\\"Federo\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Art nouveau geometric\\\"\\n },\\n {\\n name: \\\"Dorsa\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Art deco display\\\"\\n },\\n // Groovy/Psychedelic 60s-70s Style\\n {\\n name: \\\"Boogaloo\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Groovy rounded display\\\"\\n },\\n {\\n name: \\\"Gorditas\\\",\\n category: \\\"vintage\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Bubble slab with hearts\\\"\\n },\\n {\\n name: \\\"Shrikhand\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Retro curved display\\\"\\n },\\n {\\n name: \\\"Kumar One\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Rounded bubble display\\\"\\n },\\n {\\n name: \\\"Chicle\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bubble gum style\\\"\\n },\\n {\\n name: \\\"Flavors\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Retro bubble font\\\"\\n },\\n {\\n name: \\\"Chango\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Groovy rounded bold\\\"\\n },\\n {\\n name: \\\"Purple Purse\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Hippie funky casual\\\"\\n },\\n {\\n name: \\\"Super Dream\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: false,\\n description: \\\"70s groovy bubble font\\\"\\n },\\n // Retro Script & Sign Painting\\n {\\n name: \\\"Yesteryear\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Vintage cursive script\\\"\\n },\\n {\\n name: \\\"Mrs Sheppards\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Old American script\\\"\\n },\\n {\\n name: \\\"Condiment\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Vintage sign design\\\"\\n },\\n // Western/Cowboy Style\\n {\\n name: \\\"Rye\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Western Victorian\\\"\\n },\\n {\\n name: \\\"Sancreek\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Western slab serif\\\"\\n },\\n {\\n name: \\\"Smokum\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Western playful slab\\\"\\n },\\n {\\n name: \\\"Diplomata\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Bold western display\\\"\\n },\\n {\\n name: \\\"Ewert\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Ornamental wood type\\\"\\n },\\n {\\n name: \\\"Macondo\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Western carnival style\\\"\\n },\\n {\\n name: \\\"Wellfleet\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Vintage slab serif\\\"\\n },\\n {\\n name: \\\"Ranchers\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Western slab serif\\\"\\n },\\n // Circus/Carnival/Theater\\n {\\n name: \\\"Bungee Shade\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Layered circus display\\\"\\n },\\n {\\n name: \\\"Peralta\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Rounded circus style\\\"\\n },\\n {\\n name: \\\"Kelly Slab\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Retro slab serif\\\"\\n },\\n {\\n name: \\\"Snippet\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Vintage condensed\\\"\\n },\\n // Retro Gaming & Tech\\n {\\n name: \\\"Press Start 2P\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"8-bit retro gaming\\\"\\n },\\n {\\n name: \\\"VT323\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Terminal monospace\\\"\\n },\\n // Victorian/Gothic/Medieval\\n {\\n name: \\\"UnifrakturCook\\\",\\n category: \\\"vintage\\\",\\n weights: [700],\\n googleFont: true,\\n description: \\\"Gothic blackletter\\\"\\n },\\n {\\n name: \\\"Sevillana\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Victorian ornate\\\"\\n },\\n {\\n name: \\\"Uncial Antiqua\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Medieval uncial\\\"\\n },\\n {\\n name: \\\"Piedra\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Stone carved display\\\"\\n },\\n // Horror/Heavy Metal\\n {\\n name: \\\"Creepster\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Horror Halloween style\\\"\\n },\\n {\\n name: \\\"Nosifer\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Horror dripping\\\"\\n },\\n {\\n name: \\\"Eater\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Zombie horror\\\"\\n },\\n {\\n name: \\\"Metal Mania\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Heavy metal style\\\"\\n },\\n {\\n name: \\\"Butcherman\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Zombified horror\\\"\\n },\\n // Typewriter & Classic\\n {\\n name: \\\"Special Elite\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Typewriter style\\\"\\n },\\n // Soviet/Constructivist\\n {\\n name: \\\"Stalinist One\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Soviet constructivist\\\"\\n },\\n {\\n name: \\\"Ruslan Display\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Russian display style\\\"\\n },\\n // Additional Retro Display\\n {\\n name: \\\"Corben\\\",\\n category: \\\"vintage\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Mid-century rounded\\\"\\n },\\n {\\n name: \\\"Kranky\\\",\\n category: \\\"vintage\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Quirky handwritten retro\\\"\\n },\\n // Decorative/Unique (10+ fonts)\\n {\\n name: \\\"Orbitron\\\",\\n category: \\\"decorative\\\",\\n weights: [400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Futuristic geometric\\\"\\n },\\n {\\n name: \\\"Playball\\\",\\n category: \\\"decorative\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Baseball script\\\"\\n },\\n {\\n name: \\\"Sedgwick Ave Display\\\",\\n category: \\\"decorative\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Graffiti style\\\"\\n },\\n {\\n name: \\\"Modak\\\",\\n category: \\\"decorative\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Rounded heavy display\\\"\\n },\\n {\\n name: \\\"Fascinate\\\",\\n category: \\\"decorative\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Broadway/theater\\\"\\n },\\n {\\n name: \\\"Bungee Inline\\\",\\n category: \\\"decorative\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Inline display\\\"\\n },\\n {\\n name: \\\"Emblema One\\\",\\n category: \\\"decorative\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Decorative caps\\\"\\n },\\n {\\n name: \\\"Fascinate Inline\\\",\\n category: \\\"decorative\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Inline Broadway\\\"\\n },\\n {\\n name: \\\"New Rocker\\\",\\n category: \\\"decorative\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Rock and roll\\\"\\n },\\n {\\n name: \\\"Bigelow Rules\\\",\\n category: \\\"decorative\\\",\\n weights: [400],\\n googleFont: true,\\n description: \\\"Playful cursive display\\\"\\n },\\n // Monospace (useful for tech designs)\\n {\\n name: \\\"Roboto Mono\\\",\\n category: \\\"monospace\\\",\\n weights: [100, 200, 300, 400, 500, 600, 700],\\n googleFont: true,\\n description: \\\"Modern monospace\\\"\\n },\\n {\\n name: \\\"Courier Prime\\\",\\n category: \\\"monospace\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Typewriter monospace\\\"\\n },\\n {\\n name: \\\"Space Mono\\\",\\n category: \\\"monospace\\\",\\n weights: [400, 700],\\n googleFont: true,\\n description: \\\"Retro-futuristic mono\\\"\\n },\\n {\\n name: \\\"Inconsolata\\\",\\n category: \\\"monospace\\\",\\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\\n googleFont: true,\\n description: \\\"Humanist monospace\\\"\\n }\\n ];\\n function getFontNames() {\\n return TSHIRT_FONTS.map((f) => f.name);\\n }\\n\\n // src/constants.ts\\n var FONT_FAMILIES = getFontNames();\\n var HORIZONTAL_PADDING = 0;\\n var LINE_HEIGHT_MULTIPLIER = 1.2;\\n var SYSTEM_FONTS = /* @__PURE__ */ new Set([\\n \\\"Arial\\\",\\n \\\"Arial Black\\\",\\n \\\"Verdana\\\",\\n \\\"Tahoma\\\",\\n \\\"Trebuchet MS\\\",\\n \\\"Impact\\\",\\n \\\"Times New Roman\\\",\\n \\\"Georgia\\\",\\n \\\"Garamond\\\",\\n \\\"Courier New\\\",\\n \\\"Brush Script MT\\\",\\n \\\"Palatino\\\",\\n \\\"Baskerville\\\",\\n \\\"Helvetica\\\",\\n \\\"Helvetica Neue\\\",\\n \\\"Comic Sans MS\\\",\\n \\\"Lucida Console\\\",\\n \\\"Monaco\\\",\\n \\\"Consolas\\\",\\n \\\"Courier\\\"\\n ]);\\n var WAVE_SKEW_FACTOR = 0.3;\\n\\n // src/types/index.ts\\n var RichText = class _RichText {\\n constructor(spans = []) {\\n this.spans = spans.length > 0 ? spans.map((s) => ({ ...s, style: { ...s.style } })) : [{ text: \\\"\\\", style: {} }];\\n this.normalize();\\n }\\n /**\\n * Create RichText from plain text string (no special formatting)\\n */\\n static fromPlainText(text, style = {}) {\\n return new _RichText([{ text, style }]);\\n }\\n /**\\n * Get the full text content (all spans concatenated)\\n */\\n getText() {\\n return this.spans.map((s) => s.text).join(\\\"\\\");\\n }\\n /**\\n * Get the total character count\\n */\\n getLength() {\\n return this.getText().length;\\n }\\n /**\\n * Get the style at a specific character index\\n * @param charIndex Character index (0-based)\\n * @returns The style object for the span containing this character\\n */\\n getStyleAt(charIndex) {\\n if (this.spans.length === 0) return {};\\n if (charIndex < 0) return this.spans[0].style;\\n let currentIndex = 0;\\n for (const span of this.spans) {\\n if (charIndex < currentIndex + span.text.length) {\\n return span.style;\\n }\\n currentIndex += span.text.length;\\n }\\n return this.spans[this.spans.length - 1].style;\\n }\\n /**\\n * Apply a style to a character range\\n * @param start Start index (inclusive)\\n * @param end End index (exclusive)\\n * @param style Style to apply (merged with existing styles)\\n */\\n applyStyle(start, end, style) {\\n if (start >= end || start < 0 || end > this.getLength()) {\\n return;\\n }\\n const newSpans = [];\\n let currentIndex = 0;\\n for (const span of this.spans) {\\n const spanStart = currentIndex;\\n const spanEnd = currentIndex + span.text.length;\\n if (spanEnd <= start) {\\n newSpans.push(span);\\n currentIndex = spanEnd;\\n continue;\\n }\\n if (spanStart >= end) {\\n newSpans.push(span);\\n currentIndex = spanEnd;\\n continue;\\n }\\n const overlapStart = Math.max(start, spanStart);\\n const overlapEnd = Math.min(end, spanEnd);\\n if (overlapStart > spanStart) {\\n newSpans.push({\\n text: span.text.substring(0, overlapStart - spanStart),\\n style: span.style\\n });\\n }\\n newSpans.push({\\n text: span.text.substring(overlapStart - spanStart, overlapEnd - spanStart),\\n style: { ...span.style, ...style }\\n });\\n if (overlapEnd < spanEnd) {\\n newSpans.push({\\n text: span.text.substring(overlapEnd - spanStart),\\n style: span.style\\n });\\n }\\n currentIndex = spanEnd;\\n }\\n this.spans = newSpans;\\n this.normalize();\\n }\\n /**\\n * Insert text at a specific position with a given style\\n * @param index Character index to insert at\\n * @param text Text to insert\\n * @param style Style for the inserted text\\n */\\n insert(index, text, style) {\\n if (text.length === 0) return;\\n const newSpans = [];\\n let currentIndex = 0;\\n for (const span of this.spans) {\\n const spanStart = currentIndex;\\n const spanEnd = currentIndex + span.text.length;\\n if (index <= spanStart && newSpans.length === 0) {\\n newSpans.push({ text, style });\\n }\\n if (index > spanStart && index <= spanEnd) {\\n const offset = index - spanStart;\\n newSpans.push({\\n text: span.text.substring(0, offset),\\n style: span.style\\n });\\n newSpans.push({ text, style });\\n newSpans.push({\\n text: span.text.substring(offset),\\n style: span.style\\n });\\n currentIndex = spanEnd;\\n continue;\\n }\\n newSpans.push(span);\\n currentIndex = spanEnd;\\n }\\n if (index >= this.getLength() && !newSpans.some((s) => s.text === text)) {\\n newSpans.push({ text, style });\\n }\\n this.spans = newSpans;\\n this.normalize();\\n }\\n /**\\n * Delete text in a character range\\n * @param start Start index (inclusive)\\n * @param end End index (exclusive)\\n */\\n delete(start, end) {\\n const length = this.getLength();\\n start = Math.max(0, Math.min(start, length));\\n end = Math.max(0, Math.min(end, length));\\n if (start >= end) {\\n return;\\n }\\n const newSpans = [];\\n let currentIndex = 0;\\n for (const span of this.spans) {\\n const spanStart = currentIndex;\\n const spanEnd = currentIndex + span.text.length;\\n if (spanEnd <= start) {\\n newSpans.push(span);\\n currentIndex = spanEnd;\\n continue;\\n }\\n if (spanStart >= end) {\\n newSpans.push(span);\\n currentIndex = spanEnd;\\n continue;\\n }\\n const deleteStart = Math.max(start, spanStart);\\n const deleteEnd = Math.min(end, spanEnd);\\n if (deleteStart > spanStart) {\\n newSpans.push({\\n text: span.text.substring(0, deleteStart - spanStart),\\n style: span.style\\n });\\n }\\n if (deleteEnd < spanEnd) {\\n newSpans.push({\\n text: span.text.substring(deleteEnd - spanStart),\\n style: span.style\\n });\\n }\\n currentIndex = spanEnd;\\n }\\n this.spans = newSpans.length > 0 ? newSpans : [{ text: \\\"\\\", style: {} }];\\n this.normalize();\\n }\\n /**\\n * Normalize spans by:\\n * 1. Removing empty spans\\n * 2. Merging adjacent spans with identical styles\\n * This prevents fragmentation and improves performance\\n */\\n normalize() {\\n this.spans = this.spans.filter((s) => s.text !== \\\"\\\");\\n if (this.spans.length === 0) {\\n this.spans = [{ text: \\\"\\\", style: {} }];\\n return;\\n }\\n if (this.spans.length <= 1) return;\\n const merged = [];\\n let current = this.spans[0];\\n for (let i = 1; i < this.spans.length; i++) {\\n const next = this.spans[i];\\n if (this.stylesEqual(current.style, next.style)) {\\n current = {\\n text: current.text + next.text,\\n style: current.style\\n };\\n } else {\\n merged.push(current);\\n current = next;\\n }\\n }\\n merged.push(current);\\n this.spans = merged;\\n }\\n /**\\n * Check if two styles are equal\\n */\\n stylesEqual(a, b) {\\n return a.color === b.color && a.fontFamily === b.fontFamily && a.fontSize === b.fontSize && a.bold === b.bold && a.italic === b.italic && a.underline === b.underline && a.strikethrough === b.strikethrough && a.letterSpacing === b.letterSpacing;\\n }\\n /**\\n * Clone this RichText instance\\n */\\n clone() {\\n return new _RichText(\\n this.spans.map((span) => ({\\n text: span.text,\\n style: { ...span.style }\\n }))\\n );\\n }\\n /**\\n * Clear a specific style property from all spans.\\n * Used when element-level property changes should override character-level.\\n * After clearing, spans will inherit the property from element defaults.\\n * @param property The style property to clear (e.g., 'fontFamily', 'bold')\\n */\\n clearStyleProperty(property) {\\n for (const span of this.spans) {\\n if (span.style[property] !== void 0) {\\n delete span.style[property];\\n }\\n }\\n this.normalize();\\n }\\n /**\\n * Serialize to JSON\\n */\\n toJSON() {\\n return { spans: this.spans.map((s) => ({ ...s, style: { ...s.style } })) };\\n }\\n /**\\n * Deserialize from JSON\\n */\\n static fromJSON(json) {\\n return new _RichText(json.spans);\\n }\\n };\\n\\n // src/rendering/transform-renderer.ts\\n function createOffscreenCanvas(width, height) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n return new OffscreenCanvas(width, height);\\n }\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n function applyStrokeToChar(ctx, char, stroke) {\\n if (!stroke?.enabled) return;\\n ctx.strokeStyle = stroke.color;\\n ctx.lineWidth = stroke.width;\\n ctx.lineCap = stroke.lineCap || \\\"round\\\";\\n ctx.lineJoin = stroke.lineJoin || \\\"round\\\";\\n if (stroke.miterLimit !== void 0) ctx.miterLimit = stroke.miterLimit;\\n if (stroke.opacity !== void 0) {\\n const prevAlpha = ctx.globalAlpha;\\n ctx.globalAlpha = stroke.opacity;\\n ctx.strokeText(char, 0, 0);\\n ctx.globalAlpha = prevAlpha;\\n } else {\\n ctx.strokeText(char, 0, 0);\\n }\\n }\\n function renderTransformWithOffscreenStroke(ctx, elementData, renderFn) {\\n const stroke = elementData.stroke;\\n const strokeOpacity = stroke?.opacity ?? 1;\\n const elementAlpha = ctx.globalAlpha;\\n const hasStrokeOpacity = stroke?.enabled && strokeOpacity < 1;\\n const hasElementOpacity = stroke?.enabled && elementAlpha < 1;\\n const needsOffscreen = hasStrokeOpacity || hasElementOpacity;\\n if (!needsOffscreen) {\\n renderFn(ctx, elementData);\\n return;\\n }\\n const fontSize = elementData.fontSize || 24;\\n const strokeWidth = stroke.width || 0;\\n const td = elementData.transformData;\\n const textEstimate = fontSize * elementData.text.length * 0.7;\\n const containerSpan = td.width ?? (td.radius ? td.radius * 2 : 0);\\n const estimatedSpan = Math.max(containerSpan, textEstimate);\\n const featherPad = (stroke.feather || 0) * 2;\\n const padding = strokeWidth * 4 + featherPad + fontSize + 40;\\n const estWidth = estimatedSpan + padding;\\n const archExtra = td.archHeight ? Math.abs(td.archHeight) * fontSize * 2 : 0;\\n const radiusExtra = td.radius ? td.radius : 0;\\n const estHeight = fontSize * 3 + padding + archExtra + radiusExtra;\\n const transform = ctx.getTransform();\\n const scale = Math.max(Math.abs(transform.a), Math.abs(transform.d), 1);\\n const offW = Math.ceil(estWidth * scale / 2) * 2;\\n const offH = Math.ceil(estHeight * scale / 2) * 2;\\n if (offW <= 0 || offH <= 0) {\\n renderFn(ctx, elementData);\\n return;\\n }\\n const offCanvas = createOffscreenCanvas(offW, offH);\\n const offCtx = offCanvas.getContext(\\\"2d\\\");\\n if (!offCtx) {\\n renderFn(ctx, elementData);\\n return;\\n }\\n const elemX = elementData.x || 0;\\n const elemY = elementData.y || 0;\\n const centerPixelX = transform.a * elemX + transform.c * elemY + transform.e;\\n const centerPixelY = transform.b * elemX + transform.d * elemY + transform.f;\\n const drawBackX = Math.round(centerPixelX - offW / 2);\\n const drawBackY = Math.round(centerPixelY - offH / 2);\\n offCtx.setTransform(\\n transform.a,\\n transform.b,\\n transform.c,\\n transform.d,\\n offW / 2 - centerPixelX + transform.e,\\n offH / 2 - centerPixelY + transform.f\\n );\\n if (hasElementOpacity) {\\n offCtx.globalAlpha = 1;\\n const savedStrokeOpa = stroke.opacity;\\n if (hasStrokeOpacity) stroke.opacity = 1;\\n renderFn(offCtx, elementData);\\n if (hasStrokeOpacity) stroke.opacity = savedStrokeOpa;\\n ctx.save();\\n ctx.resetTransform();\\n ctx.globalAlpha = elementAlpha;\\n ctx.drawImage(offCanvas, drawBackX, drawBackY);\\n ctx.restore();\\n return;\\n }\\n const savedOpacity = stroke.opacity;\\n stroke.opacity = 1;\\n renderFn(offCtx, elementData);\\n stroke.opacity = savedOpacity;\\n const savedEnabled = stroke.enabled;\\n stroke.enabled = false;\\n renderFn(ctx, elementData);\\n stroke.enabled = savedEnabled;\\n ctx.save();\\n ctx.resetTransform();\\n ctx.globalAlpha = strokeOpacity;\\n ctx.drawImage(\\n offCanvas,\\n drawBackX,\\n drawBackY\\n );\\n ctx.restore();\\n }\\n function renderCircleTransform(ctx, elementData) {\\n renderTransformWithOffscreenStroke(ctx, elementData, renderCircleTransformDirect);\\n }\\n function renderCircleTransformDirect(ctx, elementData) {\\n const transformData = elementData.transformData;\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n ctx.scale(transformData.scale, transformData.scale);\\n const weight = elementData.bold ? \\\"bold\\\" : \\\"normal\\\";\\n const style = elementData.italic ? \\\"italic\\\" : \\\"normal\\\";\\n ctx.font = `${style} ${weight} ${elementData.fontSize}px ${elementData.fontFamily}`;\\n ctx.fillStyle = elementData.color;\\n ctx.textAlign = \\\"center\\\";\\n ctx.textBaseline = \\\"middle\\\";\\n const chars = elementData.text.split(\\\"\\\");\\n const charWidths = chars.map((char) => ctx.measureText(char).width);\\n const totalWidth = charWidths.reduce((sum, w) => sum + w, 0);\\n if (transformData.reverse) {\\n let currentAngle = Math.PI / 2 + totalWidth / (2 * transformData.radius);\\n chars.forEach((char, i) => {\\n const charWidth = charWidths[i];\\n const angleStep = charWidth / transformData.radius;\\n const x = Math.cos(currentAngle - angleStep / 2) * transformData.radius;\\n const y = Math.sin(currentAngle - angleStep / 2) * transformData.radius;\\n ctx.save();\\n ctx.translate(x, y);\\n ctx.rotate(currentAngle - angleStep / 2 - Math.PI / 2);\\n applyStrokeToChar(ctx, char, elementData.stroke);\\n ctx.fillText(char, 0, 0);\\n ctx.restore();\\n currentAngle -= angleStep;\\n });\\n } else {\\n let currentAngle = -Math.PI / 2 - totalWidth / (2 * transformData.radius);\\n chars.forEach((char, i) => {\\n const charWidth = charWidths[i];\\n const angleStep = charWidth / transformData.radius;\\n const x = Math.cos(currentAngle + angleStep / 2) * transformData.radius;\\n const y = Math.sin(currentAngle + angleStep / 2) * transformData.radius;\\n ctx.save();\\n ctx.translate(x, y);\\n ctx.rotate(currentAngle + angleStep / 2 + Math.PI / 2);\\n applyStrokeToChar(ctx, char, elementData.stroke);\\n ctx.fillText(char, 0, 0);\\n ctx.restore();\\n currentAngle += angleStep;\\n });\\n }\\n ctx.restore();\\n }\\n function renderWaveTransform(ctx, elementData) {\\n renderTransformWithOffscreenStroke(ctx, elementData, renderWaveTransformDirect);\\n }\\n function renderWaveTransformDirect(ctx, elementData) {\\n const transformData = elementData.transformData;\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\\n ctx.fillStyle = elementData.color;\\n ctx.textAlign = \\\"center\\\";\\n ctx.textBaseline = \\\"middle\\\";\\n const chars = elementData.text.split(\\\"\\\");\\n const totalWidth = chars.reduce((sum, char) => sum + ctx.measureText(char).width, 0);\\n let currentX = -totalWidth / 2;\\n chars.forEach((char) => {\\n const charWidth = ctx.measureText(char).width;\\n const x = currentX + charWidth / 2;\\n const normalizedX = x / (transformData.width / 2);\\n const y = transformData.amplitude * elementData.fontSize * Math.sin(transformData.frequency * Math.PI * normalizedX);\\n const slope = transformData.amplitude * transformData.frequency * Math.PI * Math.cos(transformData.frequency * Math.PI * normalizedX);\\n ctx.save();\\n ctx.translate(x, y);\\n ctx.transform(1, slope * WAVE_SKEW_FACTOR, 0, 1, 0, 0);\\n applyStrokeToChar(ctx, char, elementData.stroke);\\n ctx.fillText(char, 0, 0);\\n ctx.restore();\\n currentX += charWidth;\\n });\\n ctx.restore();\\n }\\n function renderArchTransform(ctx, elementData) {\\n renderTransformWithOffscreenStroke(ctx, elementData, renderArchTransformDirect);\\n }\\n function renderArchTransformDirect(ctx, elementData) {\\n const transformData = elementData.transformData;\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\\n ctx.fillStyle = elementData.color;\\n ctx.textAlign = \\\"center\\\";\\n ctx.textBaseline = \\\"middle\\\";\\n const chars = elementData.text.split(\\\"\\\");\\n const totalWidth = chars.reduce((sum, char) => sum + ctx.measureText(char).width, 0);\\n const radius = transformData.width / 2;\\n let currentX = -totalWidth / 2;\\n chars.forEach((char) => {\\n const charWidth = ctx.measureText(char).width;\\n const x = currentX + charWidth / 2;\\n const normalizedX = x / radius;\\n const y = (Math.pow(normalizedX, 2) - 1) * transformData.archHeight * elementData.fontSize;\\n const slope = 2 * normalizedX * transformData.archHeight;\\n ctx.save();\\n ctx.translate(x, y);\\n const skewFactor = 0.3;\\n ctx.transform(1, slope * skewFactor, 0, 1, 0, 0);\\n applyStrokeToChar(ctx, char, elementData.stroke);\\n ctx.fillText(char, 0, 0);\\n ctx.restore();\\n currentX += charWidth;\\n });\\n ctx.restore();\\n }\\n function renderAscendTransform(ctx, elementData) {\\n renderTransformWithOffscreenStroke(ctx, elementData, renderAscendTransformDirect);\\n }\\n function renderAscendTransformDirect(ctx, elementData) {\\n const transformData = elementData.transformData;\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\\n ctx.fillStyle = elementData.color;\\n ctx.textAlign = \\\"center\\\";\\n ctx.textBaseline = \\\"middle\\\";\\n const chars = elementData.text.split(\\\"\\\");\\n const totalWidth = chars.reduce((sum, char) => sum + ctx.measureText(char).width, 0);\\n const angleRad = transformData.ascendAngle * Math.PI / 180;\\n let currentX = -totalWidth / 2;\\n chars.forEach((char) => {\\n const charWidth = ctx.measureText(char).width;\\n const x = currentX + charWidth / 2;\\n const y = x * Math.tan(angleRad);\\n const slope = Math.tan(angleRad);\\n ctx.save();\\n ctx.translate(x, y);\\n const skewFactor = 1;\\n ctx.transform(1, slope * skewFactor, 0, 1, 0, 0);\\n applyStrokeToChar(ctx, char, elementData.stroke);\\n ctx.fillText(char, 0, 0);\\n ctx.restore();\\n currentX += charWidth;\\n });\\n ctx.restore();\\n }\\n function renderLeanTransform(ctx, elementData) {\\n renderTransformWithOffscreenStroke(ctx, elementData, renderLeanTransformDirect);\\n }\\n function renderLeanTransformDirect(ctx, elementData) {\\n const transformData = elementData.transformData;\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n const skewAngle = -transformData.leanAmount * Math.PI / 4;\\n ctx.transform(1, 0, Math.tan(skewAngle), 1, 0, 0);\\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\\n ctx.fillStyle = elementData.color;\\n ctx.textAlign = \\\"center\\\";\\n ctx.textBaseline = \\\"middle\\\";\\n if (elementData.stroke?.enabled) {\\n ctx.save();\\n ctx.strokeStyle = elementData.stroke.color;\\n ctx.lineWidth = elementData.stroke.width;\\n ctx.lineCap = elementData.stroke.lineCap || \\\"round\\\";\\n ctx.lineJoin = elementData.stroke.lineJoin || \\\"round\\\";\\n if (elementData.stroke.opacity !== void 0) ctx.globalAlpha = elementData.stroke.opacity;\\n ctx.strokeText(elementData.text, 0, 0);\\n ctx.restore();\\n }\\n ctx.fillText(elementData.text, 0, 0);\\n ctx.restore();\\n }\\n function renderFlagTransform(ctx, elementData) {\\n renderTransformWithOffscreenStroke(ctx, elementData, renderFlagTransformDirect);\\n }\\n function renderFlagTransformDirect(ctx, elementData) {\\n const transformData = elementData.transformData;\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n ctx.font = buildFontString(elementData.fontSize, elementData.fontFamily, elementData.bold, elementData.italic);\\n ctx.fillStyle = elementData.color;\\n ctx.textAlign = \\\"center\\\";\\n ctx.textBaseline = \\\"middle\\\";\\n const chars = elementData.text.split(\\\"\\\");\\n const totalWidth = chars.reduce((sum, char) => sum + ctx.measureText(char).width, 0);\\n let currentX = -totalWidth / 2;\\n chars.forEach((char) => {\\n const charWidth = ctx.measureText(char).width;\\n const x = currentX + charWidth / 2;\\n const normalizedX = x / (transformData.width / 2);\\n const distanceFromCenter = Math.abs(normalizedX);\\n const flagAmplitude = transformData.amplitude * distanceFromCenter;\\n const y = flagAmplitude * elementData.fontSize * Math.sin(transformData.frequency * Math.PI * normalizedX);\\n const cosComponent = flagAmplitude * transformData.frequency * Math.PI * Math.cos(transformData.frequency * Math.PI * normalizedX);\\n const sinComponent = transformData.amplitude * Math.sign(normalizedX) * Math.sin(transformData.frequency * Math.PI * normalizedX);\\n const slope = cosComponent + sinComponent;\\n ctx.save();\\n ctx.translate(x, y);\\n const skewFactor = 0.3;\\n ctx.transform(1, slope * skewFactor, 0, 1, 0, 0);\\n applyStrokeToChar(ctx, char, elementData.stroke);\\n ctx.fillText(char, 0, 0);\\n ctx.restore();\\n currentX += charWidth;\\n });\\n ctx.restore();\\n }\\n\\n // src/core/text-spacing.ts\\n function countSpacedChars(text) {\\n return Array.from(text).length;\\n }\\n function spacedTextWidth(rawWidth, text, letterSpacing) {\\n if (!letterSpacing) return rawWidth;\\n return rawWidth + letterSpacing * countSpacedChars(text);\\n }\\n function getSpacedCharOffsets(ctx, text, letterSpacing) {\\n const chars = Array.from(text);\\n const offsets = [0];\\n let prefix = \\\"\\\";\\n for (let i = 0; i < chars.length; i++) {\\n prefix += chars[i];\\n offsets.push(ctx.measureText(prefix).width + letterSpacing * (i + 1));\\n }\\n return offsets;\\n }\\n function leftAnchoredStartX(ctx, x, totalWidth) {\\n switch (ctx.textAlign) {\\n case \\\"center\\\":\\n return x - totalWidth / 2;\\n case \\\"right\\\":\\n case \\\"end\\\":\\n return x - totalWidth;\\n default:\\n return x;\\n }\\n }\\n function drawTextWithSpacing(op, ctx, text, x, y, letterSpacing) {\\n if (!letterSpacing || text.length === 0) {\\n ctx[op](text, x, y);\\n return;\\n }\\n const offsets = getSpacedCharOffsets(ctx, text, letterSpacing);\\n const totalWidth = offsets[offsets.length - 1];\\n const startX = leftAnchoredStartX(ctx, x, totalWidth);\\n const previousAlign = ctx.textAlign;\\n ctx.textAlign = \\\"left\\\";\\n const chars = Array.from(text);\\n for (let i = 0; i < chars.length; i++) {\\n ctx[op](chars[i], startX + offsets[i], y);\\n }\\n ctx.textAlign = previousAlign;\\n }\\n function fillTextWithSpacing(ctx, text, x, y, letterSpacing) {\\n drawTextWithSpacing(\\\"fillText\\\", ctx, text, x, y, letterSpacing);\\n }\\n function strokeTextWithSpacing(ctx, text, x, y, letterSpacing) {\\n drawTextWithSpacing(\\\"strokeText\\\", ctx, text, x, y, letterSpacing);\\n }\\n\\n // src/core/TextMetrics.ts\\n var _measureCanvas = null;\\n function getMeasureCanvas() {\\n if (!_measureCanvas) {\\n if (typeof document !== \\\"undefined\\\") {\\n _measureCanvas = document.createElement(\\\"canvas\\\");\\n } else if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n _measureCanvas = new OffscreenCanvas(1, 1);\\n } else {\\n throw new Error(\\\"No canvas available for text measurement\\\");\\n }\\n }\\n return _measureCanvas;\\n }\\n function buildFontString2(fontSize, fontFamily, bold = false, italic = false) {\\n const parts = [];\\n if (italic) {\\n parts.push(\\\"italic\\\");\\n }\\n if (bold) {\\n parts.push(\\\"bold\\\");\\n }\\n parts.push(`${fontSize}px`);\\n parts.push(fontFamily);\\n return parts.join(\\\" \\\");\\n }\\n function wrapText(text, maxWidth, fontSize, fontFamily, bold = false, italic = false, lockedLineCount, strict = false, opts) {\\n const canvas = getMeasureCanvas();\\n const ctx = canvas.getContext(\\\"2d\\\");\\n ctx.font = buildFontString2(fontSize, fontFamily, bold, italic);\\n const letterSpacing = opts?.letterSpacing ?? 0;\\n const measure = (t) => spacedTextWidth(ctx.measureText(t).width, t, letterSpacing);\\n if (text.trim().length === 0) {\\n return [text];\\n }\\n if (text.includes(\\\"\\\\n\\\")) {\\n const explicitLines = text.split(\\\"\\\\n\\\");\\n const allWrappedLines = [];\\n for (let i = 0; i < explicitLines.length; i++) {\\n const line = explicitLines[i];\\n const wrappedLine = wrapText(line, maxWidth, fontSize, fontFamily, bold, italic, void 0, strict, opts);\\n allWrappedLines.push(...wrappedLine);\\n }\\n return allWrappedLines;\\n }\\n const leadingSpacesMatch = text.match(/^\\\\s*/);\\n const trailingSpacesMatch = text.match(/\\\\s*$/);\\n const leadingSpaces = leadingSpacesMatch ? leadingSpacesMatch[0] : \\\"\\\";\\n const trailingSpaces = trailingSpacesMatch ? trailingSpacesMatch[0] : \\\"\\\";\\n const trimmedText = text.substring(leadingSpaces.length, text.length - trailingSpaces.length);\\n const words = trimmedText.split(\\\" \\\");\\n if (lockedLineCount !== void 0 && lockedLineCount > 0) {\\n if (lockedLineCount === 1) {\\n return [leadingSpaces + words.join(\\\" \\\") + trailingSpaces];\\n }\\n const lines2 = [];\\n const wordsPerLine = Math.ceil(words.length / lockedLineCount);\\n for (let i = 0; i < words.length; i += wordsPerLine) {\\n const lineWords = words.slice(i, i + wordsPerLine);\\n lines2.push(lineWords.join(\\\" \\\"));\\n }\\n if (lines2.length > 0) {\\n lines2[0] = leadingSpaces + lines2[0];\\n lines2[lines2.length - 1] = lines2[lines2.length - 1] + trailingSpaces;\\n }\\n return lines2;\\n }\\n const allText = words.join(\\\" \\\");\\n const allTextWithSpaces = leadingSpaces + allText + trailingSpaces;\\n const allTextWidth = measure(allTextWithSpaces);\\n const isSmallSize = maxWidth < 200;\\n const wrapTolerancePercent = strict ? 0 : isSmallSize ? 0.08 : 0.05;\\n const wrapTolerance = strict ? 0 : Math.max(20, maxWidth * wrapTolerancePercent);\\n if (allTextWidth <= maxWidth + wrapTolerance) {\\n return [allTextWithSpaces];\\n }\\n const lines = [];\\n let currentLine = \\\"\\\";\\n const lineTolerancePercent = strict ? 0 : isSmallSize ? 0.05 : 0.03;\\n const lineTolerance = strict ? 0 : Math.max(15, maxWidth * lineTolerancePercent);\\n for (let i = 0; i < words.length; i++) {\\n const word = words[i];\\n const wordWidth = measure(word);\\n if (wordWidth > maxWidth + lineTolerance) {\\n if (currentLine.length > 0) {\\n lines.push(currentLine);\\n currentLine = \\\"\\\";\\n }\\n const chars = Array.from(word);\\n let charBuffer = \\\"\\\";\\n for (const char of chars) {\\n const testBuffer = charBuffer + char;\\n const bufferWidth = measure(testBuffer);\\n if (bufferWidth > maxWidth + lineTolerance && charBuffer.length > 0) {\\n lines.push(charBuffer);\\n charBuffer = char;\\n } else {\\n charBuffer = testBuffer;\\n }\\n }\\n currentLine = charBuffer;\\n } else {\\n const testLine = currentLine.length > 0 ? currentLine + \\\" \\\" + word : word;\\n const testLineWidth = measure(testLine);\\n if (testLineWidth > maxWidth + lineTolerance && currentLine.length > 0) {\\n lines.push(currentLine);\\n currentLine = word;\\n } else {\\n currentLine = testLine;\\n }\\n }\\n }\\n if (currentLine.length > 0) {\\n lines.push(currentLine);\\n }\\n if (lines.length > 0) {\\n if (leadingSpaces.length > 0) {\\n const firstLineWithSpace = leadingSpaces + lines[0];\\n const firstLineWidth = measure(firstLineWithSpace);\\n if (firstLineWidth > maxWidth + lineTolerance) {\\n lines.unshift(leadingSpaces);\\n } else {\\n lines[0] = firstLineWithSpace;\\n }\\n }\\n if (trailingSpaces.length > 0) {\\n const lastIdx = lines.length - 1;\\n const lastLineWithSpace = lines[lastIdx] + trailingSpaces;\\n const lastLineWidth = measure(lastLineWithSpace);\\n if (lastLineWidth > maxWidth + lineTolerance) {\\n lines.push(trailingSpaces);\\n } else {\\n lines[lastIdx] = lastLineWithSpace;\\n }\\n }\\n }\\n return lines;\\n }\\n function getFontMetrics(fontSize, fontFamily, bold = false, italic = false) {\\n const canvas = getMeasureCanvas();\\n const ctx = canvas.getContext(\\\"2d\\\");\\n ctx.font = buildFontString2(fontSize, fontFamily, bold, italic);\\n const sampleText = \\\"\\\\xC1\\\\xC9\\\\xCDgjpqy\\\";\\n const metrics = ctx.measureText(sampleText);\\n const ascent = metrics.actualBoundingBoxAscent || fontSize * 0.8;\\n const descent = metrics.actualBoundingBoxDescent || fontSize * 0.2;\\n const height = ascent + descent;\\n return { ascent, descent, height };\\n }\\n function calculateVisualBoundsWithSpaceCollapsing(text, maxWidth, fontSize, fontFamily, bold = false, italic = false, lockedLineCount, strict = false, opts) {\\n const letterSpacing = opts?.letterSpacing ?? 0;\\n const lines = wrapText(text, maxWidth, fontSize, fontFamily, bold, italic, lockedLineCount, strict, opts);\\n const hasExplicitNewlines = text.includes(\\\"\\\\n\\\");\\n const paragraphMetadata = lines.map((_, index) => ({\\n isParagraphStart: !hasExplicitNewlines && index === 0,\\n isParagraphEnd: !hasExplicitNewlines && index === lines.length - 1\\n }));\\n const canvas = getMeasureCanvas();\\n const ctx = canvas.getContext(\\\"2d\\\");\\n ctx.font = buildFontString2(fontSize, fontFamily, bold, italic);\\n let maxLineWidth = 0;\\n const fontMetrics = getFontMetrics(fontSize, fontFamily, bold, italic);\\n const visibleLines = [];\\n let totalLineCount = 0;\\n lines.forEach((line, index) => {\\n const isParagraphStart = paragraphMetadata[index].isParagraphStart;\\n const isParagraphEnd = paragraphMetadata[index].isParagraphEnd;\\n let visibleText = line;\\n if (!isParagraphStart) {\\n const leadingSpacesMatch = line.match(/^ +/);\\n const leadingSpacesCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;\\n if (leadingSpacesCount > 0) {\\n visibleText = visibleText.substring(leadingSpacesCount);\\n }\\n }\\n if (!isParagraphEnd) {\\n const trailingSpacesMatch = visibleText.match(/ +$/);\\n const trailingSpacesCount = trailingSpacesMatch ? trailingSpacesMatch[0].length : 0;\\n if (trailingSpacesCount > 0) {\\n visibleText = visibleText.substring(0, visibleText.length - trailingSpacesCount);\\n }\\n }\\n totalLineCount++;\\n if (visibleText.length > 0) {\\n visibleLines.push(visibleText);\\n const lineWidth = spacedTextWidth(ctx.measureText(visibleText).width, visibleText, letterSpacing);\\n maxLineWidth = Math.max(maxLineWidth, lineWidth);\\n }\\n });\\n let height;\\n const lineHeight = opts?.lineHeight ?? LINE_HEIGHT_MULTIPLIER;\\n if (totalLineCount === 1) {\\n height = fontMetrics.height;\\n } else if (totalLineCount === 0) {\\n height = 0;\\n } else {\\n const lineSpacing = fontSize * lineHeight;\\n height = (totalLineCount - 1) * lineSpacing + fontMetrics.height;\\n }\\n return {\\n width: maxLineWidth,\\n height,\\n lines\\n };\\n }\\n\\n // src/rendering/stroke-utils.ts\\n function createImagePath(ctx, element) {\\n if (!element.transformData) return;\\n const { borderRadius = 0 } = element.transformData;\\n const width = element.transformData.width ?? 100;\\n const height = element.transformData.height ?? 100;\\n ctx.translate(element.x || 0, element.y || 0);\\n ctx.rotate(-(element.rotation || 0) * Math.PI / 180);\\n ctx.beginPath();\\n if (borderRadius > 0) {\\n const maxRadius = Math.min(width, height) / 2;\\n const radius = Math.min(borderRadius, maxRadius);\\n const x = -width / 2;\\n const y = -height / 2;\\n ctx.moveTo(x + radius, y);\\n ctx.lineTo(x + width - radius, y);\\n ctx.arcTo(x + width, y, x + width, y + radius, radius);\\n ctx.lineTo(x + width, y + height - radius);\\n ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);\\n ctx.lineTo(x + radius, y + height);\\n ctx.arcTo(x, y + height, x, y + height - radius, radius);\\n ctx.lineTo(x, y + radius);\\n ctx.arcTo(x, y, x + radius, y, radius);\\n ctx.closePath();\\n } else {\\n ctx.rect(-width / 2, -height / 2, width, height);\\n }\\n }\\n\\n // src/rendering/StrokeRenderer.ts\\n function applyStrokeStyle(ctx, stroke) {\\n ctx.strokeStyle = stroke.color;\\n ctx.lineWidth = stroke.width;\\n ctx.lineCap = stroke.lineCap || \\\"butt\\\";\\n ctx.lineJoin = stroke.lineJoin || \\\"miter\\\";\\n if (stroke.miterLimit !== void 0) {\\n ctx.miterLimit = stroke.miterLimit;\\n }\\n if (stroke.dashArray && stroke.dashArray.length > 0) {\\n ctx.setLineDash(stroke.dashArray);\\n } else {\\n ctx.setLineDash([]);\\n }\\n if (stroke.opacity !== void 0) {\\n ctx.globalAlpha = stroke.opacity;\\n }\\n }\\n function createOffscreenCanvas2(width, height) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n return new OffscreenCanvas(width, height);\\n }\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n function renderTextStroke(ctx, element, renderingContext) {\\n if (!element.stroke?.enabled) return;\\n const textElement = element;\\n const text = textElement.text || \\\"\\\";\\n if (!text) return;\\n const isKnockoutRender = renderingContext?.isKnockout === true;\\n const strokeOpacity = element.stroke.opacity ?? 1;\\n const needsOffscreen = !isKnockoutRender && strokeOpacity < 1;\\n if (needsOffscreen) {\\n try {\\n renderTextStrokeViaOffscreen(ctx, element, textElement, renderingContext, strokeOpacity);\\n } catch {\\n renderTextStrokeDirect(ctx, element, textElement, renderingContext, false);\\n }\\n } else {\\n renderTextStrokeDirect(ctx, element, textElement, renderingContext, isKnockoutRender);\\n }\\n }\\n function renderTextStrokeViaOffscreen(ctx, element, textElement, renderingContext, strokeOpacity) {\\n const text = textElement.text || \\\"\\\";\\n const fontSize = textElement.fontSize || 24;\\n const strokeWidth = element.stroke.width;\\n const feather = element.stroke.feather || 0;\\n const isCustomTransform = element.transformType === \\\"custom\\\" && element.transformData?.width;\\n const customWidth = isCustomTransform ? element.transformData?.width ?? 200 : 0;\\n const estWidth = isCustomTransform ? customWidth + strokeWidth * 2 + feather * 2 + 40 : fontSize * text.length * 0.7 + strokeWidth * 2 + feather * 2 + 40;\\n const estHeight = fontSize * 3 + strokeWidth * 2 + feather * 2 + 40;\\n const transform = ctx.getTransform();\\n const scale = Math.max(Math.abs(transform.a), Math.abs(transform.d), 1);\\n const offW = Math.ceil(estWidth * scale / 2) * 2;\\n const offH = Math.ceil(estHeight * scale / 2) * 2;\\n if (offW <= 0 || offH <= 0) {\\n renderTextStrokeDirect(ctx, element, textElement, renderingContext, false);\\n return;\\n }\\n const offCanvas = createOffscreenCanvas2(offW, offH);\\n const offCtx = offCanvas.getContext(\\\"2d\\\");\\n if (!offCtx) {\\n renderTextStrokeDirect(ctx, element, textElement, renderingContext, false);\\n return;\\n }\\n const elemX = element.x || 0;\\n const elemY = element.y || 0;\\n const centerPixelX = transform.a * elemX + transform.c * elemY + transform.e;\\n const centerPixelY = transform.b * elemX + transform.d * elemY + transform.f;\\n offCtx.setTransform(\\n transform.a,\\n transform.b,\\n transform.c,\\n transform.d,\\n offW / 2 - centerPixelX + transform.e,\\n offH / 2 - centerPixelY + transform.f\\n );\\n const originalOpacity = element.stroke.opacity;\\n element.stroke.opacity = 1;\\n renderTextStrokeDirect(offCtx, element, textElement, renderingContext, false);\\n element.stroke.opacity = originalOpacity;\\n ctx.save();\\n ctx.resetTransform();\\n ctx.globalAlpha = strokeOpacity;\\n ctx.drawImage(\\n offCanvas,\\n Math.round(centerPixelX - offW / 2),\\n Math.round(centerPixelY - offH / 2)\\n );\\n ctx.restore();\\n }\\n function renderTextStrokeDirect(ctx, element, textElement, renderingContext, isKnockoutRender) {\\n const text = textElement.text || \\\"\\\";\\n ctx.save();\\n if (!renderingContext?.positionApplied) {\\n ctx.translate(element.x || 0, element.y || 0);\\n ctx.rotate(-(element.rotation || 0) * Math.PI / 180);\\n }\\n const fontSize = textElement.fontSize || 24;\\n const fontFamily = textElement.fontFamily || \\\"Arial\\\";\\n const bold = textElement.bold || false;\\n const italic = textElement.italic || false;\\n const textAlign = textElement.textAlign || \\\"center\\\";\\n ctx.font = `${italic ? \\\"italic \\\" : \\\"\\\"}${bold ? \\\"bold \\\" : \\\"\\\"}${fontSize}px ${fontFamily}`;\\n ctx.textAlign = textAlign;\\n ctx.textBaseline = \\\"alphabetic\\\";\\n if (isKnockoutRender) {\\n ctx.strokeStyle = \\\"#000000\\\";\\n ctx.globalAlpha = 1;\\n } else {\\n ctx.strokeStyle = element.stroke.color;\\n if (element.stroke.opacity !== void 0) {\\n ctx.globalAlpha = element.stroke.opacity;\\n }\\n }\\n ctx.lineWidth = element.stroke.width;\\n ctx.lineCap = element.stroke.lineCap || \\\"round\\\";\\n ctx.lineJoin = element.stroke.lineJoin || \\\"round\\\";\\n if (element.stroke.miterLimit !== void 0) {\\n ctx.miterLimit = element.stroke.miterLimit;\\n }\\n if (!isKnockoutRender && element.stroke.feather && element.stroke.feather > 0) {\\n if (\\\"filter\\\" in ctx) {\\n ctx.filter = `blur(${element.stroke.feather}px)`;\\n }\\n }\\n const fontMetrics = getFontMetrics(fontSize, fontFamily, bold, italic);\\n const isCustomTransform = element.transformType === \\\"custom\\\" && element.transformData?.width;\\n if (isCustomTransform) {\\n const transformData = element.transformData;\\n const width = transformData?.width ?? 200;\\n const availableWidth = width - HORIZONTAL_PADDING * 2;\\n const letterSpacing = textElement.letterSpacing ?? 0;\\n const { lines, height: visualHeight } = calculateVisualBoundsWithSpaceCollapsing(\\n text,\\n availableWidth,\\n fontSize,\\n fontFamily,\\n bold,\\n italic,\\n void 0,\\n // No locked line count for stroke\\n true,\\n // strict: wrap exactly at maxWidth\\n { letterSpacing, lineHeight: textElement.lineHeight }\\n );\\n const topLeftX = -width / 2;\\n const topLeftY = -visualHeight / 2;\\n const lineSpacing = fontSize * (textElement.lineHeight ?? LINE_HEIGHT_MULTIPLIER);\\n lines.forEach((line, index) => {\\n const isParagraphStart = index === 0;\\n const isParagraphEnd = index === lines.length - 1;\\n let visibleText = line;\\n if (!isParagraphStart) {\\n const leadingSpacesMatch = line.match(/^ +/);\\n const leadingSpacesCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;\\n if (leadingSpacesCount > 0) {\\n visibleText = visibleText.substring(leadingSpacesCount);\\n }\\n }\\n if (!isParagraphEnd) {\\n const trailingSpacesMatch = visibleText.match(/ +$/);\\n const trailingSpacesCount = trailingSpacesMatch ? trailingSpacesMatch[0].length : 0;\\n if (trailingSpacesCount > 0) {\\n visibleText = visibleText.substring(0, visibleText.length - trailingSpacesCount);\\n }\\n }\\n let xPos = topLeftX + HORIZONTAL_PADDING;\\n if (textAlign === \\\"center\\\") {\\n xPos = topLeftX + width / 2;\\n } else if (textAlign === \\\"right\\\") {\\n xPos = topLeftX + width - HORIZONTAL_PADDING;\\n }\\n const yPos = topLeftY + fontMetrics.ascent + index * lineSpacing;\\n strokeTextWithSpacing(ctx, visibleText, xPos, yPos, letterSpacing);\\n });\\n } else {\\n const visualHeight = fontMetrics.height;\\n const topLeftY = -visualHeight / 2;\\n const yPos = topLeftY + fontMetrics.ascent;\\n ctx.strokeText(text, 0, yPos);\\n }\\n ctx.restore();\\n }\\n function renderImageStroke(ctx, element, renderingContext) {\\n if (!element.stroke?.enabled) return;\\n if (!element.transformData) return;\\n const isKnockoutRender = renderingContext?.isKnockout === true;\\n ctx.save();\\n if (isKnockoutRender) {\\n ctx.strokeStyle = \\\"#000000\\\";\\n ctx.lineWidth = element.stroke.width;\\n ctx.lineCap = element.stroke.lineCap || \\\"butt\\\";\\n ctx.lineJoin = element.stroke.lineJoin || \\\"miter\\\";\\n ctx.globalAlpha = 1;\\n if (element.stroke.miterLimit !== void 0) {\\n ctx.miterLimit = element.stroke.miterLimit;\\n }\\n } else {\\n applyStrokeStyle(ctx, element.stroke);\\n }\\n if (!isKnockoutRender && element.stroke.feather && element.stroke.feather > 0) {\\n if (\\\"filter\\\" in ctx) {\\n ctx.filter = `blur(${element.stroke.feather}px)`;\\n }\\n }\\n createImagePath(ctx, element);\\n ctx.stroke();\\n ctx.restore();\\n }\\n\\n // src/utils/logger.ts\\n var Logger = class {\\n constructor() {\\n this.level = 0 /* DEBUG */;\\n this.enabled = typeof process !== \\\"undefined\\\" && false;\\n }\\n // Only enabled in development by default\\n /**\\n * Set the minimum log level to display\\n */\\n setLevel(level) {\\n this.level = level;\\n }\\n /**\\n * Enable or disable logging globally\\n */\\n setEnabled(enabled) {\\n this.enabled = enabled;\\n }\\n /**\\n * Get current log level\\n */\\n getLevel() {\\n return this.level;\\n }\\n /**\\n * Check if logging is enabled\\n */\\n isEnabled() {\\n return this.enabled;\\n }\\n /**\\n * Log debug message (verbose, development only)\\n */\\n debug(_message, ..._args) {\\n }\\n /**\\n * Log info message (general information)\\n */\\n info(message, ...args) {\\n if (this.enabled && this.level <= 1 /* INFO */) {\\n console.info(`[INFO] ${message}`, ...args);\\n }\\n }\\n /**\\n * Log warning message (potential issues)\\n */\\n warn(message, ...args) {\\n if (this.enabled && this.level <= 2 /* WARN */) {\\n console.warn(`[WARN] ${message}`, ...args);\\n }\\n }\\n /**\\n * Log error message (critical issues)\\n */\\n error(message, ...args) {\\n if (this.enabled && this.level <= 3 /* ERROR */) {\\n console.error(`[ERROR] ${message}`, ...args);\\n }\\n }\\n /**\\n * Create a scoped logger with a prefix for a specific module\\n */\\n scope(scopeName) {\\n return new ScopedLogger(this, scopeName);\\n }\\n };\\n var ScopedLogger = class {\\n constructor(logger4, scopeName) {\\n this.logger = logger4;\\n this.scopeName = scopeName;\\n }\\n debug(message, ...args) {\\n this.logger.debug(`[${this.scopeName}] ${message}`, ...args);\\n }\\n info(message, ...args) {\\n this.logger.info(`[${this.scopeName}] ${message}`, ...args);\\n }\\n warn(message, ...args) {\\n this.logger.warn(`[${this.scopeName}] ${message}`, ...args);\\n }\\n error(message, ...args) {\\n this.logger.error(`[${this.scopeName}] ${message}`, ...args);\\n }\\n };\\n var logger = new Logger();\\n var createLogger = (scopeName) => {\\n return logger.scope(scopeName);\\n };\\n\\n // src/utils/FontAnalyzer.ts\\n var log = createLogger(\\\"FontAnalyzer\\\");\\n var fontkitModule = null;\\n async function getFontkit() {\\n if (!fontkitModule) {\\n fontkitModule = await Promise.resolve().then(() => (init_browser_module(), browser_module_exports));\\n }\\n return fontkitModule;\\n }\\n var FontAnalyzerService = class {\\n constructor() {\\n this.fontCache = /* @__PURE__ */ new Map();\\n this.failedFonts = /* @__PURE__ */ new Set();\\n // Track fonts that failed to load (CORS, network errors)\\n this.CACHE_DURATION = 1e3 * 60 * 30;\\n // 30 minutes\\n this.MAX_CACHE_SIZE = 5;\\n }\\n // Limit cache to prevent iOS Safari memory crashes\\n /**\\n * Evict the oldest font from cache if over the limit\\n * Uses LRU (Least Recently Used) strategy based on timestamp\\n */\\n evictOldestFont() {\\n if (this.fontCache.size <= this.MAX_CACHE_SIZE) return;\\n let oldestKey = null;\\n let oldestTime = Date.now();\\n this.fontCache.forEach((entry, key) => {\\n if (entry.timestamp < oldestTime) {\\n oldestTime = entry.timestamp;\\n oldestKey = key;\\n }\\n });\\n if (oldestKey) {\\n this.fontCache.delete(oldestKey);\\n }\\n }\\n /**\\n * Check if a font is a system font\\n */\\n isSystemFont(fontFamily) {\\n return SYSTEM_FONTS.has(fontFamily);\\n }\\n /**\\n * Get Google Fonts API URL for a specific font family\\n */\\n getGoogleFontUrl(fontFamily, weight = 400) {\\n const formattedFamily = fontFamily.replace(/\\\\s+/g, \\\"+\\\");\\n return `https://fonts.googleapis.com/css2?family=${formattedFamily}:wght@${weight}&display=swap`;\\n }\\n /**\\n * Extract actual font file URL from Google Fonts CSS\\n */\\n async extractFontFileUrl(fontFamily, weight = 400) {\\n try {\\n const cssUrl = this.getGoogleFontUrl(fontFamily, weight);\\n const response = await fetch(cssUrl);\\n const css = await response.text();\\n const fontFaceRegex = /@font-face\\\\s*{([^}]*)}/g;\\n const fontFaces = Array.from(css.matchAll(fontFaceRegex));\\n if (fontFaces.length === 0) {\\n log.warn(\\\"No @font-face found in CSS\\\");\\n return null;\\n }\\n let bestUrl = null;\\n let bestScore = -1;\\n for (let i = 0; i < fontFaces.length; i++) {\\n const fontFaceContent = fontFaces[i][1];\\n const urlMatch = fontFaceContent.match(/url\\\\((https:\\\\/\\\\/fonts\\\\.gstatic\\\\.com\\\\/[^)]+)\\\\)/);\\n const hasUnicodeRange = fontFaceContent.includes(\\\"unicode-range\\\");\\n const unicodeRangeMatch = fontFaceContent.match(/unicode-range:\\\\s*([^;]+);/);\\n if (!urlMatch) continue;\\n const url = urlMatch[1];\\n let score = 0;\\n if (!hasUnicodeRange) {\\n score = 1e3;\\n } else if (unicodeRangeMatch) {\\n const rangeContent = unicodeRangeMatch[1];\\n score = (rangeContent.match(/U\\\\+/g) || []).length;\\n }\\n if (score > bestScore) {\\n bestScore = score;\\n bestUrl = url;\\n }\\n }\\n if (bestUrl) {\\n return bestUrl;\\n }\\n log.warn(\\\"No font URL found in CSS for\\\", fontFamily);\\n return null;\\n } catch (error) {\\n log.error(\\\"Error extracting font file URL:\\\", error);\\n return null;\\n }\\n }\\n /**\\n * Load and parse a font file\\n */\\n async loadFont(fontFamily, weight = 400) {\\n if (this.isSystemFont(fontFamily)) {\\n return null;\\n }\\n const cacheKey = `${fontFamily}-${weight}`;\\n if (this.failedFonts.has(cacheKey)) {\\n return null;\\n }\\n const cached = this.fontCache.get(cacheKey);\\n if (cached && Date.now() - cached.timestamp < this.CACHE_DURATION) {\\n cached.timestamp = Date.now();\\n return cached.font;\\n }\\n try {\\n const fontUrl = await this.extractFontFileUrl(fontFamily, weight);\\n if (!fontUrl) {\\n this.failedFonts.add(cacheKey);\\n return null;\\n }\\n const response = await fetch(fontUrl);\\n if (!response.ok) {\\n log.error(`Font fetch failed: ${response.status} ${response.statusText}`);\\n this.failedFonts.add(cacheKey);\\n return null;\\n }\\n const arrayBuffer = await response.arrayBuffer();\\n const buffer = new Uint8Array(arrayBuffer);\\n const fontkit = await getFontkit();\\n const fontOrCollection = fontkit.create(buffer);\\n const font = \\\"fonts\\\" in fontOrCollection ? fontOrCollection.fonts[0] : fontOrCollection;\\n this.fontCache.set(cacheKey, {\\n font,\\n url: fontUrl,\\n timestamp: Date.now()\\n });\\n this.evictOldestFont();\\n return font;\\n } catch (error) {\\n log.error(`Error loading font ${fontFamily}:`, error);\\n this.failedFonts.add(cacheKey);\\n return null;\\n }\\n }\\n /**\\n * Get font from cache synchronously (for rendering)\\n * Returns null if font is not cached - font should be pre-loaded before rendering\\n */\\n getFontSync(fontFamily, weight = 400) {\\n const cacheKey = `${fontFamily}-${weight}`;\\n const cached = this.fontCache.get(cacheKey);\\n if (cached && Date.now() - cached.timestamp < this.CACHE_DURATION) {\\n cached.timestamp = Date.now();\\n return cached.font;\\n }\\n return null;\\n }\\n /**\\n * Clear font cache (useful for debugging or forcing reload)\\n * Also clears failed fonts to allow retry\\n */\\n clearCache(fontFamily, weight) {\\n if (fontFamily) {\\n const cacheKey = `${fontFamily}-${weight || 400}`;\\n this.fontCache.delete(cacheKey);\\n this.failedFonts.delete(cacheKey);\\n } else {\\n this.fontCache.clear();\\n this.failedFonts.clear();\\n }\\n }\\n /**\\n * Get all glyphs in a font (for browsing)\\n */\\n async getAllGlyphs(fontFamily, weight = 400, limit = 1500) {\\n if (this.isSystemFont(fontFamily)) {\\n return [];\\n }\\n const font = await this.loadFont(fontFamily, weight);\\n if (!font) {\\n return [];\\n }\\n const glyphs = [];\\n const maxGlyphs = Math.min(font.numGlyphs, limit);\\n for (let glyphId = 0; glyphId < maxGlyphs; glyphId++) {\\n try {\\n const glyph = font.getGlyph(glyphId);\\n if (!glyph || !glyph.name) continue;\\n if (glyph.name === \\\".notdef\\\" || glyph.name.startsWith(\\\".null\\\")) {\\n continue;\\n }\\n const codePoints = glyph.codePoints || [];\\n let unicode = codePoints.length > 0 ? String.fromCodePoint(codePoints[0]) : \\\"\\\";\\n if (!unicode || unicode.length === 0) {\\n const baseCharMatch = glyph.name.match(/^([A-Za-z0-9])[._]/);\\n if (baseCharMatch) {\\n unicode = baseCharMatch[1];\\n }\\n }\\n let friendlyName = glyph.name;\\n if (unicode && unicode.length > 0 && /\\\\S/.test(unicode)) {\\n if (glyph.name.includes(\\\".swash\\\")) {\\n friendlyName = `${unicode} Swash`;\\n } else if (glyph.name.match(/\\\\.alt(\\\\d+)?/)) {\\n const num = glyph.name.match(/\\\\.alt(\\\\d+)/)?.[1] || \\\"\\\";\\n friendlyName = `${unicode} Alternate${num ? \\\" \\\" + num : \\\"\\\"}`;\\n } else if (glyph.name.match(/\\\\.ss(\\\\d+)/)) {\\n const num = glyph.name.match(/\\\\.ss(\\\\d+)/)?.[1];\\n friendlyName = `${unicode} Stylistic Set ${num}`;\\n } else {\\n friendlyName = `${unicode} - ${glyph.name}`;\\n }\\n }\\n let category = \\\"default\\\";\\n const nameLower = glyph.name.toLowerCase();\\n if (nameLower.includes(\\\"swash\\\") || nameLower.includes(\\\"cswh\\\")) {\\n category = \\\"swash\\\";\\n } else if (glyph.name.match(/\\\\.(alt|ss\\\\d+|cv\\\\d+|salt|ornament)/)) {\\n category = \\\"stylistic\\\";\\n } else if (glyph.name.match(/_\\\\d+$/)) {\\n category = \\\"stylistic\\\";\\n } else if (nameLower.match(/liga|dlig/)) {\\n category = \\\"ligature\\\";\\n }\\n if (category === \\\"default\\\") {\\n continue;\\n }\\n if (unicode && unicode.length > 0) {\\n glyphs.push({\\n glyphIndex: glyph.id,\\n unicode,\\n name: friendlyName,\\n category,\\n previewDataUrl: this.generateGlyphPreview(font, glyph.id, 80)\\n });\\n }\\n } catch (e) {\\n }\\n }\\n return glyphs;\\n }\\n /**\\n * Get glyph alternates for a specific character\\n */\\n async getGlyphAlternates(fontFamily, character, weight = 400) {\\n const font = await this.loadFont(fontFamily, weight);\\n if (!font) {\\n return [];\\n }\\n const alternates = [];\\n const codePoint = character.codePointAt(0);\\n if (codePoint === void 0) {\\n return [];\\n }\\n const defaultGlyph = font.glyphForCodePoint(codePoint);\\n if (defaultGlyph) {\\n alternates.push({\\n glyphIndex: defaultGlyph.id,\\n unicode: character,\\n name: defaultGlyph.name || \\\"Default\\\",\\n category: \\\"default\\\",\\n previewDataUrl: this.generateGlyphPreview(font, defaultGlyph.id, 80)\\n });\\n }\\n const baseName = defaultGlyph?.name;\\n if (baseName) {\\n let foundCount = 0;\\n for (let glyphId = 0; glyphId < font.numGlyphs; glyphId++) {\\n try {\\n const glyph = font.getGlyph(glyphId);\\n if (!glyph || !glyph.name) continue;\\n const namePatterns = [\\n new RegExp(`^${baseName}\\\\\\\\.(swash|alt|ss\\\\\\\\d+|salt|ornament)`, \\\"i\\\"),\\n new RegExp(`^${baseName}_\\\\\\\\d+$`, \\\"i\\\"),\\n new RegExp(`^${baseName}\\\\\\\\.\\\\\\\\d+$`, \\\"i\\\")\\n ];\\n const isVariant = namePatterns.some((pattern) => pattern.test(glyph.name));\\n if (isVariant && glyph.id !== defaultGlyph.id) {\\n foundCount++;\\n let friendlyName = glyph.name;\\n if (glyph.name.includes(\\\".swash\\\")) {\\n friendlyName = `${character} Swash`;\\n } else if (glyph.name.match(/\\\\.alt(\\\\d+)?/)) {\\n const num = glyph.name.match(/\\\\.alt(\\\\d+)/)?.[1] || \\\"\\\";\\n friendlyName = `${character} Alternate${num ? \\\" \\\" + num : \\\"\\\"}`;\\n } else if (glyph.name.match(/\\\\.ss(\\\\d+)/)) {\\n const num = glyph.name.match(/\\\\.ss(\\\\d+)/)?.[1];\\n friendlyName = `${character} Stylistic Set ${num}`;\\n }\\n alternates.push({\\n glyphIndex: glyph.id,\\n unicode: character,\\n name: friendlyName,\\n category: \\\"stylistic\\\",\\n previewDataUrl: this.generateGlyphPreview(font, glyph.id, 80)\\n });\\n }\\n } catch (e) {\\n }\\n }\\n }\\n if (font.GSUB) {\\n const gsub = font.GSUB;\\n if (gsub.featureList) {\\n for (const feature of gsub.featureList) {\\n const tag = feature.tag;\\n if (!this.isRelevantFeature(tag)) {\\n continue;\\n }\\n if (feature.feature && feature.feature.lookupListIndexes) {\\n for (const lookupIndex of feature.feature.lookupListIndexes) {\\n const lookup = gsub.lookupList?.lookups?.[lookupIndex];\\n if (!lookup) continue;\\n if (lookup.lookupType === 1) {\\n for (const subtable of lookup.subtables || []) {\\n const coverage = subtable.coverage;\\n if (!coverage) continue;\\n const coverageIndex = this.getCoverageIndex(coverage, defaultGlyph.id);\\n if (coverageIndex !== -1) {\\n const substituteGlyphIndex = this.getSubstituteGlyph(subtable, defaultGlyph.id);\\n if (substituteGlyphIndex !== null) {\\n alternates.push({\\n glyphIndex: substituteGlyphIndex,\\n unicode: character,\\n name: `${character} (${tag})`,\\n category: this.categorizeFeature(tag),\\n previewDataUrl: this.generateGlyphPreview(font, substituteGlyphIndex, 80)\\n });\\n }\\n }\\n }\\n } else if (lookup.lookupType === 3) {\\n for (const subtable of lookup.subtables || []) {\\n const coverage = subtable.coverage;\\n if (!coverage) continue;\\n const coverageIndex = this.getCoverageIndex(coverage, defaultGlyph.id);\\n const altSubtable = subtable;\\n if (coverageIndex !== -1 && altSubtable.alternateSets) {\\n const alternateSet = altSubtable.alternateSets[coverageIndex];\\n if (alternateSet) {\\n for (const altGlyphIndex of alternateSet) {\\n alternates.push({\\n glyphIndex: altGlyphIndex,\\n unicode: character,\\n name: `${character} (${tag} alt)`,\\n category: this.categorizeFeature(tag),\\n previewDataUrl: this.generateGlyphPreview(font, altGlyphIndex, 80)\\n });\\n }\\n }\\n }\\n }\\n }\\n }\\n }\\n }\\n }\\n }\\n return alternates;\\n }\\n /**\\n * Get available OpenType features for a font\\n */\\n async getAvailableFeatures(fontFamily, weight = 400) {\\n const font = await this.loadFont(fontFamily, weight);\\n if (!font) {\\n log.warn(`Font ${fontFamily} failed to load`);\\n return [];\\n }\\n try {\\n const features = [];\\n if (font.GSUB && font.GSUB.featureList) {\\n const uniqueFeatures = /* @__PURE__ */ new Set();\\n for (const feature of font.GSUB.featureList) {\\n if (feature.tag) {\\n uniqueFeatures.add(feature.tag);\\n }\\n }\\n features.push(...Array.from(uniqueFeatures));\\n }\\n if (font.GPOS && font.GPOS.featureList) {\\n const uniqueFeatures = /* @__PURE__ */ new Set();\\n for (const feature of font.GPOS.featureList) {\\n if (feature.tag) {\\n uniqueFeatures.add(feature.tag);\\n }\\n }\\n features.push(...Array.from(uniqueFeatures));\\n }\\n return features;\\n } catch (error) {\\n log.error(`Error getting features for ${fontFamily}:`, error);\\n return [];\\n }\\n }\\n /**\\n * Generate a preview image for a glyph\\n */\\n generateGlyphPreview(font, glyphIndex, size = 80) {\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = size;\\n canvas.height = size;\\n const ctx = canvas.getContext(\\\"2d\\\");\\n if (!ctx) {\\n return \\\"\\\";\\n }\\n try {\\n const glyph = font.getGlyph(glyphIndex);\\n if (!glyph) {\\n return \\\"\\\";\\n }\\n ctx.clearRect(0, 0, size, size);\\n const bbox = glyph.bbox;\\n if (!bbox) {\\n return \\\"\\\";\\n }\\n const glyphWidth = bbox.maxX - bbox.minX;\\n const glyphHeight = bbox.maxY - bbox.minY;\\n if (glyphWidth === 0 || glyphHeight === 0) {\\n return \\\"\\\";\\n }\\n const padding = 0.6;\\n const scale = Math.min(size / glyphWidth, size / glyphHeight) * padding;\\n const glyphCenterX = (bbox.minX + bbox.maxX) / 2;\\n const glyphCenterY = (bbox.minY + bbox.maxY) / 2;\\n const canvasCenterX = size / 2;\\n const canvasCenterY = size / 2;\\n const svgPath = glyph.path.toSVG();\\n if (!svgPath) {\\n return \\\"\\\";\\n }\\n const path2D = new Path2D(svgPath);\\n ctx.save();\\n ctx.translate(canvasCenterX, canvasCenterY);\\n ctx.scale(scale, -scale);\\n ctx.translate(-glyphCenterX, -glyphCenterY);\\n ctx.fillStyle = \\\"#000000\\\";\\n ctx.fill(path2D);\\n ctx.restore();\\n return canvas.toDataURL(\\\"image/png\\\");\\n } catch (error) {\\n log.error(\\\"Error generating glyph preview:\\\", error);\\n return \\\"\\\";\\n }\\n }\\n /**\\n * Check if a feature tag is relevant for glyph alternates\\n */\\n isRelevantFeature(tag) {\\n const relevantFeatures = [\\n \\\"swsh\\\",\\n \\\"cswh\\\",\\n \\\"salt\\\",\\n \\\"ss01\\\",\\n \\\"ss02\\\",\\n \\\"ss03\\\",\\n \\\"ss04\\\",\\n \\\"ss05\\\",\\n \\\"ss06\\\",\\n \\\"ss07\\\",\\n \\\"ss08\\\",\\n \\\"ss09\\\",\\n \\\"ss10\\\",\\n \\\"ss11\\\",\\n \\\"ss12\\\",\\n \\\"ss13\\\",\\n \\\"ss14\\\",\\n \\\"ss15\\\",\\n \\\"ss16\\\",\\n \\\"ss17\\\",\\n \\\"ss18\\\",\\n \\\"ss19\\\",\\n \\\"ss20\\\",\\n \\\"cv01\\\",\\n \\\"cv02\\\",\\n \\\"cv03\\\",\\n \\\"cv04\\\",\\n \\\"cv05\\\",\\n \\\"cv06\\\",\\n \\\"cv07\\\",\\n \\\"cv08\\\",\\n \\\"cv09\\\",\\n \\\"cv10\\\",\\n \\\"aalt\\\",\\n \\\"dlig\\\",\\n \\\"liga\\\"\\n ];\\n return relevantFeatures.includes(tag);\\n }\\n /**\\n * Categorize a feature tag\\n */\\n categorizeFeature(tag) {\\n if (tag.startsWith(\\\"swsh\\\") || tag === \\\"cswh\\\") return \\\"swash\\\";\\n if (tag.startsWith(\\\"ss\\\") || tag.startsWith(\\\"cv\\\") || tag === \\\"salt\\\") return \\\"stylistic\\\";\\n if (tag === \\\"liga\\\" || tag === \\\"dlig\\\") return \\\"ligature\\\";\\n if (tag === \\\"calt\\\") return \\\"contextual\\\";\\n return \\\"stylistic\\\";\\n }\\n /**\\n * Get coverage index for a glyph\\n */\\n getCoverageIndex(coverage, glyphIndex) {\\n if (!coverage) return -1;\\n if (coverage.format === 1 && coverage.glyphs) {\\n return coverage.glyphs.indexOf(glyphIndex);\\n }\\n if (coverage.format === 2 && coverage.ranges) {\\n const ranges = coverage.ranges;\\n for (let i = 0; i < ranges.length; i++) {\\n const range = ranges[i];\\n if (glyphIndex >= range.start && glyphIndex <= range.end) {\\n return range.index + (glyphIndex - range.start);\\n }\\n }\\n }\\n return -1;\\n }\\n /**\\n * Get substitute glyph from a single substitution subtable\\n */\\n getSubstituteGlyph(subtable, glyphIndex) {\\n if (!subtable) return null;\\n if (subtable.substFormat === 1 && typeof subtable.deltaGlyphId === \\\"number\\\") {\\n return glyphIndex + subtable.deltaGlyphId;\\n }\\n if (subtable.substFormat === 2 && subtable.substitute) {\\n const coverageIndex = this.getCoverageIndex(subtable.coverage, glyphIndex);\\n const substitute = subtable.substitute;\\n if (coverageIndex !== -1 && substitute[coverageIndex] !== void 0) {\\n return substitute[coverageIndex];\\n }\\n }\\n return null;\\n }\\n /**\\n * Get the count of alternate glyphs in a font (fast - no preview generation)\\n */\\n async getAlternateGlyphCount(fontFamily, weight = 400) {\\n const font = await this.loadFont(fontFamily, weight);\\n if (!font) {\\n return 0;\\n }\\n let count = 0;\\n const maxGlyphs = Math.min(font.numGlyphs, 1500);\\n for (let glyphId = 0; glyphId < maxGlyphs; glyphId++) {\\n try {\\n const glyph = font.getGlyph(glyphId);\\n if (!glyph || !glyph.name) continue;\\n if (glyph.name === \\\".notdef\\\" || glyph.name.startsWith(\\\".null\\\")) {\\n continue;\\n }\\n const codePoints = glyph.codePoints || [];\\n let unicode = codePoints.length > 0 ? String.fromCodePoint(codePoints[0]) : \\\"\\\";\\n if (!unicode || unicode.length === 0) {\\n const baseCharMatch = glyph.name.match(/^([A-Za-z0-9])[._]/);\\n if (baseCharMatch) {\\n unicode = baseCharMatch[1];\\n }\\n }\\n let category = \\\"default\\\";\\n const nameLower = glyph.name.toLowerCase();\\n if (nameLower.includes(\\\"swash\\\") || nameLower.includes(\\\"cswh\\\")) {\\n category = \\\"swash\\\";\\n } else if (glyph.name.match(/\\\\.(alt|ss\\\\d+|cv\\\\d+|salt|ornament)/)) {\\n category = \\\"stylistic\\\";\\n } else if (glyph.name.match(/_\\\\d+$/)) {\\n category = \\\"stylistic\\\";\\n } else if (nameLower.match(/liga|dlig/)) {\\n category = \\\"ligature\\\";\\n }\\n if (category !== \\\"default\\\" && unicode && unicode.length > 0) {\\n count++;\\n }\\n } catch (e) {\\n }\\n }\\n return count;\\n }\\n /**\\n * Get cache statistics\\n */\\n getCacheStats() {\\n return {\\n size: this.fontCache.size,\\n entries: Array.from(this.fontCache.keys())\\n };\\n }\\n };\\n var FontAnalyzer = new FontAnalyzerService();\\n\\n // src/core/rich-text-layout.ts\\n var _measureCtx = null;\\n function getMeasureContext() {\\n if (!_measureCtx) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n const canvas = new OffscreenCanvas(1, 1);\\n _measureCtx = canvas.getContext(\\\"2d\\\");\\n } else if (typeof document !== \\\"undefined\\\") {\\n const canvas = document.createElement(\\\"canvas\\\");\\n _measureCtx = canvas.getContext(\\\"2d\\\");\\n } else {\\n throw new Error(\\\"No canvas context available\\\");\\n }\\n }\\n return _measureCtx;\\n }\\n function wrapRichTextSpans(spans, maxWidth, element) {\\n const ctx = getMeasureContext();\\n const lines = [];\\n const measureText = (text, style) => {\\n const fontSize = style.fontSize || element.fontSize;\\n const fontFamily = style.fontFamily || element.fontFamily;\\n const bold = style.bold !== void 0 ? style.bold : element.bold || false;\\n const italic = style.italic !== void 0 ? style.italic : element.italic || false;\\n const letterSpacing = style.letterSpacing !== void 0 ? style.letterSpacing : element.letterSpacing ?? 0;\\n ctx.font = buildFontString2(fontSize, fontFamily, bold, italic);\\n return spacedTextWidth(ctx.measureText(text).width, text, letterSpacing);\\n };\\n const stylesMatch = (s1, s2) => {\\n return s1.fontSize === s2.fontSize && s1.fontFamily === s2.fontFamily && s1.color === s2.color && s1.bold === s2.bold && s1.italic === s2.italic && s1.underline === s2.underline && s1.strikethrough === s2.strikethrough && s1.letterSpacing === s2.letterSpacing;\\n };\\n const mergedSpans = [];\\n spans.forEach((span) => {\\n if (mergedSpans.length > 0 && stylesMatch(mergedSpans[mergedSpans.length - 1].style, span.style)) {\\n mergedSpans[mergedSpans.length - 1].text += span.text;\\n } else {\\n mergedSpans.push({ text: span.text, style: span.style });\\n }\\n });\\n let fullText = \\\"\\\";\\n const charToSpan = [];\\n mergedSpans.forEach((span, spanIndex) => {\\n for (let i = 0; i < span.text.length; i++) {\\n fullText += span.text[i];\\n charToSpan.push(spanIndex);\\n }\\n });\\n const words = [];\\n let currentWord = \\\"\\\";\\n let wordStart = 0;\\n for (let i = 0; i < fullText.length; i++) {\\n const char = fullText[i];\\n if (char === \\\" \\\") {\\n if (currentWord.length > 0) {\\n words.push({ text: currentWord, startIdx: wordStart, endIdx: i - 1 });\\n currentWord = \\\"\\\";\\n }\\n words.push({ text: \\\" \\\", startIdx: i, endIdx: i });\\n } else {\\n if (currentWord.length === 0) {\\n wordStart = i;\\n }\\n currentWord += char;\\n }\\n }\\n if (currentWord.length > 0) {\\n words.push({ text: currentWord, startIdx: wordStart, endIdx: fullText.length - 1 });\\n }\\n let currentLine = [];\\n let currentLineWidth = 0;\\n const finishLine = () => {\\n if (currentLine.length > 0) {\\n lines.push(currentLine);\\n currentLine = [];\\n currentLineWidth = 0;\\n }\\n };\\n words.forEach((word, _wordIdx) => {\\n const wordSpans = [];\\n let currentSpanIdx = charToSpan[word.startIdx];\\n let currentText = \\\"\\\";\\n for (let charIdx = word.startIdx; charIdx <= word.endIdx; charIdx++) {\\n const spanIdx = charToSpan[charIdx];\\n if (spanIdx !== currentSpanIdx) {\\n wordSpans.push({ text: currentText, style: mergedSpans[currentSpanIdx].style });\\n currentText = fullText[charIdx];\\n currentSpanIdx = spanIdx;\\n } else {\\n currentText += fullText[charIdx];\\n }\\n }\\n if (currentText.length > 0) {\\n wordSpans.push({ text: currentText, style: mergedSpans[currentSpanIdx].style });\\n }\\n const wordWidth = wordSpans.reduce((sum, span) => sum + measureText(span.text, span.style), 0);\\n if (word.text === \\\" \\\") {\\n if (currentLine.length > 0) {\\n const lastSpan = currentLine[currentLine.length - 1];\\n if (stylesMatch(lastSpan.style, wordSpans[0].style)) {\\n lastSpan.text += \\\" \\\";\\n } else {\\n currentLine.push({ text: \\\" \\\", style: wordSpans[0].style });\\n }\\n } else {\\n currentLine.push({ text: \\\" \\\", style: wordSpans[0].style });\\n }\\n currentLineWidth += wordWidth;\\n } else {\\n if (wordWidth > maxWidth) {\\n if (currentLine.length > 0) {\\n finishLine();\\n }\\n for (const span of wordSpans) {\\n const chars = Array.from(span.text);\\n let charBuffer = \\\"\\\";\\n for (const char of chars) {\\n const charWidth = measureText(char, span.style);\\n if (currentLineWidth + charWidth > maxWidth && currentLineWidth > 0) {\\n if (charBuffer.length > 0) {\\n if (currentLine.length > 0) {\\n const lastSpan = currentLine[currentLine.length - 1];\\n if (stylesMatch(lastSpan.style, span.style)) {\\n lastSpan.text += charBuffer;\\n } else {\\n currentLine.push({ text: charBuffer, style: span.style });\\n }\\n } else {\\n currentLine.push({ text: charBuffer, style: span.style });\\n }\\n charBuffer = \\\"\\\";\\n }\\n finishLine();\\n }\\n charBuffer += char;\\n currentLineWidth += charWidth;\\n }\\n if (charBuffer.length > 0) {\\n if (currentLine.length > 0) {\\n const lastSpan = currentLine[currentLine.length - 1];\\n if (stylesMatch(lastSpan.style, span.style)) {\\n lastSpan.text += charBuffer;\\n } else {\\n currentLine.push({ text: charBuffer, style: span.style });\\n }\\n } else {\\n currentLine.push({ text: charBuffer, style: span.style });\\n }\\n }\\n }\\n } else {\\n if (currentLineWidth + wordWidth > maxWidth && currentLine.length > 0) {\\n finishLine();\\n }\\n wordSpans.forEach((span) => {\\n if (currentLine.length > 0) {\\n const lastSpan = currentLine[currentLine.length - 1];\\n if (stylesMatch(lastSpan.style, span.style)) {\\n lastSpan.text += span.text;\\n } else {\\n currentLine.push({ ...span });\\n }\\n } else {\\n currentLine.push({ ...span });\\n }\\n });\\n currentLineWidth += wordWidth;\\n }\\n }\\n });\\n finishLine();\\n if (lines.length === 0) {\\n lines.push([]);\\n }\\n return lines;\\n }\\n function splitRichTextIntoLines(richText) {\\n const lines = [];\\n let currentLine = [];\\n richText.spans.forEach((span) => {\\n const parts = span.text.split(\\\"\\\\n\\\");\\n parts.forEach((part, i) => {\\n if (part.length > 0) {\\n currentLine.push({ text: part, style: span.style });\\n }\\n if (i < parts.length - 1) {\\n lines.push(currentLine);\\n currentLine = [];\\n }\\n });\\n });\\n if (currentLine.length > 0) {\\n lines.push(currentLine);\\n }\\n if (lines.length === 0) {\\n lines.push([]);\\n }\\n return lines;\\n }\\n\\n // src/rendering/rich-text-renderer.ts\\n function renderRichTextFillOnly(ctx, richText, element, maxWidth, lockedLineCount) {\\n ctx.fillStyle = element.color;\\n const textAlign = element.textAlign || \\\"center\\\";\\n const resolveSpacing = (style) => style.letterSpacing !== void 0 ? style.letterSpacing : element.letterSpacing ?? 0;\\n const explicitLines = splitRichTextIntoLines(richText);\\n let lines;\\n let paragraphMetadata;\\n if (maxWidth !== void 0 && maxWidth > 0 && !lockedLineCount) {\\n lines = [];\\n paragraphMetadata = [];\\n explicitLines.forEach((lineSpans) => {\\n const wrappedLines = wrapRichTextSpans(lineSpans, maxWidth, element);\\n wrappedLines.forEach((wrappedLine, idx) => {\\n lines.push(wrappedLine);\\n paragraphMetadata.push({\\n isParagraphStart: idx === 0,\\n isParagraphEnd: idx === wrappedLines.length - 1\\n });\\n });\\n });\\n } else {\\n lines = explicitLines;\\n paragraphMetadata = explicitLines.map(() => ({\\n isParagraphStart: true,\\n isParagraphEnd: true\\n }));\\n }\\n const lineMetrics = [];\\n let maxLineHeight = 0;\\n lines.forEach((lineSpans, lineIndex) => {\\n let lineWidth = 0;\\n const spanWidths = [];\\n let lineHeight = 0;\\n let lineAscent = 0;\\n const isParagraphStart = paragraphMetadata[lineIndex].isParagraphStart;\\n const isParagraphEnd = paragraphMetadata[lineIndex].isParagraphEnd;\\n lineSpans.forEach((span) => {\\n const fontSize = span.style.fontSize !== void 0 ? span.style.fontSize : element.fontSize;\\n const fontFamily = span.style.fontFamily !== void 0 ? span.style.fontFamily : element.fontFamily;\\n const bold = span.style.bold !== void 0 ? span.style.bold : element.bold || false;\\n const italic = span.style.italic !== void 0 ? span.style.italic : element.italic || false;\\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\\n const width = spacedTextWidth(ctx.measureText(span.text).width, span.text, resolveSpacing(span.style));\\n spanWidths.push(width);\\n lineWidth += width;\\n const metrics = getFontMetrics2(fontSize, fontFamily, bold, italic);\\n lineHeight = Math.max(lineHeight, metrics.height);\\n lineAscent = Math.max(lineAscent, metrics.ascent);\\n });\\n const fullLineText = lineSpans.map((span) => span.text).join(\\\"\\\");\\n const leadingSpacesMatch = fullLineText.match(/^ +/);\\n const trailingSpacesMatch = fullLineText.match(/ +$/);\\n const leadingSpacesCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;\\n const trailingSpacesCount = trailingSpacesMatch ? trailingSpacesMatch[0].length : 0;\\n let adjustedLineWidth = 0;\\n let charIndexInLine = 0;\\n lineSpans.forEach((span) => {\\n const fontSize = span.style.fontSize !== void 0 ? span.style.fontSize : element.fontSize;\\n const fontFamily = span.style.fontFamily !== void 0 ? span.style.fontFamily : element.fontFamily;\\n const bold = span.style.bold !== void 0 ? span.style.bold : element.bold || false;\\n const italic = span.style.italic !== void 0 ? span.style.italic : element.italic || false;\\n let visibleText = span.text;\\n const spanStartIndex = charIndexInLine;\\n const spanEndIndex = charIndexInLine + span.text.length;\\n if (!isParagraphStart && leadingSpacesCount > 0 && spanStartIndex < leadingSpacesCount) {\\n const hiddenCharsInSpan = Math.min(leadingSpacesCount - spanStartIndex, span.text.length);\\n visibleText = visibleText.substring(hiddenCharsInSpan);\\n }\\n if (!isParagraphEnd && trailingSpacesCount > 0) {\\n const trailingSpaceStartIndex = fullLineText.length - trailingSpacesCount;\\n if (spanEndIndex > trailingSpaceStartIndex) {\\n const leadingTrimAmount = !isParagraphStart && leadingSpacesCount > 0 && spanStartIndex < leadingSpacesCount ? Math.min(leadingSpacesCount - spanStartIndex, span.text.length) : 0;\\n const visibleCharsInSpan = Math.max(0, trailingSpaceStartIndex - spanStartIndex - leadingTrimAmount);\\n visibleText = visibleText.substring(0, visibleCharsInSpan);\\n }\\n }\\n charIndexInLine += span.text.length;\\n if (visibleText.length > 0) {\\n ctx.save();\\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\\n adjustedLineWidth += spacedTextWidth(\\n ctx.measureText(visibleText).width,\\n visibleText,\\n resolveSpacing(span.style)\\n );\\n ctx.restore();\\n }\\n });\\n lineMetrics.push({\\n spans: lineSpans,\\n width: adjustedLineWidth,\\n // Use adjusted width for alignment (may be 0 for empty lines)\\n height: lineHeight,\\n ascent: lineAscent,\\n spanWidths,\\n isParagraphStart,\\n // Store metadata with line\\n isParagraphEnd\\n });\\n maxLineHeight = Math.max(maxLineHeight, lineHeight);\\n });\\n const elementFontMetrics = getFontMetrics2(element.fontSize, element.fontFamily, element.bold, element.italic);\\n const lineSpacing = element.fontSize * (element.lineHeight ?? LINE_HEIGHT_MULTIPLIER);\\n let totalHeight;\\n if (lineMetrics.length === 0) {\\n totalHeight = 0;\\n } else if (lineMetrics.length === 1) {\\n totalHeight = elementFontMetrics.height;\\n } else {\\n totalHeight = (lineMetrics.length - 1) * lineSpacing + elementFontMetrics.height;\\n }\\n const topLeftY = -totalHeight / 2;\\n lineMetrics.forEach((lineData, lineIndex) => {\\n const { spans, width: lineWidth, isParagraphStart, isParagraphEnd } = lineData;\\n let currentX;\\n if (textAlign === \\\"center\\\") {\\n currentX = -lineWidth / 2;\\n } else if (textAlign === \\\"right\\\") {\\n currentX = maxWidth !== void 0 ? maxWidth / 2 - lineWidth : -lineWidth;\\n } else {\\n currentX = maxWidth !== void 0 ? -maxWidth / 2 : 0;\\n }\\n const baselineY = topLeftY + elementFontMetrics.ascent + lineIndex * lineSpacing;\\n const fullLineText = spans.map((s) => s.text).join(\\\"\\\");\\n const leadingSpacesMatch = fullLineText.match(/^ +/);\\n const trailingSpacesMatch = fullLineText.match(/ +$/);\\n const leadingSpacesCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;\\n const trailingSpacesCount = trailingSpacesMatch ? trailingSpacesMatch[0].length : 0;\\n let charIndexInLine = 0;\\n spans.forEach((span) => {\\n const fontSize = span.style.fontSize !== void 0 ? span.style.fontSize : element.fontSize;\\n const fontFamily = span.style.fontFamily !== void 0 ? span.style.fontFamily : element.fontFamily;\\n const color = span.style.color !== void 0 ? span.style.color : element.color;\\n const bold = span.style.bold !== void 0 ? span.style.bold : element.bold || false;\\n const italic = span.style.italic !== void 0 ? span.style.italic : element.italic || false;\\n const underline = span.style.underline !== void 0 ? span.style.underline : element.underline || false;\\n const strikethrough = span.style.strikethrough !== void 0 ? span.style.strikethrough : element.strikethrough || false;\\n let renderText = span.text;\\n let spanStartIndex = charIndexInLine;\\n let spanEndIndex = charIndexInLine + span.text.length;\\n if (!isParagraphStart && leadingSpacesCount > 0 && spanStartIndex < leadingSpacesCount) {\\n const hiddenCharsInSpan = Math.min(leadingSpacesCount - spanStartIndex, span.text.length);\\n renderText = renderText.substring(hiddenCharsInSpan);\\n }\\n if (!isParagraphEnd && trailingSpacesCount > 0) {\\n const trailingSpaceStartIndex = fullLineText.length - trailingSpacesCount;\\n if (spanEndIndex > trailingSpaceStartIndex) {\\n const leadingTrimAmount = !isParagraphStart && leadingSpacesCount > 0 && spanStartIndex < leadingSpacesCount ? Math.min(leadingSpacesCount - spanStartIndex, span.text.length) : 0;\\n const visibleCharsInSpan = Math.max(0, trailingSpaceStartIndex - spanStartIndex - leadingTrimAmount);\\n renderText = renderText.substring(0, visibleCharsInSpan);\\n }\\n }\\n charIndexInLine += span.text.length;\\n if (renderText.length > 0) {\\n const letterSpacing = resolveSpacing(span.style);\\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\\n ctx.fillStyle = color;\\n ctx.textBaseline = \\\"alphabetic\\\";\\n ctx.textAlign = \\\"left\\\";\\n fillTextWithSpacing(ctx, renderText, currentX, baselineY, letterSpacing);\\n const renderedWidth = spacedTextWidth(ctx.measureText(renderText).width, renderText, letterSpacing);\\n if (underline) {\\n const underlineY = baselineY + fontSize * 0.1;\\n ctx.beginPath();\\n ctx.moveTo(currentX, underlineY);\\n ctx.lineTo(currentX + renderedWidth, underlineY);\\n ctx.lineWidth = Math.max(1, fontSize * 0.05);\\n ctx.strokeStyle = color;\\n ctx.stroke();\\n }\\n if (strikethrough) {\\n const strikethroughY = baselineY - fontSize * 0.25;\\n ctx.beginPath();\\n ctx.moveTo(currentX, strikethroughY);\\n ctx.lineTo(currentX + renderedWidth, strikethroughY);\\n ctx.lineWidth = Math.max(1, fontSize * 0.05);\\n ctx.strokeStyle = color;\\n ctx.stroke();\\n }\\n currentX += renderedWidth;\\n }\\n });\\n });\\n }\\n\\n // src/rendering/text-renderer.ts\\n var logger2 = createLogger(\\\"canvas-renderer\\\");\\n var _measureCtx2 = null;\\n function getMeasureContext2() {\\n if (!_measureCtx2) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n const canvas = new OffscreenCanvas(1, 1);\\n _measureCtx2 = canvas.getContext(\\\"2d\\\");\\n } else if (typeof document !== \\\"undefined\\\") {\\n const canvas = document.createElement(\\\"canvas\\\");\\n _measureCtx2 = canvas.getContext(\\\"2d\\\");\\n } else {\\n throw new Error(\\\"No canvas context available\\\");\\n }\\n }\\n return _measureCtx2;\\n }\\n function buildFontString(fontSize, fontFamily, bold = false, italic = false) {\\n const parts = [];\\n if (italic) {\\n parts.push(\\\"italic\\\");\\n }\\n if (bold) {\\n parts.push(\\\"bold\\\");\\n }\\n parts.push(`${fontSize}px`);\\n parts.push(fontFamily);\\n return parts.join(\\\" \\\");\\n }\\n function getFontMetrics2(fontSize, fontFamily, bold = false, italic = false) {\\n const ctx = getMeasureContext2();\\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\\n const sampleText = \\\"\\\\xC1\\\\xC9\\\\xCDgjpqy\\\";\\n const metrics = ctx.measureText(sampleText);\\n const ascent = metrics.actualBoundingBoxAscent || fontSize * 0.8;\\n const descent = metrics.actualBoundingBoxDescent || fontSize * 0.2;\\n const height = ascent + descent;\\n return { ascent, descent, height };\\n }\\n function renderTextFillOnly(ctx, element) {\\n const fontSize = element.fontSize;\\n const fontFamily = element.fontFamily;\\n const bold = element.bold || false;\\n const italic = element.italic || false;\\n const textAlign = element.textAlign || \\\"center\\\";\\n const text = element.text;\\n ctx.font = buildFontString(fontSize, fontFamily, bold, italic);\\n ctx.textAlign = textAlign;\\n ctx.textBaseline = \\\"alphabetic\\\";\\n ctx.fillStyle = element.color;\\n const fontMetrics = getFontMetrics2(fontSize, fontFamily, bold, italic);\\n const visualHeight = fontMetrics.height;\\n const topLeftY = -visualHeight / 2;\\n const yPos = topLeftY + fontMetrics.ascent;\\n fillTextWithSpacing(ctx, text, 0, yPos, element.letterSpacing);\\n }\\n function renderCustomTransform(ctx, elementData) {\\n renderCustomTransformNormal(ctx, elementData);\\n }\\n function renderCustomTransformNormal(ctx, elementData) {\\n if (elementData.stroke?.enabled) {\\n renderTextStroke(ctx, elementData);\\n }\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n const transformData = elementData.transformData;\\n const availableWidth = (transformData?.width ?? 100) - HORIZONTAL_PADDING * 2;\\n if (elementData.richText) {\\n const richText = RichText.fromJSON(elementData.richText);\\n ctx.save();\\n ctx.translate(0, 0);\\n const lockedLineCount = elementData._lockedLineCount;\\n renderRichTextFillOnly(\\n ctx,\\n richText,\\n {\\n fontSize: elementData.fontSize,\\n fontFamily: elementData.fontFamily,\\n color: elementData.color,\\n bold: elementData.bold,\\n italic: elementData.italic,\\n underline: elementData.underline,\\n strikethrough: elementData.strikethrough,\\n textAlign: elementData.textAlign,\\n letterSpacing: elementData.letterSpacing,\\n lineHeight: elementData.lineHeight\\n },\\n availableWidth,\\n lockedLineCount\\n );\\n ctx.restore();\\n } else {\\n if (elementData.text) {\\n ctx.fillStyle = elementData.color;\\n const lockedLineCount = elementData._lockedLineCount;\\n const letterSpacing = elementData.letterSpacing ?? 0;\\n const { lines, height: visualHeight } = calculateVisualBoundsWithSpaceCollapsing(\\n elementData.text,\\n availableWidth,\\n elementData.fontSize,\\n elementData.fontFamily,\\n elementData.bold,\\n elementData.italic,\\n lockedLineCount,\\n true,\\n // strict: true\\n { letterSpacing, lineHeight: elementData.lineHeight }\\n );\\n const fontMetrics = getFontMetrics2(\\n elementData.fontSize,\\n elementData.fontFamily,\\n elementData.bold,\\n elementData.italic\\n );\\n const topLeftX = -(transformData?.width ?? 100) / 2;\\n const topLeftY = -visualHeight / 2;\\n const lineSpacing = elementData.fontSize * (elementData.lineHeight ?? LINE_HEIGHT_MULTIPLIER);\\n ctx.font = `${elementData.italic ? \\\"italic \\\" : \\\"\\\"}${elementData.bold ? \\\"bold \\\" : \\\"\\\"}${elementData.fontSize}px ${elementData.fontFamily}`;\\n ctx.textBaseline = \\\"alphabetic\\\";\\n ctx.textAlign = elementData.textAlign;\\n lines.forEach((line, index) => {\\n const isParagraphStart = index === 0;\\n const isParagraphEnd = index === lines.length - 1;\\n let visibleText = line;\\n if (!isParagraphStart) {\\n const leadingSpacesMatch = line.match(/^ +/);\\n const leadingSpacesCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;\\n if (leadingSpacesCount > 0) {\\n visibleText = visibleText.substring(leadingSpacesCount);\\n }\\n }\\n if (!isParagraphEnd) {\\n const trailingSpacesMatch = visibleText.match(/ +$/);\\n const trailingSpacesCount = trailingSpacesMatch ? trailingSpacesMatch[0].length : 0;\\n if (trailingSpacesCount > 0) {\\n visibleText = visibleText.substring(0, visibleText.length - trailingSpacesCount);\\n }\\n }\\n let xPos = topLeftX + HORIZONTAL_PADDING;\\n if (elementData.textAlign === \\\"center\\\") {\\n xPos = topLeftX + (transformData?.width ?? 100) / 2;\\n } else if (elementData.textAlign === \\\"right\\\") {\\n xPos = topLeftX + (transformData?.width ?? 100) - HORIZONTAL_PADDING;\\n }\\n const yPos = topLeftY + fontMetrics.ascent + index * lineSpacing;\\n fillTextWithSpacing(ctx, visibleText, xPos, yPos, letterSpacing);\\n if (visibleText.length > 0) {\\n const lineWidth = spacedTextWidth(ctx.measureText(visibleText).width, visibleText, letterSpacing);\\n let decorationX = xPos;\\n if (elementData.textAlign === \\\"center\\\") decorationX -= lineWidth / 2;\\n else if (elementData.textAlign === \\\"right\\\") decorationX -= lineWidth;\\n if (elementData.underline) {\\n const underlineY = yPos + elementData.fontSize * 0.1;\\n ctx.fillRect(decorationX, underlineY, lineWidth, Math.max(1, elementData.fontSize * 0.05));\\n }\\n if (elementData.strikethrough) {\\n const strikeY = yPos - fontMetrics.ascent * 0.4;\\n ctx.fillRect(decorationX, strikeY, lineWidth, Math.max(1, elementData.fontSize * 0.05));\\n }\\n }\\n });\\n }\\n }\\n ctx.restore();\\n }\\n function renderTextElement(ctx, elementData) {\\n const elementOpacity = elementData.opacity ?? 1;\\n const hasStroke = !!elementData.stroke?.enabled;\\n const isCustomTransform = elementData.type === \\\"custom\\\";\\n if (elementOpacity < 1 && hasStroke && isCustomTransform) {\\n renderTextElementWithOffscreen(ctx, elementData, elementOpacity);\\n return;\\n }\\n const previousAlpha = ctx.globalAlpha;\\n if (elementOpacity !== 1) {\\n ctx.globalAlpha = elementOpacity;\\n }\\n renderTextElementInner(ctx, elementData);\\n ctx.globalAlpha = previousAlpha;\\n }\\n function renderTextElementWithOffscreen(ctx, elementData, elementOpacity) {\\n const td = elementData.transformData;\\n const fontSize = elementData.fontSize || 24;\\n const strokeWidth = elementData.stroke?.width || 0;\\n const estWidth = (td?.width ?? fontSize * elementData.text.length * 0.7) + strokeWidth * 2 + 40;\\n const estHeight = fontSize * 3 + strokeWidth * 2 + 40;\\n const transform = ctx.getTransform();\\n const scale = Math.max(Math.abs(transform.a), Math.abs(transform.d), 1);\\n const offW = Math.ceil(estWidth * scale);\\n const offH = Math.ceil(estHeight * scale);\\n let offCanvas;\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n offCanvas = new OffscreenCanvas(offW, offH);\\n } else {\\n offCanvas = document.createElement(\\\"canvas\\\");\\n offCanvas.width = offW;\\n offCanvas.height = offH;\\n }\\n const offCtx = offCanvas.getContext(\\\"2d\\\");\\n if (!offCtx) {\\n const prev = ctx.globalAlpha;\\n ctx.globalAlpha = elementOpacity;\\n renderTextElementInner(ctx, elementData);\\n ctx.globalAlpha = prev;\\n return;\\n }\\n const centerPixelX = transform.a * elementData.x + transform.e;\\n const centerPixelY = transform.d * elementData.y + transform.f;\\n offCtx.setTransform(\\n transform.a,\\n transform.b,\\n transform.c,\\n transform.d,\\n transform.e - centerPixelX + offW / 2,\\n transform.f - centerPixelY + offH / 2\\n );\\n renderTextElementInner(offCtx, elementData);\\n ctx.save();\\n ctx.setTransform(1, 0, 0, 1, 0, 0);\\n ctx.globalAlpha = elementOpacity;\\n ctx.drawImage(offCanvas, centerPixelX - offW / 2, centerPixelY - offH / 2);\\n ctx.restore();\\n }\\n function renderTextElementInner(ctx, elementData) {\\n switch (elementData.type) {\\n case \\\"custom\\\":\\n renderCustomTransform(ctx, elementData);\\n break;\\n case \\\"circle\\\":\\n renderCircleTransform(ctx, elementData);\\n break;\\n case \\\"wave\\\":\\n renderWaveTransform(ctx, elementData);\\n break;\\n case \\\"arch\\\":\\n renderArchTransform(ctx, elementData);\\n break;\\n case \\\"ascend\\\":\\n renderAscendTransform(ctx, elementData);\\n break;\\n case \\\"lean\\\":\\n renderLeanTransform(ctx, elementData);\\n break;\\n case \\\"flag\\\":\\n renderFlagTransform(ctx, elementData);\\n break;\\n default:\\n logger2.warn(`[canvas-renderer] Unsupported transform type: ${elementData.type}`);\\n renderCustomTransform(ctx, elementData);\\n }\\n }\\n\\n // src/rendering/image-renderer.ts\\n function resolveServerCrop(el, bitmap) {\\n if (!el.needsCropPixelConversion || el.cropWidth === void 0) return el;\\n return {\\n ...el,\\n cropX: (el.cropX ?? 0) * bitmap.width,\\n cropY: (el.cropY ?? 0) * bitmap.height,\\n cropWidth: el.cropWidth * bitmap.width,\\n cropHeight: (el.cropHeight ?? 1) * bitmap.height,\\n needsCropPixelConversion: false\\n };\\n }\\n function renderImageElement(ctx, elementData, imageBitmap) {\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n if (elementData.rotation) {\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n }\\n let scaleX = 1;\\n let scaleY = 1;\\n if (elementData.flipHorizontal) scaleX = -1;\\n if (elementData.flipVertical) scaleY = -1;\\n if (scaleX !== 1 || scaleY !== 1) {\\n ctx.scale(scaleX, scaleY);\\n }\\n if (elementData.opacity !== void 0 && elementData.opacity !== 1) {\\n ctx.globalAlpha = elementData.opacity;\\n }\\n if (elementData.borderRadius && elementData.borderRadius > 0) {\\n const radius = Math.min(\\n elementData.borderRadius / 100 * Math.min(elementData.width, elementData.height),\\n elementData.width / 2,\\n elementData.height / 2\\n );\\n ctx.beginPath();\\n const x = -elementData.width / 2;\\n const y = -elementData.height / 2;\\n const w = elementData.width;\\n const h = elementData.height;\\n ctx.moveTo(x + radius, y);\\n ctx.lineTo(x + w - radius, y);\\n ctx.arcTo(x + w, y, x + w, y + radius, radius);\\n ctx.lineTo(x + w, y + h - radius);\\n ctx.arcTo(x + w, y + h, x + w - radius, y + h, radius);\\n ctx.lineTo(x + radius, y + h);\\n ctx.arcTo(x, y + h, x, y + h - radius, radius);\\n ctx.lineTo(x, y + radius);\\n ctx.arcTo(x, y, x + radius, y, radius);\\n ctx.closePath();\\n ctx.clip();\\n }\\n if (elementData.cropX !== void 0 && elementData.cropWidth !== void 0) {\\n ctx.drawImage(\\n imageBitmap,\\n elementData.cropX,\\n elementData.cropY || 0,\\n elementData.cropWidth,\\n elementData.cropHeight || imageBitmap.height,\\n -elementData.width / 2,\\n -elementData.height / 2,\\n elementData.width,\\n elementData.height\\n );\\n } else {\\n ctx.drawImage(imageBitmap, -elementData.width / 2, -elementData.height / 2, elementData.width, elementData.height);\\n }\\n ctx.restore();\\n if (elementData.stroke?.enabled) {\\n const hasKnockoutStroke = elementData.knockoutParts?.stroke === true;\\n const imageConfig = {\\n transformType: \\\"image\\\",\\n x: elementData.x,\\n y: elementData.y,\\n rotation: elementData.rotation,\\n stroke: elementData.stroke,\\n knockoutParts: elementData.knockoutParts,\\n transformData: {\\n type: \\\"image\\\",\\n width: elementData.width,\\n height: elementData.height,\\n borderRadius: elementData.borderRadius || 0\\n }\\n };\\n if (hasKnockoutStroke) {\\n const canvas = ctx.canvas;\\n let offscreen;\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n offscreen = new OffscreenCanvas(canvas.width, canvas.height);\\n } else if (typeof document !== \\\"undefined\\\") {\\n offscreen = document.createElement(\\\"canvas\\\");\\n offscreen.width = canvas.width;\\n offscreen.height = canvas.height;\\n } else {\\n renderImageStroke(ctx, imageConfig);\\n return;\\n }\\n const offCtx = offscreen.getContext(\\\"2d\\\");\\n if (!offCtx) {\\n renderImageStroke(ctx, imageConfig);\\n return;\\n }\\n renderImageStroke(offCtx, imageConfig, { isKnockout: true });\\n ctx.save();\\n ctx.globalCompositeOperation = \\\"destination-out\\\";\\n ctx.drawImage(offscreen, 0, 0);\\n ctx.restore();\\n } else {\\n renderImageStroke(ctx, imageConfig);\\n }\\n }\\n }\\n\\n // src/rendering/shape-renderer.ts\\n function createTempCanvas(width, height) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n return new OffscreenCanvas(width, height);\\n }\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n function renderShapeElement(ctx, elementData) {\\n const elementOpacity = elementData.opacity ?? 1;\\n const hasStroke = !!elementData.stroke?.enabled;\\n const needsOffscreen = elementOpacity < 1 && hasStroke;\\n if (needsOffscreen) {\\n renderShapeWithOffscreen(ctx, elementData, elementOpacity);\\n } else {\\n renderShapeDirect(ctx, elementData, elementOpacity);\\n }\\n }\\n function renderShapeWithOffscreen(ctx, elementData, elementOpacity) {\\n const td = elementData.transformData;\\n const strokeWidth = elementData.stroke?.width || 2;\\n const padding = strokeWidth + 2;\\n const offW = Math.ceil(td.width + padding * 2);\\n const offH = Math.ceil(td.height + padding * 2);\\n const offCanvas = createTempCanvas(offW, offH);\\n const offCtx = offCanvas.getContext(\\\"2d\\\");\\n if (!offCtx) {\\n renderShapeDirect(ctx, elementData, elementOpacity);\\n return;\\n }\\n const tempData = {\\n ...elementData,\\n x: offW / 2,\\n y: offH / 2,\\n opacity: 1\\n };\\n renderShapeDirect(offCtx, tempData, 1);\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n if (elementData.rotation) {\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n }\\n ctx.globalAlpha = elementOpacity;\\n ctx.drawImage(offCanvas, -offW / 2, -offH / 2);\\n ctx.restore();\\n }\\n function renderShapeDirect(ctx, elementData, elementOpacity) {\\n const transformData = elementData.transformData;\\n const fillOpacity = transformData.fillOpacity ?? 1;\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n if (elementData.rotation) {\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n }\\n ctx.globalAlpha = elementOpacity * fillOpacity;\\n ctx.fillStyle = transformData.fillColor || \\\"#3b82f6\\\";\\n ctx.beginPath();\\n traceShapePath(ctx, transformData);\\n ctx.fill();\\n ctx.restore();\\n if (elementData.stroke?.enabled) {\\n ctx.save();\\n ctx.translate(elementData.x, elementData.y);\\n if (elementData.rotation) {\\n ctx.rotate(-elementData.rotation * Math.PI / 180);\\n }\\n const stroke = elementData.stroke;\\n ctx.globalAlpha = elementOpacity * (stroke.opacity ?? 1);\\n ctx.strokeStyle = stroke.color || \\\"#000000\\\";\\n ctx.lineWidth = stroke.width || 2;\\n ctx.lineCap = stroke.lineCap || \\\"round\\\";\\n ctx.lineJoin = stroke.lineJoin || \\\"round\\\";\\n ctx.beginPath();\\n traceShapePath(ctx, transformData);\\n ctx.stroke();\\n ctx.restore();\\n }\\n }\\n function traceShapePath(ctx, transformData) {\\n const { shapeType, width, height } = transformData;\\n switch (shapeType) {\\n case \\\"rectangle\\\": {\\n const borderRadius = transformData.borderRadius || 0;\\n const x = -width / 2;\\n const y = -height / 2;\\n if (borderRadius > 0) {\\n const radius = Math.min(borderRadius / 100 * Math.min(width, height), width / 2, height / 2);\\n ctx.roundRect(x, y, width, height, radius);\\n } else {\\n ctx.rect(x, y, width, height);\\n }\\n break;\\n }\\n case \\\"circle\\\": {\\n const radius = Math.min(width, height) / 2;\\n ctx.arc(0, 0, radius, 0, Math.PI * 2);\\n break;\\n }\\n case \\\"ellipse\\\": {\\n ctx.ellipse(0, 0, width / 2, height / 2, 0, 0, Math.PI * 2);\\n break;\\n }\\n case \\\"triangle\\\": {\\n const halfWidth = width / 2;\\n const halfHeight = height / 2;\\n ctx.moveTo(0, -halfHeight);\\n ctx.lineTo(halfWidth, halfHeight);\\n ctx.lineTo(-halfWidth, halfHeight);\\n ctx.closePath();\\n break;\\n }\\n case \\\"polygon\\\": {\\n const sides = transformData.sides || 5;\\n const radius = Math.min(width, height) / 2;\\n for (let i = 0; i < sides; i++) {\\n const angle = i * 2 * Math.PI / sides - Math.PI / 2;\\n const px = radius * Math.cos(angle);\\n const py = radius * Math.sin(angle);\\n if (i === 0) {\\n ctx.moveTo(px, py);\\n } else {\\n ctx.lineTo(px, py);\\n }\\n }\\n ctx.closePath();\\n break;\\n }\\n case \\\"star\\\": {\\n const points = transformData.points || 5;\\n const outerRadius = Math.min(width, height) / 2;\\n const innerRadius = outerRadius * (transformData.innerRadius || 0.4);\\n for (let i = 0; i < points * 2; i++) {\\n const angle = i * Math.PI / points - Math.PI / 2;\\n const r = i % 2 === 0 ? outerRadius : innerRadius;\\n const px = r * Math.cos(angle);\\n const py = r * Math.sin(angle);\\n if (i === 0) {\\n ctx.moveTo(px, py);\\n } else {\\n ctx.lineTo(px, py);\\n }\\n }\\n ctx.closePath();\\n break;\\n }\\n case \\\"line\\\": {\\n const halfWidth = width / 2;\\n const halfHeight = height / 2;\\n ctx.rect(-halfWidth, -halfHeight, width, height);\\n break;\\n }\\n default:\\n ctx.rect(-width / 2, -height / 2, width, height);\\n }\\n }\\n\\n // src/rendering/ElementRenderUtils.ts\\n function renderElement(ctx, element, options = {}) {\\n const mode = options.mode || \\\"both\\\";\\n ctx.save();\\n ctx.translate(element.x || 0, element.y || 0);\\n ctx.rotate(-(element.rotation || 0) * Math.PI / 180);\\n switch (element.transformType) {\\n case \\\"image\\\":\\n renderImageElement2(ctx, element, mode, options);\\n break;\\n case \\\"shape\\\":\\n renderShapeElement2(ctx, element, mode, options);\\n break;\\n case \\\"group\\\":\\n break;\\n default:\\n renderTextElement2(ctx, element, mode, options);\\n break;\\n }\\n ctx.restore();\\n }\\n function renderTextElement2(ctx, element, mode, options) {\\n const textElement = element;\\n const text = textElement.text || \\\"\\\";\\n if (!text) return;\\n if ((mode === \\\"stroke\\\" || mode === \\\"both\\\") && element.stroke?.enabled) {\\n ctx.save();\\n renderTextStroke(ctx, element, { ...options.renderingContext, positionApplied: true });\\n ctx.restore();\\n }\\n if (mode === \\\"fill\\\" || mode === \\\"both\\\") {\\n ctx.save();\\n renderTextFillOnly(ctx, {\\n text,\\n fontSize: textElement.fontSize || 24,\\n fontFamily: textElement.fontFamily || \\\"Arial\\\",\\n bold: textElement.bold || false,\\n italic: textElement.italic || false,\\n textAlign: textElement.textAlign || \\\"center\\\",\\n color: textElement.color || \\\"#000000\\\",\\n letterSpacing: textElement.letterSpacing\\n });\\n ctx.restore();\\n }\\n }\\n function renderImageElement2(ctx, element, mode, options) {\\n if (!element.transformData) return;\\n const transformData = element.transformData;\\n if (mode === \\\"fill\\\" || mode === \\\"both\\\") {\\n createImagePath2(ctx, element);\\n if (options.loadedImage) {\\n ctx.save();\\n ctx.clip();\\n const flipH = transformData.flipHorizontal ? -1 : 1;\\n const flipV = transformData.flipVertical ? -1 : 1;\\n ctx.scale(flipH, flipV);\\n const width = transformData.width ?? 100;\\n const height = transformData.height ?? 100;\\n ctx.drawImage(options.loadedImage, -width / 2, -height / 2, width, height);\\n ctx.restore();\\n } else {\\n ctx.fillStyle = \\\"#cccccc\\\";\\n ctx.fill();\\n }\\n }\\n if ((mode === \\\"stroke\\\" || mode === \\\"both\\\") && element.stroke?.enabled) {\\n ctx.save();\\n renderImageStroke(ctx, element, options.renderingContext);\\n ctx.restore();\\n }\\n }\\n function renderShapeElement2(ctx, element, mode, options) {\\n if (!element.transformData) return;\\n const transformData = element.transformData;\\n const isKnockoutRender = options.renderingContext?.isKnockout === true;\\n ctx.beginPath();\\n renderShapePath(ctx, transformData);\\n if (mode === \\\"fill\\\" || mode === \\\"both\\\") {\\n ctx.fillStyle = isKnockoutRender ? \\\"#000000\\\" : transformData.fillColor || \\\"#3b82f6\\\";\\n ctx.globalAlpha = isKnockoutRender ? 1 : transformData.fillOpacity ?? 1;\\n ctx.fill();\\n }\\n if ((mode === \\\"stroke\\\" || mode === \\\"both\\\") && element.stroke?.enabled) {\\n ctx.save();\\n renderShapeStroke(ctx, element, options.renderingContext);\\n ctx.restore();\\n }\\n }\\n function renderShapePath(ctx, transformData) {\\n const { shapeType } = transformData;\\n const width = transformData.width ?? 100;\\n const height = transformData.height ?? 100;\\n switch (shapeType) {\\n case \\\"rectangle\\\":\\n renderRectanglePath(ctx, transformData, width, height);\\n break;\\n case \\\"circle\\\":\\n renderCirclePath(ctx, Math.min(width, height) / 2);\\n break;\\n case \\\"ellipse\\\":\\n renderEllipsePath(ctx, width / 2, height / 2);\\n break;\\n case \\\"star\\\":\\n renderStarPath(ctx, transformData, Math.min(width, height) / 2);\\n break;\\n default:\\n renderRectanglePath(ctx, transformData, width, height);\\n }\\n }\\n function renderRectanglePath(ctx, transformData, width, height) {\\n const borderRadius = transformData.borderRadius || 0;\\n const x = -width / 2;\\n const y = -height / 2;\\n if (borderRadius > 0) {\\n const radius = Math.min(borderRadius / 100 * Math.min(width, height), width / 2, height / 2);\\n ctx.roundRect(x, y, width, height, radius);\\n } else {\\n ctx.rect(x, y, width, height);\\n }\\n }\\n function renderCirclePath(ctx, radius) {\\n ctx.arc(0, 0, radius, 0, Math.PI * 2);\\n }\\n function renderEllipsePath(ctx, radiusX, radiusY) {\\n ctx.ellipse(0, 0, radiusX, radiusY, 0, 0, Math.PI * 2);\\n }\\n function renderStarPath(ctx, transformData, outerRadius) {\\n const points = Math.max(3, Math.min(20, transformData.points || 5));\\n const innerRadiusRatio = Math.max(0.1, Math.min(0.9, transformData.innerRadius || 0.4));\\n const innerRadius = outerRadius * innerRadiusRatio;\\n const angleStep = Math.PI / points;\\n const startAngle = -Math.PI / 2;\\n for (let i = 0; i < points * 2; i++) {\\n const angle = startAngle + angleStep * i;\\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\\n const x = Math.cos(angle) * radius;\\n const y = Math.sin(angle) * radius;\\n if (i === 0) {\\n ctx.moveTo(x, y);\\n } else {\\n ctx.lineTo(x, y);\\n }\\n }\\n ctx.closePath();\\n }\\n function renderShapeStroke(ctx, element, renderingContext) {\\n if (!element.stroke?.enabled || !element.transformData) return;\\n const isKnockoutRender = renderingContext?.isKnockout === true;\\n ctx.save();\\n if (isKnockoutRender) {\\n ctx.strokeStyle = \\\"#000000\\\";\\n ctx.lineWidth = element.stroke.width;\\n ctx.lineCap = element.stroke.lineCap || \\\"butt\\\";\\n ctx.lineJoin = element.stroke.lineJoin || \\\"miter\\\";\\n ctx.globalAlpha = 1;\\n } else {\\n ctx.strokeStyle = element.stroke.color;\\n ctx.lineWidth = element.stroke.width;\\n ctx.lineCap = element.stroke.lineCap || \\\"butt\\\";\\n ctx.lineJoin = element.stroke.lineJoin || \\\"miter\\\";\\n if (element.stroke.opacity !== void 0) {\\n ctx.globalAlpha = element.stroke.opacity;\\n }\\n }\\n if (element.stroke.miterLimit !== void 0) {\\n ctx.miterLimit = element.stroke.miterLimit;\\n }\\n if (element.stroke.dashArray && element.stroke.dashArray.length > 0) {\\n ctx.setLineDash(element.stroke.dashArray);\\n }\\n if (!isKnockoutRender && element.stroke.feather && element.stroke.feather > 0) {\\n if (\\\"filter\\\" in ctx) {\\n ctx.filter = `blur(${element.stroke.feather}px)`;\\n }\\n }\\n ctx.beginPath();\\n renderShapePath(ctx, element.transformData);\\n ctx.stroke();\\n ctx.restore();\\n }\\n function createImagePath2(ctx, element) {\\n if (!element.transformData) return;\\n const { borderRadius } = element.transformData;\\n const width = element.transformData.width ?? 100;\\n const height = element.transformData.height ?? 100;\\n const x = -width / 2;\\n const y = -height / 2;\\n ctx.beginPath();\\n if (borderRadius && borderRadius > 0) {\\n const radius = Math.min(borderRadius / 100 * Math.min(width, height), width / 2, height / 2);\\n ctx.roundRect(x, y, width, height, radius);\\n } else {\\n ctx.rect(x, y, width, height);\\n }\\n }\\n\\n // src/rendering/CompositingRenderer.ts\\n function renderWithCompositing(ctx, compositingElement, allElements, renderElementFn, artboardBackgroundColor, artboard, compositeOp = \\\"destination-out\\\") {\\n if (!compositingElement.knockoutParts) return;\\n const hasAnyParts = compositingElement.knockoutParts.fill || compositingElement.knockoutParts.stroke;\\n if (!hasAnyParts) {\\n renderElementFn(ctx, compositingElement);\\n return;\\n }\\n const savedTransform = ctx.getTransform();\\n ctx.save();\\n const scope = compositingElement.knockoutParts.scope || \\\"group\\\";\\n const affectedElements = getAffectedElements(compositingElement, scope, allElements);\\n if (affectedElements.length === 0 && scope === \\\"artboard\\\") {\\n renderNonCompositingParts(ctx, compositingElement, renderElementFn);\\n ctx.restore();\\n return;\\n }\\n if (affectedElements.length === 0) {\\n renderElementFn(ctx, compositingElement);\\n ctx.restore();\\n return;\\n }\\n const canvas = ctx.canvas;\\n const mainTransform = ctx.getTransform();\\n const dpr = mainTransform.a;\\n const offscreen = createOffscreenCanvas3(canvas.width, canvas.height);\\n const offCtx = offscreen.getContext(\\\"2d\\\");\\n if (!offCtx) return;\\n offCtx.scale(dpr, dpr);\\n if (artboardBackgroundColor && artboard) {\\n offCtx.fillStyle = artboardBackgroundColor;\\n offCtx.fillRect(artboard.x, artboard.y, artboard.width, artboard.height);\\n }\\n for (const element of affectedElements) {\\n renderElementFn(offCtx, element);\\n }\\n if (compositingElement.knockoutParts.fill && !compositingElement.knockoutParts.stroke && compositingElement.stroke?.enabled) {\\n offCtx.save();\\n renderElementStroke(offCtx, compositingElement);\\n offCtx.restore();\\n }\\n offCtx.save();\\n offCtx.globalCompositeOperation = compositeOp;\\n if (compositingElement.knockoutParts.fill) {\\n renderElementFill(offCtx, compositingElement, renderElementFn);\\n }\\n if (compositingElement.knockoutParts.stroke) {\\n renderElementStroke(offCtx, compositingElement);\\n }\\n offCtx.restore();\\n if (!compositingElement.knockoutParts.fill) {\\n offCtx.save();\\n renderElementFill(offCtx, compositingElement, renderElementFn);\\n offCtx.restore();\\n }\\n const logicalWidth = canvas.width / dpr;\\n const logicalHeight = canvas.height / dpr;\\n ctx.drawImage(offscreen, 0, 0, logicalWidth, logicalHeight);\\n ctx.restore();\\n const afterRestore = ctx.getTransform();\\n if (Math.abs(afterRestore.a - savedTransform.a) > 1e-3 || Math.abs(afterRestore.d - savedTransform.d) > 1e-3 || Math.abs(afterRestore.e - savedTransform.e) > 1e-3 || Math.abs(afterRestore.f - savedTransform.f) > 1e-3) {\\n ctx.setTransform(\\n savedTransform.a,\\n savedTransform.b,\\n savedTransform.c,\\n savedTransform.d,\\n savedTransform.e,\\n savedTransform.f\\n );\\n }\\n }\\n function getAffectedElements(knockoutElement, scope, allElements) {\\n if (scope === \\\"artboard\\\") {\\n return getAllElementsBelow(knockoutElement, allElements);\\n } else {\\n return getGroupSiblings(knockoutElement, allElements);\\n }\\n }\\n function getAllElementsBelow(knockoutElement, allElements) {\\n const knockoutIndex = allElements.findIndex((el) => el.id === knockoutElement.id);\\n if (knockoutIndex === -1) return [];\\n return allElements.slice(0, knockoutIndex);\\n }\\n function getGroupSiblings(knockoutElement, allElements) {\\n const parentGroup = findParentGroup(knockoutElement, allElements);\\n if (!parentGroup) {\\n return getAllElementsBelow(knockoutElement, allElements);\\n }\\n if (parentGroup.transformType !== \\\"group\\\" || !parentGroup.children) {\\n return [];\\n }\\n const knockoutIndex = parentGroup.children.findIndex((child) => child.id === knockoutElement.id);\\n if (knockoutIndex === -1) return [];\\n return parentGroup.children.slice(0, knockoutIndex);\\n }\\n function findParentGroup(element, allElements) {\\n for (const candidate of allElements) {\\n if (candidate.transformType === \\\"group\\\" && candidate.children) {\\n if (candidate.children.some((child) => child.id === element.id)) {\\n return candidate;\\n }\\n const nestedParent = findParentGroup(element, candidate.children);\\n if (nestedParent) {\\n return nestedParent;\\n }\\n }\\n }\\n return null;\\n }\\n function renderElementFill(ctx, element, _renderFn) {\\n renderElement(ctx, element, {\\n mode: \\\"fill\\\",\\n renderingContext: { isKnockout: true }\\n });\\n }\\n function renderElementStroke(ctx, element) {\\n if (!element.stroke?.enabled) return;\\n renderElement(ctx, element, {\\n mode: \\\"stroke\\\",\\n renderingContext: { isKnockout: true }\\n });\\n }\\n function renderNonCompositingParts(ctx, element, renderFn) {\\n const knockoutParts = element.knockoutParts;\\n if (!knockoutParts) {\\n renderFn(ctx, element);\\n return;\\n }\\n if (!knockoutParts.fill) {\\n ctx.save();\\n renderElementFill(ctx, element, renderFn);\\n ctx.restore();\\n }\\n if (!knockoutParts.stroke && element.stroke?.enabled) {\\n ctx.save();\\n renderElementStroke(ctx, element);\\n ctx.restore();\\n }\\n }\\n function createOffscreenCanvas3(width, height) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n return new OffscreenCanvas(width, height);\\n } else if (typeof document !== \\\"undefined\\\") {\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n throw new Error(\\\"No canvas context available\\\");\\n }\\n\\n // src/effects/DistressGenerator.ts\\n var SimplexNoise = class {\\n constructor(seed = Math.random()) {\\n this.perm = [];\\n for (let i = 0; i < 256; i++) {\\n this.perm[i] = i;\\n }\\n const random = this.seededRandom(seed);\\n for (let i = 255; i > 0; i--) {\\n const j = Math.floor(random() * (i + 1));\\n [this.perm[i], this.perm[j]] = [this.perm[j], this.perm[i]];\\n }\\n for (let i = 0; i < 256; i++) {\\n this.perm[256 + i] = this.perm[i];\\n }\\n }\\n seededRandom(seed) {\\n let x = Math.sin(seed++) * 1e4;\\n return () => {\\n x = Math.sin(seed++) * 1e4;\\n return x - Math.floor(x);\\n };\\n }\\n fade(t) {\\n return t * t * t * (t * (t * 6 - 15) + 10);\\n }\\n lerp(t, a, b) {\\n return a + t * (b - a);\\n }\\n grad(hash, x, y) {\\n const h = hash & 15;\\n const u = h < 8 ? x : y;\\n const v = h < 4 ? y : h === 12 || h === 14 ? x : 0;\\n return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);\\n }\\n noise(x, y) {\\n const X = Math.floor(x) & 255;\\n const Y = Math.floor(y) & 255;\\n x -= Math.floor(x);\\n y -= Math.floor(y);\\n const u = this.fade(x);\\n const v = this.fade(y);\\n const a = this.perm[X] + Y;\\n const b = this.perm[X + 1] + Y;\\n return this.lerp(\\n v,\\n this.lerp(u, this.grad(this.perm[a], x, y), this.grad(this.perm[b], x - 1, y)),\\n this.lerp(u, this.grad(this.perm[a + 1], x, y - 1), this.grad(this.perm[b + 1], x - 1, y - 1))\\n );\\n }\\n };\\n function generateWornEffect(width, height, intensity, seed = Date.now()) {\\n const canvas = createCanvas(width, height);\\n const ctx = canvas.getContext(\\\"2d\\\");\\n const imageData = ctx.createImageData(width, height);\\n const data = imageData.data;\\n const noise = new SimplexNoise(seed);\\n const scale = 0.02;\\n const threshold = 1 - intensity / 100;\\n for (let y = 0; y < height; y++) {\\n for (let x = 0; x < width; x++) {\\n const idx = (y * width + x) * 4;\\n let value = 0;\\n value += noise.noise(x * scale, y * scale) * 0.5;\\n value += noise.noise(x * scale * 2, y * scale * 2) * 0.25;\\n value += noise.noise(x * scale * 4, y * scale * 4) * 0.125;\\n value = (value + 1) / 2;\\n const edgeX = Math.min(x / width, (width - x) / width) * 2;\\n const edgeY = Math.min(y / height, (height - y) / height) * 2;\\n const edgeFactor = Math.min(edgeX, edgeY);\\n value *= 0.7 + edgeFactor * 0.3;\\n const alpha = value > threshold ? 255 : 0;\\n data[idx] = 255;\\n data[idx + 1] = 255;\\n data[idx + 2] = 255;\\n data[idx + 3] = alpha;\\n }\\n }\\n return imageData;\\n }\\n function generateCrackedEffect(width, height, intensity, seed = Date.now()) {\\n const canvas = createCanvas(width, height);\\n const ctx = canvas.getContext(\\\"2d\\\");\\n ctx.clearRect(0, 0, width, height);\\n ctx.strokeStyle = \\\"#000000\\\";\\n ctx.lineWidth = 1 + intensity / 50;\\n ctx.lineCap = \\\"round\\\";\\n const random = seededRandom(seed);\\n const numCracks = Math.floor(intensity / 100 * 30 + 5);\\n for (let i = 0; i < numCracks; i++) {\\n const startX = random() * width;\\n const startY = random() * height;\\n drawCrackBranch(ctx, startX, startY, random() * Math.PI * 2, 50 + random() * 100, random, 0);\\n }\\n return ctx.getImageData(0, 0, width, height);\\n }\\n function drawCrackBranch(ctx, x, y, angle, length, random, depth) {\\n if (depth > 3 || length < 10) return;\\n const endX = x + Math.cos(angle) * length;\\n const endY = y + Math.sin(angle) * length;\\n ctx.beginPath();\\n ctx.moveTo(x, y);\\n ctx.lineTo(endX, endY);\\n ctx.stroke();\\n if (random() > 0.5) {\\n const branchAngle = angle + (random() - 0.5) * Math.PI / 2;\\n drawCrackBranch(ctx, endX, endY, branchAngle, length * 0.6, random, depth + 1);\\n }\\n if (random() > 0.7) {\\n const branchAngle = angle - (random() - 0.5) * Math.PI / 2;\\n drawCrackBranch(ctx, endX, endY, branchAngle, length * 0.6, random, depth + 1);\\n }\\n }\\n function generateGrungeEffect(width, height, intensity, seed = Date.now()) {\\n const canvas = createCanvas(width, height);\\n const ctx = canvas.getContext(\\\"2d\\\");\\n const imageData = ctx.createImageData(width, height);\\n const data = imageData.data;\\n const random = seededRandom(seed);\\n const density = intensity / 100 * 0.5;\\n for (let y = 0; y < height; y++) {\\n for (let x = 0; x < width; x++) {\\n const idx = (y * width + x) * 4;\\n const value = random();\\n const alpha = value < density ? 255 : 0;\\n data[idx] = 0;\\n data[idx + 1] = 0;\\n data[idx + 2] = 0;\\n data[idx + 3] = alpha;\\n }\\n }\\n return imageData;\\n }\\n function generateRetroEffect(width, height, intensity, seed = Date.now()) {\\n const canvas = createCanvas(width, height);\\n const ctx = canvas.getContext(\\\"2d\\\");\\n ctx.fillStyle = \\\"#000000\\\";\\n const random = seededRandom(seed);\\n const dotSize = 4 + intensity / 100 * 6;\\n const spacing = dotSize * 2;\\n for (let y = 0; y < height; y += spacing) {\\n for (let x = 0; x < width; x += spacing) {\\n if (random() < intensity / 100) {\\n const size = dotSize * (0.5 + random() * 0.5);\\n ctx.beginPath();\\n ctx.arc(x, y, size / 2, 0, Math.PI * 2);\\n ctx.fill();\\n }\\n }\\n }\\n return ctx.getImageData(0, 0, width, height);\\n }\\n function createCanvas(width, height) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n return new OffscreenCanvas(width, height);\\n } else if (typeof document !== \\\"undefined\\\") {\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n throw new Error(\\\"No canvas context available\\\");\\n }\\n function seededRandom(seed) {\\n let x = Math.sin(seed++) * 1e4;\\n return () => {\\n x = Math.sin(seed++) * 1e4;\\n return x - Math.floor(x);\\n };\\n }\\n\\n // src/effects/distress-textures.ts\\n var BUILTIN_SEED = 42;\\n var TEX_SIZE = 512;\\n var THUMB_SIZE = 64;\\n function toAlphaMask(imageData) {\\n const data = imageData.data;\\n for (let i = 0; i < data.length; i += 4) {\\n data[i] = 255;\\n data[i + 1] = 255;\\n data[i + 2] = 255;\\n }\\n return imageData;\\n }\\n function layerAlpha(a, b) {\\n const data = a.data;\\n const bData = b.data;\\n for (let i = 0; i < data.length; i += 4) {\\n data[i] = 255;\\n data[i + 1] = 255;\\n data[i + 2] = 255;\\n data[i + 3] = Math.min(255, data[i + 3] + bData[i + 3]);\\n }\\n return a;\\n }\\n var DISTRESS_TEXTURE_PRESETS = [\\n {\\n id: \\\"grunge-heavy\\\",\\n name: \\\"Heavy Grunge\\\",\\n textureUrl: \\\"builtin:grunge-heavy\\\",\\n thumbnailUrl: \\\"\\\",\\n description: \\\"Dense random splatters\\\",\\n generate: (w, h) => generateGrungeEffect(w, h, 80, BUILTIN_SEED)\\n },\\n {\\n id: \\\"grunge-fine\\\",\\n name: \\\"Fine Grunge\\\",\\n textureUrl: \\\"builtin:grunge-fine\\\",\\n thumbnailUrl: \\\"\\\",\\n description: \\\"Sparse fine grain\\\",\\n generate: (w, h) => generateGrungeEffect(w, h, 25, BUILTIN_SEED + 1)\\n },\\n {\\n id: \\\"concrete\\\",\\n name: \\\"Concrete\\\",\\n textureUrl: \\\"builtin:concrete\\\",\\n thumbnailUrl: \\\"\\\",\\n description: \\\"Rough surface via Perlin noise\\\",\\n generate: (w, h) => generateWornEffect(w, h, 55, BUILTIN_SEED + 2)\\n },\\n {\\n id: \\\"paper\\\",\\n name: \\\"Old Paper\\\",\\n textureUrl: \\\"builtin:paper\\\",\\n thumbnailUrl: \\\"\\\",\\n description: \\\"Subtle aging\\\",\\n generate: (w, h) => generateWornEffect(w, h, 20, BUILTIN_SEED + 3)\\n },\\n {\\n id: \\\"rust\\\",\\n name: \\\"Rust\\\",\\n textureUrl: \\\"builtin:rust\\\",\\n thumbnailUrl: \\\"\\\",\\n description: \\\"Noise + splatter combined\\\",\\n generate: (w, h) => {\\n const worn = generateWornEffect(w, h, 45, BUILTIN_SEED + 4);\\n const grunge = generateGrungeEffect(w, h, 35, BUILTIN_SEED + 5);\\n return layerAlpha(toAlphaMask(worn), toAlphaMask(grunge));\\n }\\n },\\n {\\n id: \\\"scratches\\\",\\n name: \\\"Scratches\\\",\\n textureUrl: \\\"builtin:scratches\\\",\\n thumbnailUrl: \\\"\\\",\\n description: \\\"Branching crack lines\\\",\\n generate: (w, h) => generateCrackedEffect(w, h, 55, BUILTIN_SEED + 6)\\n },\\n {\\n id: \\\"halftone\\\",\\n name: \\\"Halftone\\\",\\n textureUrl: \\\"builtin:halftone\\\",\\n thumbnailUrl: \\\"\\\",\\n description: \\\"Dot grid pattern\\\",\\n generate: (w, h) => generateRetroEffect(w, h, 55, BUILTIN_SEED + 7)\\n },\\n {\\n id: \\\"spray\\\",\\n name: \\\"Spray Paint\\\",\\n textureUrl: \\\"builtin:spray\\\",\\n thumbnailUrl: \\\"\\\",\\n description: \\\"Medium random splatter\\\",\\n generate: (w, h) => generateGrungeEffect(w, h, 55, BUILTIN_SEED + 8)\\n }\\n ];\\n var initialized = false;\\n function createCanvas2(width, height) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n return new OffscreenCanvas(width, height);\\n }\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n function createDOMCanvas(width, height) {\\n if (typeof document === \\\"undefined\\\") return null;\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n function generateThumbnailDataUrl(imageData) {\\n const fullCanvas = createDOMCanvas(imageData.width, imageData.height);\\n if (!fullCanvas) return \\\"\\\";\\n const fullCtx = fullCanvas.getContext(\\\"2d\\\");\\n if (!fullCtx) return \\\"\\\";\\n fullCtx.putImageData(imageData, 0, 0);\\n const canvas = createDOMCanvas(THUMB_SIZE, THUMB_SIZE);\\n if (!canvas) return \\\"\\\";\\n const ctx = canvas.getContext(\\\"2d\\\");\\n if (!ctx) return \\\"\\\";\\n ctx.drawImage(fullCanvas, 0, 0, imageData.width, imageData.height, 0, 0, THUMB_SIZE, THUMB_SIZE);\\n const thumbData = ctx.getImageData(0, 0, THUMB_SIZE, THUMB_SIZE);\\n const pixels = thumbData.data;\\n for (let i = 0; i < pixels.length; i += 4) {\\n const a = pixels[i + 3];\\n const gray = 255 - Math.round(a / 255 * 195);\\n pixels[i] = gray;\\n pixels[i + 1] = gray;\\n pixels[i + 2] = gray;\\n pixels[i + 3] = 255;\\n }\\n ctx.putImageData(thumbData, 0, 0);\\n return canvas.toDataURL(\\\"image/png\\\");\\n }\\n function ensureBuiltinTexturesReady() {\\n if (initialized) return;\\n initialized = true;\\n for (const preset of DISTRESS_TEXTURE_PRESETS) {\\n const imageData = preset.generate(TEX_SIZE, TEX_SIZE);\\n toAlphaMask(imageData);\\n const maskCanvas = createCanvas2(TEX_SIZE, TEX_SIZE);\\n const maskCtx = maskCanvas.getContext(\\\"2d\\\");\\n if (maskCtx) {\\n maskCtx.putImageData(imageData, 0, 0);\\n registerAlphaMask(preset.textureUrl, maskCanvas, TEX_SIZE, TEX_SIZE);\\n }\\n if (typeof document !== \\\"undefined\\\") {\\n preset.thumbnailUrl = generateThumbnailDataUrl(imageData);\\n }\\n }\\n }\\n\\n // src/effects/DistressTextureCache.ts\\n var loadingUrls = /* @__PURE__ */ new Set();\\n var cache = /* @__PURE__ */ new Map();\\n var pendingCallbacks = /* @__PURE__ */ new Map();\\n function createCanvas3(width, height) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n return new OffscreenCanvas(width, height);\\n }\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n function getContext(canvas) {\\n return canvas.getContext(\\\"2d\\\");\\n }\\n function convertToAlphaMask(source) {\\n const { width, height } = source;\\n const tempCanvas = createCanvas3(width, height);\\n const tempCtx = getContext(tempCanvas);\\n if (!tempCtx) throw new Error(\\\"Failed to get 2d context for temp canvas\\\");\\n tempCtx.drawImage(source, 0, 0);\\n const imageData = tempCtx.getImageData(0, 0, width, height);\\n const data = imageData.data;\\n for (let i = 0; i < data.length; i += 4) {\\n const r = data[i];\\n const g = data[i + 1];\\n const b = data[i + 2];\\n const luma = 0.299 * r + 0.587 * g + 0.114 * b;\\n const alpha = 255 - luma;\\n data[i] = 255;\\n data[i + 1] = 255;\\n data[i + 2] = 255;\\n data[i + 3] = alpha;\\n }\\n const maskCanvas = createCanvas3(width, height);\\n const maskCtx = getContext(maskCanvas);\\n if (!maskCtx) throw new Error(\\\"Failed to get 2d context for mask canvas\\\");\\n maskCtx.putImageData(imageData, 0, 0);\\n return { alphaMask: maskCanvas, width, height };\\n }\\n function getAlphaMask(url) {\\n const cached = cache.get(url);\\n if (cached) return cached;\\n if (url.startsWith(\\\"builtin:\\\")) {\\n ensureBuiltinTexturesReady();\\n const post = cache.get(url);\\n if (post) return post;\\n return null;\\n }\\n if (loadingUrls.has(url)) return null;\\n loadingUrls.add(url);\\n loadTexture(url);\\n return null;\\n }\\n function preloadTexture(url) {\\n if (cache.has(url)) return Promise.resolve();\\n return new Promise((resolve) => {\\n if (cache.has(url)) {\\n resolve();\\n return;\\n }\\n const callbacks = pendingCallbacks.get(url) || [];\\n callbacks.push(resolve);\\n pendingCallbacks.set(url, callbacks);\\n if (!loadingUrls.has(url)) {\\n loadingUrls.add(url);\\n loadTexture(url);\\n }\\n });\\n }\\n function registerAlphaMask(key, canvas, width, height) {\\n if (cache.has(key)) return;\\n cache.set(key, { alphaMask: canvas, width, height });\\n notifyPending(key);\\n }\\n function notifyPending(url) {\\n const callbacks = pendingCallbacks.get(url);\\n if (callbacks) {\\n callbacks.forEach((cb) => cb());\\n pendingCallbacks.delete(url);\\n }\\n }\\n function loadTexture(url) {\\n if (typeof document !== \\\"undefined\\\") {\\n const img = new Image();\\n img.crossOrigin = \\\"anonymous\\\";\\n img.onload = () => {\\n const entry = convertToAlphaMask(img);\\n cache.set(url, entry);\\n loadingUrls.delete(url);\\n notifyPending(url);\\n };\\n img.onerror = () => {\\n loadingUrls.delete(url);\\n notifyPending(url);\\n };\\n img.src = url;\\n } else {\\n fetch(url).then((res) => res.blob()).then((blob) => createImageBitmap(blob)).then((bitmap) => {\\n const entry = convertToAlphaMask(bitmap);\\n cache.set(url, entry);\\n loadingUrls.delete(url);\\n notifyPending(url);\\n }).catch(() => {\\n loadingUrls.delete(url);\\n notifyPending(url);\\n });\\n }\\n }\\n\\n // src/rendering/DistressTextureRenderer.ts\\n function createOffscreenCanvas4(width, height) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n return new OffscreenCanvas(width, height);\\n }\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n function applyArtboardDistressTexture(ctx, config, artboard, artboardBackgroundColor) {\\n if (!config.enabled || !config.textureUrl || config.intensity <= 0) return;\\n const mask = getAlphaMask(config.textureUrl);\\n if (!mask) return;\\n const { x, y, width, height } = artboard;\\n const transform = ctx.getTransform();\\n const pixelX = transform.a * x + transform.e;\\n const pixelY = transform.d * y + transform.f;\\n const pixelWidth = transform.a * width;\\n const pixelHeight = transform.d * height;\\n const offWidth = Math.ceil(pixelWidth);\\n const offHeight = Math.ceil(pixelHeight);\\n if (offWidth <= 0 || offHeight <= 0) return;\\n const offCanvas = createOffscreenCanvas4(offWidth, offHeight);\\n const offCtx = offCanvas.getContext(\\\"2d\\\");\\n if (!offCtx) return;\\n offCtx.drawImage(\\n ctx.canvas,\\n pixelX,\\n pixelY,\\n pixelWidth,\\n pixelHeight,\\n 0,\\n 0,\\n offWidth,\\n offHeight\\n );\\n const artMaskCtx = mask.alphaMask.getContext(\\\"2d\\\");\\n if (artMaskCtx) {\\n const artIntensity = config.intensity / 100;\\n const mData = artMaskCtx.getImageData(0, 0, mask.width, mask.height).data;\\n const mW = mask.width;\\n const mH = mask.height;\\n const content = offCtx.getImageData(0, 0, offWidth, offHeight);\\n const cData = content.data;\\n for (let y2 = 0; y2 < offHeight; y2++) {\\n const my = Math.floor(y2 / offHeight * mH);\\n for (let x2 = 0; x2 < offWidth; x2++) {\\n const mx = Math.floor(x2 / offWidth * mW);\\n const maskAlpha = mData[(my * mW + mx) * 4 + 3] / 255;\\n const ci = (y2 * offWidth + x2) * 4;\\n cData[ci + 3] = Math.round(cData[ci + 3] * (1 - maskAlpha * artIntensity));\\n }\\n }\\n offCtx.putImageData(content, 0, 0);\\n } else {\\n offCtx.globalCompositeOperation = \\\"destination-out\\\";\\n offCtx.globalAlpha = config.intensity / 100;\\n offCtx.drawImage(mask.alphaMask, 0, 0, offWidth, offHeight);\\n offCtx.globalCompositeOperation = \\\"source-over\\\";\\n }\\n offCtx.globalAlpha = 1;\\n ctx.save();\\n ctx.setTransform(1, 0, 0, 1, 0, 0);\\n ctx.clearRect(pixelX, pixelY, pixelWidth, pixelHeight);\\n if (artboardBackgroundColor) {\\n ctx.fillStyle = artboardBackgroundColor;\\n ctx.fillRect(pixelX, pixelY, pixelWidth, pixelHeight);\\n }\\n ctx.drawImage(offCanvas, pixelX, pixelY);\\n ctx.restore();\\n }\\n function applyElementDistressTexture(ctx, distress, elementBounds, renderFn) {\\n if (!distress.enabled || distress.style !== \\\"custom\\\" || !distress.textureUrl) return;\\n const mask = getAlphaMask(distress.textureUrl);\\n if (!mask) {\\n renderFn(ctx);\\n return;\\n }\\n const intensity = distress.textureOpacity ?? distress.intensity / 100;\\n const transform = ctx.getTransform();\\n const diagonal = Math.sqrt(elementBounds.width ** 2 + elementBounds.height ** 2);\\n const extraW = (diagonal - elementBounds.width) / 2;\\n const extraH = (diagonal - elementBounds.height) / 2;\\n const strokePad = 20;\\n const padX = extraW + strokePad;\\n const padY = extraH + strokePad;\\n const paddedBounds = {\\n x: elementBounds.x - padX,\\n y: elementBounds.y - padY,\\n width: elementBounds.width + padX * 2,\\n height: elementBounds.height + padY * 2\\n };\\n const pixelX = transform.a * paddedBounds.x + transform.e;\\n const pixelY = transform.d * paddedBounds.y + transform.f;\\n const pixelWidth = transform.a * paddedBounds.width;\\n const pixelHeight = transform.d * paddedBounds.height;\\n const offWidth = Math.ceil(pixelWidth);\\n const offHeight = Math.ceil(pixelHeight);\\n if (offWidth <= 0 || offHeight <= 0) {\\n renderFn(ctx);\\n return;\\n }\\n const offCanvas = createOffscreenCanvas4(offWidth, offHeight);\\n const offCtx = offCanvas.getContext(\\\"2d\\\");\\n if (!offCtx) {\\n renderFn(ctx);\\n return;\\n }\\n offCtx.setTransform(\\n transform.a,\\n transform.b,\\n transform.c,\\n transform.d,\\n transform.e - pixelX,\\n transform.f - pixelY\\n );\\n renderFn(offCtx);\\n offCtx.setTransform(1, 0, 0, 1, 0, 0);\\n const maskCtx = mask.alphaMask.getContext(\\\"2d\\\");\\n if (maskCtx) {\\n const mData = maskCtx.getImageData(0, 0, mask.width, mask.height).data;\\n const mW = mask.width;\\n const mH = mask.height;\\n const content = offCtx.getImageData(0, 0, offWidth, offHeight);\\n const cData = content.data;\\n for (let y = 0; y < offHeight; y++) {\\n const my = Math.floor(y / offHeight * mH);\\n for (let x = 0; x < offWidth; x++) {\\n const mx = Math.floor(x / offWidth * mW);\\n const maskAlpha = mData[(my * mW + mx) * 4 + 3] / 255;\\n const ci = (y * offWidth + x) * 4;\\n cData[ci + 3] = Math.round(cData[ci + 3] * (1 - maskAlpha * intensity));\\n }\\n }\\n offCtx.putImageData(content, 0, 0);\\n } else {\\n offCtx.globalCompositeOperation = \\\"destination-out\\\";\\n offCtx.globalAlpha = intensity;\\n offCtx.drawImage(mask.alphaMask, 0, 0, offWidth, offHeight);\\n offCtx.globalCompositeOperation = \\\"source-over\\\";\\n offCtx.globalAlpha = 1;\\n }\\n ctx.save();\\n ctx.setTransform(1, 0, 0, 1, 0, 0);\\n ctx.drawImage(offCanvas, pixelX, pixelY);\\n ctx.restore();\\n }\\n\\n // src/core/ImageCache.ts\\n var ImageCache = class _ImageCache {\\n constructor() {\\n this.cache = /* @__PURE__ */ new Map();\\n }\\n /**\\n * Get the singleton ImageCache instance.\\n */\\n static getInstance() {\\n if (!_ImageCache.instance) {\\n _ImageCache.instance = new _ImageCache();\\n }\\n return _ImageCache.instance;\\n }\\n /**\\n * Acquire an HTMLImageElement for the given URL.\\n * If the URL is already cached, increments the reference count and returns the existing element.\\n * If not cached, creates a new HTMLImageElement, starts loading, and caches it.\\n *\\n * @param url - The image URL to load\\n * @returns The cached or newly created HTMLImageElement\\n */\\n acquire(url) {\\n const existing = this.cache.get(url);\\n if (existing) {\\n existing.refCount++;\\n return existing.image;\\n }\\n const img = new Image();\\n img.crossOrigin = \\\"anonymous\\\";\\n const entry = {\\n image: img,\\n refCount: 1,\\n loaded: false\\n };\\n img.onload = () => {\\n entry.loaded = true;\\n };\\n img.onerror = () => {\\n entry.loaded = true;\\n };\\n this.cache.set(url, entry);\\n if (!url.includes(\\\":\\\") || /^https?:\\\\/\\\\/|^data:|^blob:/.test(url)) {\\n img.src = url;\\n }\\n return img;\\n }\\n /**\\n * Release a reference to a cached image.\\n * When the reference count reaches zero, the entry is evicted from the cache.\\n *\\n * @param url - The image URL to release\\n */\\n release(url) {\\n const entry = this.cache.get(url);\\n if (!entry) return;\\n entry.refCount--;\\n if (entry.refCount <= 0) {\\n this.cache.delete(url);\\n }\\n }\\n /**\\n * Get a cached HTMLImageElement without incrementing the reference count.\\n * Returns undefined if the URL is not in the cache.\\n *\\n * @param url - The image URL to look up\\n */\\n get(url) {\\n return this.cache.get(url)?.image;\\n }\\n /**\\n * Check if a URL is in the cache.\\n *\\n * @param url - The image URL to check\\n */\\n has(url) {\\n return this.cache.has(url);\\n }\\n /**\\n * Get cache statistics.\\n *\\n * @returns Object with entry count and total reference count across all entries\\n */\\n getStats() {\\n let totalRefs = 0;\\n for (const entry of this.cache.values()) {\\n totalRefs += entry.refCount;\\n }\\n return { entries: this.cache.size, totalRefs };\\n }\\n /**\\n * Clear the entire cache.\\n * Primarily for testing -- removes all entries regardless of reference count.\\n */\\n clear() {\\n this.cache.clear();\\n }\\n };\\n\\n // src/rendering/mask-utils.ts\\n function computeMaskCoverDimensions(parentW, parentH, maskNaturalW, maskNaturalH, oversize = 0) {\\n if (maskNaturalW <= 0 || maskNaturalH <= 0 || parentW <= 0 || parentH <= 0) {\\n return { width: parentW + oversize, height: parentH + oversize };\\n }\\n const maskAspect = maskNaturalW / maskNaturalH;\\n const parentAspect = parentW / parentH;\\n let fitW;\\n let fitH;\\n if (parentAspect > maskAspect) {\\n fitH = parentH;\\n fitW = parentH * maskAspect;\\n } else {\\n fitW = parentW;\\n fitH = parentW / maskAspect;\\n }\\n return {\\n width: fitW + oversize,\\n height: fitH + oversize\\n };\\n }\\n\\n // src/effects/mask-presets.ts\\n var THUMB_SIZE2 = 64;\\n var MASK_SIZE = 512;\\n function drawCircle(ctx, size) {\\n ctx.beginPath();\\n ctx.arc(size / 2, size / 2, size * 0.45, 0, Math.PI * 2);\\n ctx.fill();\\n }\\n function drawStar(ctx, size) {\\n const cx = size / 2, cy = size / 2;\\n const outerR = size * 0.45, innerR = outerR * 0.4;\\n const points = 5;\\n ctx.beginPath();\\n for (let i = 0; i < points * 2; i++) {\\n const angle = -Math.PI / 2 + Math.PI / points * i;\\n const r = i % 2 === 0 ? outerR : innerR;\\n const x = cx + Math.cos(angle) * r;\\n const y = cy + Math.sin(angle) * r;\\n if (i === 0) ctx.moveTo(x, y);\\n else ctx.lineTo(x, y);\\n }\\n ctx.closePath();\\n ctx.fill();\\n }\\n function drawHeart(ctx, size) {\\n const cx = size / 2, s = size * 0.42;\\n ctx.beginPath();\\n ctx.moveTo(cx, size * 0.82);\\n ctx.bezierCurveTo(cx - s * 1.1, size * 0.6, cx - s * 1.3, size * 0.2, cx, size * 0.35);\\n ctx.bezierCurveTo(cx + s * 1.3, size * 0.2, cx + s * 1.1, size * 0.6, cx, size * 0.82);\\n ctx.closePath();\\n ctx.fill();\\n }\\n function drawDiamond(ctx, size) {\\n const cx = size / 2, cy = size / 2;\\n const rx = size * 0.4, ry = size * 0.48;\\n ctx.beginPath();\\n ctx.moveTo(cx, cy - ry);\\n ctx.lineTo(cx + rx, cy);\\n ctx.lineTo(cx, cy + ry);\\n ctx.lineTo(cx - rx, cy);\\n ctx.closePath();\\n ctx.fill();\\n }\\n function drawHexagon(ctx, size) {\\n const cx = size / 2, cy = size / 2, r = size * 0.44;\\n ctx.beginPath();\\n for (let i = 0; i < 6; i++) {\\n const angle = -Math.PI / 2 + Math.PI / 3 * i;\\n const x = cx + Math.cos(angle) * r;\\n const y = cy + Math.sin(angle) * r;\\n if (i === 0) ctx.moveTo(x, y);\\n else ctx.lineTo(x, y);\\n }\\n ctx.closePath();\\n ctx.fill();\\n }\\n function drawShield(ctx, size) {\\n const cx = size / 2, w = size * 0.4, top = size * 0.12;\\n ctx.beginPath();\\n ctx.moveTo(cx, top);\\n ctx.lineTo(cx + w, size * 0.25);\\n ctx.lineTo(cx + w, size * 0.55);\\n ctx.quadraticCurveTo(cx + w * 0.3, size * 0.8, cx, size * 0.9);\\n ctx.quadraticCurveTo(cx - w * 0.3, size * 0.8, cx - w, size * 0.55);\\n ctx.lineTo(cx - w, size * 0.25);\\n ctx.closePath();\\n ctx.fill();\\n }\\n function drawSplatter(ctx, size) {\\n const cx = size / 2, cy = size / 2;\\n let seed = 42;\\n const rand = () => {\\n seed = (seed * 16807 + 0) % 2147483647;\\n return seed / 2147483647;\\n };\\n ctx.beginPath();\\n ctx.arc(cx, cy, size * 0.28, 0, Math.PI * 2);\\n ctx.fill();\\n for (let i = 0; i < 30; i++) {\\n const angle = rand() * Math.PI * 2;\\n const dist = size * 0.15 + rand() * size * 0.3;\\n const r = size * 0.02 + rand() * size * 0.06;\\n ctx.beginPath();\\n ctx.arc(cx + Math.cos(angle) * dist, cy + Math.sin(angle) * dist, r, 0, Math.PI * 2);\\n ctx.fill();\\n }\\n }\\n function drawTornEdge(ctx, size) {\\n let seed = 123;\\n const rand = () => {\\n seed = (seed * 16807 + 0) % 2147483647;\\n return seed / 2147483647;\\n };\\n const margin = size * 0.08;\\n const steps = 40;\\n ctx.beginPath();\\n ctx.moveTo(margin, margin);\\n for (let i = 1; i <= steps; i++) {\\n const x = margin + (size - 2 * margin) * (i / steps);\\n const y = margin + (rand() - 0.5) * size * 0.08;\\n ctx.lineTo(x, y);\\n }\\n for (let i = 1; i <= steps; i++) {\\n const x = size - margin + (rand() - 0.5) * size * 0.08;\\n const y = margin + (size - 2 * margin) * (i / steps);\\n ctx.lineTo(x, y);\\n }\\n for (let i = steps; i >= 0; i--) {\\n const x = margin + (size - 2 * margin) * (i / steps);\\n const y = size - margin + (rand() - 0.5) * size * 0.08;\\n ctx.lineTo(x, y);\\n }\\n for (let i = steps; i >= 0; i--) {\\n const x = margin + (rand() - 0.5) * size * 0.08;\\n const y = margin + (size - 2 * margin) * (i / steps);\\n ctx.lineTo(x, y);\\n }\\n ctx.closePath();\\n ctx.fill();\\n }\\n function drawPaintStroke(ctx, size) {\\n let seed = 77;\\n const rand = () => {\\n seed = (seed * 16807 + 0) % 2147483647;\\n return seed / 2147483647;\\n };\\n const y0 = size * 0.25, y1 = size * 0.75;\\n const margin = size * 0.1;\\n ctx.beginPath();\\n ctx.moveTo(margin, y0 + rand() * size * 0.05);\\n for (let i = 1; i <= 10; i++) {\\n const x = margin + (size - 2 * margin) * (i / 10);\\n const y = y0 + (rand() - 0.5) * size * 0.1;\\n ctx.lineTo(x, y);\\n }\\n for (let i = 10; i >= 0; i--) {\\n const x = margin + (size - 2 * margin) * (i / 10);\\n const y = y1 + (rand() - 0.5) * size * 0.1;\\n ctx.lineTo(x, y);\\n }\\n ctx.closePath();\\n ctx.fill();\\n }\\n function drawCloud(ctx, size) {\\n const cx = size / 2, cy = size * 0.55;\\n ctx.beginPath();\\n ctx.arc(cx, cy, size * 0.2, 0, Math.PI * 2);\\n ctx.fill();\\n ctx.beginPath();\\n ctx.arc(cx - size * 0.18, cy + size * 0.02, size * 0.15, 0, Math.PI * 2);\\n ctx.fill();\\n ctx.beginPath();\\n ctx.arc(cx + size * 0.18, cy + size * 0.02, size * 0.16, 0, Math.PI * 2);\\n ctx.fill();\\n ctx.beginPath();\\n ctx.arc(cx - size * 0.06, cy - size * 0.14, size * 0.14, 0, Math.PI * 2);\\n ctx.fill();\\n ctx.beginPath();\\n ctx.arc(cx + size * 0.1, cy - size * 0.12, size * 0.12, 0, Math.PI * 2);\\n ctx.fill();\\n }\\n var MASK_IMAGE_PRESETS = [\\n // Geometric\\n { id: \\\"circle\\\", name: \\\"Circle\\\", description: \\\"Perfect circle\\\", imageUrl: \\\"builtin-mask:circle\\\", thumbnailUrl: \\\"\\\", category: \\\"geometric\\\", draw: drawCircle },\\n { id: \\\"star\\\", name: \\\"Star\\\", description: \\\"5-pointed star\\\", imageUrl: \\\"builtin-mask:star\\\", thumbnailUrl: \\\"\\\", category: \\\"geometric\\\", draw: drawStar },\\n { id: \\\"heart\\\", name: \\\"Heart\\\", description: \\\"Heart shape\\\", imageUrl: \\\"builtin-mask:heart\\\", thumbnailUrl: \\\"\\\", category: \\\"geometric\\\", draw: drawHeart },\\n { id: \\\"diamond\\\", name: \\\"Diamond\\\", description: \\\"Diamond/rhombus\\\", imageUrl: \\\"builtin-mask:diamond\\\", thumbnailUrl: \\\"\\\", category: \\\"geometric\\\", draw: drawDiamond },\\n { id: \\\"hexagon\\\", name: \\\"Hexagon\\\", description: \\\"Regular hexagon\\\", imageUrl: \\\"builtin-mask:hexagon\\\", thumbnailUrl: \\\"\\\", category: \\\"geometric\\\", draw: drawHexagon },\\n { id: \\\"shield\\\", name: \\\"Shield\\\", description: \\\"Shield/crest shape\\\", imageUrl: \\\"builtin-mask:shield\\\", thumbnailUrl: \\\"\\\", category: \\\"geometric\\\", draw: drawShield },\\n // Organic\\n { id: \\\"splatter\\\", name: \\\"Splatter\\\", description: \\\"Ink splatter\\\", imageUrl: \\\"builtin-mask:splatter\\\", thumbnailUrl: \\\"\\\", category: \\\"organic\\\", draw: drawSplatter },\\n { id: \\\"torn-edge\\\", name: \\\"Torn Edge\\\", description: \\\"Rough torn paper edge\\\", imageUrl: \\\"builtin-mask:torn-edge\\\", thumbnailUrl: \\\"\\\", category: \\\"organic\\\", draw: drawTornEdge },\\n { id: \\\"paint-stroke\\\", name: \\\"Paint Stroke\\\", description: \\\"Horizontal brush stroke\\\", imageUrl: \\\"builtin-mask:paint-stroke\\\", thumbnailUrl: \\\"\\\", category: \\\"organic\\\", draw: drawPaintStroke },\\n { id: \\\"cloud\\\", name: \\\"Cloud\\\", description: \\\"Soft cloud shape\\\", imageUrl: \\\"builtin-mask:cloud\\\", thumbnailUrl: \\\"\\\", category: \\\"organic\\\", draw: drawCloud }\\n ];\\n var initialized2 = false;\\n function createDOMCanvas2(width, height) {\\n if (typeof document === \\\"undefined\\\") return null;\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n function ensureMaskPresetsReady() {\\n if (typeof document === \\\"undefined\\\") return;\\n if (initialized2) return;\\n initialized2 = true;\\n const cache2 = ImageCache.getInstance();\\n for (const preset of MASK_IMAGE_PRESETS) {\\n const maskCanvas = createDOMCanvas2(MASK_SIZE, MASK_SIZE);\\n if (!maskCanvas) continue;\\n const maskCtx = maskCanvas.getContext(\\\"2d\\\");\\n if (!maskCtx) continue;\\n maskCtx.fillStyle = \\\"white\\\";\\n preset.draw(maskCtx, MASK_SIZE);\\n const dataUrl = maskCanvas.toDataURL(\\\"image/png\\\");\\n const img = cache2.acquire(preset.imageUrl);\\n img.crossOrigin = \\\"anonymous\\\";\\n img.src = dataUrl;\\n const thumbCanvas = createDOMCanvas2(THUMB_SIZE2, THUMB_SIZE2);\\n if (thumbCanvas) {\\n const thumbCtx = thumbCanvas.getContext(\\\"2d\\\");\\n if (thumbCtx) {\\n thumbCtx.fillStyle = \\\"#1a1a2e\\\";\\n thumbCtx.fillRect(0, 0, THUMB_SIZE2, THUMB_SIZE2);\\n thumbCtx.fillStyle = \\\"white\\\";\\n preset.draw(thumbCtx, THUMB_SIZE2);\\n preset.thumbnailUrl = thumbCanvas.toDataURL(\\\"image/png\\\");\\n }\\n }\\n }\\n }\\n function generateMaskBitmap(builtinUrl) {\\n if (!builtinUrl.startsWith(\\\"builtin-mask:\\\")) return null;\\n if (typeof OffscreenCanvas === \\\"undefined\\\") return null;\\n const id = builtinUrl.replace(\\\"builtin-mask:\\\", \\\"\\\");\\n const preset = MASK_IMAGE_PRESETS.find((p) => p.id === id);\\n if (!preset) return null;\\n const canvas = new OffscreenCanvas(MASK_SIZE, MASK_SIZE);\\n const ctx = canvas.getContext(\\\"2d\\\");\\n if (!ctx) return null;\\n ctx.fillStyle = \\\"white\\\";\\n preset.draw(ctx, MASK_SIZE);\\n return canvas.transferToImageBitmap();\\n }\\n\\n // src/rendering/MaskRenderer.ts\\n var logger3 = createLogger(\\\"MaskRenderer\\\");\\n var workerMaskBitmaps = /* @__PURE__ */ new Map();\\n function registerMaskBitmap(imageUrl, bitmap) {\\n workerMaskBitmaps.set(imageUrl, bitmap);\\n }\\n function clearMaskBitmaps() {\\n workerMaskBitmaps.clear();\\n }\\n function renderWithMasks(ctx, element, renderFn) {\\n if (!element.masks || element.masks.length === 0) {\\n renderFn(ctx);\\n return;\\n }\\n const canvas = ctx.canvas;\\n const offscreen = createOffscreenCanvas5(canvas.width, canvas.height);\\n const offCtx = offscreen.getContext(\\\"2d\\\");\\n if (!offCtx) {\\n logger3.error(\\\"[renderWithMasks] Failed to get offscreen context\\\");\\n return;\\n }\\n const transform = ctx.getTransform();\\n offCtx.setTransform(transform);\\n renderFn(offCtx);\\n for (const mask of element.masks) {\\n applyMask(offCtx, mask, element);\\n }\\n ctx.save();\\n ctx.setTransform(1, 0, 0, 1, 0, 0);\\n ctx.drawImage(offscreen, 0, 0);\\n ctx.restore();\\n }\\n function applyMask(ctx, mask, parentElement) {\\n switch (mask.type) {\\n case \\\"clip\\\":\\n applyClipMask(ctx, mask, parentElement);\\n break;\\n case \\\"alpha\\\":\\n applyAlphaMask(ctx, mask, parentElement);\\n break;\\n case \\\"luma\\\":\\n applyLumaMask(ctx, mask, parentElement);\\n break;\\n case \\\"distress\\\":\\n applyDistressMask(ctx, mask, parentElement);\\n break;\\n }\\n }\\n function applyClipMask(ctx, mask, parentElement) {\\n ctx.save();\\n ctx.globalCompositeOperation = mask.inverted ? \\\"destination-out\\\" : \\\"destination-in\\\";\\n if (mask.opacity !== void 0) {\\n ctx.globalAlpha = mask.opacity;\\n }\\n renderMaskElement(ctx, mask.maskElement, parentElement);\\n ctx.restore();\\n }\\n function applyAlphaMask(ctx, mask, parentElement) {\\n ctx.save();\\n ctx.globalCompositeOperation = mask.inverted ? \\\"destination-out\\\" : \\\"destination-in\\\";\\n if (mask.opacity !== void 0) {\\n ctx.globalAlpha = mask.opacity;\\n }\\n renderMaskElement(ctx, mask.maskElement, parentElement);\\n if (mask.feather && mask.feather > 0) {\\n applyFeathering(ctx, mask.feather);\\n }\\n ctx.restore();\\n }\\n function applyLumaMask(ctx, mask, parentElement) {\\n const maskCanvas = createOffscreenCanvas5(ctx.canvas.width, ctx.canvas.height);\\n const maskCtx = maskCanvas.getContext(\\\"2d\\\");\\n if (!maskCtx) return;\\n renderMaskElement(maskCtx, mask.maskElement, parentElement);\\n const imageData = maskCtx.getImageData(0, 0, maskCanvas.width, maskCanvas.height);\\n const data = imageData.data;\\n for (let i = 0; i < data.length; i += 4) {\\n const r = data[i];\\n const g = data[i + 1];\\n const b = data[i + 2];\\n const luma = 0.299 * r + 0.587 * g + 0.114 * b;\\n data[i + 3] = mask.inverted ? 255 - luma : luma;\\n }\\n maskCtx.putImageData(imageData, 0, 0);\\n ctx.save();\\n ctx.globalCompositeOperation = \\\"destination-in\\\";\\n if (mask.opacity !== void 0) {\\n ctx.globalAlpha = mask.opacity;\\n }\\n ctx.drawImage(maskCanvas, 0, 0);\\n ctx.restore();\\n }\\n function applyDistressMask(ctx, mask, parentElement) {\\n ctx.save();\\n ctx.globalCompositeOperation = mask.inverted ? \\\"destination-in\\\" : \\\"destination-out\\\";\\n if (mask.opacity !== void 0) {\\n ctx.globalAlpha = mask.opacity;\\n }\\n renderMaskElement(ctx, mask.maskElement, parentElement);\\n if (mask.feather && mask.feather > 0) {\\n applyFeathering(ctx, mask.feather);\\n }\\n ctx.restore();\\n }\\n function renderMaskElement(ctx, maskElement, parentElement) {\\n const parentX = parentElement.x || 0;\\n const parentY = parentElement.y || 0;\\n const maskX = maskElement.x || 0;\\n const maskY = maskElement.y || 0;\\n const absoluteMaskElement = {\\n ...maskElement,\\n x: parentX + maskX,\\n y: parentY + maskY,\\n // Inherit parent rotation so mask rotates with the element\\n rotation: (maskElement.rotation || 0) + (parentElement.rotation || 0)\\n };\\n const MASK_OVERSIZE = 4;\\n const parentTd = parentElement.transformData;\\n const parentAny = parentElement;\\n const parentW = parentTd?.width || parentAny.width || 0;\\n const parentH = parentTd?.height || parentAny.height || 0;\\n const maskTd = maskElement.transformData;\\n if (parentW && parentH && maskTd) {\\n absoluteMaskElement.transformData = {\\n ...maskTd,\\n width: parentW + MASK_OVERSIZE,\\n height: parentH + MASK_OVERSIZE\\n };\\n }\\n let loadedImage;\\n let loadedBitmap;\\n if (maskElement.transformType === \\\"image\\\") {\\n const imageConfig = maskElement;\\n if (imageConfig.imageUrl) {\\n if (typeof document !== \\\"undefined\\\") {\\n if (imageConfig.imageUrl.startsWith(\\\"builtin-mask:\\\")) {\\n ensureMaskPresetsReady();\\n }\\n const cache2 = ImageCache.getInstance();\\n const img = cache2.acquire(imageConfig.imageUrl);\\n if (img.complete && img.naturalWidth > 0) {\\n loadedImage = img;\\n }\\n cache2.release(imageConfig.imageUrl);\\n } else {\\n loadedBitmap = workerMaskBitmaps.get(imageConfig.imageUrl);\\n }\\n }\\n }\\n const resolvedTd = absoluteMaskElement.transformData;\\n const maskNaturalW = maskTd?.width || 0;\\n const maskNaturalH = maskTd?.height || 0;\\n const needsContainScaling = maskNaturalW > 0 && maskNaturalH > 0 && parentW > 0 && parentH > 0 && Math.abs(maskNaturalW / maskNaturalH - parentW / parentH) > 1e-3;\\n if (loadedBitmap) {\\n ctx.save();\\n const w = resolvedTd?.width || loadedBitmap.width;\\n const h = resolvedTd?.height || loadedBitmap.height;\\n ctx.translate(absoluteMaskElement.x || 0, absoluteMaskElement.y || 0);\\n ctx.rotate(-(absoluteMaskElement.rotation || 0) * Math.PI / 180);\\n if (needsContainScaling) {\\n const contain = computeMaskCoverDimensions(\\n w,\\n h,\\n maskNaturalW,\\n maskNaturalH,\\n 0\\n );\\n ctx.drawImage(loadedBitmap, -contain.width / 2, -contain.height / 2, contain.width, contain.height);\\n } else {\\n ctx.drawImage(loadedBitmap, -w / 2, -h / 2, w, h);\\n }\\n ctx.restore();\\n } else if (needsContainScaling && loadedImage) {\\n const w = resolvedTd?.width || parentW;\\n const h = resolvedTd?.height || parentH;\\n const contain = computeMaskCoverDimensions(\\n w,\\n h,\\n maskNaturalW,\\n maskNaturalH,\\n 0\\n );\\n ctx.save();\\n ctx.translate(absoluteMaskElement.x || 0, absoluteMaskElement.y || 0);\\n ctx.rotate(-(absoluteMaskElement.rotation || 0) * Math.PI / 180);\\n ctx.drawImage(loadedImage, -contain.width / 2, -contain.height / 2, contain.width, contain.height);\\n ctx.restore();\\n } else {\\n renderElement(ctx, absoluteMaskElement, { mode: \\\"both\\\", loadedImage });\\n }\\n }\\n function applyFeathering(ctx, featherRadius) {\\n if (\\\"filter\\\" in ctx) {\\n ctx.filter = `blur(${featherRadius}px)`;\\n }\\n }\\n function createOffscreenCanvas5(width, height) {\\n if (typeof OffscreenCanvas !== \\\"undefined\\\") {\\n return new OffscreenCanvas(width, height);\\n } else if (typeof document !== \\\"undefined\\\") {\\n const canvas = document.createElement(\\\"canvas\\\");\\n canvas.width = width;\\n canvas.height = height;\\n return canvas;\\n }\\n throw new Error(\\\"No canvas context available\\\");\\n }\\n\\n // src/utils/google-fonts-loader.ts\\n var WEIGHTS_TO_REQUEST = [400, 700];\\n function buildGoogleFontUrl(family, weight) {\\n const fontName = family.replace(/ /g, \\\"+\\\");\\n return `https://fonts.googleapis.com/css2?family=${fontName}:wght@${weight}&display=swap`;\\n }\\n async function fetchGoogleFontCss(family, fetchImpl = fetch) {\\n const cssParts = await Promise.all(\\n WEIGHTS_TO_REQUEST.map((weight) => fetchOneWeightCss(family, weight, fetchImpl))\\n );\\n return cssParts.join(\\\"\\\\n\\\");\\n }\\n async function fetchOneWeightCss(family, weight, fetchImpl) {\\n const url = buildGoogleFontUrl(family, weight);\\n try {\\n const response = await fetchImpl(url);\\n if (!response.ok) return \\\"\\\";\\n return await response.text();\\n } catch {\\n return \\\"\\\";\\n }\\n }\\n function parseFontFaces(css) {\\n const fontFaceRegex = /@font-face\\\\s*{([^}]*)}/g;\\n const urlRegex = /url\\\\(([^)]+)\\\\)/;\\n const out = [];\\n let match;\\n while ((match = fontFaceRegex.exec(css)) !== null) {\\n const block = match[1];\\n const urlMatch = block.match(urlRegex);\\n if (!urlMatch) continue;\\n const fontFileUrl = urlMatch[1].replace(/['\\\"]/g, \\\"\\\");\\n const weightMatch = block.match(/font-weight:\\\\s*(\\\\d+)/);\\n const styleMatch = block.match(/font-style:\\\\s*(\\\\w+)/);\\n const rangeMatch = block.match(/unicode-range:\\\\s*([^;]+)/);\\n const descriptors = {\\n weight: weightMatch ? weightMatch[1] : \\\"400\\\",\\n style: styleMatch ? styleMatch[1] : \\\"normal\\\"\\n };\\n if (rangeMatch) descriptors.unicodeRange = rangeMatch[1].trim();\\n out.push({ fontFileUrl, descriptors });\\n }\\n return out;\\n }\\n async function loadFontFaceFromUrl(family, parsed, fetchImpl = fetch) {\\n try {\\n const response = await fetchImpl(parsed.fontFileUrl, { mode: \\\"cors\\\" });\\n if (!response.ok) return null;\\n const buffer = await response.arrayBuffer();\\n const fontFace = new FontFace(family, buffer, parsed.descriptors);\\n await fontFace.load();\\n return fontFace;\\n } catch {\\n return null;\\n }\\n }\\n\\n // src/workers/export-worker.ts\\n var MAX_BITMAP_CACHE_SIZE = 50;\\n var workerBitmapCache = /* @__PURE__ */ new Map();\\n function evictLRUBitmap() {\\n if (workerBitmapCache.size <= MAX_BITMAP_CACHE_SIZE) return;\\n let oldestKey = null;\\n let oldestTime = Infinity;\\n workerBitmapCache.forEach((entry, key) => {\\n if (entry.lastAccessed < oldestTime) {\\n oldestTime = entry.lastAccessed;\\n oldestKey = key;\\n }\\n });\\n if (oldestKey) {\\n const evicted = workerBitmapCache.get(oldestKey);\\n if (evicted) {\\n evicted.bitmap.close();\\n }\\n workerBitmapCache.delete(oldestKey);\\n }\\n }\\n function getCachedBitmap(cacheKey) {\\n const entry = workerBitmapCache.get(cacheKey);\\n if (entry) {\\n entry.lastAccessed = Date.now();\\n return entry.bitmap;\\n }\\n return void 0;\\n }\\n function handleRegisterBitmap(message) {\\n const { cacheKey, bitmap } = message;\\n const existing = workerBitmapCache.get(cacheKey);\\n if (existing) {\\n existing.bitmap.close();\\n }\\n workerBitmapCache.set(cacheKey, {\\n bitmap,\\n lastAccessed: Date.now()\\n });\\n evictLRUBitmap();\\n }\\n function handleClearBitmap(message) {\\n const { elementId } = message;\\n for (const [key, entry] of workerBitmapCache.entries()) {\\n if (key.startsWith(`${elementId}:`)) {\\n entry.bitmap.close();\\n workerBitmapCache.delete(key);\\n }\\n }\\n }\\n function handleClearAllBitmaps() {\\n for (const entry of workerBitmapCache.values()) {\\n entry.bitmap.close();\\n }\\n workerBitmapCache.clear();\\n }\\n var loadedFonts = /* @__PURE__ */ new Set();\\n var failedFonts = /* @__PURE__ */ new Set();\\n async function loadFonts(fontFamilies) {\\n if (!fontFamilies || fontFamilies.length === 0) return;\\n const loadPromises = fontFamilies.map(async (fontFamily) => {\\n if (loadedFonts.has(fontFamily) || failedFonts.has(fontFamily)) return;\\n if (SYSTEM_FONTS.has(fontFamily)) {\\n loadedFonts.add(fontFamily);\\n return;\\n }\\n try {\\n const css = await fetchGoogleFontCss(fontFamily);\\n if (!css.trim()) {\\n failedFonts.add(fontFamily);\\n return;\\n }\\n const parsedFaces = parseFontFaces(css);\\n const loadedFaces = await Promise.all(\\n parsedFaces.map((parsed) => loadFontFaceFromUrl(fontFamily, parsed))\\n );\\n for (const face of loadedFaces) {\\n if (face) self.fonts.add(face);\\n }\\n if (self.fonts && self.fonts.ready) {\\n await Promise.race([\\n self.fonts.ready,\\n new Promise((resolve) => setTimeout(resolve, 250))\\n ]);\\n }\\n void FontAnalyzer.loadFont(fontFamily, 400).catch(() => {\\n });\\n void FontAnalyzer.loadFont(fontFamily, 700).catch(() => {\\n });\\n loadedFonts.add(fontFamily);\\n } catch {\\n failedFonts.add(fontFamily);\\n }\\n });\\n await Promise.all(loadPromises);\\n }\\n var readyMessage = {\\n type: \\\"ready\\\",\\n timestamp: Date.now()\\n };\\n self.postMessage(readyMessage);\\n self.onmessage = async (event) => {\\n const message = event.data;\\n try {\\n switch (message.type) {\\n case \\\"export\\\":\\n await handleExportRequest(message);\\n break;\\n case \\\"register-bitmap\\\":\\n handleRegisterBitmap(message);\\n break;\\n case \\\"clear-bitmap\\\":\\n handleClearBitmap(message);\\n break;\\n case \\\"clear-all-bitmaps\\\":\\n handleClearAllBitmaps();\\n break;\\n case \\\"init\\\":\\n break;\\n case \\\"terminate\\\":\\n handleClearAllBitmaps();\\n self.close();\\n break;\\n default:\\n console.warn(\\\"[Export Worker] Unknown message type:\\\", message);\\n }\\n } catch (error) {\\n console.error(\\\"[Export Worker] Error handling message:\\\", error);\\n if (\\\"requestId\\\" in message) {\\n const errorResponse = {\\n type: \\\"exportError\\\",\\n requestId: message.requestId,\\n artboardId: \\\"artboardData\\\" in message ? message.artboardData.id : \\\"unknown\\\",\\n error: error instanceof Error ? error.message : String(error),\\n stack: error instanceof Error ? error.stack : void 0\\n };\\n self.postMessage(errorResponse);\\n }\\n }\\n };\\n async function handleExportRequest(request) {\\n const startTime = performance.now();\\n const {\\n requestId,\\n artboardData,\\n elements = [],\\n fonts = [],\\n scale = 1,\\n format = \\\"png\\\",\\n quality = 0.95,\\n returnFormat = \\\"dataUrl\\\"\\n } = request;\\n try {\\n if (fonts && fonts.length > 0) {\\n await loadFonts(fonts);\\n }\\n const width = artboardData.width * scale;\\n const height = artboardData.height * scale;\\n const canvas = new OffscreenCanvas(width, height);\\n const ctx = canvas.getContext(\\\"2d\\\");\\n if (!ctx) {\\n throw new Error(\\\"Failed to get 2D context from OffscreenCanvas\\\");\\n }\\n if (scale !== 1) {\\n ctx.scale(scale, scale);\\n }\\n if (artboardData.exportBackground) {\\n ctx.fillStyle = artboardData.backgroundColor || \\\"#ffffff\\\";\\n ctx.fillRect(0, 0, artboardData.width, artboardData.height);\\n }\\n await preloadDistressTextures(elements, artboardData);\\n await preloadMaskImages(elements);\\n const renderStartTime = performance.now();\\n await renderElements(ctx, elements, artboardData);\\n if (artboardData.distressTexture?.enabled) {\\n applyArtboardDistressTexture(ctx, artboardData.distressTexture, {\\n x: 0,\\n y: 0,\\n width: artboardData.width,\\n height: artboardData.height\\n });\\n }\\n if (artboardData.imageMask?.enabled) {\\n await applyWorkerArtboardImageMask(ctx, artboardData.imageMask, {\\n width: artboardData.width,\\n height: artboardData.height\\n });\\n }\\n const renderEndTime = performance.now();\\n const renderTime = renderEndTime - renderStartTime;\\n const blobStartTime = performance.now();\\n const mimeType = format === \\\"png\\\" ? \\\"image/png\\\" : format === \\\"webp\\\" ? \\\"image/webp\\\" : \\\"image/jpeg\\\";\\n const blob = await canvas.convertToBlob({\\n type: mimeType,\\n quality: format !== \\\"png\\\" ? quality : void 0\\n });\\n const blobEndTime = performance.now();\\n void (blobEndTime - blobStartTime);\\n if (returnFormat === \\\"blob\\\") {\\n const arrayBuffer = await blob.arrayBuffer();\\n const endTime = performance.now();\\n const totalTime = endTime - startTime;\\n const response = {\\n type: \\\"exportBlobComplete\\\",\\n requestId,\\n artboardId: artboardData.id,\\n artboardName: artboardData.name,\\n blobData: arrayBuffer,\\n mimeType,\\n renderTime,\\n totalTime\\n };\\n self.postMessage(response, { transfer: [arrayBuffer] });\\n } else {\\n const dataUrl = await blobToDataURL(blob);\\n const endTime = performance.now();\\n const totalTime = endTime - startTime;\\n const response = {\\n type: \\\"exportComplete\\\",\\n requestId,\\n artboardId: artboardData.id,\\n artboardName: artboardData.name,\\n dataUrl,\\n renderTime,\\n totalTime\\n };\\n self.postMessage(response);\\n }\\n } catch (error) {\\n console.error(\\\"[Export Worker] Export failed:\\\", error);\\n const errorResponse = {\\n type: \\\"exportError\\\",\\n requestId,\\n artboardId: artboardData.id,\\n error: error instanceof Error ? error.message : String(error),\\n stack: error instanceof Error ? error.stack : void 0\\n };\\n self.postMessage(errorResponse);\\n }\\n }\\n function renderSingleElement(ctx, element, artboardX, artboardY) {\\n if (element.type === \\\"text\\\" || element.type === \\\"custom\\\" || element.type === \\\"circle\\\" || element.type === \\\"wave\\\" || element.type === \\\"arch\\\" || element.type === \\\"ascend\\\" || element.type === \\\"lean\\\" || element.type === \\\"flag\\\") {\\n const adjustedElement = {\\n ...element,\\n x: element.x - artboardX,\\n y: element.y - artboardY\\n };\\n renderTextElement(ctx, adjustedElement);\\n } else if (element.type === \\\"image\\\") {\\n const imageElement = element;\\n const bitmap = getCachedBitmap(imageElement.bitmapCacheKey);\\n if (bitmap) {\\n const cropped = resolveServerCrop(imageElement, bitmap);\\n const adjustedElement = {\\n ...cropped,\\n x: cropped.x - artboardX,\\n y: cropped.y - artboardY\\n };\\n renderImageElement(ctx, adjustedElement, bitmap);\\n } else {\\n console.error(\\n `[Export Worker] Missing ImageBitmap for image: ${element.id} (cacheKey: ${imageElement.bitmapCacheKey})`\\n );\\n }\\n } else if (element.type === \\\"shape\\\") {\\n const shapeElement = element;\\n const adjustedElement = {\\n ...shapeElement,\\n x: shapeElement.x - artboardX,\\n y: shapeElement.y - artboardY\\n };\\n renderShapeElement(ctx, adjustedElement);\\n } else if (element.type === \\\"group\\\") {\\n console.warn(`[Export Worker] Group rendering not yet implemented: ${element.id}`);\\n } else {\\n console.warn(`[Export Worker] Unknown element type: ${element.type}`);\\n }\\n }\\n function renderSingleElementWithEffects(ctx, element, artboardX, artboardY) {\\n const hasDistress = element.distressEffect?.enabled && element.distressEffect.style === \\\"custom\\\" && element.distressEffect.textureUrl;\\n const hasMasks = element.masks && element.masks.length > 0;\\n if (!hasDistress && !hasMasks) {\\n renderSingleElement(ctx, element, artboardX, artboardY);\\n return;\\n }\\n const adjustedConfig = {\\n ...element,\\n transformType: element.type || element.transformType,\\n x: element.x - artboardX,\\n y: element.y - artboardY\\n };\\n let elementBounds;\\n if (element._boundingBox) {\\n const bbox = element._boundingBox;\\n elementBounds = {\\n x: bbox.x - artboardX,\\n y: bbox.y - artboardY,\\n width: bbox.width,\\n height: bbox.height\\n };\\n } else {\\n const td = element.transformData || {};\\n let width;\\n let height;\\n if (element.type === \\\"shape\\\" || element.type === \\\"image\\\") {\\n width = td.width || 100;\\n height = td.height || 100;\\n } else {\\n const fontSize = element.fontSize || 24;\\n const measureCanvas = new OffscreenCanvas(1, 1);\\n const measureCtx = measureCanvas.getContext(\\\"2d\\\");\\n const bold = element.bold ? \\\"bold \\\" : \\\"\\\";\\n const italic = element.italic ? \\\"italic \\\" : \\\"\\\";\\n measureCtx.font = `${italic}${bold}${fontSize}px ${element.fontFamily || \\\"Arial\\\"}`;\\n const textMetrics = measureCtx.measureText(element.text || \\\"\\\");\\n width = td.width || textMetrics.width + fontSize;\\n const ascent = textMetrics.actualBoundingBoxAscent || fontSize * 0.8;\\n const descent = textMetrics.actualBoundingBoxDescent || fontSize * 0.2;\\n height = ascent + descent + fontSize * 0.5;\\n }\\n elementBounds = {\\n x: (adjustedConfig.x || 0) - width / 2,\\n y: (adjustedConfig.y || 0) - height / 2,\\n width,\\n height\\n };\\n }\\n const baseRenderFn = (renderCtx) => {\\n renderSingleElement(renderCtx, element, artboardX, artboardY);\\n };\\n if (hasMasks && hasDistress) {\\n renderWithMasks(ctx, adjustedConfig, (maskCtx) => {\\n applyElementDistressTexture(\\n maskCtx,\\n element.distressEffect,\\n elementBounds,\\n baseRenderFn\\n );\\n });\\n } else if (hasMasks) {\\n renderWithMasks(ctx, adjustedConfig, baseRenderFn);\\n } else if (hasDistress) {\\n applyElementDistressTexture(\\n ctx,\\n element.distressEffect,\\n elementBounds,\\n baseRenderFn\\n );\\n }\\n }\\n async function renderElements(ctx, elements, artboardData) {\\n const artboardX = artboardData.x || 0;\\n const artboardY = artboardData.y || 0;\\n const allElementConfigs = elements.map((el) => ({\\n ...el,\\n transformType: el.type || el.transformType,\\n x: el.x - artboardX,\\n y: el.y - artboardY\\n }));\\n const renderElementForCompositing = (renderCtx, config) => {\\n const originalElement = elements.find((el) => el.id === config.id);\\n if (originalElement) {\\n renderSingleElement(renderCtx, originalElement, artboardX, artboardY);\\n } else {\\n renderElement(renderCtx, config);\\n }\\n };\\n const knockoutRenderedIds = /* @__PURE__ */ new Set();\\n for (let i = 0; i < elements.length; i++) {\\n const element = elements[i];\\n if (element.blendMode === \\\"knockout\\\" || element.blendMode === \\\"clip\\\") {\\n const elementConfig = allElementConfigs[i];\\n const compositeOp = element.blendMode === \\\"knockout\\\" ? \\\"destination-out\\\" : \\\"destination-in\\\";\\n const scope = elementConfig.knockoutParts?.scope || \\\"group\\\";\\n if (scope === \\\"artboard\\\") {\\n for (let j = 0; j < i; j++) {\\n const id = allElementConfigs[j].id;\\n if (id) knockoutRenderedIds.add(id);\\n }\\n }\\n renderWithCompositing(\\n ctx,\\n elementConfig,\\n allElementConfigs,\\n renderElementForCompositing,\\n artboardData.exportBackground ? artboardData.backgroundColor : void 0,\\n { x: 0, y: 0, width: artboardData.width, height: artboardData.height },\\n compositeOp\\n );\\n knockoutRenderedIds.add(element.id);\\n }\\n }\\n for (const element of elements) {\\n if (!knockoutRenderedIds.has(element.id)) {\\n try {\\n renderSingleElementWithEffects(ctx, element, artboardX, artboardY);\\n } catch (error) {\\n console.error(`[Export Worker] Failed to render element ${element.id}:`, error);\\n }\\n }\\n }\\n }\\n async function preloadDistressTextures(elements, artboardData) {\\n const textureUrls = /* @__PURE__ */ new Set();\\n let hasBuiltinTextures = false;\\n if (artboardData.distressTexture?.enabled && artboardData.distressTexture.textureUrl) {\\n const url = artboardData.distressTexture.textureUrl;\\n if (url.startsWith(\\\"builtin:\\\")) {\\n hasBuiltinTextures = true;\\n } else {\\n textureUrls.add(url);\\n }\\n }\\n for (const element of elements) {\\n if (element.distressEffect?.enabled && element.distressEffect.style === \\\"custom\\\" && element.distressEffect.textureUrl) {\\n const url = element.distressEffect.textureUrl;\\n if (url.startsWith(\\\"builtin:\\\")) {\\n hasBuiltinTextures = true;\\n } else {\\n textureUrls.add(url);\\n }\\n }\\n }\\n if (hasBuiltinTextures) {\\n ensureBuiltinTexturesReady();\\n }\\n if (textureUrls.size > 0) {\\n await Promise.all(Array.from(textureUrls).map((url) => preloadTexture(url)));\\n }\\n }\\n async function preloadMaskImages(elements) {\\n const builtinUrls = /* @__PURE__ */ new Set();\\n const externalUrls = /* @__PURE__ */ new Set();\\n for (const element of elements) {\\n if (!element.masks || !Array.isArray(element.masks)) continue;\\n for (const mask of element.masks) {\\n if (mask.maskElement?.transformType === \\\"image\\\" && mask.maskElement.imageUrl) {\\n const url = mask.maskElement.imageUrl;\\n if (url.startsWith(\\\"builtin-mask:\\\")) {\\n builtinUrls.add(url);\\n } else {\\n externalUrls.add(url);\\n }\\n }\\n }\\n }\\n if (builtinUrls.size === 0 && externalUrls.size === 0) return;\\n clearMaskBitmaps();\\n for (const url of builtinUrls) {\\n const bitmap = generateMaskBitmap(url);\\n if (bitmap) {\\n registerMaskBitmap(url, bitmap);\\n } else {\\n console.error(`[Export Worker] Failed to generate builtin mask: ${url}`);\\n }\\n }\\n if (externalUrls.size > 0) {\\n await Promise.all(\\n Array.from(externalUrls).map(async (url) => {\\n try {\\n const response = await fetch(url);\\n const blob = await response.blob();\\n const bitmap = await createImageBitmap(blob);\\n registerMaskBitmap(url, bitmap);\\n } catch (error) {\\n console.error(`[Export Worker] Failed to preload mask image: ${url}`, error);\\n }\\n })\\n );\\n }\\n }\\n async function applyWorkerArtboardImageMask(ctx, config, artboard) {\\n if (!config.enabled || !config.imageUrl || config.opacity <= 0) return;\\n try {\\n const response = await fetch(config.imageUrl);\\n const blob = await response.blob();\\n const img = await createImageBitmap(blob);\\n const transform = ctx.getTransform();\\n const pixelWidth = transform.a * artboard.width;\\n const pixelHeight = transform.d * artboard.height;\\n const pixelX = transform.e;\\n const pixelY = transform.f;\\n const offWidth = Math.ceil(pixelWidth);\\n const offHeight = Math.ceil(pixelHeight);\\n if (offWidth <= 0 || offHeight <= 0) return;\\n const offCanvas = new OffscreenCanvas(offWidth, offHeight);\\n const offCtx = offCanvas.getContext(\\\"2d\\\");\\n offCtx.drawImage(\\n ctx.canvas,\\n pixelX,\\n pixelY,\\n pixelWidth,\\n pixelHeight,\\n 0,\\n 0,\\n offWidth,\\n offHeight\\n );\\n const compositeOp = config.inverted ? \\\"destination-out\\\" : \\\"destination-in\\\";\\n if (config.maskType === \\\"luma\\\") {\\n const lumaCanvas = new OffscreenCanvas(offWidth, offHeight);\\n const lumaCtx = lumaCanvas.getContext(\\\"2d\\\");\\n lumaCtx.drawImage(img, 0, 0, offWidth, offHeight);\\n const imageData = lumaCtx.getImageData(0, 0, offWidth, offHeight);\\n const data = imageData.data;\\n for (let i = 0; i < data.length; i += 4) {\\n const luma = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2];\\n data[i + 3] = config.inverted ? 255 - luma : luma;\\n }\\n lumaCtx.putImageData(imageData, 0, 0);\\n offCtx.globalCompositeOperation = \\\"destination-in\\\";\\n offCtx.globalAlpha = config.opacity / 100;\\n offCtx.drawImage(lumaCanvas, 0, 0);\\n } else {\\n offCtx.globalCompositeOperation = compositeOp;\\n offCtx.globalAlpha = config.opacity / 100;\\n offCtx.drawImage(img, 0, 0, offWidth, offHeight);\\n }\\n offCtx.globalCompositeOperation = \\\"source-over\\\";\\n offCtx.globalAlpha = 1;\\n ctx.save();\\n ctx.setTransform(1, 0, 0, 1, 0, 0);\\n ctx.clearRect(pixelX, pixelY, pixelWidth, pixelHeight);\\n ctx.drawImage(offCanvas, pixelX, pixelY);\\n ctx.restore();\\n img.close();\\n } catch (error) {\\n console.error(\\\"[Export Worker] Failed to apply artboard image mask:\\\", error);\\n }\\n }\\n function blobToDataURL(blob) {\\n return new Promise((resolve, reject) => {\\n const reader = new FileReader();\\n reader.onloadend = () => {\\n if (typeof reader.result === \\\"string\\\") {\\n resolve(reader.result);\\n } else {\\n reject(new Error(\\\"FileReader result is not a string\\\"));\\n }\\n };\\n reader.onerror = () => {\\n reject(new Error(\\\"Failed to read blob as data URL\\\"));\\n };\\n reader.readAsDataURL(blob);\\n });\\n }\\n self.onerror = (error) => {\\n console.error(\\\"[Export Worker] Uncaught error:\\\", error);\\n };\\n self.onunhandledrejection = (event) => {\\n console.error(\\\"[Export Worker] Unhandled promise rejection:\\\", event.reason);\\n };\\n})();\\n\";\n","/**\n * Worker Export Manager - Non-blocking artboard export via Web Workers.\n *\n * Manages the lifecycle of a dedicated Web Worker that uses `OffscreenCanvas`\n * to render artboard exports without blocking the main thread. Falls back to\n * main-thread rendering when `OffscreenCanvas` is not available.\n *\n * Provides a Promise-based API for requesting exports (as data URLs or Blobs),\n * queues concurrent requests, manages bitmap caching in the worker, and\n * automatically recovers from worker crashes.\n *\n * For most use cases, use `ExportManager` (which delegates to this internally)\n * or the `useExport` hook. Access `WorkerExportManager` directly only when you\n * need fine-grained control over the worker lifecycle or bitmap cache.\n *\n * @example\n * ```ts\n * import { getSharedWorkerExportManager } from '@snowcone-app/canvas';\n *\n * const manager = getSharedWorkerExportManager();\n * const result = await manager.exportToDataUrl(artboard, elements, config);\n * console.log(result.dataUrl, result.renderTime);\n * ```\n *\n * @module\n */\n\nimport type {\n WorkerResponse,\n ExportRequestMessage,\n ExportSuccessResponse,\n ExportBlobSuccessResponse,\n ExportErrorResponse,\n ExportConfig,\n RegisterBitmapMessage,\n ClearBitmapMessage,\n ClearAllBitmapsMessage,\n} from '../workers/export-protocol';\nimport type { ArtboardElement } from '../core/ArtboardElement';\nimport type { BaseElement } from '../core/BaseElement';\nimport {\n serializeForWorkerExport,\n clearRegisteredBitmapKeys,\n unregisterElementBitmaps,\n registerWorkerCacheCallbacks,\n unregisterWorkerCacheCallbacks,\n type NewBitmapRegistration,\n} from '../rendering/element-serializer.js';\n// Import bundled worker code as a string. The sibling\n// `export-worker.bundle.string.js` module is auto-generated alongside\n// `export-worker.bundle.js` by `scripts/bundle-worker.js` and exports the\n// bundle source as a plain JS string constant. Going through a normal ESM\n// `export default` (instead of Vite's `?raw` query) keeps the same code\n// path working across Vite, Webpack, and Turbopack — no special asset rule\n// required, no risk of an HMR shim injecting `import.meta` into the blob.\nimport workerCode from '../workers/export-worker.bundle.string.js';\nimport { createLogger } from './logger.js';\n\nconst log = createLogger('WorkerExport');\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface PendingExportRequest {\n requestId: string;\n resolve: (response: ExportSuccessResponse) => void;\n reject: (error: Error) => void;\n startTime: number;\n returnFormat: 'dataUrl';\n}\n\ninterface PendingBlobExportRequest {\n requestId: string;\n resolve: (response: ExportBlobSuccessResponse) => void;\n reject: (error: Error) => void;\n startTime: number;\n returnFormat: 'blob';\n}\n\ntype AnyPendingExportRequest = PendingExportRequest | PendingBlobExportRequest;\n\ninterface QueuedExportRequest {\n artboard: ArtboardElement;\n elements: BaseElement[];\n config: ExportConfig;\n resolve: (result: WorkerExportResult) => void;\n reject: (error: Error) => void;\n}\n\ninterface QueuedBlobExportRequest {\n artboard: ArtboardElement;\n elements: BaseElement[];\n config: ExportConfig;\n resolve: (result: WorkerBlobExportResult) => void;\n reject: (error: Error) => void;\n}\n\n/** Result of a worker export operation returning a data URL string. */\nexport interface WorkerExportResult {\n /** Base64-encoded data URL of the exported image. */\n dataUrl: string;\n artboardId: string;\n artboardName: string;\n /** Time spent rendering in the worker (ms). */\n renderTime: number;\n /** Total round-trip time including serialization and messaging (ms). */\n totalTime: number;\n /** Time the main thread was blocked during the export (should be near 0ms). */\n mainThreadBlockTime: number;\n}\n\n/** Result of a worker export operation returning a Blob. More efficient for API uploads. */\nexport interface WorkerBlobExportResult {\n /** Binary Blob of the exported image. */\n blob: Blob;\n artboardId: string;\n artboardName: string;\n /** Time spent rendering in the worker (ms). */\n renderTime: number;\n /** Total round-trip time including serialization and messaging (ms). */\n totalTime: number;\n /** Time the main thread was blocked during the export (should be near 0ms). */\n mainThreadBlockTime: number;\n}\n\nexport interface ProgressEvent {\n requestId: string;\n progress: number; // 0-1\n message: string;\n}\n\nexport type ProgressListener = (event: ProgressEvent) => void;\n\n// ============================================================================\n// Worker Export Manager\n// ============================================================================\n\n/**\n * Manages a Web Worker for non-blocking artboard export using OffscreenCanvas.\n *\n * Features:\n * - Promise-based export API (data URL and Blob)\n * - Request queuing for concurrent export operations\n * - Bitmap caching in the worker (reduces main-thread memory by ~50%)\n * - Automatic crash recovery with fallback to main-thread rendering\n * - Idle timeout for worker cleanup (30s default)\n * - Progress reporting via listeners\n */\nexport class WorkerExportManager {\n private worker: Worker | null = null;\n private workerBlobUrl: string | null = null; // Track worker blob URL for cleanup\n private pendingRequests: Map<string, AnyPendingExportRequest> = new Map();\n private requestQueue: QueuedExportRequest[] = [];\n private blobRequestQueue: QueuedBlobExportRequest[] = [];\n private isProcessingQueue = false;\n private isReady = false;\n private readyPromise: Promise<void> | null = null;\n private requestIdCounter = 0;\n\n // Worker crash tracking\n private workerCrashCount = 0;\n private readonly MAX_CRASHES_BEFORE_FALLBACK = 3;\n private lastCrashTime = 0;\n private readonly CRASH_RESET_TIMEOUT = 60000; // Reset crash count after 1 minute\n\n // Progress reporting\n private progressListeners: Set<ProgressListener> = new Set();\n\n // Idle timeout for worker cleanup\n private idleTimeout: number | null = null;\n private readonly IDLE_TIMEOUT_MS = 30000; // 30 seconds\n\n /**\n * Add progress listener\n */\n onProgress(listener: ProgressListener): () => void {\n this.progressListeners.add(listener);\n // Return unsubscribe function\n return () => {\n this.progressListeners.delete(listener);\n };\n }\n\n /**\n * Remove progress listener\n */\n offProgress(listener: ProgressListener): void {\n this.progressListeners.delete(listener);\n }\n\n /**\n * Emit progress event to all listeners\n */\n private emitProgress(event: ProgressEvent): void {\n for (const listener of this.progressListeners) {\n try {\n listener(event);\n } catch (error) {\n log.error('Error in progress listener:', error);\n }\n }\n }\n\n /**\n * Reset idle timer\n */\n private resetIdleTimer(): void {\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout);\n }\n\n this.idleTimeout = window.setTimeout(() => {\n this.terminate();\n }, this.IDLE_TIMEOUT_MS) as unknown as number;\n }\n\n // ============================================================================\n // Worker Bitmap Cache Management\n // ============================================================================\n\n /**\n * Register bitmaps with the worker's cache.\n * This transfers the bitmaps to the worker (zero-copy) where they are cached.\n */\n private registerBitmapsWithWorker(bitmaps: NewBitmapRegistration[]): void {\n if (!this.worker || bitmaps.length === 0) {\n return;\n }\n\n for (const { cacheKey, bitmap } of bitmaps) {\n const message: RegisterBitmapMessage = {\n type: 'register-bitmap',\n cacheKey,\n bitmap,\n };\n\n // Transfer the bitmap (zero-copy!)\n this.worker.postMessage(message, [bitmap]);\n }\n }\n\n /**\n * Clear all bitmaps from the worker's cache.\n * Also clears the main thread's registration tracking.\n * Call this when exiting editor mode to free memory.\n */\n clearWorkerBitmapCache(): void {\n // Clear main thread tracking\n clearRegisteredBitmapKeys();\n\n // Tell worker to clear its cache\n if (this.worker && this.isReady) {\n const message: ClearAllBitmapsMessage = {\n type: 'clear-all-bitmaps',\n };\n this.worker.postMessage(message);\n }\n }\n\n /**\n * Clear a specific element's bitmaps from the worker's cache.\n * Call this when an element is removed or its image source changes.\n */\n clearWorkerBitmap(elementId: string): void {\n // Clear main thread tracking\n unregisterElementBitmaps(elementId);\n\n // Tell worker to clear this element's bitmaps\n if (this.worker && this.isReady) {\n const message: ClearBitmapMessage = {\n type: 'clear-bitmap',\n elementId,\n };\n this.worker.postMessage(message);\n }\n }\n\n\n /**\n * Check if browser supports OffscreenCanvas and Web Workers\n */\n static supportsWorkerExport(): boolean {\n try {\n // Check for OffscreenCanvas support\n if (typeof OffscreenCanvas === 'undefined') {\n log.warn('OffscreenCanvas not supported');\n return false;\n }\n\n // Check for Worker support\n if (typeof Worker === 'undefined') {\n log.warn('Web Workers not supported');\n return false;\n }\n\n // Check if OffscreenCanvas has getContext method\n const canvas = new OffscreenCanvas(1, 1);\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n log.warn('OffscreenCanvas 2D context not supported');\n return false;\n }\n\n return true;\n } catch (error) {\n log.warn('Feature detection failed:', error);\n return false;\n }\n }\n\n /**\n * Initialize the worker\n */\n async initialize(): Promise<void> {\n if (this.worker) {\n return this.readyPromise || Promise.resolve();\n }\n\n if (!WorkerExportManager.supportsWorkerExport()) {\n throw new Error('Browser does not support OffscreenCanvas or Web Workers');\n }\n\n\n // Create promise that resolves when worker is ready\n this.readyPromise = new Promise((resolve, reject) => {\n try {\n // Try multiple strategies to load the worker\n // Strategy 1: Native URL approach (works in Vite dev mode)\n // Strategy 2: Blob URL from inlined data (works in bundled builds)\n let workerUrl: string | URL;\n\n try {\n // SOLUTION: Use pre-bundled worker code loaded as raw text at build time\n // This avoids Vite/webpack URL handling issues entirely\n // The worker is bundled separately via esbuild as a self-contained IIFE\n\n // Create a Blob from the worker code\n const blob = new Blob([workerCode], { type: 'application/javascript' });\n workerUrl = URL.createObjectURL(blob);\n\n // Store blob URL for cleanup on terminate()\n // This prevents memory leaks on iOS Safari which has stricter limits\n this.workerBlobUrl = workerUrl;\n\n } catch (urlError) {\n log.error('Failed to create worker blob:', urlError);\n reject(new Error(`Worker creation failed: ${urlError instanceof Error ? urlError.message : String(urlError)}`));\n return;\n }\n\n // CRITICAL: Use classic worker type, not module\n // Module workers with inlined imports don't work in Next.js\n this.worker = new Worker(workerUrl, { type: 'classic' });\n\n // Set up message handler\n this.worker.onmessage = (event: MessageEvent<WorkerResponse>) => {\n this.handleWorkerMessage(event.data);\n };\n\n // Set up error handler\n this.worker.onerror = (error) => {\n log.error('Worker error:', error);\n this.handleWorkerError(error);\n };\n\n // Wait for ready message with timeout. 15s rather than 5s because\n // iOS Safari on real phones is materially slower to compile + spawn\n // a ~1MB classic Worker than desktop Chrome — 5s was borderline and\n // a couple of recent worker-bundle additions (per-weight Google\n // Fonts loader, builtin texture preset generators) pushed it over\n // on iPhones. Chrome desktop resolves in <100ms regardless, so the\n // longer ceiling only ever fires when the worker is actually wedged.\n const timeout = setTimeout(() => {\n reject(new Error('Worker initialization timeout'));\n }, 15000);\n\n // Listen for ready message\n const readyHandler = (event: MessageEvent<WorkerResponse>) => {\n if (event.data.type === 'ready') {\n clearTimeout(timeout);\n this.isReady = true;\n\n // Register callbacks so legacy API (clearImageBitmapCache) can clear worker cache\n registerWorkerCacheCallbacks(\n () => this.clearWorkerBitmapCache(),\n (elementId) => this.clearWorkerBitmap(elementId)\n );\n\n resolve();\n }\n };\n\n this.worker.addEventListener('message', readyHandler, { once: true });\n } catch (error) {\n log.error('Failed to create worker:', error);\n reject(error);\n }\n });\n\n return this.readyPromise;\n }\n\n /**\n * Restart worker after crash\n */\n private async restartWorker(): Promise<void> {\n const now = Date.now();\n\n // Reset crash count if enough time has passed since last crash\n if (now - this.lastCrashTime > this.CRASH_RESET_TIMEOUT) {\n this.workerCrashCount = 0;\n }\n\n this.workerCrashCount++;\n this.lastCrashTime = now;\n\n log.warn(`Worker crashed (${this.workerCrashCount}/${this.MAX_CRASHES_BEFORE_FALLBACK})`);\n\n if (this.workerCrashCount >= this.MAX_CRASHES_BEFORE_FALLBACK) {\n log.error('Worker crashed too many times, giving up');\n throw new Error('Worker has crashed too many times. Please refresh the page or use main thread export.');\n }\n\n // Terminate old worker and clean up resources\n if (this.worker) {\n this.worker.terminate();\n this.worker = null;\n this.isReady = false;\n this.readyPromise = null;\n\n // Revoke old worker blob URL to free memory\n if (this.workerBlobUrl) {\n URL.revokeObjectURL(this.workerBlobUrl);\n this.workerBlobUrl = null;\n }\n }\n\n // Wait a bit before restarting (exponential backoff)\n const backoffDelay = Math.min(1000 * Math.pow(2, this.workerCrashCount - 1), 5000);\n await new Promise((resolve) => setTimeout(resolve, backoffDelay));\n\n // Restart worker\n await this.initialize();\n }\n\n /**\n * Export artboard to data URL using worker\n * Uses request queue for concurrent exports\n */\n async exportArtboardToDataURL(\n artboard: ArtboardElement,\n elements: BaseElement[],\n config: ExportConfig = {}\n ): Promise<WorkerExportResult> {\n // Reset idle timer\n this.resetIdleTimer();\n\n // Add to queue and return promise\n return new Promise<WorkerExportResult>((resolve, reject) => {\n this.requestQueue.push({\n artboard,\n elements,\n config: { ...config, returnFormat: 'dataUrl' },\n resolve,\n reject,\n });\n\n // Start processing queue if not already processing\n this.processQueue();\n });\n }\n\n /**\n * Export artboard to Blob using worker\n * Returns a Blob directly - more efficient for API uploads\n * Uses request queue for concurrent exports\n */\n async exportArtboardToBlob(\n artboard: ArtboardElement,\n elements: BaseElement[],\n config: ExportConfig = {}\n ): Promise<WorkerBlobExportResult> {\n // Reset idle timer\n this.resetIdleTimer();\n\n // Add to blob queue and return promise\n return new Promise<WorkerBlobExportResult>((resolve, reject) => {\n this.blobRequestQueue.push({\n artboard,\n elements,\n config: { ...config, returnFormat: 'blob' },\n resolve,\n reject,\n });\n\n // Start processing queue if not already processing\n this.processBlobQueue();\n });\n }\n\n /**\n * Process the request queue\n */\n private async processQueue(): Promise<void> {\n // If already processing or queue is empty, return\n if (this.isProcessingQueue || this.requestQueue.length === 0) {\n return;\n }\n\n this.isProcessingQueue = true;\n\n while (this.requestQueue.length > 0) {\n const request = this.requestQueue.shift()!;\n\n try {\n const result = await this.executeExportRequest(request);\n request.resolve(result);\n } catch (error) {\n request.reject(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n this.isProcessingQueue = false;\n }\n\n /**\n * Execute a single export request\n */\n private async executeExportRequest(request: QueuedExportRequest): Promise<WorkerExportResult> {\n const { artboard, elements, config } = request;\n\n // Ensure worker is initialized\n if (!this.worker || !this.isReady) {\n await this.initialize();\n }\n\n if (!this.worker) {\n throw new Error('Worker is not initialized');\n }\n\n // Generate unique request ID\n const requestId = `export-${++this.requestIdCounter}-${Date.now()}`;\n const mainThreadStartTime = performance.now();\n\n // Serialize artboard and elements\n // This returns new bitmaps that need to be registered with the worker\n const { data: serializedData, newBitmaps } = await serializeForWorkerExport(artboard, elements);\n\n // Register any new bitmaps with the worker BEFORE sending export request\n // The worker will cache these and look them up by bitmapCacheKey during export\n if (newBitmaps.length > 0) {\n this.registerBitmapsWithWorker(newBitmaps);\n }\n\n // Create export request message\n // Note: Images are now referenced by bitmapCacheKey, not transferred inline\n const exportRequest: ExportRequestMessage = {\n type: 'export',\n requestId,\n artboardData: serializedData.artboard,\n elements: serializedData.elements,\n fonts: serializedData.fonts,\n scale: config.scale || 1,\n format: config.format || 'png',\n quality: config.quality || 0.95,\n };\n\n // Create promise for this request\n const resultPromise = new Promise<ExportSuccessResponse>((resolve, reject) => {\n this.pendingRequests.set(requestId, {\n requestId,\n resolve,\n reject,\n startTime: mainThreadStartTime,\n returnFormat: 'dataUrl',\n });\n\n // Set timeout for request (30 seconds)\n setTimeout(() => {\n if (this.pendingRequests.has(requestId)) {\n this.pendingRequests.delete(requestId);\n reject(new Error('Export request timeout'));\n }\n }, 30000);\n });\n\n // Send export request to worker (no transferables needed - just JSON)\n this.worker.postMessage(exportRequest);\n\n // Wait for response\n const response = await resultPromise;\n const mainThreadEndTime = performance.now();\n\n // Calculate main thread blocking time (should be minimal, just serialization)\n const mainThreadBlockTime = mainThreadEndTime - mainThreadStartTime;\n\n\n return {\n dataUrl: response.dataUrl,\n artboardId: response.artboardId,\n artboardName: response.artboardName,\n renderTime: response.renderTime,\n totalTime: response.totalTime,\n mainThreadBlockTime,\n };\n }\n\n /**\n * Process the blob request queue\n */\n private async processBlobQueue(): Promise<void> {\n // If already processing or queue is empty, return\n if (this.isProcessingQueue || this.blobRequestQueue.length === 0) {\n return;\n }\n\n this.isProcessingQueue = true;\n\n while (this.blobRequestQueue.length > 0) {\n const request = this.blobRequestQueue.shift()!;\n\n try {\n const result = await this.executeBlobExportRequest(request);\n request.resolve(result);\n } catch (error) {\n request.reject(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n this.isProcessingQueue = false;\n }\n\n /**\n * Execute a single blob export request\n */\n private async executeBlobExportRequest(request: QueuedBlobExportRequest): Promise<WorkerBlobExportResult> {\n const { artboard, elements, config } = request;\n\n // Ensure worker is initialized\n if (!this.worker || !this.isReady) {\n await this.initialize();\n }\n\n if (!this.worker) {\n throw new Error('Worker is not initialized');\n }\n\n // Generate unique request ID\n const requestId = `export-blob-${++this.requestIdCounter}-${Date.now()}`;\n const mainThreadStartTime = performance.now();\n\n // Serialize artboard and elements\n // This returns new bitmaps that need to be registered with the worker\n const { data: serializedData, newBitmaps } = await serializeForWorkerExport(artboard, elements);\n\n // Register any new bitmaps with the worker BEFORE sending export request\n // The worker will cache these and look them up by bitmapCacheKey during export\n if (newBitmaps.length > 0) {\n this.registerBitmapsWithWorker(newBitmaps);\n }\n\n // Create export request message with blob return format\n // Note: Images are now referenced by bitmapCacheKey, not transferred inline\n const exportRequest: ExportRequestMessage = {\n type: 'export',\n requestId,\n artboardData: serializedData.artboard,\n elements: serializedData.elements,\n fonts: serializedData.fonts,\n scale: config.scale || 1,\n format: config.format || 'png',\n quality: config.quality || 0.95,\n returnFormat: 'blob',\n };\n\n // Create promise for this request\n const resultPromise = new Promise<ExportBlobSuccessResponse>((resolve, reject) => {\n this.pendingRequests.set(requestId, {\n requestId,\n resolve,\n reject,\n startTime: mainThreadStartTime,\n returnFormat: 'blob',\n });\n\n // Set timeout for request (30 seconds)\n setTimeout(() => {\n if (this.pendingRequests.has(requestId)) {\n this.pendingRequests.delete(requestId);\n reject(new Error('Export request timeout'));\n }\n }, 30000);\n });\n\n // Send export request to worker (no transferables needed - just JSON)\n this.worker.postMessage(exportRequest);\n\n // Wait for response\n const response = await resultPromise;\n const mainThreadEndTime = performance.now();\n\n // Calculate main thread blocking time (should be minimal, just serialization)\n const mainThreadBlockTime = mainThreadEndTime - mainThreadStartTime;\n\n // Convert ArrayBuffer back to Blob\n const blob = new Blob([response.blobData], { type: response.mimeType });\n\n\n return {\n blob,\n artboardId: response.artboardId,\n artboardName: response.artboardName,\n renderTime: response.renderTime,\n totalTime: response.totalTime,\n mainThreadBlockTime,\n };\n }\n\n /**\n * Handle messages from worker\n */\n private handleWorkerMessage(message: WorkerResponse): void {\n switch (message.type) {\n case 'exportComplete':\n this.handleExportComplete(message);\n break;\n\n case 'exportBlobComplete':\n this.handleBlobExportComplete(message);\n break;\n\n case 'exportError':\n this.handleExportError(message);\n break;\n\n case 'exportProgress':\n // Emit progress event to listeners\n this.emitProgress({\n requestId: message.requestId,\n progress: message.progress,\n message: message.message,\n });\n break;\n\n case 'ready':\n // Handled in initialize()\n break;\n\n default:\n log.warn('Unknown message type:', message);\n }\n }\n\n /**\n * Handle successful export completion (dataUrl)\n */\n private handleExportComplete(response: ExportSuccessResponse): void {\n const pending = this.pendingRequests.get(response.requestId);\n if (pending && pending.returnFormat === 'dataUrl') {\n pending.resolve(response);\n this.pendingRequests.delete(response.requestId);\n } else if (pending) {\n log.warn('Received dataUrl response for blob request:', response.requestId);\n pending.reject(new Error('Received dataUrl response when expecting blob'));\n this.pendingRequests.delete(response.requestId);\n } else {\n log.warn('Received response for unknown request:', response.requestId);\n }\n }\n\n /**\n * Handle successful blob export completion\n */\n private handleBlobExportComplete(response: ExportBlobSuccessResponse): void {\n const pending = this.pendingRequests.get(response.requestId);\n if (pending && pending.returnFormat === 'blob') {\n pending.resolve(response);\n this.pendingRequests.delete(response.requestId);\n } else if (pending) {\n log.warn('Received blob response for dataUrl request:', response.requestId);\n pending.reject(new Error('Received blob response when expecting dataUrl'));\n this.pendingRequests.delete(response.requestId);\n } else {\n log.warn('Received blob response for unknown request:', response.requestId);\n }\n }\n\n /**\n * Handle export error\n */\n private handleExportError(response: ExportErrorResponse): void {\n const pending = this.pendingRequests.get(response.requestId);\n if (pending) {\n const error = new Error(response.error);\n if (response.stack) {\n error.stack = response.stack;\n }\n pending.reject(error);\n this.pendingRequests.delete(response.requestId);\n } else {\n log.warn('Received error for unknown request:', response.requestId);\n }\n }\n\n /**\n * Handle worker errors\n */\n private async handleWorkerError(error: ErrorEvent): Promise<void> {\n log.error('Worker error:', error);\n\n // Reject all pending requests\n const failedRequests = Array.from(this.pendingRequests.values());\n for (const [requestId, _pending] of this.pendingRequests.entries()) {\n this.pendingRequests.delete(requestId);\n }\n\n // Reset worker state\n this.isReady = false;\n\n // Attempt to restart worker\n try {\n await this.restartWorker();\n\n // If restart succeeded, we can let queued requests retry automatically\n } catch (restartError) {\n log.error('Failed to restart worker:', restartError);\n\n // Reject failed requests since we can't recover\n for (const pending of failedRequests) {\n pending.reject(new Error(`Worker crashed and could not be restarted: ${error.message}`));\n }\n\n // Also reject all queued requests\n while (this.requestQueue.length > 0) {\n const request = this.requestQueue.shift()!;\n request.reject(new Error('Worker crashed and could not be restarted'));\n }\n }\n }\n\n /**\n * Terminate the worker\n */\n terminate(): void {\n // Clear idle timeout\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout);\n this.idleTimeout = null;\n }\n\n if (this.worker) {\n\n // Reject all pending requests\n for (const [requestId, pending] of this.pendingRequests.entries()) {\n pending.reject(new Error('Worker terminated'));\n this.pendingRequests.delete(requestId);\n }\n\n // Reject all queued requests\n while (this.requestQueue.length > 0) {\n const request = this.requestQueue.shift()!;\n request.reject(new Error('Worker terminated'));\n }\n\n this.worker.terminate();\n this.worker = null;\n this.isReady = false;\n this.readyPromise = null;\n\n // Clear bitmap registration tracking\n // The worker's cache is gone when it terminates, so our tracking should reset too\n clearRegisteredBitmapKeys();\n\n // Unregister callbacks so legacy API doesn't try to talk to dead worker\n unregisterWorkerCacheCallbacks();\n\n // Revoke worker blob URL to free memory\n // This is especially important on iOS Safari which has stricter memory limits\n if (this.workerBlobUrl) {\n URL.revokeObjectURL(this.workerBlobUrl);\n this.workerBlobUrl = null;\n }\n }\n }\n\n /**\n * Get worker status\n */\n getStatus(): {\n isReady: boolean;\n pendingRequests: number;\n queuedRequests: number;\n crashCount: number;\n } {\n return {\n isReady: this.isReady,\n pendingRequests: this.pendingRequests.size,\n queuedRequests: this.requestQueue.length,\n crashCount: this.workerCrashCount,\n };\n }\n}\n\n// ============================================================================\n// Singleton Instance (Optional)\n// ============================================================================\n\nlet sharedInstance: WorkerExportManager | null = null;\n\n/**\n * Get the shared singleton `WorkerExportManager` instance.\n *\n * Creates the instance on first call. The shared instance is used internally\n * by `ExportManager` and is the recommended way to access the worker for\n * advanced cache control (e.g., `getSharedWorkerExportManager().clearWorkerBitmapCache()`).\n *\n * @returns The shared WorkerExportManager instance\n */\nexport function getSharedWorkerExportManager(): WorkerExportManager {\n if (!sharedInstance) {\n sharedInstance = new WorkerExportManager();\n }\n return sharedInstance;\n}\n\n/**\n * Terminate the shared `WorkerExportManager` instance and release its Web Worker.\n *\n * Call this during app cleanup to free worker resources. The next call to\n * `getSharedWorkerExportManager()` will create a fresh instance.\n */\nexport function terminateSharedWorkerExportManager(): void {\n if (sharedInstance) {\n sharedInstance.terminate();\n sharedInstance = null;\n }\n}\n","/**\n * ExportManager - High-level API for workspace and artboard export.\n *\n * Provides static methods for:\n * - **JSON export/import** of the entire workspace (artboards + elements)\n * - **Image export** of individual artboards as data URL, Blob, or downloadable file\n * - **Worker-accelerated export** via OffscreenCanvas (non-blocking, auto-fallback)\n *\n * For React components, prefer the `useExport` hook which wraps this class\n * with React state management. Use `ExportManager` directly in non-React code\n * or for advanced export workflows.\n *\n * @example\n * ```ts\n * import { ExportManager } from '@snowcone-app/canvas';\n *\n * // Export artboard as data URL\n * const dataUrl = await ExportManager.exportArtboardToDataURL(\n * artboard, elements, canvasEl, { scale: 3, format: 'png' }\n * );\n *\n * // Export entire workspace as JSON\n * ExportManager.exportWorkspace(artboardManager, elements);\n * ```\n *\n * @module\n */\n\n// Element painting goes through the paint registry (P1 element/renderer\n// split); installing the painters here guarantees they are registered before\n// any element.render() this module drives. Explicit call, not a bare\n// side-effect import — see the note in core/CanvasRenderer.ts (bundlers prune\n// bare imports under the package `sideEffects` allowlist).\nimport { installElementPainters } from '../rendering/element-painters.js';\ninstallElementPainters();\nimport type { ArtboardElement } from '../core/ArtboardElement.js';\nimport type { TextElement } from '../core/TextElement.js';\nimport type { ImageElement } from '../core/ImageElement.js';\nimport type { GroupElement } from '../core/GroupElement.js';\nimport type { ShapeElement } from '../core/ShapeElement.js';\nimport type { PathElement } from '../core/PathElement.js';\nimport type { ArtboardManager } from '../core/ArtboardManager.js';\nimport type { AnyElementConfig } from '../types/index.js';\n\n/** Union of all element types supported by export */\ntype ExportElement = TextElement | ImageElement | GroupElement | ShapeElement | PathElement;\nimport { WorkerExportManager } from './WorkerExportManager.js';\nimport { renderWithCompositing } from '../rendering/CompositingRenderer.js';\nimport type { CompositeOp } from '../rendering/CompositingRenderer.js';\nimport { applyArtboardDistressTexture, applyElementDistressTexture } from '../rendering/DistressTextureRenderer.js';\nimport { applyArtboardImageMask, renderWithMasks } from '../rendering/MaskRenderer.js';\nimport { TextureManager } from './TextureManager.js';\nimport { createLogger } from './logger.js';\n\nconst log = createLogger('Export');\n\n/**\n * Recursively collect every fontFamily referenced by an element (and its\n * group children / mask children / rich-text spans). Used by the main-thread\n * export fallback to pre-load fonts before rendering — without this, a\n * freshly-created detached `<canvas>` on iOS Safari renders with the serif\n * fallback even when the on-screen canvas paints the same font correctly.\n */\nfunction collectElementFontFamilies(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n el: any,\n out: Set<string>\n): void {\n if (!el || typeof el !== 'object') return;\n if (typeof el.fontFamily === 'string' && el.fontFamily.trim()) {\n out.add(el.fontFamily);\n }\n // Rich-text spans may carry per-character font families\n if (el.richText && Array.isArray(el.richText.spans)) {\n for (const span of el.richText.spans) {\n if (span?.style?.fontFamily && typeof span.style.fontFamily === 'string') {\n out.add(span.style.fontFamily);\n }\n }\n }\n // Group children\n if (Array.isArray(el.children)) {\n for (const child of el.children) collectElementFontFamilies(child, out);\n }\n // Mask elements\n if (Array.isArray(el.masks)) {\n for (const m of el.masks) {\n if (m?.maskElement) collectElementFontFamilies(m.maskElement, out);\n }\n }\n}\n\n/**\n * Pre-load every font used by `elements` and wait for activation.\n *\n * iOS Safari quirk: a `<canvas>` created via `document.createElement('canvas')`\n * (used by `mainThreadExportToBlob`) is *detached* — never inserted into the\n * DOM. Safari activates fonts lazily on first DOM-attached use, so the\n * detached canvas's first `fillText(\"...\", ...)` paints with the fallback\n * even when the on-screen canvas is rendering the same family correctly.\n *\n * Calling `document.fonts.load(\"size family\")` for each (size, family) pair\n * forces Safari to activate the fontface for that specifier, then awaiting\n * `document.fonts.ready` flushes any in-flight activation work. Safe on every\n * other browser since `load()` resolves immediately for already-loaded fonts.\n */\nasync function ensureFontsLoadedForExport(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n elements: any[]\n): Promise<void> {\n if (typeof document === 'undefined' || !document.fonts) return;\n const families = new Set<string>();\n for (const el of elements) collectElementFontFamilies(el, families);\n if (families.size === 0) return;\n const loadPromises: Promise<unknown>[] = [];\n for (const family of families) {\n // 16px is enough — once the font file is in the FontFaceSet it serves all sizes.\n loadPromises.push(document.fonts.load(`16px \"${family}\"`).catch(() => undefined));\n }\n await Promise.all(loadPromises);\n if (document.fonts.ready) await document.fonts.ready;\n}\n\n/** Serialized workspace document for JSON import/export. */\nexport interface CanvasDocument {\n metadata: {\n version: string;\n timestamp: string;\n appVersion?: string;\n };\n artboards: Array<{\n id: string;\n name: string;\n x: number;\n y: number;\n width: number;\n height: number;\n backgroundColor: string;\n elements: AnyElementConfig[];\n }>;\n activeArtboardId: string | null;\n}\n\n/** Options for image export operations. */\nexport interface ExportImageOptions {\n /** Image format. Default: `'png'`. */\n format?: 'png' | 'jpg' | 'jpeg' | 'webp';\n /** Compression quality for JPEG/WebP (0-1). Ignored for PNG. Default: 0.92. */\n quality?: number;\n /** Resolution multiplier (1x, 2x, 3x). Default: 3. */\n scale?: number;\n /** Export with transparent background. Should be `true` for print-on-demand designs. Default: true. */\n transparentBackground?: boolean;\n /** Background color when `transparentBackground` is false. */\n backgroundColor?: string;\n /** Suggested filename for downloads. */\n filename?: string;\n /** Force main-thread rendering (skip Web Worker). Useful for debugging. */\n forceMainThread?: boolean;\n // CRITICAL: Preview backgrounds (artboard.previewBackgroundColor) are NEVER exported\n // This is handled automatically - only artboard.backgroundColor is used\n}\n\n/**\n * Static utility class for exporting workspace data and artboard images.\n *\n * All methods are static -- there is no need to instantiate this class.\n * Internally delegates to {@link WorkerExportManager} for non-blocking\n * image exports when the browser supports `OffscreenCanvas`.\n */\nexport class ExportManager {\n private static readonly CURRENT_VERSION = '2.0.0'; // Version 2 includes artboards\n\n // Worker export manager (lazily initialized)\n private static workerManager: WorkerExportManager | null = null;\n private static workerInitPromise: Promise<void> | null = null;\n\n /**\n * Check if worker export is supported in this browser\n */\n static supportsWorkerExport(): boolean {\n return WorkerExportManager.supportsWorkerExport();\n }\n\n /**\n * Get or initialize the worker manager\n */\n private static async getWorkerManager(): Promise<WorkerExportManager | null> {\n if (!this.supportsWorkerExport()) {\n return null;\n }\n\n if (this.workerManager) {\n return this.workerManager;\n }\n\n // If initialization is already in progress, wait for it\n if (this.workerInitPromise) {\n await this.workerInitPromise;\n return this.workerManager;\n }\n\n // Initialize worker\n this.workerInitPromise = (async () => {\n try {\n this.workerManager = new WorkerExportManager();\n await this.workerManager.initialize();\n } catch (error) {\n log.error('Failed to initialize worker:', error);\n this.workerManager = null;\n }\n })();\n\n await this.workerInitPromise;\n this.workerInitPromise = null;\n\n return this.workerManager;\n }\n\n /**\n * Terminate the worker (for cleanup)\n */\n static terminateWorker(): void {\n if (this.workerManager) {\n this.workerManager.terminate();\n this.workerManager = null;\n }\n }\n\n /**\n * Export entire workspace to JSON\n */\n static exportToJSON(\n artboards: ArtboardElement[],\n elements: ExportElement[],\n artboardManager: ArtboardManager,\n filename?: string\n ): void {\n // Create document structure\n const document: CanvasDocument = {\n metadata: {\n version: this.CURRENT_VERSION,\n timestamp: new Date().toISOString(),\n appVersion: '1.0.0',\n },\n artboards: artboards.map((artboard) => {\n // Get elements for this artboard\n // PERFORMANCE: Use Set for O(1) lookup instead of O(n) includes()\n const elementIds = new Set(artboard.getElementIds());\n const artboardElements = elements.filter((e) => elementIds.has(e.id));\n\n return {\n id: artboard.id,\n name: artboard.name,\n x: artboard.x,\n y: artboard.y,\n width: artboard.width,\n height: artboard.height,\n backgroundColor: artboard.backgroundColor,\n elements: artboardElements.map((e) => e.toJSON()) as AnyElementConfig[],\n };\n }),\n activeArtboardId: artboardManager.getActiveArtboardId(),\n };\n\n // Convert to JSON string\n const jsonString = JSON.stringify(document, null, 2);\n\n // Create blob\n const blob = new Blob([jsonString], { type: 'application/json' });\n\n // Generate filename\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0];\n const finalFilename = filename || `canvas-${timestamp}.json`;\n\n // Trigger download\n this.downloadBlob(blob, finalFilename);\n }\n\n /**\n * Export artboard to image\n * Uses worker if supported, falls back to main thread\n */\n static async exportArtboardToImage(\n artboard: ArtboardElement,\n elements: ExportElement[],\n canvasElement: HTMLCanvasElement,\n options: ExportImageOptions = {}\n ): Promise<void> {\n const {\n format = 'png',\n quality = 0.95,\n scale = 1,\n transparentBackground = false,\n backgroundColor = artboard.backgroundColor,\n filename,\n forceMainThread = false,\n } = options;\n\n // Export to data URL using worker or main thread\n const dataUrl = await this.exportArtboardToDataURL(artboard, elements, canvasElement, {\n format,\n quality,\n scale,\n transparentBackground,\n backgroundColor,\n forceMainThread,\n });\n\n // Convert to blob and download\n const blob = await this.dataUrlToBlob(dataUrl);\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0];\n const finalFilename = filename || `${artboard.name}-${timestamp}.${format}`;\n\n this.downloadBlob(blob, finalFilename);\n }\n\n /**\n * Export artboard to data URL (for preview/testing)\n * Uses worker if supported, falls back to main thread\n */\n static async exportArtboardToDataURL(\n artboard: ArtboardElement,\n elements: ExportElement[],\n canvasElement: HTMLCanvasElement,\n options: ExportImageOptions = {}\n ): Promise<string> {\n const {\n format = 'png',\n quality = 0.95,\n scale = 1,\n transparentBackground = false,\n backgroundColor = artboard.backgroundColor,\n forceMainThread = false,\n } = options;\n\n // Try worker export first (unless forced to use main thread)\n if (!forceMainThread && this.supportsWorkerExport()) {\n try {\n const workerManager = await this.getWorkerManager();\n\n if (workerManager) {\n\n // Get elements for this artboard\n const artboardElementIds = new Set(artboard.getElementIds());\n const artboardElements = elements.filter((e) => artboardElementIds.has(e.id));\n\n const result = await workerManager.exportArtboardToDataURL(artboard, artboardElements, {\n scale,\n format: format === 'jpg' ? 'jpeg' : format,\n quality,\n });\n\n return result.dataUrl;\n }\n } catch (error) {\n log.warn('Worker export failed, falling back to main thread:', error);\n // Fall through to main thread export\n }\n }\n\n // Fallback: Main thread export\n return this.mainThreadExportToDataURL(artboard, elements, canvasElement, {\n format,\n quality,\n scale,\n transparentBackground,\n backgroundColor,\n });\n }\n\n /**\n * Export artboard as Blob (more efficient for API uploads)\n * Returns a Blob instead of data URL - smaller payload, faster for network operations\n * Uses worker if supported, falls back to main thread\n */\n static async exportArtboardToBlob(\n artboard: ArtboardElement,\n elements: ExportElement[],\n canvasElement: HTMLCanvasElement,\n options: ExportImageOptions = {}\n ): Promise<Blob> {\n const {\n format = 'png',\n quality = 0.95,\n scale = 1,\n transparentBackground = false,\n backgroundColor = artboard.backgroundColor,\n forceMainThread = false,\n } = options;\n\n // Try worker export first (unless forced to use main thread)\n if (!forceMainThread && this.supportsWorkerExport()) {\n try {\n const workerManager = await this.getWorkerManager();\n\n if (workerManager) {\n const artboardElementIds = new Set(artboard.getElementIds());\n const artboardElements = elements.filter((e) => artboardElementIds.has(e.id));\n\n const result = await workerManager.exportArtboardToBlob(artboard, artboardElements, {\n scale,\n format: format === 'jpg' ? 'jpeg' : format,\n quality,\n });\n\n return result.blob;\n }\n } catch (error) {\n log.warn('Worker blob export failed, falling back to main thread:', error);\n }\n }\n\n // Fallback: Main thread export\n return this.mainThreadExportToBlob(artboard, elements, canvasElement, {\n format,\n quality,\n scale,\n transparentBackground,\n backgroundColor,\n });\n }\n\n /**\n * Main thread export to Blob (fallback/legacy method).\n *\n * On iOS WebKit this is also the *primary* path (`isIOSWebKit()` skips the\n * worker), so font readiness matters here even when no fallback occurred.\n */\n private static async mainThreadExportToBlob(\n artboard: ArtboardElement,\n elements: ExportElement[],\n _canvasElement: HTMLCanvasElement,\n options: ExportImageOptions = {}\n ): Promise<Blob> {\n const {\n format = 'png',\n quality = 0.95,\n scale = 1,\n transparentBackground = false,\n backgroundColor = artboard.backgroundColor,\n } = options;\n\n // CRITICAL: Pre-load every font referenced by the elements before rendering.\n // The detached `<canvas>` we create below is never DOM-attached; iOS Safari\n // activates fonts lazily on first DOM use, so without this the offscreen\n // canvas paints text with the serif fallback even when the on-screen\n // canvas is rendering the same family correctly. See\n // `ensureFontsLoadedForExport` for the full reasoning.\n await ensureFontsLoadedForExport(elements);\n\n // Create offscreen canvas at artboard dimensions\n const offscreenCanvas = document.createElement('canvas');\n const width = artboard.width * scale;\n const height = artboard.height * scale;\n offscreenCanvas.width = width;\n offscreenCanvas.height = height;\n\n const ctx = offscreenCanvas.getContext('2d')!;\n ctx.scale(scale, scale);\n\n // Draw background if not transparent AND exportBackground is enabled\n if (!transparentBackground && artboard.exportBackground) {\n ctx.save();\n this.applyExportBackgroundClipPath(ctx, artboard);\n\n if (artboard.backgroundType === 'texture' && artboard.backgroundTexture) {\n const presetColor = TextureManager.getTexturePresetColor(artboard.backgroundTexture);\n ctx.fillStyle = presetColor;\n ctx.fillRect(0, 0, artboard.width, artboard.height);\n\n const texture = TextureManager.getTexture(artboard.backgroundTexture);\n if (texture && texture.complete) {\n ctx.drawImage(texture, 0, 0, artboard.width, artboard.height);\n }\n } else {\n ctx.fillStyle = backgroundColor || artboard.backgroundColor;\n ctx.fillRect(0, 0, artboard.width, artboard.height);\n }\n\n ctx.restore();\n }\n\n // Translate to artboard origin\n ctx.save();\n ctx.translate(-artboard.x, -artboard.y);\n\n // Clip to artboard bounds (respecting clipShape)\n this.applyExportClipPath(ctx, artboard);\n\n // Get elements for this artboard\n const artboardElementIds = new Set(artboard.getElementIds());\n const artboardElements = elements.filter((e) => artboardElementIds.has(e.id));\n\n // Create a map from element ID to actual element instance\n const elementMap = new Map<string, ExportElement>();\n artboardElements.forEach((el) => elementMap.set(el.id, el));\n\n // Helper to render actual element instance\n const renderElement = (\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n config: AnyElementConfig\n ) => {\n if (!config.id) return;\n const actualElement = elementMap.get(config.id);\n if (actualElement) {\n actualElement.render(ctx as CanvasRenderingContext2D, false);\n }\n };\n\n // Convert all elements to JSON for compositing processing\n const allElementConfigs = artboardElements.map((e) => e.toJSON()) as AnyElementConfig[];\n const knockoutRenderedIds = new Set<string>();\n\n // First pass: render compositing elements (knockout and clip)\n artboardElements.forEach((element, index) => {\n if (element.blendMode === 'knockout' || element.blendMode === 'clip') {\n const elementConfig = allElementConfigs[index];\n const compositeOp: CompositeOp = element.blendMode === 'knockout' ? 'destination-out' : 'destination-in';\n\n // Get affected elements and mark them as rendered\n const scope = elementConfig.knockoutParts?.scope || 'group';\n const compositingIndex = allElementConfigs.findIndex((el) => el.id === elementConfig.id);\n if (compositingIndex !== -1) {\n if (scope === 'artboard') {\n for (let i = 0; i < compositingIndex; i++) {\n const id = allElementConfigs[i].id;\n if (id) knockoutRenderedIds.add(id);\n }\n }\n }\n\n renderWithCompositing(\n ctx,\n elementConfig,\n allElementConfigs,\n renderElement,\n transparentBackground || !artboard.exportBackground ? undefined : backgroundColor,\n artboard,\n compositeOp\n );\n\n knockoutRenderedIds.add(element.id);\n }\n });\n\n // Second pass: render normal elements\n artboardElements.forEach((element) => {\n if (!knockoutRenderedIds.has(element.id)) {\n element.render(ctx, false);\n }\n });\n\n ctx.restore();\n\n // Convert to blob\n return new Promise<Blob>((resolve, reject) => {\n offscreenCanvas.toBlob(\n (blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new Error('Failed to create blob from canvas'));\n }\n },\n format === 'jpg' || format === 'jpeg' ? 'image/jpeg' : format === 'webp' ? 'image/webp' : 'image/png',\n quality\n );\n });\n }\n\n /**\n * Main thread export to data URL (fallback/legacy method).\n *\n * On iOS WebKit this is also the *primary* path (`isIOSWebKit()` skips the\n * worker), so font readiness matters here even when no fallback occurred.\n */\n private static async mainThreadExportToDataURL(\n artboard: ArtboardElement,\n elements: ExportElement[],\n _canvasElement: HTMLCanvasElement,\n options: ExportImageOptions = {}\n ): Promise<string> {\n const {\n format = 'png',\n quality = 0.95,\n scale = 1,\n transparentBackground = false,\n backgroundColor = artboard.backgroundColor,\n } = options;\n\n // CRITICAL: pre-load element fonts before rendering — see\n // `mainThreadExportToBlob` for the iOS Safari font-activation reasoning.\n await ensureFontsLoadedForExport(elements);\n\n // Create offscreen canvas at artboard dimensions\n const offscreenCanvas = document.createElement('canvas');\n const width = artboard.width * scale;\n const height = artboard.height * scale;\n offscreenCanvas.width = width;\n offscreenCanvas.height = height;\n\n const ctx = offscreenCanvas.getContext('2d')!;\n ctx.scale(scale, scale);\n\n // Draw background if not transparent AND exportBackground is enabled\n // Background is clipped to the artboard's clipShape\n if (!transparentBackground && artboard.exportBackground) {\n ctx.save();\n // Apply clip for background (coordinates are 0,0 relative since we haven't translated yet)\n this.applyExportBackgroundClipPath(ctx, artboard);\n\n // Check if artboard has a texture background\n if (artboard.backgroundType === 'texture' && artboard.backgroundTexture) {\n // Render preset color for this texture\n const presetColor = TextureManager.getTexturePresetColor(artboard.backgroundTexture);\n ctx.fillStyle = presetColor;\n ctx.fillRect(0, 0, artboard.width, artboard.height);\n\n // Render texture on top (if already loaded)\n const texture = TextureManager.getTexture(artboard.backgroundTexture);\n if (texture && texture.complete) {\n ctx.drawImage(texture, 0, 0, artboard.width, artboard.height);\n } else {\n // Texture not loaded - it should already be loaded by the time we export\n log.warn('Texture not loaded for export:', artboard.backgroundTexture);\n }\n } else {\n // Solid color background\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, artboard.width, artboard.height);\n }\n\n ctx.restore();\n }\n\n // Translate to artboard origin\n ctx.save();\n ctx.translate(-artboard.x, -artboard.y);\n\n // Clip to artboard bounds (respecting clipShape)\n this.applyExportClipPath(ctx, artboard);\n\n // Render elements within this artboard\n const artboardElementIds = new Set(artboard.getElementIds());\n const artboardElements = elements.filter((e) => artboardElementIds.has(e.id));\n\n // Create a map from element ID to actual element instance (preserves loaded images, etc.)\n const elementMap = new Map<string, ExportElement>();\n artboardElements.forEach((el) => elementMap.set(el.id, el));\n\n // Helper to render actual element instance\n const renderElement = (\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n config: AnyElementConfig\n ) => {\n if (!config.id) return;\n const actualElement = elementMap.get(config.id);\n if (actualElement) {\n actualElement.render(ctx as CanvasRenderingContext2D, false);\n } else {\n log.warn('Element not found in map:', config.id);\n }\n };\n\n // Convert all elements to JSON for compositing processing\n const allElementConfigs = artboardElements.map((e) => e.toJSON()) as AnyElementConfig[];\n const knockoutRenderedIds = new Set<string>();\n\n // First pass: render compositing elements (knockout and clip)\n artboardElements.forEach((element, index) => {\n if (element.blendMode === 'knockout' || element.blendMode === 'clip') {\n const elementConfig = allElementConfigs[index];\n const compositeOp: CompositeOp = element.blendMode === 'knockout' ? 'destination-out' : 'destination-in';\n\n // Get affected elements and mark them as rendered\n const scope = elementConfig.knockoutParts?.scope || 'group';\n const compositingIndex = allElementConfigs.findIndex((el) => el.id === elementConfig.id);\n if (compositingIndex !== -1) {\n if (scope === 'artboard') {\n // Mark all elements below this one as rendered (they're part of compositing)\n for (let i = 0; i < compositingIndex; i++) {\n const id = allElementConfigs[i].id;\n if (id) knockoutRenderedIds.add(id);\n }\n }\n }\n\n renderWithCompositing(\n ctx,\n elementConfig,\n allElementConfigs,\n renderElement,\n transparentBackground || !artboard.exportBackground ? undefined : backgroundColor,\n artboard,\n compositeOp\n );\n\n knockoutRenderedIds.add(element.id);\n }\n });\n\n // Second pass: render normal elements (with per-element effects)\n artboardElements.forEach((element, index) => {\n if (!knockoutRenderedIds.has(element.id)) {\n const elementConfig = allElementConfigs[index];\n const hasDistress = elementConfig?.distressEffect?.enabled &&\n elementConfig.distressEffect.style === 'custom' &&\n elementConfig.distressEffect.textureUrl;\n const hasMasks = elementConfig?.masks && elementConfig.masks.length > 0;\n\n const baseRenderFn = (renderCtx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D) => {\n element.render(renderCtx as CanvasRenderingContext2D, false);\n };\n\n if (hasMasks && hasDistress) {\n renderWithMasks(ctx, elementConfig, (maskCtx) => {\n const bbox = element.getVisualBoundingBox();\n applyElementDistressTexture(maskCtx, elementConfig.distressEffect!, bbox, baseRenderFn);\n });\n } else if (hasMasks) {\n renderWithMasks(ctx, elementConfig, baseRenderFn);\n } else if (hasDistress) {\n const bbox = element.getVisualBoundingBox();\n applyElementDistressTexture(ctx, elementConfig.distressEffect!, bbox, baseRenderFn);\n } else {\n element.render(ctx, false);\n }\n }\n });\n\n // Apply artboard-level distress texture (after all elements, before restore)\n if (artboard.distressTexture?.enabled) {\n applyArtboardDistressTexture(ctx, artboard.distressTexture, {\n x: artboard.x,\n y: artboard.y,\n width: artboard.width,\n height: artboard.height,\n });\n }\n\n // Apply artboard-level image mask (after distress, before restore)\n if (artboard.imageMask?.enabled) {\n applyArtboardImageMask(ctx, artboard.imageMask, {\n x: artboard.x,\n y: artboard.y,\n width: artboard.width,\n height: artboard.height,\n });\n }\n\n ctx.restore();\n\n // Convert to data URL and return\n const mimeType = format === 'png' ? 'image/png' : format === 'webp' ? 'image/webp' : 'image/jpeg';\n return offscreenCanvas.toDataURL(mimeType, quality);\n }\n\n /**\n * Apply clip path for export background (uses 0,0 as origin since background is drawn before translate)\n */\n private static applyExportBackgroundClipPath(ctx: CanvasRenderingContext2D, artboard: ArtboardElement): void {\n const { width, height, clipShape } = artboard;\n const x = 0;\n const y = 0;\n\n ctx.beginPath();\n\n // No clip shape or 'rectangle' = standard rectangular clip\n if (!clipShape || clipShape === 'rectangle') {\n ctx.rect(x, y, width, height);\n } else if (clipShape === 'circle') {\n // Circle inscribed in artboard\n const centerX = x + width / 2;\n const centerY = y + height / 2;\n const radius = Math.min(width, height) / 2;\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n } else if (typeof clipShape === 'object' && clipShape.type === 'rounded') {\n // Rounded rectangle\n const radius = Math.min(clipShape.radius, Math.min(width, height) / 2);\n if (typeof ctx.roundRect === 'function') {\n ctx.roundRect(x, y, width, height, radius);\n } else {\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.arcTo(x + width, y, x + width, y + radius, radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);\n ctx.lineTo(x + radius, y + height);\n ctx.arcTo(x, y + height, x, y + height - radius, radius);\n ctx.lineTo(x, y + radius);\n ctx.arcTo(x, y, x + radius, y, radius);\n }\n } else if (typeof clipShape === 'object' && clipShape.type === 'path') {\n try {\n const path = new Path2D(clipShape.d);\n ctx.clip(path);\n return;\n } catch (e) {\n log.warn('Invalid SVG path, falling back to rectangle:', e);\n ctx.rect(x, y, width, height);\n }\n }\n\n ctx.clip();\n }\n\n /**\n * Apply clip path for export based on artboard's clipShape\n * This creates the clip region for the given artboard during export\n */\n private static applyExportClipPath(ctx: CanvasRenderingContext2D, artboard: ArtboardElement): void {\n const { x, y, width, height, clipShape } = artboard;\n\n ctx.beginPath();\n\n // No clip shape or 'rectangle' = standard rectangular clip\n if (!clipShape || clipShape === 'rectangle') {\n ctx.rect(x, y, width, height);\n } else if (clipShape === 'circle') {\n // Circle inscribed in artboard\n const centerX = x + width / 2;\n const centerY = y + height / 2;\n const radius = Math.min(width, height) / 2;\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n } else if (typeof clipShape === 'object' && clipShape.type === 'rounded') {\n // Rounded rectangle\n const radius = Math.min(clipShape.radius, Math.min(width, height) / 2);\n // Use built-in roundRect if available\n if (typeof ctx.roundRect === 'function') {\n ctx.roundRect(x, y, width, height, radius);\n } else {\n // Fallback for older browsers\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.arcTo(x + width, y, x + width, y + radius, radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);\n ctx.lineTo(x + radius, y + height);\n ctx.arcTo(x, y + height, x, y + height - radius, radius);\n ctx.lineTo(x, y + radius);\n ctx.arcTo(x, y, x + radius, y, radius);\n }\n } else if (typeof clipShape === 'object' && clipShape.type === 'path') {\n // Custom SVG path - use Path2D for parsing\n try {\n const path = new Path2D(clipShape.d);\n // Translate the path to artboard position\n ctx.translate(x, y);\n ctx.clip(path);\n ctx.translate(-x, -y);\n return; // Path2D handles the clip itself\n } catch (e) {\n log.warn('Invalid SVG path, falling back to rectangle:', e);\n ctx.rect(x, y, width, height);\n }\n }\n\n ctx.clip();\n }\n\n /**\n * Export all artboards as separate images (HIGH PERFORMANCE - parallel rendering)\n */\n static async exportAllArtboardsToImages(\n artboards: ArtboardElement[],\n elements: ExportElement[],\n canvasElement: HTMLCanvasElement,\n options: ExportImageOptions = {}\n ): Promise<void> {\n // PERFORMANCE OPTIMIZATION: Export all artboards in parallel instead of sequentially\n // This dramatically improves export speed for multiple artboards\n const exportPromises = artboards.map((artboard) =>\n this.exportArtboardToImage(artboard, elements, canvasElement, {\n ...options,\n filename: options.filename ? `${options.filename}-${artboard.name}.${options.format || 'png'}` : undefined,\n })\n );\n\n await Promise.all(exportPromises);\n }\n\n /**\n * Download a blob as a file\n */\n private static downloadBlob(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n\n /**\n * Convert data URL to blob\n */\n private static async dataUrlToBlob(dataUrl: string): Promise<Blob> {\n const response = await fetch(dataUrl);\n return response.blob();\n }\n\n /**\n * Get export summary (for UI display)\n */\n static getExportSummary(\n artboards: ArtboardElement[],\n elements: ExportElement[]\n ): {\n artboardCount: number;\n totalElementCount: number;\n estimatedFileSize: string;\n } {\n const artboardCount = artboards.length;\n const totalElementCount = elements.length;\n\n // Rough estimate of JSON file size (in KB)\n const avgElementSize = 500; // bytes per element (rough estimate)\n const avgArtboardSize = 200; // bytes per artboard\n const estimatedBytes = artboardCount * avgArtboardSize + totalElementCount * avgElementSize;\n const estimatedKB = Math.ceil(estimatedBytes / 1024);\n\n return {\n artboardCount,\n totalElementCount,\n estimatedFileSize: estimatedKB < 1024 ? `${estimatedKB} KB` : `${(estimatedKB / 1024).toFixed(1)} MB`,\n };\n }\n\n /**\n * Performance benchmark: Compare worker vs main thread export\n * Returns timing data for both methods\n */\n static async benchmarkExport(\n artboard: ArtboardElement,\n elements: ExportElement[],\n canvasElement: HTMLCanvasElement,\n options: ExportImageOptions = {}\n ): Promise<{\n workerSupported: boolean;\n mainThread: {\n time: number;\n dataUrl: string;\n };\n worker?: {\n time: number;\n dataUrl: string;\n mainThreadBlockTime: number;\n };\n speedup?: number;\n recommendation: string;\n }> {\n\n // Benchmark main thread export\n const mainThreadStart = performance.now();\n const mainThreadDataUrl = await this.exportArtboardToDataURL(artboard, elements, canvasElement, {\n ...options,\n forceMainThread: true,\n });\n const mainThreadTime = performance.now() - mainThreadStart;\n\n const result = {\n workerSupported: this.supportsWorkerExport(),\n mainThread: {\n time: mainThreadTime,\n dataUrl: mainThreadDataUrl,\n },\n recommendation: '',\n };\n\n // Benchmark worker export if supported\n if (this.supportsWorkerExport()) {\n try {\n const workerStart = performance.now();\n\n // Get worker manager (will initialize if needed)\n const workerManager = await this.getWorkerManager();\n\n if (workerManager) {\n const artboardElementIds = new Set(artboard.getElementIds());\n const artboardElements = elements.filter((e) => artboardElementIds.has(e.id));\n\n const workerResult = await workerManager.exportArtboardToDataURL(artboard, artboardElements, {\n scale: options.scale || 1,\n format: (options.format === 'jpg' ? 'jpeg' : options.format) || 'png',\n quality: options.quality || 0.95,\n });\n\n const workerTime = performance.now() - workerStart;\n const speedup = mainThreadTime / workerTime;\n\n return {\n ...result,\n worker: {\n time: workerTime,\n dataUrl: workerResult.dataUrl,\n mainThreadBlockTime: workerResult.mainThreadBlockTime,\n },\n speedup,\n recommendation:\n speedup > 1.2\n ? `Worker export is ${speedup.toFixed(2)}x faster - recommended for continuous export`\n : speedup < 0.8\n ? `Main thread export is ${(1 / speedup).toFixed(2)}x faster - worker overhead not worth it for single exports`\n : 'Performance is similar, but worker keeps UI responsive during export',\n };\n }\n } catch (error) {\n log.error('Worker benchmark failed:', error);\n result.recommendation = 'Worker export not available - using main thread export';\n }\n } else {\n result.recommendation = 'Worker export not supported in this browser - using main thread export';\n }\n\n return result;\n }\n\n /**\n * Performance benchmark: Test continuous exports to measure UI impact\n * Returns statistics about export performance over time\n */\n static async benchmarkContinuousExport(\n artboard: ArtboardElement,\n elements: ExportElement[],\n canvasElement: HTMLCanvasElement,\n options: {\n duration?: number; // Duration in milliseconds\n interval?: number; // Interval between exports in milliseconds\n useWorker?: boolean;\n } = {}\n ): Promise<{\n totalExports: number;\n duration: number;\n averageTime: number;\n minTime: number;\n maxTime: number;\n totalMainThreadBlockTime: number;\n exportsPerSecond: number;\n recommendation: string;\n }> {\n const {\n duration = 5000, // 5 seconds\n interval = 500, // Every 500ms\n useWorker = this.supportsWorkerExport(),\n } = options;\n\n\n const exportTimes: number[] = [];\n let totalMainThreadBlockTime = 0;\n let running = true;\n\n // Stop after duration\n setTimeout(() => {\n running = false;\n }, duration);\n\n // Export continuously\n while (running) {\n const start = performance.now();\n\n await this.exportArtboardToDataURL(artboard, elements, canvasElement, {\n forceMainThread: !useWorker,\n });\n\n const time = performance.now() - start;\n exportTimes.push(time);\n\n if (!useWorker) {\n // Main thread export blocks the main thread for the entire duration\n totalMainThreadBlockTime += time;\n }\n\n // Wait for interval\n await new Promise((resolve) => setTimeout(resolve, Math.max(0, interval - time)));\n }\n\n const totalExports = exportTimes.length;\n const averageTime = exportTimes.reduce((sum, t) => sum + t, 0) / totalExports;\n const minTime = Math.min(...exportTimes);\n const maxTime = Math.max(...exportTimes);\n const exportsPerSecond = (totalExports / duration) * 1000;\n\n const blockPercent = (totalMainThreadBlockTime / duration) * 100;\n const recommendation =\n blockPercent > 20\n ? `Main thread blocked ${blockPercent.toFixed(1)}% of the time - STRONGLY recommend worker export`\n : blockPercent > 10\n ? `Main thread blocked ${blockPercent.toFixed(1)}% of the time - consider worker export`\n : `Main thread blocked ${blockPercent.toFixed(1)}% of the time - performance is acceptable`;\n\n return {\n totalExports,\n duration,\n averageTime,\n minTime,\n maxTime,\n totalMainThreadBlockTime,\n exportsPerSecond,\n recommendation,\n };\n }\n\n /**\n * Get performance statistics for the worker (if initialized)\n */\n static getWorkerStats(): {\n workerSupported: boolean;\n workerInitialized: boolean;\n workerStatus?: {\n isReady: boolean;\n pendingRequests: number;\n queuedRequests: number;\n crashCount: number;\n };\n } {\n return {\n workerSupported: this.supportsWorkerExport(),\n workerInitialized: this.workerManager !== null,\n workerStatus: this.workerManager?.getStatus(),\n };\n }\n\n /**\n * Get recommended export options for t-shirt designs\n * T-shirt designs should ALWAYS use transparent backgrounds with knockout effects\n */\n static getTShirtExportOptions(options: Partial<ExportImageOptions> = {}): ExportImageOptions {\n return {\n format: 'png', // PNG for transparency support\n scale: 2, // 2x for print quality\n quality: 1.0, // Maximum quality\n ...options,\n // Force transparent background - critical for knockout effects\n transparentBackground: true,\n };\n }\n\n /**\n * Get recommended export options for pillow/pattern designs\n * These may use group-scoped knockout with pattern backgrounds\n */\n static getPatternExportOptions(options: Partial<ExportImageOptions> = {}): ExportImageOptions {\n return {\n format: 'png',\n scale: 2,\n transparentBackground: false, // Patterns often include background\n quality: 1.0,\n ...options,\n };\n }\n\n /**\n * Validate export options for common issues\n * Returns warnings if options might cause problems\n */\n static validateExportOptions(options: ExportImageOptions, hasKnockout: boolean): string[] {\n const warnings: string[] = [];\n\n // Check for knockout with non-transparent background\n if (hasKnockout && !options.transparentBackground) {\n warnings.push(\n 'WARNING: Document has knockout effects but transparentBackground is false. ' +\n 'Knockout effects work best with transparent backgrounds for t-shirt designs.'\n );\n }\n\n // Check for JPEG with transparency\n if (options.transparentBackground && (options.format === 'jpg' || options.format === 'jpeg')) {\n warnings.push('WARNING: JPEG format does not support transparency. Use PNG format for transparent backgrounds.');\n }\n\n // Check for low quality with effects\n if (options.quality && options.quality < 0.9) {\n warnings.push('NOTE: Using quality < 0.9 may reduce the appearance of distress and other effects.');\n }\n\n // Check for low scale with print\n if (options.scale && options.scale < 2) {\n warnings.push('NOTE: For print-ready designs, recommend scale of 2x or higher.');\n }\n\n return warnings;\n }\n\n /**\n * Check if any elements in the list have knockout effects\n */\n static hasKnockoutEffects(elements: ExportElement[]): boolean {\n const checkElement = (el: ExportElement): boolean => {\n if ((el.blendMode === 'knockout' || el.blendMode === 'clip') && el.knockoutParts) {\n return true;\n }\n if ('children' in el && Array.isArray(el.children)) {\n return (el.children as ExportElement[]).some((child) => checkElement(child));\n }\n return false;\n };\n\n return elements.some((el) => checkElement(el));\n }\n\n /**\n * CRITICAL: Ensure artboard is export-safe\n * Strips preview background color to prevent accidental export\n * Returns a copy of the artboard safe for export\n */\n static makeArtboardExportSafe(artboard: ArtboardElement): ArtboardElement {\n // Clone the artboard\n const exportArtboard = Object.assign(Object.create(Object.getPrototypeOf(artboard)), artboard);\n\n // CRITICAL: Remove preview background - must NEVER be exported\n if ('previewBackgroundColor' in exportArtboard) {\n delete (exportArtboard as Record<string, unknown>).previewBackgroundColor;\n }\n\n return exportArtboard;\n }\n}\n\nexport default ExportManager;\n"],"names":["elementPreviewPainter","registerElementPreviewPainter","painter","getElementPreviewPainter","logger","createLogger","_TextureManager","idOrUrl","url","loadingPromise","resolve","reject","img","idsOrUrls","id","t","texture","category","textureId","TextureManager","DEFAULT_OPTIONS","generateElementPreview","element","options","installElementPainters","opts","canvas","ctx","GroupElement","renderGroupPreview","renderElementUsingActualRenderer","error","bbox","_a","elementWidth","elementHeight","renderFallbackPreview","availableWidth","availableHeight","scale","scaledWidth","scaledHeight","offsetX","offsetY","label","x","y","folderHeight","folderY","tabWidth","tabHeight","createTextPath","_renderingContext","textElement","fontSize","fontFamily","bold","italic","buildFontString","text","width","textWidth","measureTextWidth","actualWidth","height","createImagePath","borderRadius","maxRadius","radius","createCirclePath","createRectPath","applyStrokeStyle","stroke","createOffscreenCanvas","renderTextStroke","renderingContext","isKnockoutRender","strokeOpacity","renderTextStrokeViaOffscreen","renderTextStrokeDirect","strokeWidth","feather","isCustomTransform","customWidth","_b","estWidth","estHeight","transform","offW","offH","offCanvas","offCtx","elemX","elemY","centerPixelX","centerPixelY","originalOpacity","textAlign","fontMetrics","getFontMetrics","transformData","HORIZONTAL_PADDING","letterSpacing","lines","visualHeight","calculateVisualBoundsWithSpaceCollapsing","topLeftX","topLeftY","lineSpacing","LINE_HEIGHT_MULTIPLIER","line","index","isParagraphStart","isParagraphEnd","visibleText","leadingSpacesMatch","leadingSpacesCount","trailingSpacesMatch","trailingSpacesCount","xPos","yPos","strokeTextWithSpacing","renderImageStroke","renderPathStroke","pathFn","renderTextWithOpenTypeFeaturesSync","font","features","featureArray","tag","enabled","availableFeatures","feat","featuresObject","run","totalWidth","glyph","startX","currentX","position","pathData","svgPath","dMatch","e","path2D","renderTextWithGlyphOverridesSync","glyphOverrides","hasPUA","str","char","cp","overrideMap","override","chars","codePoint","glyphId","defaultGlyph","renderRichTextFillOnly","richText","maxWidth","lockedLineCount","resolveSpacing","style","explicitLines","splitRichTextIntoLines","paragraphMetadata","lineSpans","wrappedLines","wrapRichTextSpans","wrappedLine","idx","lineMetrics","lineIndex","spanWidths","lineHeight","lineAscent","span","spacedTextWidth","metrics","fullLineText","adjustedLineWidth","charIndexInLine","spanStartIndex","spanEndIndex","hiddenCharsInSpan","trailingSpaceStartIndex","leadingTrimAmount","visibleCharsInSpan","elementFontMetrics","totalHeight","lineData","spans","lineWidth","baselineY","s","color","underline","strikethrough","renderText","fillTextWithSpacing","renderedWidth","underlineY","strikethroughY","_measureCtx","getMeasureContext","parts","ascent","descent","applySpaceLayoutRules","hasExplicitNewlines","_","renderTextFillOnly","wrapText","allWrappedLines","i","leadingSpaces","trailingSpaces","words","wordsPerLine","lineText","allText","allTextWithSpaces","allTextWidth","isSmallSize","wrapTolerance","currentLine","lineTolerance","word","testLine","renderMultilineText","alignment","containerWidth","horizontalPadding","openTypeFeatures","containsPUACharacters","hasOpenTypeFeatures","hasGlyphOverrides","hasPUACharacters","needsFontkitRendering","fontkitFont","FontAnalyzer","err","charOffset","lineLength","lineGlyphOverrides","relativeIndex","underlineX","strikethroughX","renderCustomTransform","elementData","renderCustomTransformNormal","RichText","decorationX","strikeY","renderTextElement","elementOpacity","hasStroke","renderTextElementWithOffscreen","previousAlpha","renderTextElementInner","td","prev","renderCircleTransform","renderWaveTransform","renderArchTransform","renderAscendTransform","renderLeanTransform","renderFlagTransform","applyStrokeToChar","prevAlpha","renderTransformWithOffscreenStroke","renderFn","elementAlpha","hasStrokeOpacity","hasElementOpacity","textEstimate","containerSpan","estimatedSpan","featherPad","padding","archExtra","radiusExtra","drawBackX","drawBackY","savedStrokeOpa","savedOpacity","savedEnabled","renderCircleTransformDirect","weight","charWidths","sum","w","currentAngle","angleStep","renderWaveTransformDirect","charWidth","normalizedX","slope","WAVE_SKEW_FACTOR","renderArchTransformDirect","renderAscendTransformDirect","angleRad","renderLeanTransformDirect","skewAngle","renderFlagTransformDirect","distanceFromCenter","flagAmplitude","cosComponent","sinComponent","asTransformPainter","paint","serialized","renderGroupWithClipping","children","segments","currentContent","child","segment","contentCanvas","contentCtx","maskCanvas","maskCtx","installed","registerTextTransformPainter","registerGroupClippingPainter","renderElement","mode","renderImageElement","renderShapeElement","flipH","flipV","renderShapePath","renderShapeStroke","shapeType","renderRectanglePath","renderCirclePath","renderEllipsePath","renderStarPath","radiusX","radiusY","outerRadius","points","innerRadiusRatio","innerRadius","startAngle","angle","renderWithCompositing","compositingElement","allElements","renderElementFn","artboardBackgroundColor","artboard","compositeOp","savedTransform","scope","affectedElements","getAffectedElements","renderNonCompositingParts","dpr","offscreen","renderElementStroke","renderElementFill","logicalWidth","logicalHeight","afterRestore","renderWithKnockout","knockoutElement","getAllElementsBelow","getGroupSiblings","knockoutIndex","el","parentGroup","findParentGroup","candidate","nestedParent","_renderFn","knockoutParts","computeMaskCoverDimensions","parentW","parentH","maskNaturalW","maskNaturalH","oversize","maskAspect","parentAspect","fitW","fitH","THUMB_SIZE","MASK_SIZE","drawCircle","size","drawStar","cx","cy","outerR","innerR","r","drawHeart","drawDiamond","rx","ry","drawHexagon","drawShield","top","drawSplatter","seed","rand","dist","drawTornEdge","margin","steps","drawPaintStroke","y0","y1","drawCloud","MASK_IMAGE_PRESETS","initialized","createDOMCanvas","ensureMaskPresetsReady","cache","ImageCache","preset","dataUrl","thumbCanvas","thumbCtx","maskCache","workerMaskBitmaps","invalidateMaskCache","elementId","keysToDelete","key","clearMaskCache","renderWithMasks","mask","applyMask","parentElement","applyClipMask","applyAlphaMask","applyLumaMask","applyDistressMask","renderMaskElement","applyFeathering","imageData","data","g","b","luma","maskElement","parentX","parentY","maskX","maskY","absoluteMaskElement","MASK_OVERSIZE","parentTd","parentAny","maskTd","loadedImage","loadedBitmap","imageConfig","resolvedTd","needsContainScaling","h","contain","featherRadius","applyArtboardImageMask","config","pixelX","pixelY","pixelWidth","pixelHeight","offWidth","offHeight","lumaCanvas","lumaCtx","SimplexNoise","random","j","a","hash","u","v","X","Y","generateWornEffect","intensity","createCanvas","noise","threshold","value","edgeX","edgeY","edgeFactor","alpha","generateCrackedEffect","seededRandom","numCracks","startY","drawCrackBranch","length","depth","endX","endY","branchAngle","generateGrungeEffect","density","generateRetroEffect","dotSize","spacing","BUILTIN_SEED","TEX_SIZE","toAlphaMask","layerAlpha","bData","DISTRESS_TEXTURE_PRESETS","worn","grunge","generateThumbnailDataUrl","fullCanvas","fullCtx","thumbData","pixels","gray","ensureBuiltinTexturesReady","registerAlphaMask","loadingUrls","pendingCallbacks","getContext","convertToAlphaMask","source","tempCanvas","tempCtx","getAlphaMask","cached","post","loadTexture","preloadTexture","callbacks","notifyPending","cb","entry","res","blob","bitmap","applyArtboardDistressTexture","artMaskCtx","artIntensity","mData","mW","mH","content","cData","my","mx","maskAlpha","ci","applyElementDistressTexture","distress","elementBounds","diagonal","extraW","extraH","strokePad","padX","padY","paddedBounds","ElementFactory","transformType","CustomTransform","CircleTransform","LeanTransform","ArchTransform","AscendTransform","WaveTransform","FlagTransform","ImageElement","childConfig","_childConfigs","groupConfig","group","ShapeElement","PathElement","exhaustiveCheck","configs","obj","o","c","baseConfig","json","_ImportManager","file","document","artboards","artboardData","ArtboardElement","elements","elementConfig","_c","deserializedElements","maxSize","doc","reader","errors","artboardIds","elementIds","validation","imageElements","findImages","loadPromises","imgEl","onLoad","onError","ImportManager","DEFAULT_MAX_BITMAP_DIMENSION","registeredBitmapKeys","getImageCacheKey","imageSrc","srcHash","hashString","clearRegisteredBitmapKeys","unregisterElementBitmaps","markBitmapRegistered","cacheKey","isBitmapRegistered","createCappedImageBitmap","maxDimension","naturalWidth","naturalHeight","targetWidth","targetHeight","workerCacheClearCallback","workerElementClearCallback","registerWorkerCacheCallbacks","clearAll","clearElement","unregisterWorkerCacheCallbacks","clearImageBitmapCache","removeFromImageBitmapCache","collectFonts","elementJson","fonts","spanObj","resolveMaskImageUrls","masks","imageUrl","serializeForWorkerExport","maxBitmapDimension","artboardElements","serializedElements","newBitmaps","hasMasks","visibleWidth","visibleHeight","bitmapWidth","bitmapHeight","serializedImage","fontsList","workerCode","log","WorkerExportManager","listener","event","bitmaps","message","workerUrl","urlError","timeout","readyHandler","now","backoffDelay","request","result","requestId","mainThreadStartTime","serializedData","exportRequest","resultPromise","response","mainThreadBlockTime","pending","failedRequests","_pending","restartError","sharedInstance","getSharedWorkerExportManager","terminateSharedWorkerExportManager","collectElementFontFamilies","out","m","ensureFontsLoadedForExport","families","family","_ExportManager","artboardManager","filename","jsonString","timestamp","finalFilename","canvasElement","format","quality","transparentBackground","backgroundColor","forceMainThread","workerManager","artboardElementIds","_canvasElement","offscreenCanvas","presetColor","elementMap","actualElement","allElementConfigs","knockoutRenderedIds","compositingIndex","hasDistress","baseRenderFn","renderCtx","mimeType","clipShape","centerX","centerY","path","exportPromises","link","artboardCount","totalElementCount","estimatedBytes","estimatedKB","mainThreadStart","mainThreadDataUrl","mainThreadTime","workerStart","workerResult","workerTime","speedup","duration","interval","useWorker","exportTimes","totalMainThreadBlockTime","running","start","time","totalExports","averageTime","minTime","maxTime","exportsPerSecond","blockPercent","recommendation","hasKnockout","warnings","checkElement","exportArtboard","ExportManager"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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"}
|