ziya 0.3.0__py3-none-any.whl → 0.3.2__py3-none-any.whl
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.
Potentially problematic release.
This version of ziya might be problematic. Click here for more details.
- app/agents/agent.py +71 -73
- app/agents/direct_streaming.py +1 -1
- app/agents/prompts.py +1 -1
- app/agents/prompts_manager.py +14 -10
- app/agents/wrappers/google_direct.py +31 -1
- app/agents/wrappers/nova_tool_execution.py +2 -2
- app/agents/wrappers/nova_wrapper.py +1 -1
- app/agents/wrappers/ziya_bedrock.py +53 -31
- app/config/models_config.py +61 -20
- app/config/shell_config.py +5 -1
- app/extensions/prompt_extensions/claude_extensions.py +27 -5
- app/extensions/prompt_extensions/mcp_prompt_extensions.py +82 -56
- app/main.py +5 -3
- app/mcp/client.py +19 -10
- app/mcp/manager.py +68 -10
- app/mcp/tools.py +8 -9
- app/mcp_servers/shell_server.py +3 -3
- app/middleware/streaming.py +29 -41
- app/routes/file_validation.py +35 -0
- app/routes/mcp_routes.py +54 -8
- app/server.py +525 -614
- app/streaming_tool_executor.py +748 -137
- app/templates/asset-manifest.json +20 -20
- app/templates/index.html +1 -1
- app/templates/static/css/{main.0297bfee.css → main.e7109b49.css} +2 -2
- app/templates/static/css/main.e7109b49.css.map +1 -0
- app/templates/static/js/14386.65fcfe53.chunk.js +2 -0
- app/templates/static/js/14386.65fcfe53.chunk.js.map +1 -0
- app/templates/static/js/35589.0368973a.chunk.js +2 -0
- app/templates/static/js/35589.0368973a.chunk.js.map +1 -0
- app/templates/static/js/{50295.ab92f61b.chunk.js → 50295.90aca393.chunk.js} +3 -3
- app/templates/static/js/50295.90aca393.chunk.js.map +1 -0
- app/templates/static/js/55734.5f0fd567.chunk.js +2 -0
- app/templates/static/js/55734.5f0fd567.chunk.js.map +1 -0
- app/templates/static/js/58542.57fed736.chunk.js +2 -0
- app/templates/static/js/58542.57fed736.chunk.js.map +1 -0
- app/templates/static/js/{68418.2554bb1e.chunk.js → 68418.f7b4d2d9.chunk.js} +3 -3
- app/templates/static/js/68418.f7b4d2d9.chunk.js.map +1 -0
- app/templates/static/js/99948.b280eda0.chunk.js +2 -0
- app/templates/static/js/99948.b280eda0.chunk.js.map +1 -0
- app/templates/static/js/main.e075582c.js +3 -0
- app/templates/static/js/main.e075582c.js.map +1 -0
- app/utils/code_util.py +5 -2
- app/utils/context_cache.py +11 -0
- app/utils/conversation_filter.py +90 -0
- app/utils/custom_bedrock.py +43 -1
- app/utils/diff_utils/validation/validators.py +32 -22
- app/utils/file_cache.py +5 -3
- app/utils/precision_prompt_system.py +116 -0
- app/utils/streaming_optimizer.py +100 -0
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/METADATA +3 -2
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/RECORD +59 -55
- app/templates/static/css/main.0297bfee.css.map +0 -1
- app/templates/static/js/14386.567bf803.chunk.js +0 -2
- app/templates/static/js/14386.567bf803.chunk.js.map +0 -1
- app/templates/static/js/35589.278ecda2.chunk.js +0 -2
- app/templates/static/js/35589.278ecda2.chunk.js.map +0 -1
- app/templates/static/js/50295.ab92f61b.chunk.js.map +0 -1
- app/templates/static/js/55734.90d8bd52.chunk.js +0 -2
- app/templates/static/js/55734.90d8bd52.chunk.js.map +0 -1
- app/templates/static/js/58542.08fb5cf4.chunk.js +0 -2
- app/templates/static/js/58542.08fb5cf4.chunk.js.map +0 -1
- app/templates/static/js/68418.2554bb1e.chunk.js.map +0 -1
- app/templates/static/js/99948.71670e91.chunk.js +0 -2
- app/templates/static/js/99948.71670e91.chunk.js.map +0 -1
- app/templates/static/js/main.1d79eac2.js +0 -3
- app/templates/static/js/main.1d79eac2.js.map +0 -1
- /app/templates/static/js/{50295.ab92f61b.chunk.js.LICENSE.txt → 50295.90aca393.chunk.js.LICENSE.txt} +0 -0
- /app/templates/static/js/{68418.2554bb1e.chunk.js.LICENSE.txt → 68418.f7b4d2d9.chunk.js.LICENSE.txt} +0 -0
- /app/templates/static/js/{main.1d79eac2.js.LICENSE.txt → main.e075582c.js.LICENSE.txt} +0 -0
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/WHEEL +0 -0
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/entry_points.txt +0 -0
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"static/js/55734.90d8bd52.chunk.js","mappings":"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","sources":["plugins/d3/networkDiagram.ts","plugins/d3/basicChart.ts","utils/diagramUtils.ts","plugins/d3/mermaidPlugin.ts","plugins/d3/graphvizPlugin.ts","plugins/d3/vegaLitePlugin.ts","plugins/d3/registry.ts","utils/containerSizing.ts","components/D3Renderer.tsx","plugins/d3/mermaidEnhancer.ts"],"sourcesContent":["import { D3RenderPlugin, D3Node, D3Link, D3Style } from '../../types/d3';\n\nexport interface NetworkDiagramSpec {\n width: number;\n height: number;\n nodes: D3Node[];\n links: D3Link[];\n groups?: Array<{\n id: string;\n label: string;\n members: string[];\n }>;\n styles?: {\n [key: string]: D3Style;\n };\n};\n\nconst isNetworkDiagramSpec = (spec: any): spec is NetworkDiagramSpec => {\n return (\n typeof spec === 'object' &&\n spec.type === 'network' && // Check for network type\n Array.isArray(spec.nodes) &&\n Array.isArray(spec.links) &&\n spec.nodes.length >= 0 &&\n spec.nodes.every((n: any) => typeof n.id === 'string') &&\n spec.links.length >= 0 &&\n spec.links.every((l: any) => typeof l.source === 'string' && typeof l.target === 'string')\n );\n};\n\nexport const networkDiagramPlugin: D3RenderPlugin = {\n name: 'network-diagram',\n priority: 1,\n sizingConfig: {\n sizingStrategy: 'responsive',\n needsDynamicHeight: false,\n needsOverflowVisible: false,\n observeResize: false,\n containerStyles: {\n height: '400px',\n overflow: 'auto'\n }\n },\n canHandle: isNetworkDiagramSpec,\n render: (container: HTMLElement, d3: any, spec: any) => {\n console.debug('Network diagram plugin rendering:', { spec });\n\n if (!isNetworkDiagramSpec(spec)) {\n throw new Error('Invalid network diagram specification');\n }\n\n console.debug('Network diagram render:', {\n nodeCount: spec.nodes.length,\n linkCount: spec.links.length,\n groupCount: spec.groups?.length\n });\n try {\n const svg = d3.select(container)\n .selectAll('*').remove() // Clear existing content\n .append('svg')\n .attr('width', spec.width)\n .attr('height', spec.height)\n .attr('viewBox', [0, 0, spec.width, spec.height]);\n // Create board containers if groups exist\n if (spec.groups?.length) {\n const boards = svg.selectAll('.board')\n .data(spec.groups)\n .enter()\n .append('g')\n .attr('class', 'board')\n .attr('transform', 'translate(0,0)');\n boards.append('rect')\n .attr('x', d => d.id === 'modem_board' ? 180 : 680)\n .attr('y', 50)\n .attr('width', d => d.id === 'modem_board' ? 350 : 200)\n .attr('height', 500)\n .attr('fill', 'none')\n .attr('stroke', '#666')\n .attr('stroke-dasharray', '5,5');\n boards.append('text')\n .attr('x', d => d.id === 'modem_board' ? 200 : 700)\n .attr('y', 80)\n .text(d => d.label)\n .attr('fill', '#666');\n }\n // Draw links first (rest of the rendering code remains the same)\n // ... (previous link rendering code)\n // Draw nodes\n // ... (previous node rendering code)\n } catch (error) {\n console.error('Network diagram render error:', error);\n // Clean up on error\n d3.select(container).selectAll('*').remove();\n throw error;\n }\n }\n};\n","import { D3RenderPlugin } from '../../types/d3';\n\nexport interface BasicChartSpec {\n type: 'bar' | 'line';\n data: Array<{\n label: string;\n value: number;\n }>;\n width?: number;\n height?: number;\n margin?: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n };\n}\n\nconst defaultMargin = { top: 20, right: 20, bottom: 30, left: 40 };\n\nexport const basicChartPlugin: D3RenderPlugin = {\n name: 'basic-chart',\n priority: 10, // Higher priority than network diagram\n sizingConfig: {\n sizingStrategy: 'responsive',\n needsDynamicHeight: false,\n needsOverflowVisible: false,\n observeResize: false,\n containerStyles: {\n height: '400px',\n overflow: 'auto'\n }\n },\n canHandle: (spec: any) => {\n return (\n typeof spec === 'object' &&\n (spec.type === 'bar' || spec.type === 'line' || spec.type === 'scatter' || spec.type === 'bubble')\n );\n },\n render: (container: HTMLElement, d3: any, spec: any) => {\n console.debug('Basic chart plugin rendering:', spec);\n\n try {\n // Clear any existing content\n d3.select(container).selectAll('*').remove();\n\n const margin = spec.margin || defaultMargin;\n const width = (spec.width || 600) - margin.left - margin.right;\n const height = (spec.height || 400) - margin.top - margin.bottom;\n\n // Create SVG\n const svg = d3.select(container)\n .append('svg')\n .attr('width', width + margin.left + margin.right)\n .attr('height', height + margin.top + margin.bottom)\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`)\n\n const data = Array.isArray(spec.data) ? spec.data : [];;\n\n // Create scales\n const x = d3.scaleBand()\n .range([0, width])\n .domain(spec.data.map((d: any) => d.label))\n .padding(0.1);\n\n const y = d3.scaleLinear()\n .range([height, 0])\n .domain([0, d3.max(spec.data, (d: any) => d.value)]);\n\n // Add X axis\n svg.append('g')\n .attr('transform', `translate(0,${height})`)\n .call(d3.axisBottom(x));\n\n // Add Y axis\n svg.append('g')\n .call(d3.axisLeft(y));\n\n if (spec.type === 'bar') {\n // Add bars\n svg.selectAll('rect')\n .data(data)\n .join('rect')\n .attr('x', (d: any) => x(d.label))\n .attr('y', (d: any) => y(d.value))\n .attr('width', x.bandwidth())\n .attr('height', (d: any) => height - y(d.value))\n .attr('fill', (d: any) => d.color || 'steelblue');\n } else if (spec.type === 'line' || spec.type === 'scatter') {\n // Create line generator\n const line = d3.line()\n .x((d: any) => x(d.label) + x.bandwidth() / 2)\n .y((d: any) => y(d.value));\n\n if (spec.type === 'line') {\n // Add line\n svg.append('path')\n .datum(data)\n .attr('fill', 'none')\n .attr('stroke', 'steelblue')\n .attr('stroke-width', 2)\n .attr('d', line);\n }\n\n // Add points\n svg.selectAll('circle')\n .data(data)\n .join('circle')\n .attr('cx', (d: any) => x(d.label) + x.bandwidth() / 2)\n .attr('cy', (d: any) => y(d.value))\n .attr('r', spec.type === 'bubble' ? (d: any) => d.size || 5 : 4)\n .attr('fill', (d: any) => d.color || 'steelblue')\n .attr('stroke', '#fff')\n .attr('stroke-width', 1);\n }\n\n } catch (error) {\n console.error('Basic chart render error:', error);\n throw error;\n }\n }\n};\n","/**\n * Extract diagram definition from YAML-wrapped content\n * Handles cases where diagram specs are wrapped in YAML metadata like:\n * type: mermaid\n * definition: |\n * graph TD\n * A --> B\n */\nexport function extractDefinitionFromYAML(definition: string, diagramType: string): string {\n // Check if this looks like YAML-wrapped content\n const typePattern = `type: ${diagramType}`;\n if (!definition.includes(typePattern) || !definition.includes('definition:')) {\n return definition; // Not YAML-wrapped, return as-is\n }\n\n console.log(`🔧 Detected YAML-wrapped ${diagramType} definition, extracting content...`);\n const lines = definition.split('\\n');\n let inDefinition = false;\n const contentLines: string[] = [];\n \n for (const line of lines) {\n if (line.trim() === 'definition: |' || line.trim().startsWith('definition: |')) {\n inDefinition = true;\n continue;\n }\n if (inDefinition) {\n // Remove the leading spaces that are part of YAML indentation (usually 2 spaces)\n const cleanedLine = line.replace(/^ /, '');\n contentLines.push(cleanedLine);\n }\n }\n \n const extractedContent = contentLines.join('\\n').trim();\n console.log(`✅ Extracted ${diagramType} definition (${extractedContent.length} chars):`, extractedContent.substring(0, 200));\n return extractedContent;\n}\n\n/**\n * Check if a diagram definition appears to be complete based on the diagram type\n * @param definition - The diagram definition string\n * @param diagramType - The type of diagram (mermaid, graphviz, vega-lite, etc.)\n * @returns boolean indicating if the definition appears complete\n */\nexport function isDiagramDefinitionComplete(definition: string, diagramType: string): boolean {\n if (!definition || definition.trim().length === 0) return false;\n\n // Extract actual content if YAML-wrapped\n const actualDefinition = extractDefinitionFromYAML(definition, diagramType);\n \n switch (diagramType.toLowerCase()) {\n case 'mermaid':\n return isMermaidDefinitionComplete(actualDefinition);\n case 'graphviz':\n return isGraphvizDefinitionComplete(actualDefinition);\n case 'vega-lite':\n return isVegaLiteDefinitionComplete(actualDefinition);\n default:\n // Generic check - at least 2 lines and doesn't end with incomplete markers\n const lines = actualDefinition.trim().split('\\n');\n return lines.length >= 2 && !actualDefinition.endsWith('```');\n }\n}\n\nfunction isMermaidDefinitionComplete(definition: string): boolean {\n const lines = definition.trim().split('\\n');\n if (lines.length < 2) return false;\n \n const firstLine = lines[0].trim().toLowerCase();\n if (firstLine.startsWith('graph') || firstLine.startsWith('flowchart')) {\n // For flowcharts, check for balanced braces if any\n const openBraces = definition.split('{').length - 1;\n const closeBraces = definition.split('}').length - 1;\n return openBraces === closeBraces;\n }\n \n return lines.length >= 3 && !definition.endsWith('```');\n}\n\nfunction isGraphvizDefinitionComplete(definition: string): boolean {\n if (!definition || definition.trim().length === 0) return false;\n \n // Check for balanced braces\n const openBraces = definition.split('{').length - 1;\n const closeBraces = definition.split('}').length - 1;\n \n return openBraces === closeBraces && openBraces > 0 && definition.includes('}');\n}\n\nfunction isVegaLiteDefinitionComplete(definition: string): boolean {\n if (!definition || definition.trim().length === 0) return false;\n \n try {\n const parsed = JSON.parse(definition);\n \n // Basic completeness checks\n if (!parsed || typeof parsed !== 'object') return false;\n \n // Check for required Vega-Lite properties\n const hasData = parsed.data !== undefined;\n const hasVisualization = parsed.mark || parsed.layer || parsed.concat || parsed.facet || parsed.repeat;\n \n return hasData && hasVisualization;\n } catch (error) {\n return false;\n }\n}\n","import mermaid from 'mermaid';\nimport { D3RenderPlugin } from '../../types/d3';\nimport initMermaidSupport from './mermaidEnhancer';\nimport { isDiagramDefinitionComplete } from '../../utils/diagramUtils';\nimport { extractDefinitionFromYAML } from '../../utils/diagramUtils';\n\n// Add mermaid to window for TypeScript\ndeclare global {\n interface Window {\n mermaid: typeof mermaid;\n }\n}\n\n// Define the specification for Mermaid diagrams\nexport interface MermaidSpec {\n type: 'mermaid';\n isStreaming?: boolean;\n isMarkdownBlockClosed?: boolean;\n forceRender?: boolean;\n definition: string;\n theme?: 'default' | 'dark' | 'neutral' | 'forest'; // Optional theme override\n}\n\n// Type guard to check if a spec is for Mermaid\nconst isMermaidSpec = (spec: any): spec is MermaidSpec => {\n return (\n typeof spec === 'object' &&\n spec !== null &&\n spec.type === 'mermaid' &&\n typeof spec.definition === 'string' &&\n spec.definition.trim().length > 0\n );\n};\n\nconst SCALE_CONFIG = {\n TARGET_FONT_SIZE: 14, // Target font size in pixels\n MIN_FONT_SIZE: 12, // Minimum font size in pixels\n MAX_SCALE: 1.0 // Maximum scale (natural size)\n};\n\n// Global render queue to serialize Mermaid rendering and prevent conflicts\nclass MermaidRenderQueue {\n private queue: Array<() => Promise<any>> = [];\n private isProcessing = false;\n\n async enqueue<T>(renderFn: () => Promise<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n this.queue.push(async () => {\n try {\n const result = await renderFn();\n resolve(result);\n } catch (error) {\n reject(error);\n }\n });\n\n this.processQueue();\n });\n }\n\n private async processQueue() {\n if (this.isProcessing || this.queue.length === 0) return;\n\n this.isProcessing = true;\n const renderFn = this.queue.shift()!;\n await renderFn();\n this.isProcessing = false;\n\n this.processQueue(); // Process next item\n }\n}\n\nconst renderQueue = new MermaidRenderQueue();\n\n// Initialize Mermaid support with preprocessing and error handling\ninitMermaidSupport(mermaid);\n\n// Also ensure window.mermaid is enhanced if it exists\nif (typeof window !== 'undefined' && window.mermaid) {\n initMermaidSupport(window.mermaid);\n}\n\nexport const mermaidPlugin: D3RenderPlugin = {\n name: 'mermaid-renderer',\n priority: 5,\n sizingConfig: {\n sizingStrategy: 'auto-expand',\n needsDynamicHeight: true,\n needsOverflowVisible: true,\n observeResize: true,\n containerStyles: {\n width: '100%',\n height: 'auto',\n overflow: 'visible'\n }\n },\n\n canHandle: (spec: any): boolean => {\n return isMermaidSpec(spec);\n },\n\n // Helper to check if a mermaid definition is complete\n isDefinitionComplete: (definition: string): boolean => {\n if (!definition || definition.trim().length === 0) return false;\n\n // Check for basic completeness indicators\n const lines = definition.trim().split('\\n');\n if (lines.length < 2) return false;\n\n const firstLine = lines[0].trim().toLowerCase();\n\n // Check for specific diagram types\n if (firstLine.startsWith('graph') || firstLine.startsWith('flowchart')) {\n // For flowcharts, check for balanced braces\n const openBraces = definition.split('{').length - 1;\n const closeBraces = definition.split('}').length - 1;\n return openBraces === closeBraces && openBraces > 0;\n }\n\n // For other diagram types, check if there are at least a few lines\n // and the definition doesn't end with an incomplete code block\n return lines.length >= 3 && !definition.endsWith('```');\n },\n\n\n render: async (container: HTMLElement, d3: any, spec: MermaidSpec, isDarkMode: boolean): Promise<void> => {\n // Use render queue to serialize all Mermaid operations\n return renderQueue.enqueue(async () => {\n return await renderSingleDiagram(container, d3, spec, isDarkMode);\n });\n }\n};\n\nasync function renderSingleDiagram(container: HTMLElement, d3: any, spec: MermaidSpec, isDarkMode: boolean): Promise<void> {\n console.log(`🎯 MERMAID SINGLE RENDER with spec:`, spec);\n console.log(`Mermaid plugin render called with spec type: ${spec.type}, definition length: ${spec.definition.length}`);\n console.log('📊 DIAGRAM PREVIEW:', spec.definition.substring(0, 100).replace(/\\n/g, '\\\\n'));\n console.log('🔍 HAS HTML TAGS:', spec.definition.includes('<br'));\n\n let renderSuccessful = false;\n try {\n container.innerHTML = '';\n\n // Add loading spinner while mermaid renders\n const loadingSpinner = document.createElement('div');\n loadingSpinner.className = 'mermaid-loading-spinner';\n loadingSpinner.style.cssText = `\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 2em;\n min-height: 150px;\n width: 100%;\n `;\n\n // Add spinner animation\n loadingSpinner.innerHTML = `\n <div style=\"\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-top: 4px solid ${isDarkMode ? '#4cc9f0' : '#3498db'};\n border-radius: 50%;\n width: 40px;\n height: 40px;\n animation: mermaid-spin 1s linear infinite;\n margin-bottom: 15px;\n \"></div>\n <div style=\"font-family: system-ui, -apple-system, sans-serif; color: ${isDarkMode ? '#eceff4' : '#333333'};\">\n Rendering diagram...\n </div>\n `;\n\n container.appendChild(loadingSpinner);\n\n // This allows the content to display as highlighted code during streaming\n if (spec.isStreaming && !spec.isMarkdownBlockClosed && !spec.forceRender) {\n console.log('Mermaid: Markdown block still open, letting content display as code');\n // Don't show a waiting message - let the markdown renderer show the code\n // Just remove the loading spinner and return\n try {\n container.innerHTML = '';\n } catch (e) {\n console.warn('Could not remove loading spinner:', e);\n }\n return; // Exit early - let markdown renderer handle the streaming content\n }\n\n // Only proceed with rendering when we have a complete definition\n if (!spec.definition || spec.definition.trim().length < 10) {\n console.log('Mermaid: Definition too short, waiting for more content');\n return; // Exit early and wait for complete definition\n }\n // Initialize mermaid with graph-specific settings\n\n // Extract actual content from YAML wrapper if present, but don't do other preprocessing\n // The enhanced render function will handle all preprocessing\n let rawDefinition = extractDefinitionFromYAML(spec.definition, 'mermaid');\n console.log('Raw definition (first 200 chars):', rawDefinition.substring(0, 200));\n\n // Detect diagram type\n const firstLine = rawDefinition.trim().split('\\n')[0].toLowerCase();\n const diagramType = firstLine.replace(/^(\\w+).*$/, '$1').toLowerCase();\n\n // Create a guaranteed unique ID that won't conflict with other diagrams\n const containerId = container.id || container.className || 'mermaid';\n const mermaidId = `${containerId}-${Date.now()}-${Math.random().toString(16).substring(2, 10)}`;\n\n mermaid.initialize({\n startOnLoad: false,\n theme: isDarkMode ? 'dark' : 'default',\n securityLevel: 'loose',\n fontFamily: '\"Arial\", sans-serif',\n fontSize: 14,\n themeVariables: isDarkMode ? {\n // High contrast dark theme\n primaryColor: '#88c0d0',\n primaryTextColor: '#ffffff',\n primaryBorderColor: '#88c0d0',\n lineColor: '#88c0d0',\n secondaryColor: '#5e81ac',\n tertiaryColor: '#2e3440',\n\n // Text colors\n textColor: '#eceff4',\n loopTextColor: '#eceff4',\n\n // Node colors\n mainBkg: '#3b4252',\n secondBkg: '#434c5e',\n nodeBorder: '#88c0d0',\n\n // Edge colors\n edgeLabelBackground: '#4c566a',\n\n // Contrast colors\n altBackground: '#2e3440',\n\n // Flowchart specific\n nodeBkg: '#3b4252',\n clusterBkg: '#2e3440',\n titleColor: '#88c0d0',\n\n // Class diagram specific\n classText: '#ffffff',\n\n // State diagram specific\n labelColor: '#ffffff',\n\n // Sequence diagram specific\n actorBkg: '#4c566a',\n actorBorder: '#88c0d0',\n activationBkg: '#5e81ac',\n\n // Gantt chart specific\n sectionBkgColor: '#3b4252',\n altSectionBkgColor: '#434c5e',\n gridColor: '#eceff4',\n todayLineColor: '#88c0d0'\n } : {},\n flowchart: {\n htmlLabels: true,\n curve: 'basis',\n padding: 15,\n nodeSpacing: 50,\n rankSpacing: 50,\n diagramPadding: 8,\n },\n sequence: {\n diagramMarginX: 50,\n diagramMarginY: 30,\n actorMargin: 50,\n width: 150,\n height: 65,\n boxMargin: 10,\n boxTextMargin: 5,\n noteMargin: 10,\n messageMargin: 35,\n mirrorActors: true,\n bottomMarginAdj: 1,\n useMaxWidth: true,\n },\n gantt: {\n titleTopMargin: 25,\n barHeight: 20,\n barGap: 4,\n topPadding: 50,\n leftPadding: 75,\n gridLineStartPadding: 35,\n fontSize: 11,\n sectionFontSize: 11,\n numberSectionStyles: 4,\n axisFormat: '%Y-%m-%d',\n topAxis: false,\n },\n });\n\n // Render the diagram\n console.log(`Attempting to render mermaid with ID: ${mermaidId}`);\n\n let svg: string;\n let renderError: Error | null = null;\n try {\n const result = await mermaid.render(mermaidId, rawDefinition);\n\n // Check if result is valid\n if (!result || typeof result !== 'object') {\n console.error('Invalid mermaid render result:', result);\n throw new Error('Mermaid render returned invalid result');\n }\n console.log('Mermaid render result:', result);\n svg = result.svg;\n\n // Check if we got a valid SVG\n if (!svg || svg.trim() === '') {\n console.error('Empty SVG returned from Mermaid render - likely parse error');\n console.error('Definition that failed (first 500 chars):', rawDefinition.substring(0, 500));\n\n // Check if there was a parsing error that Mermaid swallowed\n // This is a common issue where Mermaid returns empty result instead of throwing\n throw new Error('Mermaid parsing failed - empty SVG returned. This usually indicates syntax errors in the diagram definition.');\n }\n\n // Additional validation - check if SVG contains actual content\n if (svg.length < 100 || !svg.includes('<svg')) {\n console.error('SVG appears to be malformed or too short:', svg.substring(0, 200));\n throw new Error('Mermaid returned malformed SVG - likely parsing error');\n }\n\n renderSuccessful = true;\n console.log(`Mermaid render successful, got SVG of length: ${svg.length}`);\n\n // Check if the SVG contains an error message\n if (svg.includes('syntax error') || svg.includes('Parse error')) {\n throw new Error('Mermaid syntax error in diagram');\n }\n } catch (renderError) {\n console.error('Error rendering mermaid diagram:', renderError);\n\n // Store the error for better error reporting\n renderError = renderError instanceof Error ? renderError : new Error(String(renderError));\n\n // Log the specific error details\n if (renderError instanceof Error) {\n console.error('Error name:', renderError.name);\n console.error('Error message:', renderError.message);\n console.error('Error stack:', renderError.stack);\n }\n\n console.error('Failed definition (first 500 chars):', rawDefinition.substring(0, 500));\n console.error('Raw definition that failed:', rawDefinition.substring(0, 500));\n throw renderError;\n }\n\n // Add the animation keyframes if they don't exist yet\n if (!document.querySelector('#mermaid-spinner-keyframes')) {\n const keyframes = document.createElement('style');\n keyframes.id = 'mermaid-spinner-keyframes';\n keyframes.textContent = `\n @keyframes mermaid-spin {\n 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); }\n }\n `;\n document.head.appendChild(keyframes);\n }\n\n // Create wrapper div\n const wrapper = document.createElement('div');\n wrapper.className = 'mermaid-wrapper';\n wrapper.style.cssText = `\n width: 100%;\n max-width: 100%;\n overflow: auto;\n padding: 1em;\n display: flex;\n justify-content: center;\n `;\n wrapper.innerHTML = svg;\n\n // Remove the loading spinner\n try {\n if (loadingSpinner && loadingSpinner.parentNode === container) {\n container.removeChild(loadingSpinner);\n }\n } catch (e) {\n console.warn('Could not remove loading spinner (this is normal for multiple renders):', e instanceof Error ? e.message : String(e));\n }\n\n // Add wrapper to container\n container.appendChild(wrapper);\n\n if (!renderSuccessful) return;\n\n // Get the SVG element after it's in the DOM\n const svgElement = wrapper.querySelector('svg');\n if (!svgElement) {\n throw new Error('Failed to get SVG element after rendering');\n }\n\n // Helper function to apply custom styles from the diagram definition\n const applyCustomStyles = (svgElement: SVGElement) => {\n // Process all style directives in the SVG\n const styleElements = svgElement.querySelectorAll('style');\n styleElements.forEach(styleEl => {\n // Extract class names and their style definitions\n const styleText = styleEl.textContent || '';\n const styleRules = styleText.match(/\\.(\\w+)\\s*{([^}]*)}/g) || [];\n\n styleRules.forEach(rule => {\n // Apply these styles directly to the elements with matching classes\n const classMatch = rule.match(/\\.(\\w+)\\s*{/);\n const styleMatch = rule.match(/{([^}]*)}/);\n\n if (classMatch && styleMatch) {\n const className = classMatch[1];\n const styles = styleMatch[1].trim();\n\n // Find elements with this class and apply styles directly\n svgElement.querySelectorAll(`.${className}`).forEach(el => {\n // Parse individual style properties\n styles.split(';').forEach(style => {\n const [prop, value] = style.split(':').map(s => s.trim());\n if (prop && value) {\n (el as SVGElement).style.setProperty(prop, value);\n }\n });\n });\n }\n });\n });\n };\n\n // Enhanced function to improve text visibility in dark mode\n const enhanceDarkModeTextVisibility = (svgElement: SVGElement) => {\n // Get all text elements\n const textElements = svgElement.querySelectorAll('text');\n\n textElements.forEach(textEl => {\n // Find the parent node to get its styling context\n let parentNode = textEl.parentElement;\n while (parentNode && !parentNode.classList.contains('node') && !parentNode.classList.contains('cluster')) {\n parentNode = parentNode.parentElement;\n }\n\n if (parentNode) {\n // Look for shape elements (rect, circle, polygon, path) in the parent\n const shapeElement = parentNode.querySelector('rect, circle, polygon, path');\n if (shapeElement) {\n const stroke = shapeElement.getAttribute('stroke');\n const fill = shapeElement.getAttribute('fill');\n\n // If we have a stroke color, use it for text (it's usually darker/more saturated)\n if (stroke && stroke !== 'none' && stroke !== '#333' && stroke !== '#333333') {\n textEl.setAttribute('fill', stroke);\n } else if (fill && fill !== 'none') {\n // If no good stroke, derive optimal contrasting color from fill\n const contrastColor = getTextContrastColor(fill);\n textEl.setAttribute('fill', contrastColor);\n } else {\n // Fallback to high contrast color\n textEl.setAttribute('fill', '#000000');\n }\n }\n }\n });\n\n // Special handling for edge labels and other floating text\n svgElement.querySelectorAll('.edgeLabel text').forEach(textEl => {\n const currentFill = textEl.getAttribute('fill');\n // If text is white or very light, make it more visible\n if (!currentFill || currentFill === '#ffffff' || currentFill === 'white' || currentFill === '#eceff4') {\n textEl.setAttribute('fill', '#000000');\n }\n });\n\n // Handle gantt chart and other diagram text that might be on colored backgrounds\n svgElement.querySelectorAll('text').forEach(textEl => {\n const parentRect = textEl.closest('g')?.querySelector('rect');\n if (parentRect) {\n const bgColor = parentRect.getAttribute('fill');\n if (bgColor && bgColor !== 'none') {\n const optimalColor = getOptimalTextColor(bgColor);\n textEl.setAttribute('fill', optimalColor);\n }\n }\n });\n };\n\n // Enhance dark theme visibility for specific elements\n if (isDarkMode && svgElement) {\n requestAnimationFrame(() => {\n // Enhance specific elements that might still have poor contrast\n svgElement.querySelectorAll('.edgePath path').forEach(el => {\n el.setAttribute('stroke', '#88c0d0');\n el.setAttribute('stroke-width', '1.5px');\n });\n\n // Fix for arrow markers in dark mode\n svgElement.querySelectorAll('defs marker path').forEach(el => {\n el.setAttribute('stroke', '#88c0d0');\n el.setAttribute('fill', '#88c0d0');\n });\n\n // Fix for all SVG paths and lines\n svgElement.querySelectorAll('line, path:not([fill])').forEach(el => {\n el.setAttribute('stroke', '#88c0d0');\n el.setAttribute('stroke-width', '1.5px');\n });\n\n // Apply enhanced text visibility improvements\n enhanceDarkModeTextVisibility(svgElement);\n\n svgElement.querySelectorAll('path.path, path.messageText, .flowchart-link').forEach(el => {\n el.setAttribute('stroke', '#88c0d0');\n el.setAttribute('stroke-width', '1.5px');\n });\n\n svgElement.querySelectorAll('.node rect, .node circle, .node polygon, .node path').forEach(el => {\n el.setAttribute('stroke', '#81a1c1');\n el.setAttribute('fill', '#5e81ac');\n });\n\n svgElement.querySelectorAll('.cluster rect').forEach(el => {\n el.setAttribute('stroke', '#81a1c1');\n el.setAttribute('fill', '#4c566a');\n });\n\n // Apply custom styles from the diagram definition\n applyCustomStyles(svgElement);\n });\n } else {\n // Even in light mode, apply custom styles\n applyCustomStyles(svgElement);\n }\n\n // Helper functions for contrast calculation\n const getColorLuminance = (color: string): number => {\n const rgb = color.match(/\\d+/g);\n if (!rgb || rgb.length < 3) return 0.5;\n const [r, g, b] = rgb.map(x => {\n const val = parseInt(x) / 255;\n return val <= 0.03928 ? val / 12.92 : Math.pow((val + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n };\n\n const calculateContrastRatio = (textColor: string, backgroundColor: string): number => {\n const textLum = getColorLuminance(textColor);\n const bgLum = getColorLuminance(backgroundColor);\n const lighter = Math.max(textLum, bgLum);\n const darker = Math.min(textLum, bgLum);\n return (lighter + 0.05) / (darker + 0.05);\n };\n\n // TEXT VISIBILITY FIX - Focus on foreignObject children only\n setTimeout(() => {\n console.log('🔍 TEXT VISIBILITY FIX: Starting analysis');\n const foreignObjects = container.querySelectorAll('foreignObject');\n console.log(`Found ${foreignObjects.length} foreignObject elements`);\n let fixCount = 0;\n let totalTextElements = 0;\n let elementsWithBackground = 0;\n\n foreignObjects.forEach((foreignObj, foreignIndex) => {\n const textElements = foreignObj.querySelectorAll('div, span');\n console.log(`ForeignObject ${foreignIndex}: contains ${textElements.length} text elements`);\n\n textElements.forEach((textEl) => {\n const content = textEl.textContent?.trim();\n if (!content) return;\n\n totalTextElements++;\n console.log(`Text element ${totalTextElements}: \"${content}\"`);\n\n const computedStyle = window.getComputedStyle(textEl);\n const textColor = computedStyle.color;\n console.log(` Text color: ${textColor}`);\n\n // Find background color by walking up the DOM within this foreignObject\n let backgroundColor: string | null = null;\n let currentElement: Element | null = textEl;\n let depth = 0;\n\n while (currentElement && currentElement !== foreignObj) {\n const elementStyle = window.getComputedStyle(currentElement);\n const bgColor = elementStyle.backgroundColor;\n console.log(` Level ${depth}: element ${currentElement.tagName}, bg: ${bgColor}`);\n\n if (bgColor && bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent') {\n backgroundColor = bgColor;\n console.log(` Found background: ${backgroundColor}`);\n break;\n }\n currentElement = currentElement.parentElement;\n depth++;\n }\n\n // Strategy 2: If no background found in DOM hierarchy, look for sibling SVG elements\n if (!backgroundColor) {\n console.log(` No background in DOM hierarchy, checking SVG siblings`);\n\n // Look at the parent group of this foreignObject\n const parentGroup = foreignObj.parentElement;\n if (parentGroup) {\n console.log(` Parent group: ${parentGroup.tagName}`);\n\n // Look for rect, circle, polygon, path elements in the same group\n const shapeElements = parentGroup.querySelectorAll('rect, circle, polygon, path, ellipse');\n console.log(` Found ${shapeElements.length} shape elements in parent group`);\n\n for (const shape of shapeElements) {\n const fill = shape.getAttribute('fill');\n const computedFill = window.getComputedStyle(shape).fill;\n console.log(` Shape ${shape.tagName}: fill=\"${fill}\" computed=\"${computedFill}\"`);\n\n if (fill && fill !== 'none' && fill !== 'transparent') {\n backgroundColor = fill;\n console.log(` Found SVG background: ${backgroundColor}`);\n break;\n } else if (computedFill && computedFill !== 'none' && computedFill !== 'transparent' && computedFill !== 'rgb(0, 0, 0)') {\n backgroundColor = computedFill;\n console.log(` Found computed SVG background: ${backgroundColor}`);\n break;\n }\n }\n }\n }\n\n // Strategy 3: If still no background, search the entire SVG for ALL shapes\n if (!backgroundColor) {\n console.log(` Still no background, searching entire SVG`);\n const allShapes = container.querySelectorAll('rect, circle, polygon, path, ellipse');\n console.log(` Found ${allShapes.length} total shapes in SVG`);\n\n // Log all shapes and their colors to see what we're missing\n const allColors = new Set<string>();\n allShapes.forEach((shape, i) => {\n const fill = shape.getAttribute('fill');\n const computedFill = window.getComputedStyle(shape).fill;\n if (fill && fill !== 'none') allColors.add(fill);\n if (computedFill && computedFill !== 'none' && computedFill !== 'rgb(0, 0, 0)') allColors.add(computedFill);\n\n // Log first 10 shapes for debugging\n if (i < 10) {\n console.log(` All shapes ${i}: ${shape.tagName} fill=\"${fill}\" computed=\"${computedFill}\"`);\n }\n });\n\n console.log(` All unique colors found:`, Array.from(allColors));\n\n // For now, don't assign a background from this broad search\n // We just want to see what colors are available\n }\n\n if (backgroundColor) {\n elementsWithBackground++;\n console.log(` Background found: ${backgroundColor}`);\n const isProblematic = isProblematicBackground(backgroundColor);\n console.log(` Is problematic: ${isProblematic}`);\n\n if (isProblematic) {\n const contrastRatio = calculateContrastRatio(textColor, backgroundColor);\n console.log(` Contrast ratio: ${contrastRatio.toFixed(2)}`);\n\n if (contrastRatio < 3.0) {\n console.log(` 🔧 FIXING: \"${content}\" - poor contrast (${contrastRatio.toFixed(2)})`);\n (textEl as HTMLElement).style.color = '#000000';\n (textEl as HTMLElement).style.setProperty('color', '#000000', 'important');\n fixCount++;\n } else {\n console.log(` ✓ SKIPPING: \"${content}\" - good contrast (${contrastRatio.toFixed(2)})`);\n }\n }\n } else {\n console.log(` No background found for: \"${content}\"`);\n }\n\n // Check if we need to fix this text\n });\n });\n console.log(`🔍 SUMMARY: Processed ${totalTextElements} text elements, ${elementsWithBackground} had backgrounds, fixed ${fixCount}`);\n }, 1000);\n\n // Wait for next frame to ensure SVG is rendered\n requestAnimationFrame(() => {\n // Find all text elements\n const textElements = svgElement.querySelectorAll('text');\n if (textElements.length === 0) return;\n // Get the computed font size of the first text element\n const computedStyle = window.getComputedStyle(textElements[0]);\n const currentFontSize = parseFloat(computedStyle.fontSize);\n\n // Calculate scale based on target font size\n const scale = SCALE_CONFIG.TARGET_FONT_SIZE / currentFontSize;\n\n // Apply transform scale to the SVG\n const finalScale = Math.min(scale, SCALE_CONFIG.MAX_SCALE);\n svgElement.style.transform = `scale(${finalScale})`;\n svgElement.style.transformOrigin = 'center center';\n svgElement.style.width = '100%';\n svgElement.style.height = 'auto';\n\n // Override any existing transform scale in the SVG's style attribute\n const svgStyleAttr = svgElement.getAttribute('style') || '';\n if (svgStyleAttr.includes('transform: scale')) {\n // Remove any transform scale from the style attribute\n const newStyleAttr = svgStyleAttr.replace(/transform:\\s*scale\\([^)]+\\);?/g, '');\n svgElement.setAttribute('style', newStyleAttr);\n // Re-apply our controlled scale\n svgElement.style.transform = `scale(${finalScale})`;\n }\n });\n\n // Add action buttons\n const actionsContainer = document.createElement('div');\n actionsContainer.className = 'diagram-actions';\n\n // Add Open button\n const openButton = document.createElement('button');\n openButton.innerHTML = '↗️ Open';\n openButton.className = 'diagram-action-button mermaid-open-button';\n openButton.onclick = () => {\n // Get the SVG element\n const svgElement = wrapper.querySelector('svg');\n if (!svgElement) return;\n\n // Get the SVG dimensions\n const svgGraphics = svgElement as unknown as SVGGraphicsElement;\n let width = 600;\n let height = 400;\n\n try {\n // Try to get the bounding box\n const bbox = svgGraphics.getBBox();\n width = Math.max(bbox.width + 50, 400); // Add padding, minimum 400px\n height = Math.max(bbox.height + 100, 300); // Add padding, minimum 300px\n } catch (e) {\n console.warn('Could not get SVG dimensions, using defaults', e);\n }\n\n // Create a new SVG with proper XML declaration and doctype\n const svgData = new XMLSerializer().serializeToString(svgElement);\n\n // Create an HTML document that will display the SVG responsively\n const htmlContent = `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>Mermaid Diagram</title>\n <style>\n :root {\n --bg-color: #f8f9fa;\n --text-color: #212529;\n --toolbar-bg: #f1f3f5;\n --toolbar-border: #dee2e6;\n --button-bg: #4361ee;\n --button-hover: #3a0ca3;\n }\n \n [data-theme=\"dark\"] {\n --bg-color: #212529;\n --text-color: #f8f9fa;\n --toolbar-bg: #343a40;\n --toolbar-border: #495057;\n --button-bg: #4361ee;\n --button-hover: #5a72f0;\n }\n \n body {\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n height: 100vh;\n background-color: var(--bg-color);\n color: var(--text-color);\n font-family: system-ui, -apple-system, sans-serif;\n transition: background-color 0.3s ease, color 0.3s ease;\n }\n \n .toolbar {\n background-color: var(--toolbar-bg);\n border-bottom: 1px solid var(--toolbar-border);\n padding: 8px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n transition: background-color 0.3s ease, border-color 0.3s ease;\n }\n \n .toolbar button {\n background-color: var(--button-bg);\n color: white;\n border: none;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n margin-right: 8px;\n font-size: 14px;\n transition: background-color 0.3s ease;\n }\n \n .toolbar button:hover {\n background-color: var(--button-hover);\n }\n \n .theme-toggle {\n background-color: transparent;\n border: 1px solid var(--text-color);\n color: var(--text-color);\n padding: 4px 8px;\n font-size: 12px;\n }\n \n .theme-toggle:hover {\n background-color: var(--text-color);\n color: var(--bg-color);\n }\n \n .container {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: auto;\n padding: 20px;\n }\n \n svg {\n max-width: 100%;\n max-height: 100%;\n height: auto;\n width: auto;\n transition: all 0.3s ease;\n }\n </style>\n </head>\n <body data-theme=\"light\">\n <div class=\"toolbar\">\n <div>\n <button onclick=\"zoomIn()\">Zoom In</button>\n <button onclick=\"zoomOut()\">Zoom Out</button>\n <button onclick=\"resetZoom()\">Reset</button>\n <button class=\"theme-toggle\" onclick=\"toggleTheme()\">🌙 Dark</button>\n </div>\n <div>\n <button onclick=\"downloadSvg()\">Download SVG</button>\n </div>\n </div>\n <div class=\"container\" id=\"svg-container\">\n ${svgData}\n </div>\n <script>\n const svg = document.querySelector('svg');\n let currentScale = 1;\n let isDarkMode = false;\n \n // Make sure SVG is responsive\n svg.setAttribute('width', '100%');\n svg.setAttribute('height', '100%');\n svg.style.maxWidth = '100%';\n svg.style.maxHeight = '100%';\n svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n \n function zoomIn() {\n currentScale *= 1.2;\n svg.style.transform = \\`scale(\\${currentScale})\\`;\n }\n \n function zoomOut() {\n currentScale /= 1.2;\n svg.style.transform = \\`scale(\\${currentScale})\\`;\n }\n \n function resetZoom() {\n currentScale = 1;\n svg.style.transform = 'scale(1)';\n }\n \n function toggleTheme() {\n isDarkMode = !isDarkMode;\n const body = document.body;\n const themeButton = document.querySelector('.theme-toggle');\n \n if (isDarkMode) {\n body.setAttribute('data-theme', 'dark');\n themeButton.textContent = '☀️ Light';\n } else {\n body.setAttribute('data-theme', 'light');\n themeButton.textContent = '🌙 Dark';\n }\n \n // Re-render Mermaid diagram with new theme\n reRenderMermaidDiagram();\n }\n \n function reRenderMermaidDiagram() {\n const svgContainer = document.getElementById('svg-container');\n const currentSvg = svgContainer.querySelector('svg');\n \n if (!currentSvg) return;\n \n // Apply Mermaid-specific theme styling\n applyMermaidTheme(currentSvg, isDarkMode);\n }\n \n function applyMermaidTheme(svgElement, isDark) {\n const darkTheme = {\n primaryColor: '#88c0d0',\n primaryTextColor: '#ffffff',\n primaryBorderColor: '#88c0d0',\n lineColor: '#88c0d0',\n secondaryColor: '#5e81ac',\n tertiaryColor: '#2e3440',\n textColor: '#eceff4',\n mainBkg: '#3b4252',\n secondBkg: '#434c5e',\n nodeBorder: '#88c0d0',\n edgeLabelBackground: '#4c566a',\n altBackground: '#2e3440',\n nodeBkg: '#3b4252',\n clusterBkg: '#2e3440'\n };\n \n const lightTheme = {\n primaryColor: '#1890ff',\n primaryTextColor: '#000000',\n primaryBorderColor: '#1890ff',\n lineColor: '#333333',\n secondaryColor: '#f0f0f0',\n tertiaryColor: '#ffffff',\n textColor: '#333333',\n mainBkg: '#ffffff',\n secondBkg: '#f8f9fa',\n nodeBorder: '#cccccc',\n edgeLabelBackground: '#ffffff',\n altBackground: '#f5f5f5',\n nodeBkg: '#ffffff',\n clusterBkg: '#f8f9fa'\n };\n \n const colors = isDark ? darkTheme : lightTheme;\n \n // Apply theme to Mermaid elements\n svgElement.querySelectorAll('.edgePath path').forEach(el => {\n el.setAttribute('stroke', colors.lineColor);\n el.setAttribute('stroke-width', '1.5px');\n });\n \n svgElement.querySelectorAll('defs marker path').forEach(el => {\n el.setAttribute('stroke', colors.lineColor);\n el.setAttribute('fill', colors.lineColor);\n });\n \n svgElement.querySelectorAll('.node rect, .node circle, .node polygon, .node path').forEach(el => {\n el.setAttribute('stroke', colors.nodeBorder);\n el.setAttribute('fill', colors.nodeBkg);\n });\n \n svgElement.querySelectorAll('.cluster rect').forEach(el => {\n el.setAttribute('stroke', colors.nodeBorder);\n el.setAttribute('fill', colors.clusterBkg);\n });\n \n // Text styling - node labels should contrast with node background\n svgElement.querySelectorAll('.node .label text, .cluster .label text').forEach(el => {\n el.setAttribute('fill', isDark ? '#000000' : '#333333');\n });\n \n // Edge labels and other text should use theme text color\n svgElement.querySelectorAll('.edgeLabel text, text:not(.node .label text):not(.cluster .label text)').forEach(el => {\n el.setAttribute('fill', colors.textColor);\n });\n \n // Flow chart links\n svgElement.querySelectorAll('.flowchart-link, path.path, path.messageText').forEach(el => {\n el.setAttribute('stroke', colors.lineColor);\n el.setAttribute('stroke-width', '1.5px');\n });\n }\n \n function downloadSvg() {\n const svgData = new XMLSerializer().serializeToString(svg);\n const svgBlob = new Blob([svgData], {type: 'image/svg+xml'});\n const url = URL.createObjectURL(svgBlob);\n \n const link = document.createElement('a');\n link.href = url;\n link.download = 'mermaid-diagram-${Date.now()}.svg';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n \n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }\n \n // Initialize theme based on system preference\n if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n toggleTheme();\n }\n </script>\n </body>\n </html>\n `;\n\n // Create a blob with the HTML content\n const blob = new Blob([htmlContent], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n\n // Open in a new window with specific dimensions\n const popupWindow = window.open(\n url,\n 'MermaidDiagram',\n `width=${width},height=${height},resizable=yes,scrollbars=yes,status=no,toolbar=no,menubar=no,location=no`\n );\n\n // Focus the new window\n if (popupWindow) {\n popupWindow.focus();\n }\n\n // Clean up the URL object after a delay\n setTimeout(() => URL.revokeObjectURL(url), 10000);\n };\n actionsContainer.appendChild(openButton);\n\n // Add Save button\n const saveButton = document.createElement('button');\n saveButton.innerHTML = '💾 Save';\n saveButton.className = 'diagram-action-button mermaid-save-button';\n saveButton.onclick = () => {\n // Get the SVG element\n const svgElement = wrapper.querySelector('svg');\n if (!svgElement) return;\n\n // Create a new SVG with proper XML declaration and doctype\n const svgData = new XMLSerializer().serializeToString(svgElement);\n\n // Create a properly formatted SVG document with XML declaration\n const svgDoc = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n${svgData}`;\n\n // Create a blob with the SVG content\n const blob = new Blob([svgDoc], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n\n // Create a download link\n const link = document.createElement('a');\n link.href = url;\n link.download = `mermaid-diagram-${Date.now()}.svg`;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n // Clean up the URL object after a delay\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n };\n actionsContainer.appendChild(saveButton);\n\n // Add Source button\n let showingSource = false;\n const originalContent = wrapper.innerHTML;\n const sourceButton = document.createElement('button');\n sourceButton.innerHTML = showingSource ? '🎨 View' : '📝 Source';\n sourceButton.className = 'diagram-action-button mermaid-source-button';\n sourceButton.onclick = () => {\n showingSource = !showingSource;\n sourceButton.innerHTML = showingSource ? '🎨 View' : '📝 Source';\n\n if (showingSource) {\n wrapper.innerHTML = `<pre style=\"\n background-color: ${isDarkMode ? '#1f1f1f' : '#f6f8fa'};\n padding: 16px;\n border-radius: 4px;\n overflow: auto;\n color: ${isDarkMode ? '#e6e6e6' : '#24292e'};\n \"><code>${spec.definition}</code></pre>`;\n } else {\n wrapper.innerHTML = originalContent;\n }\n };\n actionsContainer.appendChild(sourceButton);\n\n // Add actions container\n container.insertBefore(actionsContainer, wrapper);\n\n } catch (error: any) {\n console.error('Mermaid rendering error:', error);\n\n // Remove any loading spinner if it exists\n const spinner = container.querySelector('.mermaid-loading-spinner');\n if (spinner) {\n container.removeChild(spinner);\n }\n\n // Clear container before showing error\n if (container.innerHTML.includes('Rendering diagram')) {\n container.innerHTML = '';\n }\n\n // Extract the first line to check for diagram type\n const lines = spec.definition.trim().split('\\n');\n const firstLine = lines[0]?.trim() || '';\n const diagramType = firstLine.split(' ')[0];\n\n // Enhanced error analysis\n let errorTitle = 'Mermaid Rendering Error';\n let errorMessage = 'There was an error rendering the diagram.';\n\n // Analyze the error message for common patterns\n const errorMsg = error.message || '';\n\n if (errorMsg.includes('Parse error') || errorMsg.includes('Expecting')) {\n errorTitle = 'Mermaid Syntax Error';\n errorMessage = 'There is a syntax error in the Mermaid diagram definition. The diagram may have malformed connections or invalid characters.';\n } else if (errorMsg.includes('Lexical error') || errorMsg.includes('Unrecognized text')) {\n errorTitle = 'Mermaid Lexical Error';\n errorMessage = 'Mermaid encountered unrecognized text or invalid syntax in the diagram definition.';\n } else if (errorMsg.includes('empty SVG returned')) {\n // Check if this diagram type is actually supported\n try {\n const { detectSupportedDiagramTypes, normalizeDiagramType } = await import('./mermaidEnhancer');\n const supportedTypes = detectSupportedDiagramTypes(mermaid);\n const normalizedType = normalizeDiagramType(diagramType, mermaid);\n \n console.log('Type detection debug:', {\n diagramType,\n normalizedType,\n supportedTypesSize: supportedTypes.size,\n supportedTypes: Array.from(supportedTypes),\n hasOriginal: supportedTypes.has(diagramType),\n hasNormalized: supportedTypes.has(normalizedType)\n });\n \n // If detection failed (empty set), fall back to parsing error\n if (supportedTypes.size === 0) {\n console.warn('Type detection returned empty set, falling back to parsing error');\n errorTitle = 'Mermaid Parsing Error';\n errorMessage = 'Mermaid parsing failed - this usually indicates syntax errors in the diagram definition.';\n } else if (diagramType && !supportedTypes.has(diagramType) && !supportedTypes.has(normalizedType)) {\n errorTitle = 'Unsupported Diagram Type';\n errorMessage = `The diagram type \"${diagramType}\" is not supported in the current version of Mermaid. This may be a beta feature that hasn't been released yet.`;\n } else {\n errorTitle = 'Mermaid Parsing Error';\n errorMessage = 'Mermaid parsing failed - this usually indicates syntax errors in the diagram definition.';\n }\n } catch (detectionError) {\n console.warn('Could not detect supported types:', detectionError);\n errorTitle = 'Mermaid Parsing Error';\n errorMessage = 'Mermaid parsing failed - this usually indicates syntax errors in the diagram definition.';\n }\n }\n\n if (!spec.isStreaming || spec.forceRender) {\n // First clear the container and add the error message\n container.innerHTML = `\n <div class=\"mermaid-error\">\n <strong>${errorTitle}:</strong>\n <p>${errorMessage}</p>\n <pre>${error.message || 'Unknown error'}</pre>\n <details>\n <summary>Show Definition</summary>\n <pre><code>${spec.definition}</code></pre>\n </details>\n </div>\n `;\n\n // Create buttons\n const viewSourceButton = document.createElement('button');\n viewSourceButton.innerHTML = '📝 View Source';\n viewSourceButton.className = 'diagram-action-button mermaid-source-button';\n viewSourceButton.style.cssText = `\n background-color: #4361ee;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 10px 5px;\n cursor: pointer;\n display: inline-block;\n `;\n\n // Add retry button\n const retryButton = document.createElement('button');\n retryButton.innerHTML = '🔄 Retry Rendering';\n retryButton.className = 'diagram-action-button mermaid-retry-button';\n retryButton.style.cssText = `\n background-color: #4361ee;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 10px auto;\n cursor: pointer;\n display: block;\n `;\n\n // Create button container\n const buttonContainer = document.createElement('div');\n buttonContainer.style.textAlign = 'center';\n buttonContainer.appendChild(viewSourceButton);\n buttonContainer.appendChild(retryButton);\n container.appendChild(buttonContainer);\n\n // Add event listeners\n retryButton.onclick = () => mermaidPlugin.render(container, d3, spec, isDarkMode);\n viewSourceButton.onclick = () => {\n // Toggle between error view and source view\n const errorView = container.querySelector('.mermaid-error');\n if (errorView) {\n // Create source view\n container.innerHTML = `<pre style=\"\n background-color: ${isDarkMode ? '#1f1f1f' : '#f6f8fa'};\n padding: 16px;\n border-radius: 4px;\n overflow: auto;\n color: ${isDarkMode ? '#e6e6e6' : '#24292e'};\n \"><code>${spec.definition}</code></pre>`;\n\n // Add back button\n const backButton = document.createElement('button');\n backButton.innerHTML = '⬅️ Back to Error';\n backButton.className = 'diagram-action-button';\n backButton.style.cssText = `\n background-color: #4361ee;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 10px auto;\n cursor: pointer;\n display: block;\n `;\n backButton.onclick = () => mermaidPlugin.render(container, d3, spec, isDarkMode);\n container.appendChild(backButton);\n }\n };\n }\n } \n};\n\n/** \n * Get a contrasting text color based on background color\n * @param backgroundColor - The background color (hex) \n * @returns - A contrasting color for text\n */\nfunction getTextContrastColor(backgroundColor: string): string {\n // Convert hex to RGB\n const hexToRgb = (hex: string) => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n };\n\n const rgb = hexToRgb(backgroundColor);\n if (!rgb) return '#000000';\n\n // Special handling for yellow and yellow-ish colors\n // Yellow has high luminance but white text on yellow is terrible\n if (rgb.r > 200 && rgb.g > 200 && rgb.b < 100) {\n return '#000000'; // Always use black on yellow/yellow-ish\n }\n\n // Special handling for beige/cream colors (high R, G, moderate B)\n if (rgb.r > 220 && rgb.g > 200 && rgb.b > 150) {\n return '#000000'; // Always use black on beige/cream\n }\n\n // Calculate relative luminance using proper sRGB formula\n const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;\n\n // Use a more conservative threshold - prefer black text unless background is quite dark\n return luminance > 0.4 ? '#000000' : '#ffffff';\n}\n\n/**\n * Get optimal text color based on background color with special handling for problematic colors\n * @param backgroundColor - The background color (hex)\n * @returns - The best contrasting text color\n */\nfunction getOptimalTextColor(backgroundColor: string): string {\n // Convert hex to RGB\n const hexToRgb = (hex: string) => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n };\n\n const rgb = hexToRgb(backgroundColor);\n if (!rgb) return '#000000';\n\n // Special handling for yellow and yellow-ish colors\n if (rgb.r > 200 && rgb.g > 200 && rgb.b < 100) {\n return '#000000'; // Always use black on yellow/yellow-ish\n }\n\n // Special handling for beige/cream colors\n if (rgb.r > 220 && rgb.g > 200 && rgb.b > 150) {\n return '#000000'; // Always use black on beige/cream\n }\n\n // Calculate relative luminance and use conservative threshold\n const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;\n return luminance > 0.4 ? '#000000' : '#ffffff';\n}\n\nfunction isProblematicBackground(color: string): boolean {\n if (!color || color === 'none' || color === 'transparent') return false;\n\n // Normalize the color to uppercase and remove # if present\n console.log(` Checking if background is problematic: ${color}`);\n\n let normalizedColor: string;\n\n // Handle RGB format: rgb(255, 245, 157) -> FFF59D\n if (color.startsWith('rgb(')) {\n const rgbMatch = color.match(/rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)/);\n if (rgbMatch) {\n const [, r, g, b] = rgbMatch;\n normalizedColor = [r, g, b]\n .map(x => parseInt(x).toString(16).padStart(2, '0'))\n .join('').toUpperCase();\n console.log(` Converted RGB ${color} to hex: ${normalizedColor}`);\n } else {\n return false;\n }\n } else {\n normalizedColor = color.toUpperCase();\n }\n\n if (normalizedColor.startsWith('#')) {\n normalizedColor = normalizedColor.substring(1);\n }\n\n // The exact list of problematic background colors you identified\n const problematicColors = [\n 'FFEA2E', 'FFB50D', 'FFF58C', 'FFF59D', 'FFF0D9', 'E2F4E2', 'F0DDF3',\n 'DBF2FE', 'FFF7DA', 'DDEFFD', 'FDC0C8', 'F5A9D1', 'D4EA8C',\n 'FFEB3B'\n ];\n\n const result = problematicColors.includes(normalizedColor);\n console.log(` ${normalizedColor} in problematic list: ${result}`);\n // Check if this color matches any of the problematic ones\n return result;\n}\n","import * as Viz from '@viz-js/viz';\nimport { D3RenderPlugin } from '../../types/d3';\nimport { isDiagramDefinitionComplete } from '../../utils/diagramUtils';\nimport { extractDefinitionFromYAML } from '../../utils/diagramUtils';\n\nexport interface GraphvizSpec {\n type: 'graphviz';\n isStreaming?: boolean;\n isMarkdownBlockClosed?: boolean;\n forceRender?: boolean;\n definition: string;\n}\n\nconst isGraphvizSpec = (spec: any): spec is GraphvizSpec => {\n return (\n typeof spec === 'object' &&\n spec !== null &&\n spec.type === 'graphviz' &&\n typeof spec.definition === 'string' &&\n spec.definition.trim().length > 0\n );\n};\n\n// Store the current theme for each container to detect changes\nconst containerThemes = new WeakMap<HTMLElement, boolean>();\n\nexport const graphvizPlugin: D3RenderPlugin = {\n name: 'graphviz-renderer',\n priority: 5,\n sizingConfig: {\n sizingStrategy: 'auto-expand',\n needsDynamicHeight: true,\n needsOverflowVisible: true,\n observeResize: true,\n containerStyles: {\n width: '100%',\n height: 'auto',\n overflow: 'visible'\n }\n },\n canHandle: isGraphvizSpec,\n\n // Helper to check if a graphviz definition is complete\n isDefinitionComplete: (definition: string): boolean => {\n if (!definition || definition.trim().length === 0) return false;\n\n // Check for balanced braces which is a good indicator of completeness\n const openBraces = definition.split('{').length - 1;\n const closeBraces = definition.split('}').length - 1;\n\n // A complete definition should have balanced braces and end with a closing brace\n return openBraces === closeBraces && openBraces > 0 && definition.includes('}');\n },\n\n render: async (container: HTMLElement, d3: any, spec: GraphvizSpec, isDarkMode: boolean) => {\n try {\n const hasExistingContent = container.querySelector('svg') !== null;\n // Show loading spinner immediately\n const loadingSpinner = document.createElement('div');\n loadingSpinner.innerHTML = `\n <div style=\"\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 2em;\n width: 100%;\n height: 100%;\n min-height: 150px;\n \">\n <div style=\"\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-top: 4px solid ${isDarkMode ? '#4cc9f0' : '#3498db'};\n border-radius: 50%;\n width: 40px;\n height: 40px;\n animation: graphviz-spin 1s linear infinite;\n margin-bottom: 15px;\n \"></div>\n <div style=\"\n font-family: system-ui, -apple-system, sans-serif;\n color: ${isDarkMode ? '#eceff4' : '#333333'};\n \">Rendering Visualization...</div>\n </div>\n <style>\n @keyframes graphviz-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n `;\n container.innerHTML = loadingSpinner.innerHTML;\n\n // Conservative streaming approach - only render when markdown block is closed\n // This allows the content to display as highlighted code during streaming\n if (spec.isStreaming && !spec.isMarkdownBlockClosed && !spec.forceRender) {\n console.log('Graphviz: Markdown block still open, letting content display as code');\n // Don't show a waiting message - let the markdown renderer show the code\n // Just remove the loading spinner and return\n try {\n container.innerHTML = '';\n } catch (e) {\n console.warn('Could not remove loading spinner:', e);\n }\n return; // Exit early - let markdown renderer handle the streaming content\n }\n\n // Only proceed with rendering when we have a complete definition\n if (!spec.definition || spec.definition.trim().length < 10) {\n console.log('Graphviz: Definition too short, waiting for more content');\n return; // Exit early and wait for complete definition\n }\n\n // If we already have content and we're streaming, don't show errors\n if (hasExistingContent && spec.isStreaming) {\n return; // Keep existing content during streaming if definition is incomplete\n }\n console.log(`Rendering Graphviz diagram with ${spec.definition.length} chars`);\n\n // Store the current theme for this container\n containerThemes.set(container, isDarkMode);\n\n // Enhanced theme colors with better contrast\n const themeColors = {\n light: {\n text: '#333333', // Darker text for better contrast\n stroke: '#555555', // Darker stroke\n nodeFill: '#f5f5f5', // Light gray node fill\n nodeBorder: '#999999', // Medium gray node border\n edgeColor: '#333333', // Dark edge color for better visibility\n background: 'transparent',\n labelText: '#333333', // Dark label text\n clusterBg: '#f0f0f0', // Cluster background\n clusterBorder: '#cccccc' // Cluster border\n },\n dark: {\n // Bright, happy colors for dark mode\n text: '#ffffff', // White text for high contrast\n stroke: '#00b7ff', // Bright cyan stroke\n nodeFill: '#2a3990', // Rich blue node fill\n nodeBorder: '#4cc9f0', // Bright blue node border\n edgeColor: '#f72585', // Vibrant pink edge color for high visibility\n background: 'transparent',\n labelText: '#ffffff', // White text for labels\n clusterBg: '#1a1a2e', // Dark cluster background\n clusterBorder: '#4cc9f0', // Bright cluster border\n\n // Alternative node colors for variety\n nodeColors: [\n '#4361ee', // Royal blue\n '#3a0ca3', // Deep purple\n '#7209b7', // Vibrant purple\n '#f72585', // Hot pink\n '#4cc9f0', // Bright cyan\n '#06d6a0', // Mint green\n '#118ab2', // Teal\n ]\n }\n };\n\n const colors = isDarkMode ? themeColors.dark : themeColors.light;\n\n const vizInstance = await Viz.instance();\n\n // Extract actual content from YAML wrapper if present\n let processedDefinition = extractDefinitionFromYAML(spec.definition, 'graphviz');\n\n // This converts all standard string labels to the more robust HTML-like label format.\n processedDefinition = processedDefinition.replace(/label\\s*=\\s*\"((?:\\\\\"|[^\"])*)\"/g, (match, content) => {\n // First, unescape any `\\\"` that might be in the original content string.\n const unescapedContent = content.replace(/\\\\\"/g, '\"');\n\n // Now, escape for HTML-like label format.\n const escapedForHtml = unescapedContent\n .replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')\n .replace(/\"/g, '"').replace(/\\\\n/g, '<br/>').replace(/\\n/g, '<br/>');\n\n return `label=<${escapedForHtml}>`;\n\n });\n\n // Add theme attributes to dot with more styling options\n let themedDot = processedDefinition;\n\n // Only add theme attributes if the graph has a proper structure\n if (processedDefinition.match(/^(\\s*(?:di)?graph\\s+[^{]*{)/)) {\n // Set default text color based on page mode\n const defaultTextColor = isDarkMode ? '#ffffff' : '#000000';\n\n themedDot = processedDefinition.replace(\n /^(\\s*(?:di)?graph\\s+[^{]*{)/,\n `$1\n bgcolor=\"transparent\";\n node [color=\"${colors.nodeBorder}\", style=\"filled\", fillcolor=\"${colors.nodeFill}\", penwidth=1.5];\n edge [color=\"${colors.edgeColor}\", fontcolor=\"${defaultTextColor}\", penwidth=1.5];\n graph [fontcolor=\"${defaultTextColor}\", color=\"${colors.clusterBorder}\", fontname=\"Arial\"];`\n );\n // Handle graph label if present\n const labelMatch = spec.definition.match(/^\\s*label\\s*=\\s*\"([^\"]+)\"/m);\n if (labelMatch) {\n const originalLabel = labelMatch[1];\n themedDot = themedDot.replace(\n /^\\s*label\\s*=\\s*\"([^\"]+)\"/m,\n ` label=<<font color=\"${defaultTextColor}\">${originalLabel}</font>>`\n );\n }\n }\n\n const element = await vizInstance.renderSVGElement(themedDot);\n\n // Apply theme to SVG elements with more specific styling\n const elements = element.getElementsByTagName('*');\n\n // For dark mode, prepare to assign different colors to nodes\n let nodeIndex = 0;\n const nodeColors = isDarkMode ? themeColors.dark.nodeColors : [];\n\n // First pass: Apply colors to nodes and collect background colors\n const nodeBackgroundColors = new Map(); // Map to store node background colors\n const clusterBackgroundColors = new Map(); // Map to store cluster background colors\n\n // First identify all clusters and their background colors\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i];\n\n // Identify cluster backgrounds\n if (el.tagName === 'polygon' && el.parentElement && el.parentElement.classList.contains('cluster')) {\n const originalFill = el.getAttribute('fill');\n if (originalFill) {\n clusterBackgroundColors.set(el.parentElement, originalFill);\n\n // In dark mode, override light cluster backgrounds\n if (isDarkMode) {\n // Check if this is a light color that needs to be darkened\n if (isLightColor(originalFill)) {\n // Use a darker color based on the original hue\n const darkColor = getDarkVersionOfColor(originalFill);\n el.setAttribute('fill', darkColor);\n el.setAttribute('stroke', colors.clusterBorder);\n\n // Store the fact that we changed this color\n el.setAttribute('data-original-fill', originalFill);\n el.setAttribute('data-darkened', 'true');\n }\n }\n }\n }\n }\n\n // Then process nodes\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i];\n\n if (el.tagName === 'ellipse' || el.tagName === 'polygon') {\n // Node shapes\n if (el.getAttribute('fill') !== 'none') {\n // Store the original fill color before we modify it\n const originalFill = el.getAttribute('fill');\n if (originalFill) {\n // Store the element and its original fill color\n nodeBackgroundColors.set(el, originalFill);\n }\n\n // In dark mode, handle node colors\n if (isDarkMode) {\n // Check if this is a light color that needs to be darkened\n if (originalFill && isLightColor(originalFill)) {\n // For white or very light colors, use our node colors\n if (originalFill.toLowerCase() === '#ffffff' ||\n originalFill.toLowerCase() === 'white' ||\n getBrightness(originalFill) > 0.9) {\n\n if (nodeColors.length > 0) {\n const colorIndex = nodeIndex % nodeColors.length;\n el.setAttribute('fill', nodeColors[colorIndex]);\n\n // Store the fact that we changed this color\n el.setAttribute('data-original-fill', originalFill);\n el.setAttribute('data-darkened', 'true');\n\n nodeIndex++;\n } else {\n el.setAttribute('fill', colors.nodeFill);\n\n // Store the fact that we changed this color\n el.setAttribute('data-original-fill', originalFill);\n el.setAttribute('data-darkened', 'true');\n }\n } else {\n // For other light colors, darken them\n const darkColor = getDarkVersionOfColor(originalFill);\n el.setAttribute('fill', darkColor);\n\n // Store the fact that we changed this color\n el.setAttribute('data-original-fill', originalFill);\n el.setAttribute('data-darkened', 'true');\n }\n }\n\n // Set border color\n el.setAttribute('stroke', colors.nodeBorder);\n el.setAttribute('stroke-width', '1.5');\n }\n }\n }\n }\n\n // Second pass: Apply text colors based on their parent node colors\n // and ensure edges are visible against backgrounds\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i];\n\n if (el.tagName === 'text') {\n // Default text color based on page mode\n // Use the opposite of the page background for maximum visibility\n const defaultTextColor = isDarkMode ? '#ffffff' : '#000000';\n el.setAttribute('fill', defaultTextColor);\n\n // For node labels, ensure text is readable against node background\n const parent = el.parentElement;\n if (parent) {\n // Find the node shape element (ellipse, polygon) in the parent\n const nodeShape = parent.querySelector('ellipse, polygon');\n\n if (nodeShape) {\n // Get the current fill color of the node\n const currentFill = nodeShape.getAttribute('fill');\n\n // If we have a background color, set text color based on its brightness\n if (currentFill) {\n const isLightBackground = isLightColor(currentFill);\n el.setAttribute('fill', isLightBackground ? '#000000' : '#ffffff');\n }\n\n // Add debug attributes\n el.setAttribute('data-bg-color', currentFill || 'unknown');\n el.setAttribute('data-is-light', isLightColor(currentFill || '') ? 'true' : 'false');\n } else if (parent.classList.contains('cluster')) {\n // This is a cluster label\n // Find the cluster background\n const clusterBg = parent.querySelector('polygon');\n if (clusterBg) {\n const bgColor = clusterBg.getAttribute('fill');\n // If we have a background color, set text color based on its brightness\n if (bgColor) {\n const isLightBackground = isLightColor(bgColor);\n el.setAttribute('fill', isLightBackground ? '#000000' : '#ffffff');\n }\n }\n } else if (parent.classList.contains('edge')) {\n // This is an edge label - use the default text color based on page mode\n // This ensures edge labels are visible against the page background\n el.setAttribute('fill', defaultTextColor);\n }\n }\n\n // Special case for graph labels (which might not have a direct node parent)\n if (parent && parent.classList.contains('graph')) {\n // Graph labels should match the default text color for the page mode\n el.setAttribute('fill', defaultTextColor);\n }\n } else if (el.tagName === 'path') {\n // Edge paths\n if (!el.getAttribute('fill') || el.getAttribute('fill') === 'none') {\n // Make sure edges are visible with high contrast color\n el.setAttribute('stroke', colors.edgeColor);\n el.setAttribute('stroke-width', '1.5');\n }\n } else if (el.tagName === 'polygon' && el.classList.contains('arrow')) {\n // This is an arrowhead\n el.setAttribute('fill', colors.edgeColor);\n el.setAttribute('stroke', colors.edgeColor);\n }\n }\n\n // Clear container and append SVG\n container.innerHTML = '';\n\n // Create wrapper div similar to mermaid plugin\n const wrapper = document.createElement('div');\n wrapper.className = 'graphviz-wrapper';\n wrapper.style.cssText = `\n width: 100%;\n max-width: 100%;\n overflow: auto;\n padding: 1em;\n display: flex;\n justify-content: center;\n `;\n\n // Add the SVG to the wrapper\n wrapper.appendChild(element);\n\n // Add wrapper to container\n container.appendChild(wrapper);\n\n // Add action buttons container\n const actionsContainer = document.createElement('div');\n actionsContainer.className = 'diagram-actions';\n\n // Add Open button\n const openButton = document.createElement('button');\n openButton.innerHTML = '↗️ Open';\n openButton.className = 'diagram-action-button graphviz-open-button';\n openButton.onclick = () => {\n // Get the SVG dimensions\n const svgGraphics = element as unknown as SVGGraphicsElement;\n let width = 600;\n let height = 400;\n\n try {\n // Try to get the bounding box\n const bbox = svgGraphics.getBBox();\n width = Math.max(bbox.width + 50, 400); // Add padding, minimum 400px\n height = Math.max(bbox.height + 100, 300); // Add padding, minimum 300px\n } catch (e) {\n console.warn('Could not get SVG dimensions, using defaults', e);\n }\n\n // Create a new SVG with proper XML declaration and doctype\n const svgData = new XMLSerializer().serializeToString(element);\n\n // Create an HTML document that will display the SVG responsively\n const htmlContent = `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>Graphviz Diagram</title>\n <style>\n body {\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n height: 100vh;\n background-color: #f8f9fa;\n font-family: system-ui, -apple-system, sans-serif;\n }\n .toolbar {\n background-color: #f1f3f5;\n border-bottom: 1px solid #dee2e6;\n padding: 8px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .toolbar button {\n background-color: #4361ee;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n margin-right: 8px;\n font-size: 14px;\n }\n .toolbar button:hover {\n background-color: #3a0ca3;\n }\n .container {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: auto;\n padding: 20px;\n }\n svg {\n max-width: 100%;\n max-height: 100%;\n height: auto;\n width: auto;\n }\n @media (prefers-color-scheme: dark) {\n body {\n background-color: #212529;\n color: #f8f9fa;\n }\n .toolbar {\n background-color: #343a40;\n border-bottom: 1px solid #495057;\n }\n }\n </style>\n </head>\n <body>\n <div class=\"toolbar\">\n <div>\n <button onclick=\"zoomIn()\">Zoom In</button>\n <button onclick=\"zoomOut()\">Zoom Out</button>\n <button onclick=\"resetZoom()\">Reset</button>\n </div>\n <div>\n <button onclick=\"downloadSvg()\">Download SVG</button>\n </div>\n </div>\n <div class=\"container\" id=\"svg-container\">\n ${svgData}\n </div>\n <script>\n const svg = document.querySelector('svg');\n let currentScale = 1;\n \n // Make sure SVG is responsive\n svg.setAttribute('width', '100%');\n svg.setAttribute('height', '100%');\n svg.style.maxWidth = '100%';\n svg.style.maxHeight = '100%';\n svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n \n function zoomIn() {\n currentScale *= 1.2;\n svg.style.transform = \\`scale(\\${currentScale})\\`;\n }\n \n function zoomOut() {\n currentScale /= 1.2;\n svg.style.transform = \\`scale(\\${currentScale})\\`;\n }\n \n function resetZoom() {\n currentScale = 1;\n svg.style.transform = 'scale(1)';\n }\n \n function downloadSvg() {\n const svgData = new XMLSerializer().serializeToString(svg);\n const svgBlob = new Blob([svgData], {type: 'image/svg+xml'});\n const url = URL.createObjectURL(svgBlob);\n \n const link = document.createElement('a');\n link.href = url;\n link.download = 'graphviz-diagram.svg';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n \n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }\n </script>\n </body>\n </html>\n `;\n\n // Create a blob with the HTML content\n const blob = new Blob([htmlContent], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n\n // Open in a new window with specific dimensions\n const popupWindow = window.open(\n url,\n 'GraphvizDiagram',\n `width=${width},height=${height},resizable=yes,scrollbars=yes,status=no,toolbar=no,menubar=no,location=no`\n );\n\n // Focus the new window\n if (popupWindow) {\n popupWindow.focus();\n }\n\n // Clean up the URL object after a delay\n setTimeout(() => URL.revokeObjectURL(url), 10000);\n };\n actionsContainer.appendChild(openButton);\n\n // Add Save button\n const saveButton = document.createElement('button');\n saveButton.innerHTML = '💾 Save';\n saveButton.className = 'diagram-action-button graphviz-save-button';\n saveButton.onclick = () => {\n // Create a new SVG with proper XML declaration and doctype\n const svgData = new XMLSerializer().serializeToString(element);\n\n // Create a properly formatted SVG document with XML declaration\n const svgDoc = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n${svgData}`;\n\n // Create a blob with the SVG content\n const blob = new Blob([svgDoc], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n\n // Create a download link\n const link = document.createElement('a');\n link.href = url;\n link.download = `graphviz-diagram-${Date.now()}.svg`;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n // Clean up the URL object after a delay\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n };\n actionsContainer.appendChild(saveButton);\n\n // Add Source button with toggle functionality like in mermaid plugin\n let showingSource = false;\n const originalContent = wrapper.innerHTML;\n const sourceButton = document.createElement('button');\n sourceButton.innerHTML = showingSource ? '🎨 View' : '📝 Source';\n sourceButton.className = 'diagram-action-button graphviz-source-button';\n sourceButton.onclick = () => {\n showingSource = !showingSource;\n sourceButton.innerHTML = showingSource ? '🎨 View' : '📝 Source';\n\n if (showingSource) {\n wrapper.innerHTML = `<pre style=\"\n background-color: ${isDarkMode ? '#1f1f1f' : '#f6f8fa'};\n padding: 16px;\n border-radius: 4px;\n overflow: auto;\n color: ${isDarkMode ? '#e6e6e6' : '#24292e'};\n \"><code>${spec.definition}</code></pre>`;\n } else {\n wrapper.innerHTML = originalContent;\n }\n };\n actionsContainer.appendChild(sourceButton);\n\n // Add actions container before the wrapper\n container.insertBefore(actionsContainer, wrapper);\n\n // Add a theme button to manually re-render with the opposite theme\n const themeButton = document.createElement('button');\n themeButton.innerHTML = isDarkMode ? '☀️ Light' : '🌙 Dark';\n themeButton.className = 'diagram-action-button graphviz-theme-button';\n themeButton.onclick = () => {\n // Re-render with the opposite theme\n graphvizPlugin.render(container, d3, spec, !isDarkMode);\n };\n actionsContainer.appendChild(themeButton);\n } catch (error) {\n console.error('Graphviz rendering error:', error);\n\n // Only show error if we're not streaming or if we have no existing content\n if (!spec.isStreaming || !container.querySelector('svg')) {\n container.innerHTML = `\n <div class=\"graphviz-error\">\n <strong>Graphviz Error:</strong>\n <pre>${error instanceof Error ? error.message : 'Unknown error'}</pre>\n <details>\n <summary>Show Definition</summary>\n <pre><code>${spec.definition}</code></pre>\n </details>\n </div>\n `;\n }\n }\n }\n};\n\n// Helper function to determine if a color is light or dark\nfunction isLightColor(color: string): boolean {\n // Default to assuming it's a dark color if we can't parse it\n if (!color || color === 'transparent' || color === 'none') {\n return false;\n }\n\n // Handle specific named colors that we know are light\n const lightNamedColors = [\n 'white', 'lightblue', 'lightgreen', 'lightgrey', 'lightgray', 'pink',\n '#aed6f1', '#d4e6f1', '#d5f5e3', '#f5f5f5', '#e6e6e6', '#f0f0f0',\n '#ffffff', '#f8f9fa', '#e9ecef', '#dee2e6', '#ced4da', '#adb5bd'\n ];\n\n // Case-insensitive check for light named colors\n if (lightNamedColors.some(c => c.toLowerCase() === color.toLowerCase())) {\n return true;\n }\n\n // Get brightness value\n const brightness = getBrightness(color);\n\n // More conservative threshold - if in doubt, assume it's light\n // This ensures we don't put white text on ambiguous backgrounds\n return brightness > 0.5;\n}\n\n// Helper function to calculate brightness of a color\nfunction getBrightness(color: string): number {\n // Convert hex or named colors to RGB\n let r, g, b;\n\n if (color.startsWith('#')) {\n // Handle hex colors\n const hex = color.substring(1);\n if (hex.length === 3) {\n r = parseInt(hex[0] + hex[0], 16);\n g = parseInt(hex[1] + hex[1], 16);\n b = parseInt(hex[2] + hex[2], 16);\n } else {\n r = parseInt(hex.substring(0, 2), 16);\n g = parseInt(hex.substring(2, 4), 16);\n b = parseInt(hex.substring(4, 6), 16);\n }\n } else if (color.startsWith('rgb')) {\n // Handle rgb/rgba colors\n const match = color.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*[\\d.]+)?\\)/);\n if (match) {\n r = parseInt(match[1], 10);\n g = parseInt(match[2], 10);\n b = parseInt(match[3], 10);\n } else {\n // Can't parse, assume dark\n return 0;\n }\n } else {\n // Can't parse, assume dark\n return 0;\n }\n\n // Calculate perceived brightness using the formula:\n // (0.299*R + 0.587*G + 0.114*B)\n return (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n}\n\n// Helper function to get a dark version of a color\nfunction getDarkVersionOfColor(color: string): string {\n // For named colors, map to dark equivalents\n const colorMap: Record<string, string> = {\n 'white': '#2e3440',\n 'lightblue': '#5e81ac',\n 'lightgreen': '#8fbcbb',\n 'lightgrey': '#4c566a',\n 'lightgray': '#4c566a',\n 'pink': '#b48ead'\n };\n\n // Check if we have a direct mapping\n if (colorMap[color.toLowerCase()]) {\n return colorMap[color.toLowerCase()];\n }\n\n // Otherwise, try to darken the color\n try {\n let r, g, b;\n\n if (color.startsWith('#')) {\n // Handle hex colors\n const hex = color.substring(1);\n if (hex.length === 3) {\n r = parseInt(hex[0] + hex[0], 16);\n g = parseInt(hex[1] + hex[1], 16);\n b = parseInt(hex[2] + hex[2], 16);\n } else {\n r = parseInt(hex.substring(0, 2), 16);\n g = parseInt(hex.substring(2, 4), 16);\n b = parseInt(hex.substring(4, 6), 16);\n }\n } else if (color.startsWith('rgb')) {\n // Handle rgb/rgba colors\n const match = color.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*[\\d.]+)?\\)/);\n if (match) {\n r = parseInt(match[1], 10);\n g = parseInt(match[2], 10);\n b = parseInt(match[3], 10);\n } else {\n return '#2e3440'; // Default dark color\n }\n } else {\n return '#2e3440'; // Default dark color\n }\n\n // Darken the color by reducing each component by 60%\n r = Math.max(Math.floor(r * 0.4), 0);\n g = Math.max(Math.floor(g * 0.4), 0);\n b = Math.max(Math.floor(b * 0.4), 0);\n\n // Convert back to hex\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n } catch (e) {\n return '#2e3440'; // Default dark color if parsing fails\n }\n}\n","import { D3RenderPlugin } from '../../types/d3';\nimport { isDiagramDefinitionComplete } from '../../utils/diagramUtils';\nimport { extractDefinitionFromYAML } from '../../utils/diagramUtils';\n\nimport vegaEmbed, { EmbedOptions } from 'vega-embed';\n\nexport interface VegaLiteSpec {\n type: 'vega-lite';\n isStreaming?: boolean;\n isMarkdownBlockClosed?: boolean;\n forceRender?: boolean;\n definition?: string;\n spec?: any; // The actual Vega-Lite specification\n $schema?: string;\n data?: any;\n mark?: any;\n encoding?: any;\n width?: number | string;\n height?: number;\n [key: string]: any; // Allow other Vega-Lite properties\n}\n\n// Type guard to check if a spec is for Vega-Lite\nconst isVegaLiteSpec = (spec: any): spec is VegaLiteSpec => {\n if (typeof spec === 'string') {\n try {\n const parsed = JSON.parse(spec);\n return isVegaLiteObject(parsed);\n } catch {\n return false;\n }\n }\n\n return isVegaLiteObject(spec);\n};\n\n// Helper to check if an object is a Vega-Lite specification\nconst isVegaLiteObject = (obj: any): boolean => {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n // Explicitly reject other known diagram types to prevent mis-identification\n (!obj.type || !['mermaid', 'graphviz', 'network', 'd2', 'joint'].includes(obj.type)) &&\n (\n obj.type === 'vega-lite' ||\n (obj.$schema && typeof obj.$schema === 'string' && obj.$schema.includes('vega-lite')) ||\n (obj.mark && (obj.encoding || obj.data)) ||\n (obj.layer && Array.isArray(obj.layer)) ||\n (obj.vconcat && Array.isArray(obj.vconcat)) ||\n (obj.hconcat && Array.isArray(obj.hconcat)) ||\n (obj.facet && obj.spec)\n )\n );\n};\n\nfunction sanitizeSpec(obj: any): any {\n if (obj === null || obj === undefined) {\n return undefined;\n }\n if (Array.isArray(obj)) {\n return obj.map(sanitizeSpec).filter(v => v !== undefined);\n }\n if (typeof obj === 'object') {\n const newObj: any = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const value = sanitizeSpec(obj[key]);\n if (value !== undefined) {\n newObj[key] = value;\n }\n }\n }\n return newObj;\n }\n return obj;\n}\n\n// Helper to check if a Vega-Lite definition is complete\nconst isVegaLiteDefinitionComplete = (definition: string): boolean => {\n if (!definition || definition.trim().length === 0) return false;\n\n // Check for obviously incomplete JSON (common during streaming)\n const trimmed = definition.trim();\n if (trimmed.endsWith(',') || trimmed.endsWith('{') || trimmed.endsWith('[')) {\n return false;\n }\n\n // Check for unterminated strings (common streaming issue)\n if (trimmed.includes('\"$') && !trimmed.includes('\"$schema\"')) {\n return false;\n }\n\n try {\n const parsed = JSON.parse(definition);\n\n // Basic completeness checks\n if (!parsed || typeof parsed !== 'object') return false;\n\n // Check for incomplete schema URLs (common during streaming)\n if (parsed.$schema && typeof parsed.$schema === 'string' && !parsed.$schema.endsWith('.json')) {\n return false;\n }\n\n // Check for required Vega-Lite properties\n const hasData = parsed.data !== undefined;\n const hasVisualization = parsed.mark || parsed.layer || parsed.concat || parsed.facet || parsed.repeat;\n\n // A complete spec should have both data and visualization\n return hasData && hasVisualization;\n } catch (error) {\n // If JSON is malformed, it's not complete\n return false;\n }\n};\n\nexport const vegaLitePlugin: D3RenderPlugin = {\n name: 'vega-lite-renderer',\n priority: 8, // Higher priority than basic chart but lower than mermaid/graphviz\n sizingConfig: {\n sizingStrategy: 'content-driven',\n needsDynamicHeight: true,\n needsOverflowVisible: true,\n observeResize: true,\n containerStyles: {\n width: '100%',\n height: 'auto'\n }\n },\n\n canHandle: (spec: any): boolean => {\n return isVegaLiteSpec(spec);\n },\n\n // Helper to check if a vega-lite definition is complete\n isDefinitionComplete: (definition: string): boolean => {\n return isVegaLiteDefinitionComplete(definition);\n },\n\n render: async (container: HTMLElement, d3: any, spec: VegaLiteSpec, isDarkMode: boolean): Promise<void> => {\n console.log('Vega-Lite plugin render called with spec:', spec);\n console.log('Vega-Lite streaming state:', {\n isStreaming: spec.isStreaming,\n isMarkdownBlockClosed: spec.isMarkdownBlockClosed,\n forceRender: spec.forceRender\n });\n\n // Clean up any existing Vega view first\n const existingView = (container as any)._vegaView;\n if (existingView) {\n existingView.finalize();\n delete (container as any)._vegaView;\n }\n\n // Clear container\n container.innerHTML = '';\n\n // Remove any existing vega-embed instances\n const existingEmbeds = container.querySelectorAll('.vega-embed');\n existingEmbeds.forEach(embed => {\n if (embed.parentNode) embed.parentNode.removeChild(embed);\n });\n\n const loadingSpinner = document.createElement('div');\n loadingSpinner.className = 'vega-lite-loading-spinner';\n loadingSpinner.style.cssText = `\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 2em;\n min-height: 150px;\n width: 100%;\n `;\n loadingSpinner.innerHTML = `\n <div style=\"\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-top: 4px solid ${isDarkMode ? '#4cc9f0' : '#3498db'};\n border-radius: 50%;\n width: 40px;\n height: 40px;\n animation: vega-lite-spin 1s linear infinite;\n margin-bottom: 15px;\n \"></div>\n <div style=\"font-family: system-ui, -apple-system, sans-serif; color: ${isDarkMode ? '#eceff4' : '#333333'};\">\n Loading Vega-Lite visualization...\n </div>\n `;\n container.appendChild(loadingSpinner);\n\n // Add spinner animation\n if (!document.querySelector('#vega-lite-spinner-keyframes')) {\n const keyframes = document.createElement('style');\n keyframes.id = 'vega-lite-spinner-keyframes';\n keyframes.textContent = `\n @keyframes vega-lite-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n `;\n document.head.appendChild(keyframes);\n }\n\n // Determine if we should wait for more content\n // Priority: explicit streaming flags, then content analysis\n let shouldWaitForComplete = false;\n\n // Content analysis - this takes priority over streaming flags\n // Check if this is a complete Vega-Lite object (has schema, data, mark, etc.)\n const isCompleteVegaLiteObject = spec.$schema && (spec.data || spec.datasets) &&\n (spec.mark || spec.layer || spec.vconcat || spec.hconcat || spec.facet || spec.repeat);\n\n if (isCompleteVegaLiteObject) {\n console.log('Vega-Lite: Complete object spec detected, proceeding with render');\n shouldWaitForComplete = false;\n } else if (spec.definition) {\n // Only check definition if we don't have a complete object\n if (spec.definition) {\n const definition = spec.definition || JSON.stringify(spec);\n\n // If definition is empty or just whitespace, always wait unless forced\n if (!definition || definition.trim().length === 0) {\n console.log('Vega-Lite: Waiting due to empty definition', { isStreaming: spec.isStreaming, isMarkdownBlockClosed: spec.isMarkdownBlockClosed });\n shouldWaitForComplete = !spec.forceRender;\n } else {\n\n const isComplete = isDiagramDefinitionComplete(definition, 'vega-lite');\n console.log('Vega-Lite definition completeness check:', {\n isComplete,\n definitionLength: definition.length,\n definitionPreview: definition.substring(0, 100)\n });\n\n // If definition is incomplete and we're not forcing render, wait\n if (!isComplete && !spec.forceRender) {\n console.log('Vega-Lite: Waiting due to incomplete definition', { isStreaming: spec.isStreaming, isMarkdownBlockClosed: spec.isMarkdownBlockClosed });\n shouldWaitForComplete = true;\n }\n\n // Special case: obvious streaming indicators\n if (definition.includes('Unterminated string') || definition.includes('Unexpected end')) {\n console.log('Vega-Lite: Waiting due to JSON parsing indicators');\n shouldWaitForComplete = true;\n }\n }\n } else if (!isCompleteVegaLiteObject) {\n // No definition at all, wait unless forced\n console.log('Vega-Lite: Waiting due to missing definition', { isStreaming: spec.isStreaming, isMarkdownBlockClosed: spec.isMarkdownBlockClosed });\n shouldWaitForComplete = !spec.forceRender;\n }\n }\n\n // Final override: if markdown block is closed, try to render regardless of other conditions\n if (spec.isMarkdownBlockClosed && (isCompleteVegaLiteObject || (spec.definition && spec.definition.trim().length > 0))) {\n console.log('Vega-Lite: Markdown block closed with content, forcing render');\n shouldWaitForComplete = false;\n }\n\n // Additional check: if we're actively streaming and block isn't closed, wait regardless of content\n if (spec.isStreaming && !spec.isMarkdownBlockClosed && !spec.forceRender) {\n console.log('Vega-Lite: Waiting due to active streaming state');\n shouldWaitForComplete = true;\n }\n\n console.log('Vega-Lite: After all checks, shouldWaitForComplete =', shouldWaitForComplete);\n\n console.log('Vega-Lite: About to check shouldWaitForComplete condition...');\n if (shouldWaitForComplete) {\n console.log('Vega-Lite: Inside shouldWaitForComplete block');\n // Create enhanced waiting interface with debugging options like Mermaid\n const waitingContainer = document.createElement('div');\n waitingContainer.style.cssText = `\n text-align: center; \n padding: 20px; \n background-color: ${isDarkMode ? '#1f1f1f' : '#f6f8fa'}; \n border: 1px dashed #ccc; \n border-radius: 4px;\n position: relative;\n `;\n \n waitingContainer.innerHTML = `\n <p>Waiting for complete Vega-Lite specification...</p>\n <div style=\"margin-top: 15px;\">\n <button class=\"vega-lite-retry-btn\" style=\"\n background-color: #4361ee;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 0 5px;\n cursor: pointer;\n font-size: 14px;\n \">🔄 Force Render</button>\n <button class=\"vega-lite-source-btn\" style=\"\n background-color: #6c757d;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 0 5px;\n cursor: pointer;\n font-size: 14px;\n \">📝 View Source</button>\n </div>\n `;\n \n container.innerHTML = '';\n container.appendChild(waitingContainer);\n \n // Add event listeners for the buttons using querySelector instead of getElementById\n const retryButton = waitingContainer.querySelector('.vega-lite-retry-btn') as HTMLButtonElement;\n const sourceButton = waitingContainer.querySelector('.vega-lite-source-btn') as HTMLButtonElement;\n \n if (retryButton) {\n retryButton.onclick = () => {\n console.log('Force rendering Vega-Lite visualization');\n const forceSpec = { ...spec, forceRender: true };\n vegaLitePlugin.render(container, d3, forceSpec, isDarkMode);\n };\n }\n \n if (sourceButton) {\n sourceButton.onclick = () => {\n console.log('Showing Vega-Lite source for debugging');\n const sourceDefinition = spec.definition || JSON.stringify(spec, null, 2);\n container.innerHTML = `\n <div style=\"\n background-color: ${isDarkMode ? '#1f1f1f' : '#f6f8fa'};\n border: 1px solid ${isDarkMode ? '#444' : '#e1e4e8'};\n border-radius: 6px;\n padding: 16px;\n margin: 10px 0;\n \">\n <div style=\"margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center;\">\n <strong style=\"color: ${isDarkMode ? '#f8f9fa' : '#24292e'};\">Vega-Lite Source:</strong>\n <div>\n <button class=\"force-render-from-source\" style=\"\n background-color: #28a745;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 6px 12px;\n margin-right: 8px;\n cursor: pointer;\n font-size: 13px;\n \">🔄 Force Render</button>\n <button class=\"expand-source\" style=\"\n background-color: #6c757d;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n font-size: 13px;\n \">📄 Expand</button>\n </div>\n </div>\n <pre style=\"\n background-color: ${isDarkMode ? '#0d1117' : '#f6f8fa'};\n padding: 12px;\n border-radius: 4px;\n overflow: auto;\n max-height: 300px;\n margin: 0;\n border: 1px solid ${isDarkMode ? '#30363d' : '#e1e4e8'};\n font-family: 'SFMono-Regular', 'Monaco', 'Inconsolata', 'Liberation Mono', 'Courier New', monospace;\n font-size: 13px;\n line-height: 1.45;\n color: ${isDarkMode ? '#e6edf3' : '#24292f'};\n \"><code>${sourceDefinition}</code></pre>\n <div style=\"margin-top: 12px; font-size: 13px; color: ${isDarkMode ? '#8b949e' : '#656d76'};\">\n <strong>Debug Info:</strong><br>\n • Streaming: ${spec.isStreaming ? 'Yes' : 'No'}<br>\n • Block Closed: ${spec.isMarkdownBlockClosed ? 'Yes' : 'No'}<br>\n • Definition Length: ${sourceDefinition.length} characters<br>\n • Complete Object: ${isCompleteVegaLiteObject ? 'Yes' : 'No'}\n </div>\n </div>\n `;\n \n // Add event listeners for the new buttons in the source view\n setTimeout(() => {\n const forceRenderBtn = container.querySelector('.force-render-from-source') as HTMLButtonElement;\n const expandBtn = container.querySelector('.expand-source') as HTMLButtonElement;\n \n if (forceRenderBtn) {\n forceRenderBtn.onclick = () => {\n console.log('Force rendering from source view');\n const forceSpec = { ...spec, forceRender: true };\n vegaLitePlugin.render(container, d3, forceSpec, isDarkMode);\n };\n }\n \n if (expandBtn) {\n expandBtn.onclick = () => {\n const pre = container.querySelector('pre') as HTMLElement;\n if (pre) {\n const isExpanded = pre.style.maxHeight === 'none';\n pre.style.maxHeight = isExpanded ? '300px' : 'none';\n expandBtn.textContent = isExpanded ? '📄 Expand' : '📄 Collapse';\n }\n };\n }\n }, 0);\n };\n }\n \n return; // Exit early and wait for complete definition\n }\n console.log('Vega-Lite: Past shouldWaitForComplete check, about to declare vegaSpec');\n console.log('Vega-Lite: Proceeding with spec processing...');\n let vegaSpec: any;\n\n // CRITICAL PREPROCESSING: Fix common issues that cause \"Cannot read properties of undefined (reading 'type')\"\n const preprocessVegaSpec = (rawSpec: any): any => {\n if (!rawSpec || typeof rawSpec !== 'object') {\n return rawSpec;\n }\n\n const spec = JSON.parse(JSON.stringify(rawSpec)); // Deep clone\n \n console.log('🔧 VEGA-PREPROCESS: Starting comprehensive preprocessing');\n \n // Fix 1: Remove problematic shape encodings entirely - this is the most common cause\n if (spec.encoding?.shape) {\n console.log('🔧 VEGA-PREPROCESS: Found shape encoding, analyzing...');\n const shapeEnc = spec.encoding.shape;\n \n // Remove shape encoding in these problematic cases:\n let shouldRemoveShape = false;\n \n if (shapeEnc.type === 'ordinal' && spec.data?.values) {\n const fieldValues = spec.data.values.map((d: any) => d[shapeEnc.field]).filter((v: any) => v !== undefined);\n const isNumeric = fieldValues.length > 0 && fieldValues.every((v: any) => typeof v === 'number');\n if (isNumeric) {\n console.log('🔧 VEGA-PREPROCESS: Removing ordinal shape encoding with numeric data');\n shouldRemoveShape = true;\n }\n }\n \n if (shapeEnc.scale?.range?.some((s: any) => typeof s === 'string' && s.includes('triangle'))) {\n console.log('🔧 VEGA-PREPROCESS: Removing shape encoding with problematic triangle shapes');\n shouldRemoveShape = true;\n }\n \n if (!shapeEnc.field || !spec.data?.values) {\n console.log('🔧 VEGA-PREPROCESS: Removing shape encoding without proper field/data');\n shouldRemoveShape = true;\n }\n \n if (shouldRemoveShape) {\n delete spec.encoding.shape;\n console.log('🔧 VEGA-PREPROCESS: Removed problematic shape encoding');\n }\n }\n \n // Fix 2: Validate all encoding field references\n if (spec.encoding && spec.data?.values && Array.isArray(spec.data.values) && spec.data.values.length > 0) {\n const availableFields = Object.keys(spec.data.values[0]);\n console.log('🔧 VEGA-PREPROCESS: Available fields:', availableFields);\n \n Object.keys(spec.encoding).forEach(channel => {\n const channelSpec = spec.encoding[channel];\n if (channelSpec?.field && !availableFields.includes(channelSpec.field)) {\n console.log(`🔧 VEGA-PREPROCESS: Removing ${channel} encoding with invalid field: ${channelSpec.field}`);\n delete spec.encoding[channel];\n }\n });\n }\n \n // Fix 3: Clean up null/undefined values in scale domains\n ['x', 'y', 'color', 'fill', 'stroke', 'opacity', 'size'].forEach(channel => {\n if (spec.encoding?.[channel]?.scale?.domain) {\n const domain = spec.encoding[channel].scale.domain;\n if (Array.isArray(domain)) {\n const cleanDomain = domain.filter(v => v !== null && v !== undefined);\n if (cleanDomain.length !== domain.length) {\n console.log(`🔧 VEGA-PREPROCESS: Cleaned null values from ${channel} domain`);\n if (cleanDomain.length > 0) {\n spec.encoding[channel].scale.domain = cleanDomain;\n } else {\n delete spec.encoding[channel].scale.domain;\n }\n }\n } else if (domain === null || domain === undefined) {\n console.log(`🔧 VEGA-PREPROCESS: Removed null ${channel} domain`);\n delete spec.encoding[channel].scale.domain;\n }\n }\n });\n \n // Fix 4: Ensure schema exists\n if (!spec.$schema) {\n spec.$schema = 'https://vega.github.io/schema/vega-lite/v5.json';\n }\n \n console.log('🔧 VEGA-PREPROCESS: Preprocessing complete');\n return spec;\n };\n\n if (typeof spec === 'string') {\n const extractedContent = extractDefinitionFromYAML(spec, 'vega-lite');\n try {\n const rawSpec = JSON.parse(extractedContent);\n vegaSpec = preprocessVegaSpec(sanitizeSpec(rawSpec));\n } catch (parseError) {\n console.debug('Vega-Lite: JSON parse error during processing:', parseError);\n throw parseError; // Re-throw to be handled by outer try-catch\n }\n } else if (spec.definition) {\n const extractedContent = extractDefinitionFromYAML(spec.definition, 'vega-lite');\n try {\n const rawSpec = JSON.parse(extractedContent);\n vegaSpec = preprocessVegaSpec(sanitizeSpec(rawSpec));\n } catch (parseError) {\n console.debug('Vega-Lite: JSON parse error during processing:', parseError);\n throw parseError; // Re-throw to be handled by outer try-catch\n }\n } else {\n // Use the spec object directly, but remove our custom properties\n const rawSpec = sanitizeSpec({ ...spec });\n ['type', 'isStreaming', 'forceRender', 'definition'].forEach(prop => delete rawSpec[prop]);\n vegaSpec = preprocessVegaSpec(rawSpec);\n }\n\n console.log('Vega-Lite: Spec processed, starting try block for rendering...');\n\n try {\n // COMPREHENSIVE FIX: Handle all cases that cause \"Cannot read properties of null (reading 'slice')\" error\n // This error occurs when Vega-Lite tries to process invalid scale domains or ranges\n \n // Fix 0: Upgrade old schema versions that may be causing compatibility issues\n if (vegaSpec.$schema && vegaSpec.$schema.includes('v4')) {\n console.log('SCHEMA FIX: Upgrading old v4 schema to v5 for better compatibility');\n vegaSpec.$schema = 'https://vega.github.io/schema/vega-lite/v5.json';\n }\n \n // Fix 0.1: Handle nominal fields with many categories that might cause slice errors\n if (vegaSpec.encoding?.x?.field === 'file' && vegaSpec.data?.values) {\n const fileCount = vegaSpec.data.values.length;\n if (fileCount > 20) {\n console.log('FILE COUNT FIX: Too many files for x-axis, limiting to top 20');\n vegaSpec.data.values = vegaSpec.data.values.slice(0, 20);\n }\n }\n \n // Fix 1: Handle shape encoding with null/undefined values\n if (vegaSpec.encoding?.shape) {\n const shapeEncoding = vegaSpec.encoding.shape;\n console.log('SHAPE FIX: Processing shape encoding:', JSON.stringify(shapeEncoding, null, 2));\n \n // Check if we have data to validate against\n if (vegaSpec.data?.values && Array.isArray(vegaSpec.data.values)) {\n const fieldValues = vegaSpec.data.values\n .map(d => d[shapeEncoding.field])\n .filter(v => v !== null && v !== undefined);\n \n // If field has null/undefined values or is numeric with ordinal type, remove shape encoding\n if (fieldValues.length === 0 || \n (shapeEncoding.type === 'ordinal' && fieldValues.every(v => typeof v === 'number'))) {\n console.log('SHAPE FIX: Removing problematic shape encoding');\n delete vegaSpec.encoding.shape;\n } else if (shapeEncoding.scale?.range) {\n // Fix invalid shape names in scale range\n const validShapes = ['circle', 'square', 'cross', 'diamond', 'triangle-up', 'triangle-down', 'triangle-right', 'triangle-left'];\n vegaSpec.encoding.shape.scale.range = shapeEncoding.scale.range\n .map(shape => validShapes.includes(shape) ? shape : 'circle')\n .slice(0, Math.min(shapeEncoding.scale.range.length, fieldValues.length));\n }\n } else {\n // No data available to validate, remove shape encoding as safety measure\n console.log('SHAPE FIX: No data available, removing shape encoding as safety measure');\n delete vegaSpec.encoding.shape;\n }\n }\n \n // Fix 2: Handle color encoding with invalid scale domains\n ['color', 'fill', 'stroke', 'opacity', 'size'].forEach(channel => {\n if (vegaSpec.encoding?.[channel]?.scale?.domain) {\n const domain = vegaSpec.encoding[channel].scale.domain;\n if (domain === null || (Array.isArray(domain) && domain.some(v => v === null || v === undefined))) {\n console.log(`DOMAIN FIX: Removing null values from ${channel} domain`);\n if (Array.isArray(domain)) {\n vegaSpec.encoding[channel].scale.domain = domain.filter(v => v !== null && v !== undefined);\n } else {\n delete vegaSpec.encoding[channel].scale.domain;\n }\n }\n }\n });\n \n // Fix 3: Validate data fields before rendering\n if (vegaSpec.data?.values && Array.isArray(vegaSpec.data.values)) {\n // Remove any rows with all null/undefined values\n const cleanedValues = vegaSpec.data.values.filter(row => \n row && typeof row === 'object' && Object.values(row).some(v => v !== null && v !== undefined)\n );\n \n if (cleanedValues.length < vegaSpec.data.values.length) {\n console.log(`DATA FIX: Cleaned ${vegaSpec.data.values.length - cleanedValues.length} empty rows`);\n vegaSpec.data.values = cleanedValues;\n }\n }\n \n // CRITICAL FIX: Handle shape encoding that causes \"Cannot read properties of null (reading 'slice')\" error\n\n // Apply this fix EARLY in the preprocessing pipeline\n // Additional post-preprocessing validations and fixes\n console.log('🔧 VEGA-POST-PROCESS: Starting additional fixes');\n \n // Handle problematic axis configurations\n if (vegaSpec.encoding?.x?.axis?.labelLimit !== undefined && vegaSpec.encoding.x.axis.labelLimit <= 0) {\n console.log('🔧 VEGA-POST-PROCESS: Fixing problematic axis labelLimit');\n delete vegaSpec.encoding.x.axis.labelLimit;\n }\n \n // Fix invalid color names like \"#green\" \n try {\n let specStringForColorFix = JSON.stringify(vegaSpec);\n specStringForColorFix = specStringForColorFix.replace(/\"#(green|red|orange|blue|yellow|purple|black|white|gray|grey|cyan|magenta|pink|brown|violet|indigo|gold|silver)\"/gi, '\"$1\"');\n vegaSpec = JSON.parse(specStringForColorFix);\n } catch (e) {\n console.warn(\"Could not apply color fix to Vega-Lite spec\", e);\n }\n \n // Validate the spec before rendering\n if (!vegaSpec || typeof vegaSpec !== 'object') {\n throw new Error('Invalid Vega-Lite specification: spec must be an object');\n }\n \n // Ensure required properties exist\n if (!vegaSpec.data && !vegaSpec.datasets) {\n throw new Error('Invalid Vega-Lite specification: missing data or datasets');\n }\n \n // Check for valid mark or composition\n if (!vegaSpec.mark && !vegaSpec.layer && !vegaSpec.vconcat && !vegaSpec.hconcat && \n !vegaSpec.facet && !vegaSpec.repeat && !vegaSpec.transform) {\n throw new Error('Invalid Vega-Lite specification: missing mark or composition');\n }\n\n // Get container dimensions for responsive sizing\n const containerRect = container.getBoundingClientRect();\n const availableWidth = Math.max(containerRect.width - 40, 400); // Account for padding, minimum 400px\n const availableHeight = Math.max(containerRect.height || 400, 300); // Minimum 300px height\n\n // Only override dimensions if they're not explicitly set in the spec\n if (!vegaSpec.width && vegaSpec.width !== 0) {\n vegaSpec.width = availableWidth;\n }\n\n // Only set height if not explicitly specified and not using complex layouts\n if (!vegaSpec.height && vegaSpec.height !== 0 && !vegaSpec.vconcat && !vegaSpec.hconcat && !vegaSpec.facet) {\n // For simple charts without explicit height, use a reasonable default\n vegaSpec.height = Math.min(availableHeight * 0.8, 500);\n }\n\n // Only set autosize if not already configured\n if (!vegaSpec.autosize) {\n vegaSpec.autosize = {\n type: 'fit',\n contains: 'content'\n };\n } else if (vegaSpec.autosize && typeof vegaSpec.autosize === 'object') {\n // Preserve existing autosize configuration\n vegaSpec.autosize = { ...vegaSpec.autosize };\n }\n\n // For charts with explicit dimensions, use a more conservative autosize\n if ((vegaSpec.width && vegaSpec.width > 0) || (vegaSpec.height && vegaSpec.height > 0)) {\n vegaSpec.autosize = {\n type: 'fit',\n contains: 'content'\n };\n }\n\n // Ensure axis labels are properly displayed without overriding user config\n if (vegaSpec.layer) {\n vegaSpec.layer.forEach(layer => {\n if (layer.encoding?.x && !layer.encoding.x.axis) {\n // Only add default axis config if none exists\n layer.encoding.x.axis = {\n labelAngle: 0,\n labelLimit: 0, // No limit to prevent truncation\n labelFontSize: 11\n };\n }\n if (layer.encoding?.y && !layer.encoding.y.axis) {\n // Ensure y-axis labels are also properly displayed\n layer.encoding.y.axis = {\n labelLimit: 0,\n labelFontSize: 11\n };\n }\n });\n }\n\n // Ensure it has a schema if not present\n if (!vegaSpec.$schema) {\n vegaSpec.$schema = 'https://vega.github.io/schema/vega-lite/v5.json';\n }\n\n // Fix radar chart specifications that use theta/radius encoding\n if (vegaSpec.encoding?.theta && vegaSpec.encoding?.radius) {\n // Convert to proper radar chart using arc mark\n vegaSpec.mark = { type: \"arc\", innerRadius: 20, outerRadius: 100 };\n vegaSpec.encoding = {\n theta: { field: \"level\", type: \"quantitative\", scale: { type: \"linear\", range: [0, 6.28] } },\n radius: { field: \"level\", type: \"quantitative\", scale: { type: \"linear\", range: [20, 100] } },\n color: { field: \"skill\", type: \"nominal\" },\n tooltip: [\n { field: \"skill\", type: \"nominal\" },\n { field: \"level\", type: \"quantitative\", title: \"Mastery Level\" }\n ]\n };\n }\n\n // Fix common violin plot specification issues - correct field mappings for density transform\n if (vegaSpec.transform && vegaSpec.transform.some((t: any) => t.density)) {\n console.log('Processing violin plot specification');\n\n // For violin plots with density transform, we need to fix the encoding\n // The density transform creates 'value' (x-axis) and 'density' (y-axis) fields\n if (vegaSpec.encoding) {\n // Check if this is incorrectly mapping original data fields instead of density output\n const hasIncorrectMapping = vegaSpec.encoding.x && vegaSpec.encoding.y &&\n (vegaSpec.encoding.x.field !== 'value' || vegaSpec.encoding.y.field !== 'density');\n\n if (hasIncorrectMapping) {\n console.log('Fixing violin plot field mappings for density transform');\n\n // Store the grouping field for faceting/coloring\n const groupField = vegaSpec.transform.find((t: any) => t.density)?.groupby?.[0];\n\n // Fix the encoding to use density transform output fields\n vegaSpec.encoding = {\n x: {\n field: 'value',\n type: 'quantitative',\n title: vegaSpec.encoding.y?.title || 'Value'\n },\n y: {\n field: 'density',\n type: 'quantitative',\n title: 'Density'\n },\n // Preserve color/faceting based on the grouping field\n ...(groupField && vegaSpec.encoding.color && { color: { ...vegaSpec.encoding.color, field: groupField } }),\n ...(groupField && vegaSpec.encoding.column && { column: { ...vegaSpec.encoding.column, field: groupField } }),\n ...(groupField && vegaSpec.encoding.row && { row: { ...vegaSpec.encoding.row, field: groupField } })\n };\n }\n }\n\n // Ensure proper mark configuration for violin plots \n if (!vegaSpec.mark || (typeof vegaSpec.mark === 'string' && vegaSpec.mark === 'area')) {\n vegaSpec.mark = { type: \"area\", opacity: 0.7 };\n };\n }\n\n // Ensure reasonable minimum dimensions for complex visualizations\n if (vegaSpec.width && vegaSpec.width < 200) {\n vegaSpec.width = 400;\n }\n if (vegaSpec.height && vegaSpec.height < 250) {\n vegaSpec.height = 300;\n }\n\n // Fix unrecognized signal references that may be added during preprocessing\n const removeInvalidSignals = (obj: any): any => {\n if (obj && typeof obj === 'object') {\n if (Array.isArray(obj)) {\n return obj.map(removeInvalidSignals);\n } else {\n const cleaned: any = {};\n for (const [key, value] of Object.entries(obj)) {\n // Skip signal references that aren't defined\n if (key === 'signal' && typeof value === 'string' && value.includes('tier_focus')) {\n console.log('Removing invalid signal reference:', value);\n continue;\n }\n cleaned[key] = removeInvalidSignals(value);\n }\n return cleaned;\n }\n }\n return obj;\n };\n \n vegaSpec = removeInvalidSignals(vegaSpec);\n\n // Fix treemap charts missing x and color encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'rect' || vegaSpec.mark === 'rect') &&\n vegaSpec.params && vegaSpec.params.some(p => p.bind && p.bind.input === 'select') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.aggregate) &&\n vegaSpec.encoding && vegaSpec.encoding.y && !vegaSpec.encoding.x && !vegaSpec.encoding.color) {\n console.log('Fixing treemap chart x and color encodings');\n \n vegaSpec.encoding.x = {\n field: 'total_budget',\n type: 'quantitative',\n title: 'Budget'\n };\n vegaSpec.encoding.color = {\n field: 'display_category',\n type: 'nominal',\n title: 'Category'\n };\n }\n\n // Fix population density plots with sequence/coordinate issues\n if (vegaSpec.transform && vegaSpec.data?.values && vegaSpec.data.values[0]?.lat && vegaSpec.data.values[0]?.lon) {\n console.log('Fixing population density plot sequence and coordinates');\n \n // Fix any sequence transform that uses datum.count instead of datum.dot_count\n vegaSpec.transform.forEach(transform => {\n if (transform.calculate && transform.calculate.includes('datum.count')) {\n transform.calculate = transform.calculate.replace('datum.count', 'datum.dot_count');\n console.log('Fixed sequence transform to use dot_count');\n }\n });\n \n // Fix x/y encodings to use jittered coordinates correctly\n if (vegaSpec.encoding && (vegaSpec.encoding.x?.field === 'lat' || vegaSpec.encoding.y?.field === 'lon')) {\n vegaSpec.encoding.x = {\n field: 'jittered_lon',\n type: 'quantitative',\n axis: null\n };\n vegaSpec.encoding.y = {\n field: 'jittered_lat', \n type: 'quantitative',\n axis: null\n };\n console.log('Fixed x/y encodings to use jittered coordinates');\n }\n }\n\n // Fix sequence transforms that use expressions (need to be flattened)\n if (vegaSpec.transform && vegaSpec.transform.some(t => t.sequence && t.sequence.stop && t.sequence.stop.expr)) {\n console.log('Fixing sequence transform with expression');\n \n // Find the sequence transform and convert it to a flatten transform\n const sequenceIndex = vegaSpec.transform.findIndex(t => t.sequence);\n if (sequenceIndex >= 0) {\n const sequenceTransform = vegaSpec.transform[sequenceIndex];\n \n // Replace sequence with flatten transform\n vegaSpec.transform[sequenceIndex] = {\n flatten: [sequenceTransform.as || 'unit']\n };\n \n // Add a calculate transform to generate the sequence data\n vegaSpec.transform.splice(sequenceIndex, 0, {\n calculate: `sequence(1, datum.count + 1)`,\n as: sequenceTransform.as || 'unit'\n });\n }\n }\n\n // Fix indexOf function usage in calculate transforms (not supported in Vega-Lite)\n if (vegaSpec.transform && Array.isArray(vegaSpec.transform)) {\n vegaSpec.transform.forEach((transform, index) => {\n if (transform.calculate && transform.calculate.includes('indexOf(')) {\n console.log(`Fixing indexOf usage in transform ${index}: ${transform.calculate}`);\n \n // Replace indexOf with conditional expressions using regex\n let newCalculate = transform.calculate.replace(\n /indexOf\\(\\[([^\\]]+)\\],\\s*([^)]+)\\)/g,\n (match, arrayStr, field) => {\n console.log(`Match found: ${match}, Array: ${arrayStr}, Field: ${field}`);\n const items = arrayStr.split(',').map(item => item.trim().replace(/['\"]/g, ''));\n console.log(`Parsed items:`, items);\n const conditions = items.map((item, idx) => \n `${field.trim()} == '${item}' ? ${idx}`\n ).join(' : ');\n const result = `(${conditions} : -1)`;\n console.log(`Generated replacement: ${result}`);\n return result;\n }\n );\n \n transform.calculate = newCalculate;\n console.log(`Final calculate: ${newCalculate}`);\n }\n });\n }\n\n // Fix strokeDash encoding without proper scale (causes 'slice' error)\n if (vegaSpec.encoding?.strokeDash && vegaSpec.encoding.strokeDash.type === 'nominal' && !vegaSpec.encoding.strokeDash.scale) {\n console.log('Fixing strokeDash encoding scale');\n vegaSpec.encoding.strokeDash.scale = {\n range: [[1, 0], [5, 5]] // solid line, dashed line\n };\n }\n\n // Fix radar chart transform order - window transforms must come before calculate transforms that use them\n if (vegaSpec.transform && Array.isArray(vegaSpec.transform)) {\n const hasWindowTransform = vegaSpec.transform.some(t => t.window);\n const hasCalculateUsingSkillIndex = vegaSpec.transform.some(t => \n t.calculate && t.calculate.includes('skill_index')\n );\n \n if (hasWindowTransform && hasCalculateUsingSkillIndex) {\n console.log('Fixing radar chart transform order');\n // Move window transforms before calculate transforms\n const windowTransforms = vegaSpec.transform.filter(t => t.window);\n const otherTransforms = vegaSpec.transform.filter(t => !t.window);\n vegaSpec.transform = [...windowTransforms, ...otherTransforms];\n }\n }\n\n // Fix population pyramid charts missing x and color encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'bar' || vegaSpec.mark === 'bar') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.fold && t.fold.includes('male') && t.fold.includes('female')) &&\n vegaSpec.encoding && vegaSpec.encoding.y && !vegaSpec.encoding.x && !vegaSpec.encoding.color) {\n console.log('Fixing population pyramid chart x and color encodings');\n \n vegaSpec.encoding.x = {\n field: 'signed_population',\n type: 'quantitative',\n title: 'Population',\n axis: {\n format: '~s'\n }\n };\n vegaSpec.encoding.color = {\n field: 'gender',\n type: 'nominal',\n scale: {\n domain: ['male', 'female'],\n range: ['#4575b4', '#d73027']\n },\n title: 'Gender'\n };\n }\n\n // Fix hierarchical drill-down charts missing x,y encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'bar' || vegaSpec.mark === 'bar') &&\n vegaSpec.params && vegaSpec.params.some(p => p.bind && p.bind.input === 'select') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.calculate && t.calculate.includes('drill_level')) &&\n vegaSpec.encoding && vegaSpec.encoding.color && !vegaSpec.encoding.x && !vegaSpec.encoding.y) {\n console.log('Fixing hierarchical drill-down chart x,y encodings');\n \n vegaSpec.encoding.x = {\n field: 'display_category',\n type: 'nominal',\n title: 'Category'\n };\n vegaSpec.encoding.y = {\n field: 'total_value',\n type: 'quantitative',\n title: 'Value'\n };\n }\n\n // Fix 2D histograms missing x,y,color encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'rect' || vegaSpec.mark === 'rect') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.aggregate && t.groupby && t.groupby.length === 2 && t.groupby.every(g => g.bin)) &&\n vegaSpec.encoding && !vegaSpec.encoding.x && !vegaSpec.encoding.y && !vegaSpec.encoding.color) {\n console.log('Fixing 2D histogram x,y,color encodings');\n \n vegaSpec.encoding.x = {\n field: 'x_center',\n type: 'quantitative',\n title: 'X'\n };\n vegaSpec.encoding.y = {\n field: 'y_center',\n type: 'quantitative',\n title: 'Y'\n };\n vegaSpec.encoding.color = {\n field: 'count',\n type: 'quantitative',\n scale: { scheme: 'blues' },\n title: 'Count'\n };\n }\n\n // Fix combined violin/box plots with incorrect field references\n if (vegaSpec.layer && Array.isArray(vegaSpec.layer)) {\n vegaSpec.layer.forEach((layer, index) => {\n if (layer.transform && layer.transform.some(t => t.density) &&\n layer.mark && (layer.mark.type === 'area' || layer.mark === 'area') &&\n layer.encoding && layer.encoding.x && layer.encoding.x.field === 'value') {\n console.log(`Fixing violin layer ${index} field references`);\n \n // For violin plots, x should be the density transform output field 'value', not the original 'value'\n // The density transform creates new 'value' and 'density' fields\n layer.encoding.x = {\n field: 'value', // This is the density transform output, not original data\n type: 'quantitative',\n title: layer.encoding.x.title || 'Value'\n };\n \n // Remove xOffset as it's causing issues - the density field should control the shape\n if (layer.encoding.xOffset) {\n delete layer.encoding.xOffset;\n console.log(`Removed xOffset from violin layer ${index}`);\n }\n }\n });\n }\n\n // Fix gauge charts missing theta2 encoding (enhanced for multi-layer gauges)\n if (vegaSpec.facet && vegaSpec.spec && vegaSpec.spec.layer &&\n vegaSpec.spec.layer.some(layer => layer.mark && layer.mark.type === 'arc')) {\n console.log('Fixing multi-layer gauge chart encodings');\n \n vegaSpec.spec.layer.forEach((layer, index) => {\n if (layer.mark && layer.mark.type === 'arc') {\n // Case 1: Background arc with theta2 in mark - don't add theta encoding\n if (layer.mark.theta2 && layer.encoding?.color?.value) {\n // This is a background arc, remove any theta encodings we might have added\n if (layer.encoding.theta) {\n delete layer.encoding.theta;\n console.log(`Removed theta encoding from background arc layer ${index}`);\n }\n if (layer.encoding.theta2) {\n delete layer.encoding.theta2;\n console.log(`Removed theta2 encoding from background arc layer ${index}`);\n }\n }\n // Case 2: Data arc with theta field but missing theta2\n else if (layer.encoding && layer.encoding.theta && layer.encoding.theta.field && !layer.encoding.theta2) {\n layer.encoding.theta2 = { value: 0 };\n console.log(`Added theta2 to data arc layer ${index}`);\n }\n }\n });\n }\n\n // Fix geographic dot density plots with wrong x,y field references\n if (vegaSpec.mark && (vegaSpec.mark.type === 'circle' || vegaSpec.mark === 'circle') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.sequence) &&\n vegaSpec.encoding && vegaSpec.encoding.x && vegaSpec.encoding.y &&\n (vegaSpec.encoding.x.field === 'x' || vegaSpec.encoding.y.field === 'y') &&\n vegaSpec.data?.values && vegaSpec.data.values[0]?.lat && vegaSpec.data.values[0]?.lon) {\n console.log('Fixing geographic dot density plot x,y field references');\n \n vegaSpec.encoding.x = {\n field: 'jittered_lon',\n type: 'quantitative',\n axis: null\n };\n vegaSpec.encoding.y = {\n field: 'jittered_lat',\n type: 'quantitative',\n axis: null\n };\n }\n\n // Fix annual calendar charts missing y-axis encoding\n if (vegaSpec.mark && (vegaSpec.mark.type === 'rect' || vegaSpec.mark === 'rect') &&\n vegaSpec.encoding && vegaSpec.encoding.x && vegaSpec.encoding.x.field === 'weekday' && !vegaSpec.encoding.y &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.calculate && t.calculate.includes('week('))) {\n console.log('Fixing annual calendar chart y-axis encoding');\n \n vegaSpec.encoding.y = {\n field: 'week',\n type: 'ordinal',\n title: 'Week of Year'\n };\n }\n\n // Fix hexbin plots missing x,y,size encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'circle' || vegaSpec.mark === 'circle') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.aggregate && t.groupby && t.groupby.some(g => g.bin)) &&\n vegaSpec.encoding && !vegaSpec.encoding.x && !vegaSpec.encoding.y) {\n console.log('Fixing hexbin plot x,y,size encodings');\n \n vegaSpec.encoding.x = {\n field: 'x_center',\n type: 'quantitative',\n title: 'X'\n };\n vegaSpec.encoding.y = {\n field: 'y_center',\n type: 'quantitative',\n title: 'Y'\n };\n vegaSpec.encoding.size = {\n field: 'count',\n type: 'quantitative',\n title: 'Count',\n scale: { range: [50, 500] }\n };\n }\n\n // Fix stacked bar charts missing x,y encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'bar' || vegaSpec.mark === 'bar') &&\n vegaSpec.encoding && vegaSpec.encoding.color && !vegaSpec.encoding.x && !vegaSpec.encoding.y &&\n vegaSpec.data?.values && vegaSpec.data.values.length > 0) {\n console.log('Fixing stacked bar chart x,y encodings');\n \n const firstRow = vegaSpec.data.values[0];\n const fields = Object.keys(firstRow);\n const categoricalField = fields.find(f => typeof firstRow[f] === 'string' && f !== vegaSpec.encoding.color.field);\n const quantitativeField = fields.find(f => typeof firstRow[f] === 'number' && (f.includes('revenue') || f.includes('value') || f.includes('amount')));\n \n if (categoricalField && quantitativeField) {\n vegaSpec.encoding.x = {\n field: categoricalField,\n type: 'nominal',\n title: categoricalField.charAt(0).toUpperCase() + categoricalField.slice(1)\n };\n vegaSpec.encoding.y = {\n field: quantitativeField,\n type: 'quantitative',\n title: quantitativeField.charAt(0).toUpperCase() + quantitativeField.slice(1)\n };\n }\n }\n\n // Fix spiral charts missing x,y encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'circle' || vegaSpec.mark === 'circle') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.calculate && (t.calculate.includes('cos(') || t.calculate.includes('sin('))) &&\n vegaSpec.encoding && !vegaSpec.encoding.x && !vegaSpec.encoding.y) {\n console.log('Fixing spiral chart x,y encodings');\n \n vegaSpec.encoding.x = {\n field: 'x',\n type: 'quantitative',\n axis: null\n };\n vegaSpec.encoding.y = {\n field: 'y',\n type: 'quantitative',\n axis: null\n };\n }\n\n // Fix diverging bar charts missing x and color encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'bar' || vegaSpec.mark === 'bar') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.fold && t.fold.includes('positive') && t.fold.includes('negative')) &&\n vegaSpec.encoding && vegaSpec.encoding.y && !vegaSpec.encoding.x && !vegaSpec.encoding.color) {\n console.log('Fixing diverging bar chart x and color encodings');\n \n vegaSpec.encoding.x = {\n field: 'value',\n type: 'quantitative',\n title: 'Value'\n };\n vegaSpec.encoding.color = {\n field: 'sentiment',\n type: 'nominal',\n scale: {\n domain: ['positive', 'negative'],\n range: ['#2ca02c', '#d62728']\n },\n title: 'Sentiment'\n };\n }\n\n // Fix scatter plots missing encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'point' || vegaSpec.mark === 'point' || vegaSpec.mark.type === 'circle') &&\n vegaSpec.data?.values && !vegaSpec.encoding?.x && !vegaSpec.encoding?.y) {\n console.log('Fixing scatter plot x,y encodings');\n const firstRow = vegaSpec.data.values[0];\n const numericFields = Object.keys(firstRow).filter(key => typeof firstRow[key] === 'number');\n if (numericFields.length >= 2) {\n vegaSpec.encoding = vegaSpec.encoding || {};\n vegaSpec.encoding.x = { field: numericFields[0], type: 'quantitative' };\n vegaSpec.encoding.y = { field: numericFields[1], type: 'quantitative' };\n }\n }\n\n // Fix line charts missing encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'line' || vegaSpec.mark === 'line') &&\n vegaSpec.data?.values && !vegaSpec.encoding?.x && !vegaSpec.encoding?.y && !vegaSpec.transform?.some(t => t.fold)) {\n console.log('Fixing line chart x,y encodings');\n const firstRow = vegaSpec.data.values[0];\n const fields = Object.keys(firstRow);\n const dateField = fields.find(f => firstRow[f] && (f.includes('date') || f.includes('time') || typeof firstRow[f] === 'string' && firstRow[f].match(/\\d{4}-\\d{2}-\\d{2}/)));\n const numericField = fields.find(f => typeof firstRow[f] === 'number');\n \n if (dateField && numericField) {\n vegaSpec.encoding = vegaSpec.encoding || {};\n vegaSpec.encoding.x = { field: dateField, type: 'temporal' };\n vegaSpec.encoding.y = { field: numericField, type: 'quantitative' };\n }\n }\n\n // Fix heatmaps missing encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'rect' || vegaSpec.mark === 'rect') &&\n vegaSpec.encoding?.color && !vegaSpec.encoding?.x && !vegaSpec.encoding?.y &&\n !vegaSpec.transform?.some(t => t.calculate && (t.calculate.includes('day(') || t.calculate.includes('week(')))) {\n console.log('Fixing heatmap x,y encodings');\n const firstRow = vegaSpec.data?.values?.[0];\n if (firstRow) {\n const fields = Object.keys(firstRow);\n const categoricalFields = fields.filter(f => typeof firstRow[f] === 'string' || typeof firstRow[f] === 'number');\n if (categoricalFields.length >= 2) {\n vegaSpec.encoding.x = { field: categoricalFields[0], type: 'nominal' };\n vegaSpec.encoding.y = { field: categoricalFields[1], type: 'nominal' };\n }\n }\n }\n\n // Fix violin plots missing x,y encodings after density transform\n if (vegaSpec.mark && (vegaSpec.mark.type === 'area' || vegaSpec.mark === 'area') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.density) &&\n vegaSpec.encoding && !vegaSpec.encoding.x && !vegaSpec.encoding.y) {\n console.log('Fixing violin plot x,y encodings');\n \n // Add x and y encodings for density plot\n vegaSpec.encoding.x = {\n field: 'value',\n type: 'quantitative',\n title: 'Response Time'\n };\n vegaSpec.encoding.y = {\n field: 'density',\n type: 'quantitative',\n title: 'Density'\n };\n }\n\n // Fix histograms with aggregate count issues (enhanced)\n if (vegaSpec.mark === 'bar' && vegaSpec.encoding && vegaSpec.encoding.x && vegaSpec.encoding.x.bin &&\n vegaSpec.encoding.y && vegaSpec.encoding.y.aggregate === 'count') {\n console.log('Fixing histogram aggregate count encoding');\n \n // Ensure proper y encoding structure for count aggregate\n vegaSpec.encoding.y = {\n aggregate: 'count',\n type: 'quantitative',\n title: vegaSpec.encoding.y.title || 'Count'\n };\n // Remove any incorrect field reference\n delete vegaSpec.encoding.y.field;\n }\n\n // Fix calendar heatmaps missing x,y encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'rect' || vegaSpec.mark === 'rect') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.calculate && (t.calculate.includes('day(') || t.calculate.includes('week('))) &&\n vegaSpec.encoding && vegaSpec.encoding.color && !vegaSpec.encoding.x && !vegaSpec.encoding.y) {\n console.log('Fixing calendar heatmap x,y encodings');\n \n // Add x and y encodings for calendar layout\n vegaSpec.encoding.x = {\n field: 'day',\n type: 'ordinal',\n title: 'Day of Week'\n };\n vegaSpec.encoding.y = {\n field: 'week',\n type: 'ordinal',\n title: 'Week'\n };\n }\n\n // Fix parallel coordinates charts missing x,y encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'line' || vegaSpec.mark === 'line') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.fold) &&\n vegaSpec.encoding && vegaSpec.encoding.detail && !vegaSpec.encoding.x && !vegaSpec.encoding.y) {\n console.log('Fixing parallel coordinates chart x,y encodings');\n \n // Add x and y encodings for parallel coordinates\n vegaSpec.encoding.x = {\n field: 'dimension',\n type: 'nominal',\n title: 'Dimensions'\n };\n vegaSpec.encoding.y = {\n field: 'value',\n type: 'quantitative',\n title: 'Value'\n };\n }\n\n // Fix isotope/dot plot charts missing x,y encodings\n if (vegaSpec.mark && (vegaSpec.mark.type === 'circle' || vegaSpec.mark === 'circle') &&\n vegaSpec.transform && vegaSpec.transform.some(t => t.sequence) &&\n vegaSpec.encoding && !vegaSpec.encoding.x && !vegaSpec.encoding.y) {\n console.log('Fixing isotope chart x,y encodings');\n \n // Add x and y encodings using calculated positions\n vegaSpec.encoding.x = {\n field: 'x',\n type: 'ordinal',\n axis: null // Hide axis for cleaner look\n };\n vegaSpec.encoding.y = {\n field: 'y',\n type: 'ordinal',\n axis: null // Hide axis for cleaner look\n };\n }\n\n // Fix waterfall charts missing y-axis encoding\n if (vegaSpec.mark === 'bar' && vegaSpec.transform && \n vegaSpec.transform.some(t => t.window && t.window.some(w => w.op === 'sum')) &&\n vegaSpec.encoding && vegaSpec.encoding.x && !vegaSpec.encoding.y) {\n console.log('Fixing waterfall chart y-axis encoding');\n \n // Add y and y2 encoding for proper waterfall display\n vegaSpec.encoding.y = {\n field: 'previous_sum',\n type: 'quantitative',\n title: 'Value'\n };\n vegaSpec.encoding.y2 = {\n field: 'sum',\n type: 'quantitative'\n };\n }\n\n // Fix for bar charts missing y-axis encoding (common issue with flow/journey charts)\n if (vegaSpec.mark && (vegaSpec.mark === 'bar' || vegaSpec.mark.type === 'bar') && \n vegaSpec.encoding && vegaSpec.encoding.x && !vegaSpec.encoding.y) {\n console.log('Fixing bar chart missing y-axis encoding');\n \n // Check if we have a calculated flow field or similar categorical field\n const flowField = vegaSpec.transform?.find(t => t.calculate && t.as)?.as;\n const categoricalFields = ['flow', 'source', 'target', 'category', 'group'];\n \n let yField = flowField;\n if (!yField) {\n // Look for a suitable categorical field in the data\n if (vegaSpec.data?.values && vegaSpec.data.values.length > 0) {\n const firstRow = vegaSpec.data.values[0];\n yField = categoricalFields.find(field => firstRow.hasOwnProperty(field));\n }\n }\n \n if (yField) {\n vegaSpec.encoding.y = {\n field: yField,\n type: 'nominal',\n title: yField.charAt(0).toUpperCase() + yField.slice(1)\n };\n console.log(`Added y-axis encoding with field: ${yField}`);\n }\n }\n\n // Fix for layered charts with selections\n if ((vegaSpec.layer || vegaSpec.facet || vegaSpec.vconcat || vegaSpec.hconcat) && vegaSpec.params) {\n // Check if we have selection parameters\n const selectionParams = vegaSpec.params.filter(param => param.select);\n\n if (selectionParams.length > 0) {\n console.log(\"Found top-level selection parameters in composite chart, applying fix\");\n\n // Create a deep clone of the spec to avoid modifying the original\n const modifiedSpec = JSON.parse(JSON.stringify(vegaSpec));\n\n // Remove the top-level params\n delete modifiedSpec.params;\n\n if (modifiedSpec.layer) {\n if (!modifiedSpec.layer[0].params) modifiedSpec.layer[0].params = [];\n modifiedSpec.layer[0].params.push(...selectionParams);\n console.log(\"Moved selection parameters to first layer\");\n } else if (modifiedSpec.facet) {\n if (!modifiedSpec.spec.params) modifiedSpec.spec.params = [];\n modifiedSpec.spec.params.push(...selectionParams);\n console.log(\"Moved selection parameters to facet spec\");\n } else if (modifiedSpec.vconcat) {\n if (!modifiedSpec.vconcat[0].params) modifiedSpec.vconcat[0].params = [];\n modifiedSpec.vconcat[0].params.push(...selectionParams);\n console.log(\"Moved selection parameters to first vconcat view\");\n } else if (modifiedSpec.hconcat) {\n if (!modifiedSpec.hconcat[0].params) modifiedSpec.hconcat[0].params = [];\n modifiedSpec.hconcat[0].params.push(...selectionParams);\n console.log(\"Moved selection parameters to first hconcat view\");\n }\n\n // Use the modified spec\n vegaSpec = modifiedSpec;\n }\n }\n\n // Fix for top-level facet with transforms - transforms should be in spec\n if (vegaSpec.facet && vegaSpec.transform && !vegaSpec.spec) {\n console.log(\"Found top-level facet with transforms, moving transforms to spec\");\n console.log(\"Original spec:\", JSON.stringify(vegaSpec, null, 2));\n\n // Extract facet configuration and transforms\n const { facet, transform, layer, mark, encoding, ...otherProps } = vegaSpec;\n\n // Create the corrected spec structure\n const correctedSpec = {\n ...otherProps, // Preserve $schema, data, description, etc.\n facet: facet,\n spec: {\n transform: transform,\n ...(layer && { layer }),\n ...(mark && { mark }),\n ...(encoding && { encoding })\n }\n };\n\n vegaSpec = correctedSpec;\n console.log(\"Corrected facet specification structure:\");\n console.log(\"New spec:\", JSON.stringify(vegaSpec, null, 2));\n }\n\n // Fix for facet encoding incorrectly placed inside encoding object (common LLM mistake)\n if (vegaSpec.encoding?.facet) {\n console.log(\"Found facet in encoding, moving to top level\");\n console.log(\"Original spec:\", JSON.stringify(vegaSpec, null, 2));\n\n // Extract facet configuration\n const facetConfig = vegaSpec.encoding.facet;\n\n // Create new spec structure - preserve all original properties except mark and encoding\n const { mark, encoding, ...otherProps } = vegaSpec;\n\n // Create the corrected encoding without facet\n const correctedEncoding = { ...encoding };\n delete correctedEncoding.facet;\n\n const correctedSpec = {\n ...otherProps, // Preserve $schema, data, description, etc.\n facet: facetConfig,\n spec: {\n mark: mark,\n encoding: correctedEncoding\n }\n };\n\n vegaSpec = correctedSpec;\n console.log(\"Corrected facet specification structure:\");\n console.log(\"New spec:\", JSON.stringify(vegaSpec, null, 2));\n }\n\n // Pre-render legend optimization - configure legends to wrap based on estimated size\n const optimizeLegendLayout = (spec: any) => {\n const chartHeight = spec.height || 400;\n const maxLegendHeight = chartHeight * 0.6; // Legend shouldn't exceed 60% of chart height\n const estimatedItemHeight = 20; // Approximate height per legend item including padding\n const maxItemsPerColumn = Math.floor(maxLegendHeight / estimatedItemHeight);\n \n console.log(`Legend optimization: Chart height=${chartHeight}, Max legend height=${maxLegendHeight}, Max items per column=${maxItemsPerColumn}`);\n \n // Helper to count unique values in a field\n const countUniqueValues = (fieldName: string, data: any[]): number => {\n if (!data || !Array.isArray(data)) return 0;\n const uniqueValues = new Set();\n data.forEach((row: any) => {\n if (row[fieldName] !== undefined && row[fieldName] !== null) {\n uniqueValues.add(row[fieldName]);\n }\n });\n return uniqueValues.size;\n };\n \n // Helper to apply legend column wrapping\n const applyLegendWrapping = (encoding: any, channel: string, data: any[]) => {\n if (!encoding[channel] || !encoding[channel].field) return;\n \n const fieldName = encoding[channel].field;\n const uniqueCount = countUniqueValues(fieldName, data);\n \n if (uniqueCount > maxItemsPerColumn) {\n const neededColumns = Math.ceil(uniqueCount / maxItemsPerColumn);\n const columns = Math.min(neededColumns, 3); // Cap at 3 columns to prevent horizontal overflow\n \n console.log(`Applying legend wrapping to ${channel} field \"${fieldName}\": ${uniqueCount} items -> ${columns} columns`);\n \n if (!encoding[channel].legend) {\n encoding[channel].legend = {};\n }\n \n encoding[channel].legend = {\n ...encoding[channel].legend,\n columns: columns,\n symbolLimit: 0,\n labelLimit: 80, // Shorter labels to fit multiple columns\n titleLimit: 100,\n orient: 'bottom', // Move to bottom to avoid vertical overflow\n offset: 5,\n padding: 3,\n rowPadding: 2,\n columnPadding: 6\n };\n }\n };\n \n // Get the main data source\n const mainData = spec.data?.values || [];\n \n // Apply to main spec encoding\n if (spec.encoding) {\n ['color', 'fill', 'stroke', 'shape', 'size', 'opacity'].forEach(channel => {\n applyLegendWrapping(spec.encoding, channel, mainData);\n });\n }\n \n // Apply to layer encodings\n if (spec.layer && Array.isArray(spec.layer)) {\n spec.layer.forEach((layer: any, layerIndex: number) => {\n if (layer.encoding) {\n // Use layer-specific data if available, otherwise use main data\n const layerData = layer.data?.values || mainData;\n ['color', 'fill', 'stroke', 'shape', 'size', 'opacity'].forEach(channel => {\n applyLegendWrapping(layer.encoding, channel, layerData);\n });\n }\n });\n }\n };\n \n // Apply legend optimization before rendering\n optimizeLegendLayout(vegaSpec);\n\n // Generic fix for specifications that have conflicting width/height with container\n if (vegaSpec.width === 0 || vegaSpec.height === 0) {\n delete vegaSpec.width;\n delete vegaSpec.height;\n }\n\n // Remove resolve scales that can cause rendering issues\n if (vegaSpec.resolve && vegaSpec.resolve.scale) {\n delete vegaSpec.resolve;\n }\n\n // Apply theme\n const embedOptions: EmbedOptions = {\n actions: false,\n theme: isDarkMode ? 'dark' : 'excel',\n renderer: 'svg' as const, // Use SVG for better scaling with complex layouts\n scaleFactor: 1,\n // Don't override width/height in embed options if they're set in the spec\n ...((!vegaSpec.width || vegaSpec.width === 0) && { width: availableWidth }),\n ...((!vegaSpec.height || vegaSpec.height === 0) && { height: availableHeight * 0.6 }),\n config: {\n view: {\n // Only set continuous dimensions if not explicitly specified\n ...((!vegaSpec.width || vegaSpec.width === 0) && { continuousWidth: availableWidth }),\n ...((!vegaSpec.height || vegaSpec.height === 0) && { continuousHeight: availableHeight * 0.6 }),\n stroke: 'transparent' // Remove default border\n }\n }\n }\n\n // Final validation: ensure the spec is still valid after preprocessing\n if (vegaSpec.encoding && Object.keys(vegaSpec.encoding).length === 0) {\n throw new Error('Invalid Vega-Lite specification: all encoding channels were invalid and removed');\n }\n\n // Set explicit container dimensions for complex layouts\n if (vegaSpec.vconcat || vegaSpec.hconcat || vegaSpec.facet) {\n container.style.minHeight = `${availableHeight}px`;\n }\n\n // Remove loading spinner\n try {\n if (loadingSpinner && loadingSpinner.parentNode) {\n container.removeChild(loadingSpinner);\n }\n } catch (e) {\n console.warn('Could not remove loading spinner (this is normal for multiple renders):', e instanceof Error ? e.message : String(e));\n }\n\n // Create a fresh container div to ensure no conflicts\n const renderContainer = document.createElement('div');\n renderContainer.style.width = '100%';\n renderContainer.style.maxWidth = '100%';\n renderContainer.style.overflow = 'hidden';\n renderContainer.style.boxSizing = 'border-box';\n container.appendChild(renderContainer);\n\n const sanitizedSpec = vegaSpec;\n\n // Render the visualization\n // Deep clone and sanitize the spec one last time to be safe by serializing and parsing.\n // This removes any non-plain-object properties that might be causing issues.\n const finalSpec = JSON.parse(JSON.stringify(sanitizedSpec));\n\n console.log('Vega-Lite: About to call vegaEmbed with finalSpec:', finalSpec);\n\n // Log final spec before rendering for violin plots\n if (finalSpec.transform && finalSpec.transform.some((t: any) => t.density)) {\n console.log('Final spec being sent to vega-embed for violin plot:', JSON.stringify(finalSpec, null, 2));\n }\n\n\n // Additional validation before calling vega-embed\n try {\n // Validate that all field references exist in the data\n if (finalSpec.encoding && finalSpec.data?.values && Array.isArray(finalSpec.data.values) && finalSpec.data.values.length > 0) {\n const dataFields = new Set();\n Object.keys(finalSpec.data.values[0]).forEach(key => dataFields.add(key));\n\n // Check encoding fields\n Object.values(finalSpec.encoding).forEach((encoding: any) => {\n if (encoding?.field && !dataFields.has(encoding.field) && !finalSpec.transform) {\n console.warn(`Field '${encoding.field}' referenced in encoding but not found in data`);\n }\n });\n } else if (finalSpec.transform) {\n // For specs with transforms (like violin plots), skip field validation\n // as fields may be generated by the transform\n console.log('Spec uses transforms, skipping field validation');\n } else if (finalSpec.data?.url) {\n // For specs with external data, skip field validation\n console.log('Spec uses external data, skipping field validation');\n } else {\n console.log('Skipping field validation for this spec type');\n }\n } catch (validationError) {\n console.warn('Spec validation warning:', validationError);\n }\n\n const result = await vegaEmbed(renderContainer, finalSpec, embedOptions);\n\n console.log('Vega-Lite: vegaEmbed completed successfully:', result);\n\n // Log successful render for violin plots\n if (finalSpec.transform && finalSpec.transform.some((t: any) => t.density)) {\n console.log('Violin plot vega-embed result:', result);\n console.log('Violin plot SVG element:', renderContainer.querySelector('svg'));\n console.log('Violin plot container dimensions:', renderContainer.getBoundingClientRect());\n }\n\n // Store the view for cleanup\n (container as any)._vegaView = result.view;\n\n // Simple fix: Make parent containers fit the Vega-Lite content\n setTimeout(() => {\n const vegaEmbedDiv = renderContainer.querySelector('.vega-embed') as HTMLElement;\n if (vegaEmbedDiv) {\n const vegaHeight = vegaEmbedDiv.offsetHeight;\n const vegaWidth = vegaEmbedDiv.offsetWidth;\n\n // Adjust parent d3-container to fit\n let parent = container.parentElement;\n while (parent && parent.classList.contains('d3-container')) {\n const parentEl = parent as HTMLElement;\n if (parentEl.offsetHeight < vegaHeight) {\n parentEl.style.height = `${vegaHeight + 20}px`;\n parentEl.style.minHeight = `${vegaHeight + 20}px`;\n }\n parent = parent.parentElement;\n }\n }\n }, 100);\n\n // Set up Vega-Lite specific resize handling\n const setupVegaLiteResizing = () => {\n const vegaEmbedDiv = renderContainer.querySelector('.vega-embed') as HTMLElement;\n const vegaSvg = renderContainer.querySelector('svg') as SVGSVGElement;\n\n console.log('Setting up Vega-Lite specific resizing:', {\n vegaEmbedDiv: !!vegaEmbedDiv,\n vegaSvg: !!vegaSvg,\n renderContainer: renderContainer.getBoundingClientRect(),\n container: container.getBoundingClientRect()\n });\n\n if (vegaEmbedDiv || vegaSvg) {\n const targetElement = vegaEmbedDiv || vegaSvg;\n\n const vegaResizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const actualHeight = entry.contentRect.height;\n const actualWidth = entry.contentRect.width;\n\n console.log(`Vega-Lite element resized: ${actualWidth}x${actualHeight}`);\n\n // Update parent containers\n let parent = container.parentElement;\n while (parent && (parent.classList.contains('d3-container') || parent.classList.contains('vega-lite-container'))) {\n const parentElement = parent as HTMLElement;\n const currentHeight = parentElement.getBoundingClientRect().height;\n\n console.log(`Parent ${parentElement.className}: current=${currentHeight}, needed=${actualHeight + 40}`);\n\n if (currentHeight < actualHeight + 40) {\n parentElement.style.height = `${actualHeight + 40}px`;\n parentElement.style.minHeight = `${actualHeight + 40}px`;\n parentElement.style.overflow = 'visible';\n console.log(`Updated parent ${parentElement.className} height to ${actualHeight + 40}px`);\n }\n\n parent = parent.parentElement;\n }\n }\n });\n\n vegaResizeObserver.observe(targetElement);\n console.log('Vega-Lite resize observer attached to:', targetElement.tagName, targetElement.className);\n }\n };\n\n // Also set up a MutationObserver to catch when Vega-Lite adds elements\n const mutationObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.type === 'childList') {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n if (element.classList.contains('vega-embed') || element.tagName.toLowerCase() === 'svg') {\n console.log('Vega-Lite element added via mutation observer:', element.tagName, element.className);\n setTimeout(setupVegaLiteResizing, 100);\n }\n }\n });\n }\n });\n });\n\n // Observe the render container for changes\n mutationObserver.observe(renderContainer, {\n childList: true,\n subtree: true\n });\n\n // Clean up mutation observer after a reasonable time\n setTimeout(() => {\n mutationObserver.disconnect();\n }, 5000);\n\n // Set up resizing with multiple attempts\n setTimeout(setupVegaLiteResizing, 100);\n setTimeout(setupVegaLiteResizing, 500);\n setTimeout(setupVegaLiteResizing, 1000);\n\n // Immediate size check and adjustment\n setTimeout(() => {\n const vegaEmbedDiv = renderContainer.querySelector('.vega-embed') as HTMLElement;\n if (vegaEmbedDiv) {\n const vegaRect = vegaEmbedDiv.getBoundingClientRect();\n console.log('Immediate Vega-Lite size check:', vegaRect);\n\n let parent = container.parentElement;\n while (parent && parent.classList.contains('d3-container')) {\n const parentRect = parent.getBoundingClientRect();\n console.log(`Parent ${parent.className} size:`, parentRect);\n\n if (parentRect.height < vegaRect.height + 40) {\n (parent as HTMLElement).style.height = `${vegaRect.height + 40}px`;\n (parent as HTMLElement).style.minHeight = `${vegaRect.height + 40}px`;\n console.log(`Immediately adjusted parent ${parent.className} to ${vegaRect.height + 40}px`);\n }\n parent = parent.parentElement;\n }\n }\n }, 200);\n\n // Store references to the vega view and container content\n const vegaContainer = renderContainer.querySelector('.vega-embed') as HTMLElement;\n\n // Add action buttons container\n const actionsContainer = document.createElement('div');\n actionsContainer.className = 'diagram-actions';\n // Position the buttons in the top-right corner, 12px higher than default\n actionsContainer.style.cssText = `\n position: absolute;\n top: -4px;\n right: 8px;\n z-index: 1000;\n opacity: 0;\n transition: opacity 0.2s ease-in-out;\n `;\n // The diagram-actions class from index.css will handle additional styling\n\n // Force container to have position: relative for absolute positioning\n container.style.position = 'relative';\n\n // Add Open button\n const openButton = document.createElement('button');\n openButton.innerHTML = '↗️ Open';\n openButton.className = 'diagram-action-button vega-lite-open-button';\n openButton.onclick = () => {\n // Get the SVG element - check both the stored container and current container\n let svgElement = vegaContainer?.querySelector('svg');\n if (!svgElement) {\n // Fallback: look in the current container\n svgElement = container.querySelector('svg');\n }\n if (!svgElement) return;\n\n console.log('Opening Vega-Lite visualization in popup');\n\n // Get the SVG dimensions\n const svgGraphics = svgElement as unknown as SVGGraphicsElement;\n let width = 800;\n let height = 600;\n\n try {\n // Try to get the bounding box\n const bbox = svgGraphics.getBBox();\n width = Math.max(bbox.width + 100, 600); // Add padding, minimum 600px\n height = Math.max(bbox.height + 150, 400); // Add padding, minimum 400px\n } catch (e) {\n console.warn('Could not get SVG dimensions, using defaults', e);\n }\n\n // Get SVG data\n const svgData = new XMLSerializer().serializeToString(svgElement);\n\n // Create an HTML document that will display the SVG responsively\n const htmlContent = `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>Vega-Lite Visualization</title>\n <style>\n :root {\n --bg-color: #f8f9fa;\n --text-color: #212529;\n --toolbar-bg: #f1f3f5;\n --toolbar-border: #dee2e6;\n --button-bg: #4361ee;\n --button-hover: #3a0ca3;\n }\n \n [data-theme=\"dark\"] {\n --bg-color: #212529;\n --text-color: #f8f9fa;\n --toolbar-bg: #343a40;\n --toolbar-border: #495057;\n --button-bg: #4361ee;\n --button-hover: #5a72f0;\n }\n \n body {\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n height: 100vh;\n background-color: var(--bg-color);\n color: var(--text-color);\n font-family: system-ui, -apple-system, sans-serif;\n transition: background-color 0.3s ease, color 0.3s ease;\n }\n \n .toolbar {\n background-color: var(--toolbar-bg);\n border-bottom: 1px solid var(--toolbar-border);\n padding: 8px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n transition: background-color 0.3s ease, border-color 0.3s ease;\n }\n \n .toolbar button {\n background-color: var(--button-bg);\n color: white;\n border: none;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n margin-right: 8px;\n font-size: 14px;\n transition: background-color 0.3s ease;\n }\n \n .toolbar button:hover {\n background-color: var(--button-hover);\n }\n \n .theme-toggle {\n background-color: transparent;\n border: 1px solid var(--text-color);\n color: var(--text-color);\n padding: 4px 8px;\n font-size: 12px;\n }\n \n .theme-toggle:hover {\n background-color: var(--text-color);\n color: var(--bg-color);\n }\n \n .container {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: auto;\n padding: 20px;\n }\n \n svg {\n max-width: 100%;\n max-height: 100%;\n height: auto;\n width: auto;\n transition: all 0.3s ease;\n }\n </style>\n </head>\n <body data-theme=\"${isDarkMode ? 'dark' : 'light'}\">\n <div class=\"toolbar\">\n <div>\n <button onclick=\"zoomIn()\">Zoom In</button>\n <button onclick=\"zoomOut()\">Zoom Out</button>\n <button onclick=\"resetZoom()\">Reset</button>\n <button class=\"theme-toggle\" onclick=\"toggleTheme()\">${isDarkMode ? '☀️ Light' : '🌙 Dark'}</button>\n </div>\n <div>\n <button onclick=\"downloadSvg()\">Download SVG</button>\n <button onclick=\"downloadSpec()\">Download Spec</button>\n </div>\n </div>\n <div class=\"container\" id=\"svg-container\">\n ${svgData}\n </div>\n <script>\n const svg = document.querySelector('svg');\n let currentScale = 1;\n let isDarkMode = ${isDarkMode};\n \n // Store the original Vega-Lite spec\n const vegaSpec = ${JSON.stringify(vegaSpec, null, 2)};\n \n // Make sure SVG is responsive\n svg.setAttribute('width', '100%');\n svg.setAttribute('height', '100%');\n svg.style.maxWidth = '100%';\n svg.style.maxHeight = '100%';\n svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n \n function zoomIn() {\n currentScale *= 1.2;\n svg.style.transform = \\`scale(\\${currentScale})\\`;\n }\n \n function zoomOut() {\n currentScale /= 1.2;\n svg.style.transform = \\`scale(\\${currentScale})\\`;\n }\n \n function resetZoom() {\n currentScale = 1;\n svg.style.transform = 'scale(1)';\n }\n \n function toggleTheme() {\n isDarkMode = !isDarkMode;\n const body = document.body;\n const themeButton = document.querySelector('.theme-toggle');\n \n if (isDarkMode) {\n body.setAttribute('data-theme', 'dark');\n themeButton.textContent = '☀️ Light';\n } else {\n body.setAttribute('data-theme', 'light');\n themeButton.textContent = '🌙 Dark';\n }\n \n // Re-render Vega-Lite visualization with new theme\n reRenderVegaVisualization();\n }\n \n function reRenderVegaVisualization() {\n const container = document.getElementById('svg-container');\n if (!container) return;\n \n // Clear the container\n container.innerHTML = '';\n \n // Import vega-embed dynamically in the popup\n import('https://cdn.jsdelivr.net/npm/vega-embed@6').then(vegaEmbedModule => {\n const vegaEmbed = vegaEmbedModule.default || vegaEmbedModule;\n \n // Re-render with new theme\n vegaEmbed(container, vegaSpec, {\n actions: false,\n theme: isDarkMode ? 'dark' : 'excel',\n renderer: 'svg',\n scaleFactor: 1\n }).then(result => {\n // Make sure SVG is responsive\n const svg = container.querySelector('svg');\n if (svg) {\n svg.setAttribute('width', '100%');\n svg.setAttribute('height', '100%');\n svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n }\n });\n });\n }\n \n function downloadSvg() {\n const svgData = new XMLSerializer().serializeToString(svg);\n const svgDoc = \\`<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n\\${svgData}\\`;\n \n const svgBlob = new Blob([svgDoc], {type: 'image/svg+xml'});\n const url = URL.createObjectURL(svgBlob);\n \n const link = document.createElement('a');\n link.href = url;\n link.download = 'vega-lite-visualization-${Date.now()}.svg';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n \n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }\n \n function downloadSpec() {\n const specBlob = new Blob([JSON.stringify(vegaSpec, null, 2)], {type: 'application/json'});\n const url = URL.createObjectURL(specBlob);\n \n const link = document.createElement('a');\n link.href = url;\n link.download = 'vega-lite-spec-${Date.now()}.json';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n \n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }\n </script>\n </body>\n </html>\n `;\n\n // Create a blob with the HTML content\n const blob = new Blob([htmlContent], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n\n // Open in a new window with specific dimensions\n const popupWindow = window.open(\n url,\n 'VegaLiteVisualization',\n `width=${width},height=${height},resizable=yes,scrollbars=yes,status=no,toolbar=no,menubar=no,location=no`\n );\n\n // Focus the new window\n if (popupWindow) {\n popupWindow.focus();\n console.log('Popup window opened successfully');\n } else {\n console.error('Failed to open popup window - popup blocked?');\n alert('Popup blocked! Please allow popups for this site to open the visualization.');\n }\n\n // Clean up the URL object after a delay\n setTimeout(() => URL.revokeObjectURL(url), 10000);\n };\n actionsContainer.appendChild(openButton);\n\n // Add Save button\n const saveButton = document.createElement('button');\n saveButton.innerHTML = '💾 Save';\n saveButton.className = 'diagram-action-button vega-lite-save-button';\n saveButton.onclick = () => {\n // Get the SVG element - check both the stored container and current container\n let svgElement = vegaContainer?.querySelector('svg');\n if (!svgElement) {\n // Fallback: look in the current container\n svgElement = container.querySelector('svg');\n }\n if (!svgElement) return;\n\n console.log('Saving Vega-Lite visualization as SVG');\n\n // Create a new SVG with proper XML declaration and doctype\n const svgData = new XMLSerializer().serializeToString(svgElement);\n\n // Create a properly formatted SVG document with XML declaration\n const svgDoc = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n${svgData}`;\n\n // Create a blob with the SVG content\n const blob = new Blob([svgDoc], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n\n // Create a download link\n const link = document.createElement('a');\n link.href = url;\n link.download = `vega-lite-visualization-${Date.now()}.svg`;\n document.body.appendChild(link);\n console.log('Triggering download for:', link.download);\n link.click();\n document.body.removeChild(link);\n\n // Clean up the URL object after a delay\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n };\n actionsContainer.appendChild(saveButton);\n\n // Add Source button\n let showingSource = false;\n const originalVegaContainer = vegaContainer;\n const sourceButton = document.createElement('button');\n sourceButton.innerHTML = showingSource ? '🎨 View' : '📝 Source';\n sourceButton.className = 'diagram-action-button vega-lite-source-button';\n sourceButton.onclick = () => {\n showingSource = !showingSource;\n sourceButton.innerHTML = showingSource ? '🎨 View' : '📝 Source';\n\n if (showingSource) {\n // Hide the vega container and show source\n if (originalVegaContainer) {\n vegaContainer.style.display = 'none';\n }\n\n // Clear container and add source view\n const sourceView = document.createElement('pre');\n sourceView.style.cssText = `\n background-color: ${isDarkMode ? '#1f1f1f' : '#f6f8fa'};\n padding: 16px;\n border-radius: 4px;\n overflow: auto;\n width: 100%;\n height: auto;\n max-height: 80vh;\n margin: 0;\n box-sizing: border-box;\n color: ${isDarkMode ? '#e6e6e6' : '#24292e'};\n `;\n sourceView.innerHTML = `<code>${JSON.stringify(vegaSpec, null, 2)}</code>`;\n \n container.innerHTML = '';\n container.appendChild(sourceView);\n \n // Force parent container to accommodate the source view\n let parent = container.parentElement;\n while (parent && (parent.classList.contains('d3-container') || parent.classList.contains('vega-lite-renderer-container'))) {\n const parentElement = parent as HTMLElement;\n parentElement.style.height = 'auto';\n parentElement.style.minHeight = 'auto';\n parentElement.style.overflow = 'auto';\n parent = parent.parentElement;\n }\n\n // Re-add the actions container after clearing innerHTML\n if (actionsContainer.parentNode !== container) {\n container.insertBefore(actionsContainer, container.firstChild);\n }\n } else {\n // Restore the visualization\n const sourceView = container.querySelector('pre');\n if (sourceView) {\n container.removeChild(sourceView);\n }\n // Restore the vega container\n if (originalVegaContainer) {\n originalVegaContainer.style.display = '';\n if (originalVegaContainer.parentNode !== container) {\n container.appendChild(originalVegaContainer);\n }\n } else {\n // Re-render the visualization if the container was lost\n vegaEmbed(container, vegaSpec, embedOptions);\n }\n // Re-add the actions container\n container.insertBefore(actionsContainer, container.firstChild);\n \n // Restore parent container sizing for visualization\n let parent = container.parentElement;\n while (parent && (parent.classList.contains('d3-container') || parent.classList.contains('vega-lite-renderer-container'))) {\n const parentElement = parent as HTMLElement;\n // Let the visualization determine its own height again\n parentElement.style.height = '';\n parent = parent.parentElement;\n }\n };\n };\n actionsContainer.appendChild(sourceButton);\n\n // Force the container to have position: relative\n container.style.position = 'relative';\n\n // Insert actions container at the beginning of the container\n container.insertBefore(actionsContainer, container.firstChild);\n\n // Ensure the actions container is visible on hover\n container.addEventListener('mouseenter', () => actionsContainer.style.opacity = '1');\n container.addEventListener('mouseleave', () => actionsContainer.style.opacity = '0');\n\n // Post-render fixes for sizing issues\n setTimeout(() => {\n const svgElement = container.querySelector('svg');\n const vegaEmbedDiv = container.querySelector('.vega-embed') as HTMLElement;\n\n // Fix SVG scaling when content is smaller than container\n const svg = container.querySelector('svg');\n const embedDiv = container.querySelector('.vega-embed') as HTMLElement;\n\n if (svg && embedDiv) {\n const containerRect = embedDiv.getBoundingClientRect();\n const svgRect = svg.getBoundingClientRect();\n \n // Only scale if SVG is significantly smaller than container\n const scaleX = containerRect.width / svgRect.width;\n const scaleY = containerRect.height / svgRect.height;\n const scale = Math.min(scaleX, scaleY);\n \n if (scale > 1.2) { // Only scale if there's significant wasted space\n const finalScale = Math.min(scale, 2.5); // Cap scaling\n svg.style.transform = `scale(${finalScale})`;\n svg.style.transformOrigin = 'center center';\n console.log(`Scaled SVG by ${finalScale}x to reduce wasted space`);\n }\n }\n\n // Fix SVG to fill vega-embed container properly\n const svgEl = container.querySelector('svg');\n const embedContainer = container.querySelector('.vega-embed') as HTMLElement;\n\n if (svgEl && embedContainer) {\n // Make SVG fill the container\n svgEl.style.width = '100%';\n svgEl.style.height = '100%';\n svgEl.removeAttribute('width');\n svgEl.removeAttribute('height');\n svgEl.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n \n console.log('Made SVG responsive to fill vega-embed container');\n }\n\n // Critical fix: Ensure vega-embed div doesn't exceed parent width\n if (vegaEmbedDiv) {\n vegaEmbedDiv.style.maxWidth = '100%';\n vegaEmbedDiv.style.overflow = 'hidden';\n }\n\n if (svgElement) {\n // Only apply responsive sizing if the chart doesn't have explicit dimensions\n const hasExplicitWidth = vegaSpec.width && vegaSpec.width > 0;\n const hasExplicitHeight = vegaSpec.height && vegaSpec.height > 0;\n\n if (!hasExplicitWidth) {\n svgElement.style.width = '100%';\n svgElement.style.maxWidth = '100%';\n }\n\n if (!hasExplicitHeight) {\n svgElement.style.height = 'auto';\n }\n\n svgElement.style.display = 'block';\n\n console.log(\">>> vegaLitePlugin: SVG sizing applied:\", {\n svgWidth: svgElement.style.width,\n containerWidth: container.getBoundingClientRect().width,\n svgRect: svgElement.getBoundingClientRect()\n });\n }\n\n if (vegaEmbedDiv) {\n // Only apply responsive width if not explicitly set\n const hasExplicitWidth = vegaSpec.width && vegaSpec.width > 0;\n\n if (!hasExplicitWidth) {\n vegaEmbedDiv.style.width = '100%';\n vegaEmbedDiv.style.maxWidth = '100%';\n }\n }\n\n // Force parent containers to use full width\n let parent = container.parentElement;\n while (parent && parent.classList.contains('d3-container')) {\n (parent as HTMLElement).style.width = '100%';\n (parent as HTMLElement).style.maxWidth = '100%';\n parent = parent.parentElement;\n }\n\n // Add global debugging functions to window\n (window as any).debugVegaLite = {\n container,\n svgElement,\n vegaEmbedDiv,\n getSVGActualSize: () => {\n if (!svgElement) return null;\n const rect = svgElement.getBoundingClientRect();\n const viewBox = svgElement.getAttribute('viewBox');\n const [vbX, vbY, vbWidth, vbHeight] = viewBox ? viewBox.split(' ').map(Number) : [0, 0, 0, 0];\n return {\n actualWidth: rect.width,\n actualHeight: rect.height,\n viewBoxWidth: vbWidth,\n viewBoxHeight: vbHeight,\n scaleRatio: rect.width / vbWidth\n };\n },\n inspect: () => {\n console.log('=== Vega-Lite Debug Info ===');\n console.log('Container:', container);\n console.log('SVG Element:', svgElement);\n console.log('Vega Embed Div:', vegaEmbedDiv);\n\n if (svgElement) {\n console.log('SVG getBoundingClientRect():', svgElement.getBoundingClientRect());\n console.log('SVG viewBox:', svgElement.getAttribute('viewBox'));\n console.log('SVG style:', svgElement.style.cssText);\n console.log('SVG computed style:', window.getComputedStyle(svgElement));\n }\n\n if (vegaEmbedDiv) {\n console.log('Embed div getBoundingClientRect():', vegaEmbedDiv.getBoundingClientRect());\n console.log('Embed div style:', vegaEmbedDiv.style.cssText);\n console.log('Embed div computed style:', window.getComputedStyle(vegaEmbedDiv));\n }\n\n console.log('Container getBoundingClientRect():', container.getBoundingClientRect());\n\n // Check if SVG is being clipped\n const svgRect = svgElement?.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n if (svgRect && containerRect) {\n console.log('SVG overflow check:', {\n svgBottom: svgRect.bottom,\n containerBottom: containerRect.bottom,\n isOverflowing: svgRect.bottom > containerRect.bottom,\n overflowAmount: svgRect.bottom - containerRect.bottom\n });\n }\n\n // Check parent containers that might be constraining height\n let parent = container.parentElement;\n let level = 0;\n while (parent && level < 3) {\n const parentRect = parent.getBoundingClientRect();\n console.log(`Parent level ${level}:`, {\n element: parent,\n className: parent.className,\n rect: parentRect,\n style: parent.style.cssText,\n computedHeight: window.getComputedStyle(parent).height\n });\n parent = parent.parentElement;\n level++;\n }\n }\n };\n\n console.log('Vega-Lite debugging available: window.debugVegaLite.inspect()');\n\n if (svgElement) {\n // Get the SVG viewBox dimensions (the actual content size)\n const viewBox = svgElement.getAttribute('viewBox');\n let svgWidth = 680;\n let svgHeight = 774;\n\n if (viewBox) {\n const [, , width, height] = viewBox.split(' ').map(Number);\n svgWidth = width;\n svgHeight = height;\n } else {\n // Try to get dimensions from the SVG attributes\n const width = svgElement.getAttribute('width');\n const height = svgElement.getAttribute('height');\n if (width && height) {\n svgWidth = parseFloat(width);\n svgHeight = parseFloat(height);\n }\n }\n\n console.log('SVG content dimensions:', { svgWidth, svgHeight, viewBox });\n\n // Only apply responsive sizing if chart doesn't have explicit dimensions\n const hasExplicitWidth = vegaSpec.width && vegaSpec.width > 0;\n const hasExplicitHeight = vegaSpec.height && vegaSpec.height > 0;\n\n if (!hasExplicitWidth) {\n svgElement.style.width = '100%';\n svgElement.style.maxWidth = '100%';\n }\n\n if (!hasExplicitHeight) {\n svgElement.style.height = 'auto';\n }\n\n svgElement.style.overflow = 'visible';\n\n // Force the vega-embed container to accommodate the full SVG content\n if (vegaEmbedDiv) {\n // Only calculate responsive height if height isn't explicitly set\n if (!hasExplicitHeight) {\n const containerWidth = vegaEmbedDiv.getBoundingClientRect().width;\n const aspectRatio = svgHeight / svgWidth;\n const neededHeight = containerWidth * aspectRatio;\n\n vegaEmbedDiv.style.height = `${neededHeight}px`;\n vegaEmbedDiv.style.minHeight = `${neededHeight}px`;\n\n console.log('Container sizing:', { containerWidth, aspectRatio, neededHeight });\n }\n\n vegaEmbedDiv.style.display = 'block';\n vegaEmbedDiv.style.overflow = 'visible';\n }\n\n // Force container and all parents to accommodate the content\n const forceContainerResize = () => {\n const actualHeight = svgElement.getBoundingClientRect().height;\n let parent = container.parentElement;\n while (parent && parent.classList.contains('d3-container')) {\n const parentElement = parent as HTMLElement;\n if (parentElement.getBoundingClientRect().height < actualHeight + 40) {\n parentElement.style.height = `${actualHeight + 40}px`;\n parentElement.style.minHeight = `${actualHeight + 40}px`;\n console.log(`Force resized parent ${parentElement.className} to ${actualHeight + 40}px`);\n }\n parent = parent.parentElement;\n }\n };\n\n setTimeout(forceContainerResize, 100);\n setTimeout(forceContainerResize, 500);\n\n // Only adjust parent containers if height isn't explicitly set\n if (!hasExplicitHeight) {\n let parent = container.parentElement;\n while (parent) {\n if (parent.classList.contains('vega-lite-renderer-container')) {\n (parent as HTMLElement).style.height = 'auto';\n (parent as HTMLElement).style.minHeight = `${svgHeight}px`;\n (parent as HTMLElement).style.overflow = 'visible';\n console.log('Updated Vega-Lite parent container:', parent.className, 'to height: auto, minHeight:', svgHeight);\n break; // Only modify our own container\n }\n parent = parent.parentElement;\n }\n }\n\n // For complex layouts, ensure proper scaling\n if (vegaSpec.vconcat || vegaSpec.hconcat || vegaSpec.facet) {\n svgElement.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n\n // Force a reflow to ensure proper sizing\n setTimeout(() => {\n container.style.display = 'none';\n void container.offsetHeight; // Trigger reflow\n container.style.display = '';\n }, 100);\n }\n \n console.log('Vega-Lite visualization rendered successfully');\n }\n }, 100);\n } catch (error) {\n console.error('Vega-Lite rendering error:', error);\n\n // Log streaming state during error for debugging\n console.log('Vega-Lite error context:', {\n isStreaming: spec.isStreaming,\n isMarkdownBlockClosed: spec.isMarkdownBlockClosed,\n forceRender: spec.forceRender\n });\n\n // Check if this looks like a streaming/incomplete JSON error\n const isStreamingError = (error instanceof Error) && (\n error.message.includes('Unterminated string') ||\n error.message.includes('Unexpected end of JSON input') ||\n error.message.includes('Unexpected token')\n );\n \n // Separate check for incomplete definition (only relevant if we're actually streaming)\n const isIncompleteDefinition = spec.definition && !isVegaLiteDefinitionComplete(spec.definition);\n\n // During streaming or with incomplete JSON, don't show errors unless forced\n // CRITICAL: Don't suppress errors when forceRender is true - user explicitly wants to see what's wrong\n const shouldSuppressError = (\n !spec.forceRender && (\n (spec.isStreaming && !spec.isMarkdownBlockClosed) ||\n (spec.isStreaming && isIncompleteDefinition)\n ) ||\n (!spec.definition || spec.definition.trim().length === 0) ||\n (isStreamingError && !spec.forceRender)\n );\n\n if (shouldSuppressError) {\n console.debug('Suppressing Vega-Lite streaming error:', error instanceof Error ? error.message : String(error));\n // Show waiting message instead of error\n const suppressedErrorContainer = document.createElement('div');\n suppressedErrorContainer.style.cssText = `\n text-align: center; \n padding: 20px; \n background-color: ${isDarkMode ? '#1f1f1f' : '#f6f8fa'}; \n border: 1px dashed #ccc; \n border-radius: 4px;\n position: relative;\n `;\n \n suppressedErrorContainer.innerHTML = `\n <p>Waiting for complete Vega-Lite specification...</p>\n <div style=\"margin-top: 15px;\">\n <button class=\"vega-lite-force-retry-btn\" style=\"\n background-color: #dc3545;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 0 5px;\n cursor: pointer;\n font-size: 14px;\n \">🔄 Force Render Anyway</button>\n <button id=\"vega-lite-debug-source-${Date.now()}\" style=\"\n background-color: #6c757d;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 0 5px;\n cursor: pointer;\n font-size: 14px;\n \">🔍 Debug Source</button>\n </div>\n <div style=\"margin-top: 10px; font-size: 12px; color: ${isDarkMode ? '#8b949e' : '#656d76'};\">\n Error: ${error instanceof Error ? error.message : String(error)}\n </div>\n `;\n \n container.innerHTML = '';\n container.appendChild(suppressedErrorContainer);\n \n // Add event listeners\n const forceRetryId = suppressedErrorContainer.querySelector('[id^=\"vega-lite-force-retry-\"]')?.id;\n const debugSourceId = suppressedErrorContainer.querySelector('[id^=\"vega-lite-debug-source-\"]')?.id;\n \n if (forceRetryId) {\n const forceRetryButton = document.getElementById(forceRetryId);\n if (forceRetryButton) {\n forceRetryButton.onclick = () => {\n console.log('Force rendering Vega-Lite despite streaming error');\n const forceSpec = { ...spec, forceRender: true };\n vegaLitePlugin.render(container, d3, forceSpec, isDarkMode);\n };\n }\n }\n \n if (debugSourceId) {\n const debugSourceButton = document.getElementById(debugSourceId);\n if (debugSourceButton) {\n debugSourceButton.onclick = () => {\n showVegaLiteDebugView(container, spec, isDarkMode, error instanceof Error ? error : new Error(String(error)));\n };\n }\n }\n \n return;\n }\n\n // Special error handling for violin plots\n if (vegaSpec && vegaSpec.transform && vegaSpec.transform.some((t: any) => t.density || t.kde)) {\n console.error('Violin plot specific error details:', {\n hasData: !!vegaSpec.data,\n hasTransform: !!vegaSpec.transform,\n hasMark: !!vegaSpec.mark,\n transformTypes: vegaSpec.transform.map((t: any) => Object.keys(t))\n });\n }\n\n // Add more specific error information for debugging\n if (error instanceof Error) {\n console.error('Error details:', {\n message: error.message,\n stack: error.stack\n });\n }\n\n // Remove loading spinner if it exists\n try {\n const spinner = container.querySelector('.vega-lite-loading-spinner') as HTMLElement;\n if (spinner && spinner.parentNode) {\n container.removeChild(spinner);\n }\n } catch (e) {\n console.warn('Could not remove loading spinner during error handling:', e instanceof Error ? e.message : String(e));\n }\n\n // Create error container with proper sizing\n showVegaLiteErrorView(container, spec, isDarkMode, error instanceof Error ? error : new Error(String(error)));\n\n // Apply the same container sizing logic used for successful renders\n setTimeout(() => {\n const errorDiv = container.querySelector('.vega-lite-error, .vega-lite-debug') as HTMLElement;\n if (errorDiv) {\n const errorRect = errorDiv.getBoundingClientRect();\n console.log('Error container size:', errorRect);\n\n // Force parent containers to accommodate the error content\n let parent = container.parentElement;\n while (parent && (parent.classList.contains('d3-container') || parent.classList.contains('vega-lite-renderer-container'))) {\n const parentElement = parent as HTMLElement;\n\n // Only modify Vega-Lite containers, not all d3-containers\n if (parentElement.classList.contains('vega-lite-renderer-container')) {\n // Force auto height and visible overflow for error display\n parentElement.style.height = 'auto';\n parentElement.style.minHeight = `${errorRect.height + 40}px`;\n parentElement.style.overflow = 'visible';\n\n // Also ensure the container can grow\n if (parentElement.style.maxHeight) {\n parentElement.style.maxHeight = 'none';\n }\n console.log(`Updated parent ${parentElement.className} height to ${errorRect.height + 40}px for error display`);\n }\n parent = parent.parentElement;\n }\n }\n }, 100);\n}\n}\n};\n\n/**\n * Show enhanced error view with debugging options similar to Mermaid\n */\nfunction showVegaLiteErrorView(container: HTMLElement, spec: VegaLiteSpec, isDarkMode: boolean, error: Error): void {\n const sourceDefinition = spec.definition || JSON.stringify(spec, null, 2);\n const isCompleteVegaLiteObject = spec.$schema && (spec.data || spec.datasets) &&\n (spec.mark || spec.layer || spec.vconcat || spec.hconcat || spec.facet || spec.repeat);\n\n container.innerHTML = `\n <div class=\"vega-lite-error\" style=\"\n padding: 16px;\n margin: 16px 0;\n border-radius: 6px;\n background-color: ${isDarkMode ? '#2a1f1f' : '#fff2f0'};\n border: 1px solid ${isDarkMode ? '#a61d24' : '#ffa39e'};\n color: ${isDarkMode ? '#ff7875' : '#cf1322'};\n \">\n <div style=\"margin-bottom: 15px;\">\n <strong>Vega-Lite Rendering Error:</strong>\n <p>${error.message || 'Unknown error'}</p>\n </div>\n \n <div style=\"margin-bottom: 15px;\">\n <button class=\"vega-lite-retry-error-btn\" style=\"\n background-color: #28a745;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 0 5px;\n cursor: pointer;\n font-size: 14px;\n \">🔄 Retry Rendering</button>\n <button class=\"vega-lite-show-source-btn\" style=\"\n background-color: #007bff;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 0 5px;\n cursor: pointer;\n font-size: 14px;\n \">📝 Show Source</button>\n <button class=\"vega-lite-force-render-btn\" style=\"\n background-color: #dc3545;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 0 5px;\n cursor: pointer;\n font-size: 14px;\n \">⚡ Force Render</button>\n </div>\n \n <div style=\"font-size: 13px; color: ${isDarkMode ? '#8b949e' : '#656d76'};\">\n <strong>Debug Info:</strong><br>\n • Streaming: ${spec.isStreaming ? 'Yes' : 'No'}<br>\n • Block Closed: ${spec.isMarkdownBlockClosed ? 'Yes' : 'No'}<br>\n • Definition Length: ${sourceDefinition.length} characters<br>\n • Complete Object: ${isCompleteVegaLiteObject ? 'Yes' : 'No'}<br>\n • Error Type: ${error.constructor.name}\n </div>\n </div>\n `;\n\n // Add event listeners\n const retryButton = container.querySelector('.vega-lite-retry-error-btn') as HTMLButtonElement;\n const sourceButton = container.querySelector('.vega-lite-show-source-btn') as HTMLButtonElement;\n const forceButton = container.querySelector('.vega-lite-force-render-btn') as HTMLButtonElement;\n\n if (retryButton) {\n retryButton.onclick = () => vegaLitePlugin.render(container, null, spec, isDarkMode);\n }\n\n if (sourceButton) {\n sourceButton.onclick = () => showVegaLiteDebugView(container, spec, isDarkMode, error);\n }\n\n if (forceButton) {\n forceButton.onclick = () => {\n const forceSpec = { ...spec, forceRender: true };\n vegaLitePlugin.render(container, null, forceSpec, isDarkMode);\n };\n }\n}\n\n/**\n * Show debug view with source code and detailed information\n */\nfunction showVegaLiteDebugView(container: HTMLElement, spec: VegaLiteSpec, isDarkMode: boolean, error?: Error): void {\n const sourceDefinition = spec.definition || JSON.stringify(spec, null, 2);\n const isCompleteVegaLiteObject = spec.$schema && (spec.data || spec.datasets) &&\n (spec.mark || spec.layer || spec.vconcat || spec.hconcat || spec.facet || spec.repeat);\n\n container.innerHTML = `\n <div class=\"vega-lite-debug\" style=\"\n background-color: ${isDarkMode ? '#1f1f1f' : '#f6f8fa'};\n border: 1px solid ${isDarkMode ? '#444' : '#e1e4e8'};\n border-radius: 6px;\n padding: 16px;\n margin: 10px 0;\n \">\n <div style=\"margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center;\">\n <strong style=\"color: ${isDarkMode ? '#f8f9fa' : '#24292e'};\">Vega-Lite Debug View</strong>\n <div>\n <button class=\"vega-lite-debug-retry-btn\" style=\"\n background-color: #28a745;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 6px 12px;\n margin-right: 8px;\n cursor: pointer;\n font-size: 13px;\n \">🔄 Retry</button>\n <button id=\"vega-lite-debug-force-${Date.now()}\" style=\"\n background-color: #dc3545;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n font-size: 13px;\n \">⚡ Force Render</button>\n </div>\n </div>\n \n ${error ? `\n <div style=\"\n background-color: ${isDarkMode ? '#2d1b1b' : '#ffeaea'};\n border: 1px solid ${isDarkMode ? '#a61d24' : '#ffa39e'};\n border-radius: 4px;\n padding: 12px;\n margin-bottom: 15px;\n \">\n <strong style=\"color: ${isDarkMode ? '#ff7875' : '#cf1322'};\">Error Details:</strong><br>\n <code style=\"color: ${isDarkMode ? '#ffa7cc' : '#d1242f'};\">${error.message}</code>\n </div>\n ` : ''}\n \n <div style=\"margin-bottom: 15px;\">\n <strong style=\"color: ${isDarkMode ? '#f8f9fa' : '#24292e'};\">Debug Information:</strong><br>\n <div style=\"font-size: 13px; color: ${isDarkMode ? '#8b949e' : '#656d76'}; margin-top: 8px;\">\n • Streaming State: ${spec.isStreaming ? 'Active' : 'Inactive'}<br>\n • Markdown Block: ${spec.isMarkdownBlockClosed ? 'Closed' : 'Open'}<br>\n • Force Render: ${spec.forceRender ? 'Yes' : 'No'}<br>\n • Definition Length: ${sourceDefinition.length} characters<br>\n • Complete Object: ${isCompleteVegaLiteObject ? 'Yes' : 'No'}<br>\n • Has Schema: ${spec.$schema ? 'Yes' : 'No'}<br>\n • Has Data: ${spec.data || spec.datasets ? 'Yes' : 'No'}<br>\n • Has Mark/Layer: ${spec.mark || spec.layer ? 'Yes' : 'No'}\n </div>\n </div>\n \n <details open>\n <summary style=\"cursor: pointer; margin-bottom: 10px; color: ${isDarkMode ? '#f8f9fa' : '#24292e'};\">\n <strong>Source Specification</strong>\n </summary>\n <pre style=\"\n background-color: ${isDarkMode ? '#0d1117' : '#f6f8fa'};\n padding: 12px;\n border-radius: 4px;\n overflow: auto;\n max-height: 400px;\n margin: 0;\n border: 1px solid ${isDarkMode ? '#30363d' : '#e1e4e8'};\n font-family: 'SFMono-Regular', 'Monaco', 'Inconsolata', 'Liberation Mono', 'Courier New', monospace;\n font-size: 13px;\n line-height: 1.45;\n color: ${isDarkMode ? '#e6edf3' : '#24292f'};\n \"><code>${sourceDefinition}</code></pre>\n </details>\n </div>\n `;\n\n // Add event listeners for debug view buttons using querySelector scoped to the container\n const retryButton = container.querySelector('.vega-lite-debug-retry-btn') as HTMLButtonElement;\n const forceButton = container.querySelector('.vega-lite-debug-force-btn') as HTMLButtonElement;\n\n if (retryButton) {\n retryButton.onclick = () => vegaLitePlugin.render(container, null, spec, isDarkMode);\n }\n\n if (forceButton) {\n forceButton.onclick = () => {\n const forceSpec = { ...spec, forceRender: true };\n };\n }\n \n // Force parent containers to accommodate the debug content\n setTimeout(() => {\n const debugDiv = container.querySelector('.vega-lite-debug') as HTMLElement;\n if (debugDiv) {\n const debugRect = debugDiv.getBoundingClientRect();\n console.log('Debug container size:', debugRect);\n\n // Force parent containers to accommodate the debug content\n let parent = container.parentElement;\n while (parent && (parent.classList.contains('d3-container') || parent.classList.contains('vega-lite-renderer-container'))) {\n const parentElement = parent as HTMLElement;\n \n // Force auto height and visible overflow for debug display\n parentElement.style.height = 'auto';\n parentElement.style.minHeight = `${Math.max(debugRect.height + 40, 400)}px`;\n parentElement.style.overflow = 'visible';\n \n // Also ensure the container can grow\n if (parentElement.style.maxHeight) {\n parentElement.style.maxHeight = 'none';\n }\n console.log(`Updated parent ${parentElement.className} height to ${debugRect.height + 40}px for debug display`);\n parent = parent.parentElement;\n }\n }\n }, 100);\n}\n","import { D3RenderPlugin } from '../../types/d3';\nimport { networkDiagramPlugin } from './networkDiagram';\nimport { basicChartPlugin } from './basicChart';\nimport { mermaidPlugin } from './mermaidPlugin';\nimport { graphvizPlugin } from './graphvizPlugin';\nimport { vegaLitePlugin } from './vegaLitePlugin';\n\n// Registry for D3 visualization plugins\nconst pluginRegistry: D3RenderPlugin[] = [\n networkDiagramPlugin,\n basicChartPlugin,\n mermaidPlugin,\n graphvizPlugin,\n vegaLitePlugin\n // Add more plugins here as needed\n];\npluginRegistry.forEach(plugin => {\n if (!plugin.name) {\n throw new Error('Plugin missing required name property');\n }\n if (typeof plugin.priority !== 'number') {\n throw new Error(`Plugin ${plugin.name} missing required priority number`);\n }\n if (typeof plugin.canHandle !== 'function') {\n throw new Error(`Plugin ${plugin.name} missing required canHandle function`);\n }\n if (typeof plugin.render !== 'function') {\n throw new Error(`Plugin ${plugin.name} missing required render function`);\n }\n});\nexport const d3RenderPlugins = Object.freeze(pluginRegistry);\nexport const getPluginByName = (name: string) => d3RenderPlugins.find(p => p.name === name);\n","import { PluginSizingConfig } from '../types/d3';\n\nexport class ContainerSizingManager {\n private resizeObservers: Map<HTMLElement, ResizeObserver> = new Map();\n private cleanupFunctions: Set<() => void> = new Set();\n\n /**\n * Apply sizing configuration to a container based on plugin requirements\n */\n applySizingConfig(\n container: HTMLElement,\n config: PluginSizingConfig,\n isDarkMode: boolean\n ): void {\n // Apply container styles\n if (config.containerStyles) {\n Object.assign(container.style, config.containerStyles);\n }\n\n // Apply sizing strategy\n switch (config.sizingStrategy) {\n case 'responsive':\n container.style.width = '100%';\n container.style.maxWidth = '100%';\n if (config.needsDynamicHeight) {\n container.style.height = 'auto';\n container.style.minHeight = config.minHeight ? `${config.minHeight}px` : 'auto';\n }\n break;\n \n case 'content-driven':\n container.style.width = '100%';\n container.style.height = 'auto';\n container.style.minHeight = 'auto';\n break;\n \n case 'auto-expand':\n container.style.width = '100%';\n container.style.height = 'auto';\n container.style.minHeight = config.minHeight ? `${config.minHeight}px` : '200px';\n break;\n \n case 'fixed':\n default:\n if (config.minWidth) container.style.minWidth = `${config.minWidth}px`;\n if (config.minHeight) container.style.minHeight = `${config.minHeight}px`;\n break;\n }\n\n // Handle overflow\n if (config.needsOverflowVisible) {\n container.style.overflow = 'visible';\n this.updateParentOverflow(container);\n }\n\n // Set up resize observation if needed\n if (config.observeResize) {\n this.setupResizeObserver(container, config);\n }\n }\n\n private updateParentOverflow(container: HTMLElement): void {\n let parent = container.parentElement;\n while (parent && (parent.classList.contains('d3-container') || parent.classList.contains('vega-lite-container'))) {\n parent.style.overflow = 'visible';\n parent = parent.parentElement;\n }\n }\n\n private setupResizeObserver(container: HTMLElement, config: PluginSizingConfig): void {\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const actualHeight = entry.contentRect.height;\n const actualWidth = entry.contentRect.width;\n \n this.adjustParentContainers(container, actualWidth, actualHeight, config);\n }\n });\n\n // Observe the main content element (could be svg, .vega-embed, etc.)\n setTimeout(() => {\n const contentElement = container.querySelector('svg, .vega-embed, .mermaid, .graphviz') as HTMLElement;\n if (contentElement) {\n observer.observe(contentElement);\n this.resizeObservers.set(container, observer);\n }\n }, 100);\n }\n\n private adjustParentContainers(\n container: HTMLElement,\n actualWidth: number,\n actualHeight: number,\n config: PluginSizingConfig\n ): void {\n if (!config.needsDynamicHeight) return;\n\n let parent = container.parentElement;\n while (parent && (parent.classList.contains('d3-container') || parent.classList.contains('vega-lite-container'))) {\n const parentElement = parent as HTMLElement;\n const currentHeight = parentElement.getBoundingClientRect().height;\n \n if (currentHeight < actualHeight + 40) { // Add padding\n parentElement.style.height = `${actualHeight + 40}px`;\n parentElement.style.minHeight = `${actualHeight + 40}px`;\n }\n \n if (!parentElement.style.width || parentElement.style.width === 'auto') {\n parentElement.style.width = '100%';\n parentElement.style.maxWidth = '100%';\n }\n \n parent = parent.parentElement;\n }\n }\n\n /**\n * Clean up all observers and resources\n */\n cleanup(): void {\n this.resizeObservers.forEach(observer => observer.disconnect());\n this.resizeObservers.clear();\n this.cleanupFunctions.forEach(cleanup => cleanup());\n this.cleanupFunctions.clear();\n }\n\n /**\n * Add a cleanup function to be called when the manager is destroyed\n */\n addCleanupFunction(cleanup: () => void): void {\n this.cleanupFunctions.add(cleanup);\n }\n}\n","import React, { useState, useEffect, useRef, useMemo, CSSProperties, useCallback } from 'react';\nimport { useTheme } from '../context/ThemeContext';\nimport { Spin, Modal } from 'antd';\nimport vegaEmbed from 'vega-embed';\nimport * as d3 from 'd3';\nimport { D3RenderPlugin } from '../types/d3';\nimport { d3RenderPlugins } from '../plugins/d3/registry';\nimport { isDiagramDefinitionComplete } from '../utils/diagramUtils';\nimport { ContainerSizingManager } from '../utils/containerSizing';\n\ntype RenderType = 'auto' | 'vega-lite' | 'd3';\n\ninterface D3RendererProps {\n spec: any;\n width?: number;\n height?: number;\n containerId?: string;\n type?: RenderType;\n onLoad?: () => void;\n onError?: (error: Error) => void;\n isStreaming?: boolean;\n isMarkdownBlockClosed?: boolean;\n forceRender?: boolean;\n config?: any;\n}\n\nfunction findPlugin(spec: any): D3RenderPlugin | undefined {\n // First check for explicit type\n if (spec.visualizationType) {\n const exactMatch = d3RenderPlugins.find(p => p.name === spec.visualizationType);\n if (exactMatch) return exactMatch;\n }\n // Then check all plugins in priority order\n const matchingPlugins = d3RenderPlugins\n .filter(p => p.canHandle(spec))\n .sort((a, b) => b.priority - a.priority);\n if (matchingPlugins.length > 0) {\n console.debug(`Found ${matchingPlugins.length} matching plugins:`,\n matchingPlugins.map(p => `${p.name} (priority: ${p.priority})`));\n return matchingPlugins[0];\n }\n}\n\n// Helper function to sanitize specs by removing null/undefined values\nfunction sanitizeSpec(obj: any): any {\n if (obj === undefined) {\n return undefined;\n }\n if (obj === null) {\n return null;\n }\n if (Array.isArray(obj)) {\n return obj.map(sanitizeSpec).filter(v => v !== undefined);\n }\n if (typeof obj === 'object') {\n const newObj: any = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const value = sanitizeSpec(obj[key]);\n if (value !== undefined) {\n newObj[key] = value;\n }\n }\n }\n return newObj;\n }\n return obj;\n}\n// Helper function to estimate diagram size based on content\nfunction estimateDiagramSize(spec: any, plugin?: D3RenderPlugin): { width: number; height: number } {\n // Default fallback sizes\n const defaults = { width: 600, height: 400 };\n\n if (!spec || typeof spec !== 'object') return defaults;\n\n // If explicit dimensions are provided, use them\n if (spec.width && spec.height) {\n return { width: spec.width, height: spec.height };\n }\n\n // Plugin-specific size estimation\n if (plugin?.name === 'mermaid-renderer' && spec.definition) {\n const lines = spec.definition.split('\\n').length;\n const avgCharsPerLine = spec.definition.length / lines;\n\n // Rough estimation based on content complexity\n const estimatedWidth = Math.min(Math.max(avgCharsPerLine * 8, 400), 1200);\n const estimatedHeight = Math.min(Math.max(lines * 25, 200), 800);\n\n return { width: estimatedWidth, height: estimatedHeight };\n }\n\n return defaults;\n}\n\nexport const D3Renderer: React.FC<D3RendererProps> = ({\n spec,\n width = 600,\n height = 400,\n containerId,\n type = 'auto',\n onLoad,\n onError,\n isStreaming = false,\n forceRender = false,\n isMarkdownBlockClosed = true,\n config = {}\n}) => {\n const { isDarkMode } = useTheme();\n const vegaContainerRef = useRef<HTMLDivElement>(null);\n const d3ContainerRef = useRef<HTMLDivElement>(null);\n const vegaViewRef = useRef<any>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [renderError, setRenderError] = useState<string | null>(null);\n const [displayWaitingMessage, setDisplayWaitingMessage] = useState<boolean>(false);\n const [hasAttemptedRender, setHasAttemptedRender] = useState<boolean>(false);\n const [errorDetails, setErrorDetails] = useState<string[]>([]);\n const cleanupRef = useRef<(() => void) | null>(null);\n const simulationRef = useRef<any>(null);\n const [isSourceModalVisible, setIsSourceModalVisible] = useState(false);\n const renderIdRef = useRef<number>(0);\n const mounted = useRef(true);\n const lastSpecRef = useRef<any>(null);\n const streamingContentRef = useRef<string | null>(null);\n const lastUsedPluginRef = useRef<D3RenderPlugin | null>(null);\n const lastValidSpecRef = useRef<any>(null);\n const [renderingStarted, setRenderingStarted] = useState<boolean>(false);\n const initialThemeRef = useRef<boolean>(isDarkMode);\n const hasSuccessfulRenderRef = useRef<boolean>(false);\n\n // New state for size reservation and rendering control\n const cleanupFunctionsRef = useRef<(() => void)[]>([]);\n const [reservedSize, setReservedSize] = useState<{ width: number; height: number } | null>(null);\n const sizingManagerRef = useRef<ContainerSizingManager | null>(null);\n\n // Store the spec in a ref to avoid unnecessary re-renders\n useEffect(() => { lastSpecRef.current = spec; }, [spec]);\n\n // Estimate and reserve size early\n useEffect(() => {\n if (spec && !reservedSize) {\n const plugin = findPlugin(spec);\n const estimated = estimateDiagramSize(spec, plugin);\n setReservedSize(estimated);\n console.debug('Reserved size for diagram:', estimated);\n }\n }, [spec, reservedSize]);\n\n // Comprehensive cleanup on unmount\n useEffect(() => {\n return () => {\n // Clean up sizing manager\n if (sizingManagerRef.current) {\n sizingManagerRef.current.cleanup();\n sizingManagerRef.current = null;\n }\n mounted.current = false;\n console.debug('D3Renderer cleanup triggered');\n\n // Execute all cleanup functions\n cleanupFunctionsRef.current.forEach(cleanup => {\n try {\n cleanup();\n } catch (e) {\n console.warn('Error during cleanup:', e);\n }\n });\n cleanupFunctionsRef.current = [];\n\n // Clean up Vega view\n try {\n if (vegaViewRef.current) {\n vegaViewRef.current.finalize();\n vegaViewRef.current = null;\n }\n } catch (e) {\n console.warn('Error finalizing Vega view:', e);\n }\n\n // Clean up D3 and simulations\n try {\n if (simulationRef.current) {\n simulationRef.current.stop();\n simulationRef.current = null;\n }\n if (d3ContainerRef.current) {\n d3.select(d3ContainerRef.current).selectAll('*').on('.', null);\n d3ContainerRef.current.innerHTML = '';\n }\n } catch (e) {\n console.warn('Error cleaning up D3:', e);\n }\n };\n }, []);\n\n // Initialize visualization with useCallback for better performance and dependency tracking\n const initializeVisualization = useCallback(async (forceRender = false) => {\n if (!mounted.current) return;\n // Once we start rendering, hide the spinner permanently\n if (!renderingStarted) {\n setRenderingStarted(true);\n }\n\n if ((!hasAttemptedRender || !isStreaming) && !hasSuccessfulRenderRef.current) {\n setIsLoading(true);\n }\n try {\n // Clear previous cleanup functions\n cleanupFunctionsRef.current.forEach(cleanup => cleanup());\n cleanupFunctionsRef.current = [];\n\n if (!spec) {\n throw new Error('No specification provided');\n }\n\n let parsed: any;\n let specLines: string[];\n\n // Determine if we should attempt to render or show waiting message\n let attemptRender = !isStreaming || isMarkdownBlockClosed || forceRender;\n let localShouldShowWaitingPlaceholder = isStreaming && !isMarkdownBlockClosed && !forceRender;\n\n try {\n if (typeof spec === 'string') {\n console.debug('Parsing string spec:', spec.substring(0, 100) + '...');\n // Clean up the spec string\n specLines = spec\n .replace(/\\r\\n/g, '\\n')\n .split('\\n')\n .map(line => line.trim())\n .filter(line => !line.trim().startsWith('//') && line.trim() !== '');\n\n // Check if we have a complete code block\n if (!specLines.length) {\n setIsLoading(true);\n return; // Exit early if code block is incomplete\n }\n\n const cleanSpec = specLines.join('\\n').replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n parsed = JSON.parse(cleanSpec);\n } else {\n console.debug('Using object spec directly');\n parsed = spec;\n }\n } catch (parseError) {\n // During streaming, this could be an incomplete JSON\n if (isStreaming && !isMarkdownBlockClosed) {\n streamingContentRef.current = typeof spec === 'string' ? spec : null;\n if (isLoading && !hasSuccessfulRenderRef.current) setIsLoading(false);\n setDisplayWaitingMessage(true);\n return;\n } else {\n setIsLoading(true); // Keep loading while we wait for complete spec\n console.debug('Waiting for complete spec:', parseError);\n return;\n }\n }\n\n // If we have a parsed spec, determine if it's complete enough to render\n if (parsed) {\n const specType = parsed.type || '';\n\n // For streaming content, check if the definition is complete enough\n if (isStreaming && !isMarkdownBlockClosed) {\n const plugin = findPlugin(parsed);\n\n // If we have a plugin with isDefinitionComplete method, use it on the original spec string\n if (plugin?.isDefinitionComplete && typeof spec === 'string') {\n const isComplete = plugin.isDefinitionComplete(spec);\n console.debug(`Checking if ${plugin.name} definition is complete:`, isComplete);\n\n if (!isComplete) {\n attemptRender = false;\n }\n } else if (specType === 'mermaid' || specType === 'graphviz') {\n // Use the generic isDiagramDefinitionComplete utility\n const isComplete = isDiagramDefinitionComplete(\n parsed.definition || '',\n specType\n );\n\n if (!isComplete) {\n attemptRender = false;\n }\n }\n }\n\n // If we're going to attempt rendering, store this as our last valid spec\n if (attemptRender) {\n lastValidSpecRef.current = parsed;\n }\n }\n\n // Update the waiting message state based on streaming and render attempt\n setDisplayWaitingMessage(localShouldShowWaitingPlaceholder);\n\n // If we're not attempting to render, exit early\n if (!attemptRender) {\n return;\n } else {\n // Mark that we've attempted a render\n setHasAttemptedRender(true);\n }\n\n // Log the parsed spec for debugging\n console.debug('D3Renderer: Successfully parsed spec:', {\n type: parsed.type,\n renderer: parsed.renderer\n });\n\n // Only proceed with rendering if we have a valid parsed spec\n if (!parsed) return;\n\n const plugin = findPlugin(parsed);\n if (type === 'd3' || parsed.renderer === 'd3' || typeof parsed.render === 'function' || plugin) {\n const container = d3ContainerRef.current;\n if (!container) return;\n\n // Check if this is a Graphviz or Mermaid plugin\n const plugin = findPlugin(parsed);\n lastUsedPluginRef.current = plugin || null;\n\n // Initialize sizing manager if we have a plugin with sizing config\n if (plugin?.sizingConfig && !sizingManagerRef.current) {\n sizingManagerRef.current = new ContainerSizingManager();\n sizingManagerRef.current.applySizingConfig(container, plugin.sizingConfig, isDarkMode);\n cleanupFunctionsRef.current.push(() => {\n sizingManagerRef.current?.cleanup();\n });\n }\n\n // Cleanup existing simulation\n if (simulationRef.current) {\n try {\n simulationRef.current.stop();\n simulationRef.current = null;\n } catch (error) {\n console.warn('Error cleaning up simulation:', error);\n }\n }\n\n // Set container dimensions\n container.style.width = `${width}px`;\n container.style.height = `${height}px`;\n container.style.position = 'relative';\n container.style.overflow = 'hidden';\n\n const isGraphvizOrMermaid = plugin?.name === 'graphviz-renderer' || plugin?.name === 'mermaid-renderer';\n\n // For Graphviz or Mermaid, override the container style to be more flexible\n if (isGraphvizOrMermaid) {\n container.style.width = '100%';\n container.style.height = 'auto';\n container.style.minHeight = 'unset';\n container.style.overflow = 'visible';\n }\n\n // Create temporary container for safe rendering\n const tempContainer = document.createElement('div');\n tempContainer.style.width = '100%';\n tempContainer.style.height = 'auto';\n\n let renderSuccessful = false;\n\n try {\n // Clear any existing content\n if (container.firstChild) {\n container.removeChild(container.firstChild);\n }\n\n const sanitizedParsed = sanitizeSpec(parsed);\n if (typeof parsed.render === 'function') {\n const result = sanitizedParsed.render.call(sanitizedParsed, tempContainer, d3);\n renderSuccessful = true;\n\n // If result is a function, use it as cleanup\n if (typeof result === 'function') {\n cleanupRef.current = result;\n cleanupFunctionsRef.current.push(result);\n }\n\n // Register simulation cleanup if it exists\n if (simulationRef.current) {\n cleanupFunctionsRef.current.push(() => {\n if (simulationRef.current) {\n simulationRef.current.stop();\n simulationRef.current = null;\n }\n });\n }\n } else if (sanitizedParsed.type === 'network') {\n const plugin = findPlugin(sanitizedParsed);\n if (plugin) {\n plugin.render(tempContainer, d3, {\n ...sanitizedParsed,\n width: width || 600,\n height: height || 400,\n isStreaming: isStreaming,\n isMarkdownBlockClosed: isMarkdownBlockClosed,\n forceRender: forceRender,\n }, isDarkMode);\n renderSuccessful = true;\n }\n } else {\n // Register cleanup for plugin renders\n const pluginCleanup = () => {\n if (tempContainer && tempContainer.parentNode) {\n tempContainer.innerHTML = '';\n }\n };\n cleanupFunctionsRef.current.push(pluginCleanup);\n\n const plugin = findPlugin(sanitizedParsed);\n if (!plugin) {\n throw new Error('No render function or compatible plugin found');\n }\n\n console.debug('Using plugin:', plugin.name);\n plugin.render(tempContainer, d3, {\n ...sanitizedParsed,\n isStreaming: isStreaming,\n isMarkdownBlockClosed: isMarkdownBlockClosed,\n forceRender: forceRender,\n }, isDarkMode);\n renderSuccessful = true;\n if (mounted.current) setRenderError(null);\n }\n\n\n\n } catch (renderError) {\n console.error('D3 render error:', renderError);\n if (mounted.current) {\n setRenderError(renderError instanceof Error ? renderError.message : 'Render failed');\n setErrorDetails([renderError instanceof Error ? renderError.message : 'Unknown error']);\n }\n }\n\n // Only replace main container content if render was successful\n if (renderSuccessful) {\n container.innerHTML = '';\n container.appendChild(tempContainer);\n }\n\n\n if (!renderSuccessful) {\n throw new Error('Render did not complete successfully');\n }\n\n // Add retry button for Mermaid diagrams if there was an error\n if (renderError && (plugin?.name === 'mermaid-renderer')) {\n const retryButton = document.createElement('button');\n retryButton.innerHTML = '🔄 Retry Rendering';\n retryButton.className = 'diagram-action-button mermaid-retry-button';\n retryButton.style.cssText = `\n background-color: #4361ee;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n margin: 10px auto;\n cursor: pointer;\n display: block;\n `;\n retryButton.onclick = () => initializeVisualization();\n container.appendChild(retryButton);\n }\n\n if (mounted.current) setIsLoading(false);\n setRenderError(null);\n onLoad?.();\n hasSuccessfulRenderRef.current = true;\n return;\n }\n } catch (error: any) {\n if (isStreaming && !isMarkdownBlockClosed) {\n console.debug('Suppressing streaming error:', error.message);\n // Keep the waiting message visible\n if (!hasSuccessfulRenderRef.current) {\n setDisplayWaitingMessage(true);\n }\n // Don't update error state during streaming\n } else {\n console.error('Visualization error:', error);\n if (mounted.current) {\n setRenderError(error.message);\n setIsLoading(false);\n }\n }\n }\n }, [spec, type, width, height, isDarkMode, isStreaming, isMarkdownBlockClosed, config, onLoad, onError, isLoading, hasAttemptedRender, mounted, renderingStarted, renderError]);\n\n // Main rendering useEffect with stable dependencies\n useEffect(() => {\n if (!mounted.current) return;\n\n // Re-render when:\n // 1. We haven't had a successful render yet\n // 2. Markdown block just closed (streaming completed)\n // 3. We're forcing a render\n const shouldRender = !hasSuccessfulRenderRef.current ||\n (!isStreaming && isMarkdownBlockClosed) ||\n forceRender;\n\n if (shouldRender) {\n const currentRender = ++renderIdRef.current;\n console.debug(`Starting render #${currentRender}`);\n initializeVisualization(forceRender);\n }\n }, [spec, isStreaming, isMarkdownBlockClosed, forceRender, initializeVisualization]);\n // Separate effect for theme changes to avoid circular dependencies\n useEffect(() => {\n // Only re-render for theme changes if we've already had a successful render\n // and this isn't the initial theme setting \n if (lastSpecRef.current && hasSuccessfulRenderRef.current && renderingStarted &&\n isDarkMode !== initialThemeRef.current) {\n console.log('Theme changed, re-rendering visualization');\n setTimeout(() => {\n initializeVisualization();\n }, 100);\n }\n }, [isDarkMode, initializeVisualization]);\n\n const isD3Render = useMemo(() => {\n const plugin = typeof spec === 'object' && spec !== null ? findPlugin(spec) : undefined;\n return type === 'd3' || (typeof spec === 'object' && (spec?.renderer === 'd3' || !!plugin));\n }, [type, spec]);\n\n // Get current plugin for styling decisions\n const currentPlugin = useMemo(() => {\n return typeof spec === 'object' && spec !== null ? findPlugin(spec) : undefined;\n }, [spec]);\n\n // Get container styles from plugin config or use defaults\n const containerStyles = useMemo(() => {\n const plugin = currentPlugin;\n if (plugin?.sizingConfig?.containerStyles) {\n const baseStyles = plugin.sizingConfig.containerStyles;\n\n // Apply sizing strategy overrides\n if (plugin.sizingConfig.sizingStrategy === 'auto-expand') {\n return {\n ...baseStyles,\n height: 'auto',\n minHeight: 'auto',\n overflow: plugin.sizingConfig.needsOverflowVisible ? 'visible' : (baseStyles.overflow || 'auto')\n };\n }\n\n return baseStyles;\n }\n return {\n height: height || '400px',\n overflow: 'auto'\n };\n }, [currentPlugin, height]);\n\n const outerContainerStyle: CSSProperties = {\n position: 'relative',\n width: '100%',\n maxWidth: '100%',\n height: 'auto',\n display: 'block',\n margin: '1em 0',\n padding: 0,\n boxSizing: 'border-box',\n minWidth: '100%',\n // Reserve space based on estimated size to prevent layout shifts\n ...(reservedSize && !hasSuccessfulRenderRef.current ? {\n minHeight: `${reservedSize.height}px`,\n minWidth: `${Math.min(reservedSize.width, 800)}px` // Cap width to prevent horizontal overflow\n } : {})\n };\n\n // Function to open visualization in a popout window\n const openInPopout = (svg: SVGElement, title: string = 'Visualization') => {\n if (!svg) return;\n\n // Get the SVG dimensions - need to cast to SVGGraphicsElement to access getBBox\n const svgGraphics = svg as unknown as SVGGraphicsElement;\n let width = 600;\n let height = 400;\n\n try {\n // Try to get the bounding box\n const bbox = svgGraphics.getBBox();\n width = Math.max(bbox.width + 50, 400); // Add padding, minimum 400px\n height = Math.max(bbox.height + 100, 300); // Add padding, minimum 300px\n } catch (e) {\n console.warn('Could not get SVG dimensions, using defaults', e);\n // Use default dimensions if getBBox fails\n }\n\n // Get SVG data\n const svgData = new XMLSerializer().serializeToString(svg);\n\n // Create an HTML document that will display the SVG responsively\n const htmlContent = `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>${title}</title>\n <style>\n body {\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n height: 100vh;\n background-color: #f8f9fa;\n font-family: system-ui, -apple-system, sans-serif;\n }\n .toolbar {\n background-color: #f1f3f5;\n border-bottom: 1px solid #dee2e6;\n padding: 8px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .toolbar button {\n background-color: #4361ee;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n margin-right: 8px;\n font-size: 14px;\n }\n .toolbar button:hover {\n background-color: #3a0ca3;\n }\n .container {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: auto;\n padding: 20px;\n }\n svg {\n max-width: 100%;\n max-height: 100%;\n height: auto;\n width: auto;\n }\n @media (prefers-color-scheme: dark) {\n body {\n background-color: #212529;\n color: #f8f9fa;\n }\n .toolbar {\n background-color: #343a40;\n border-bottom: 1px solid #495057;\n }\n }\n </style>\n </head>\n <body>\n <div class=\"toolbar\">\n <div>\n <button onclick=\"zoomIn()\">Zoom In</button>\n <button onclick=\"zoomOut()\">Zoom Out</button>\n <button onclick=\"resetZoom()\">Reset</button>\n </div>\n <div>\n <button onclick=\"downloadSvg()\">Download SVG</button>\n </div>\n </div>\n <div class=\"container\" id=\"svg-container\">\n ${svgData}\n </div>\n <script>\n const svg = document.querySelector('svg');\n let currentScale = 1;\n \n // Make sure SVG is responsive\n svg.setAttribute('width', '100%');\n svg.setAttribute('height', '100%');\n svg.style.maxWidth = '100%';\n svg.style.maxHeight = '100%';\n svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n \n function zoomIn() {\n currentScale *= 1.2;\n svg.style.transform = \\`scale(\\${currentScale})\\`;\n }\n \n function zoomOut() {\n currentScale /= 1.2;\n svg.style.transform = \\`scale(\\${currentScale})\\`;\n }\n \n function resetZoom() {\n currentScale = 1;\n svg.style.transform = 'scale(1)';\n }\n \n function downloadSvg() {\n const svgData = new XMLSerializer().serializeToString(svg);\n const svgBlob = new Blob([svgData], {type: 'image/svg+xml'});\n const url = URL.createObjectURL(svgBlob);\n \n const link = document.createElement('a');\n link.href = url;\n link.download = '${title.toLowerCase().replace(/[^a-z0-9]/g, '-')}-${Date.now()}.svg';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n \n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }\n </script>\n </body>\n </html>\n `;\n\n // Create a blob with the HTML content\n const blob = new Blob([htmlContent], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n\n // Open in a new window with specific dimensions\n const popupWindow = window.open(\n url,\n 'D3Visualization',\n `width=${width},height=${height},resizable=yes,scrollbars=yes,status=no,toolbar=no,menubar=no,location=no`\n );\n\n // Focus the new window\n if (popupWindow) {\n popupWindow.focus();\n }\n\n // Clean up the URL object after a delay\n setTimeout(() => URL.revokeObjectURL(url), 10000);\n };\n\n // Function to save SVG\n const saveSvg = (svg: SVGElement, filename: string = `visualization-${Date.now()}.svg`) => {\n if (!svg) return;\n\n // Create a new SVG with proper XML declaration and doctype\n const svgData = new XMLSerializer().serializeToString(svg);\n\n // Create a properly formatted SVG document with XML declaration\n const svgDoc = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n${svgData}`;\n\n // Create a blob with the SVG content\n const blob = new Blob([svgDoc], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n\n // Create a download link\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\n // Clean up the URL object after a delay\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n };\n\n return (\n <div\n id={containerId || 'd3-container'}\n style={outerContainerStyle}\n className={`d3-container ${isStreaming ? 'streaming' : ''}`}\n data-render-id={renderIdRef.current}\n data-visualization-type={typeof spec === 'object' && spec?.type ? spec.type : 'unknown'}\n >\n {isStreaming && !isMarkdownBlockClosed && !hasSuccessfulRenderRef.current ? (\n <div style={{ textAlign: 'center', padding: '20px', backgroundColor: isDarkMode ? '#1f1f1f' : '#f6f8fa', border: '1px dashed #ccc', borderRadius: '4px' }}>\n <p>Waiting for complete {typeof spec === 'object' && spec?.type ? spec.type : 'diagram'} definition...</p>\n </div>\n ) : (\n <>\n {displayWaitingMessage && (\n <div style={{ textAlign: 'center', padding: '20px', backgroundColor: isDarkMode ? '#1f1f1f' : '#f6f8fa', border: '1px dashed #ccc', borderRadius: '4px' }}>\n <p>Waiting for complete diagram definition...</p>\n </div>\n )}\n </>\n )}\n\n {isD3Render ? (\n <div\n ref={d3ContainerRef}\n className={`d3-container ${currentPlugin?.name ? `${currentPlugin.name}-container` : ''}`}\n style={{\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n // Apply containerStyles last so they can override defaults\n ...containerStyles\n }}\n />\n ) : (\n <div\n ref={vegaContainerRef}\n id=\"vega-container\"\n className=\"vega-lite-container\"\n style={{\n width: '100%',\n minWidth: '100%',\n maxWidth: '100%',\n display: !isD3Render ? 'block' : 'none',\n position: 'relative',\n height: height || '100%'\n }}\n >\n {(isLoading || !spec) && !renderingStarted && (\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'rgba(0, 0, 0, 0.1)'\n }}>\n <Spin size=\"large\" />\n <div style={{ marginTop: '10px', color: isDarkMode ? '#ffffff' : '#000000' }}>\n Preparing visualization...\n </div>\n </div>\n )}\n {renderError && !isStreaming && isMarkdownBlockClosed && (\n <pre style={{\n padding: '16px',\n margin: '8px',\n backgroundColor: isDarkMode ? '#2a1215' : '#fff1f0',\n border: `1px solid ${isDarkMode ? '#5c2223' : '#ffa39e'}`,\n borderRadius: '4px',\n color: isDarkMode ? '#ff4d4f' : '#cf1322',\n whiteSpace: 'pre-wrap',\n wordWrap: 'break-word',\n maxHeight: '200px',\n overflowY: 'auto',\n fontSize: '14px',\n lineHeight: '1.5',\n fontFamily: 'monospace'\n }}>\n <strong>Error:</strong>\n {errorDetails.map((line, i) => <div key={i}>{line}</div>)}\n </pre>\n )}\n </div>\n )}\n <Modal\n title=\"Visualization Source\"\n open={isSourceModalVisible}\n onCancel={() => setIsSourceModalVisible(false)}\n footer={null}\n width={800}\n >\n <pre style={{\n backgroundColor: isDarkMode ? '#1f1f1f' : '#f6f8fa',\n padding: '16px',\n borderRadius: '4px',\n overflow: 'auto',\n maxHeight: '60vh',\n color: isDarkMode ? '#e6e6e6' : '#24292e'\n }}>\n <code>{typeof spec === 'string' ? spec : JSON.stringify(spec, null, 2)}</code>\n </pre>\n </Modal>\n <Modal\n title=\"Visualization Source\"\n open={isSourceModalVisible}\n onCancel={() => setIsSourceModalVisible(false)}\n footer={null}\n width={800}\n >\n <pre style={{\n backgroundColor: isDarkMode ? '#1f1f1f' : '#f6f8fa',\n padding: '16px',\n borderRadius: '4px',\n overflow: 'auto',\n maxHeight: '60vh',\n color: isDarkMode ? '#e6e6e6' : '#24292e'\n }}>\n <code>{typeof spec === 'string' ? spec : JSON.stringify(spec, null, 2)}</code>\n </pre>\n </Modal>\n </div>\n );\n};\n","/**\n * Mermaid Enhancer\n * \n * A generic enhancement layer for Mermaid diagrams that:\n * 1. Preprocesses diagram definitions to fix common syntax issues\n * 2. Provides error recovery mechanisms for rendering failures\n * 3. Allows for extensible preprocessing rules\n */\n\n// Types for preprocessors and error handlers\ninterface Preprocessor {\n process: (definition: string, diagramType: string) => string;\n priority: number;\n diagramTypes: string[];\n name: string;\n}\n\ninterface ErrorHandler {\n handle: (error: Error, context: ErrorContext) => boolean;\n priority: number;\n errorTypes: string[];\n name: string;\n}\n\ninterface ErrorContext {\n container?: HTMLElement;\n definition: string;\n diagramType: string;\n error: Error;\n}\n\ninterface PreprocessorOptions {\n name?: string;\n priority?: number;\n diagramTypes?: string[];\n}\n\ninterface ErrorHandlerOptions {\n name?: string;\n priority?: number;\n errorTypes?: string[];\n}\n\n// Registry of preprocessors that can be extended\nconst preprocessors: Preprocessor[] = [];\n\n// Registry of error handlers that can be extended\nconst errorHandlers: ErrorHandler[] = [];\n\n// Cache for supported diagram types\nlet supportedDiagramTypes: Set<string> | null = null;\nlet mermaidInstance: any = null;\n\n/**\n * Dynamically detect supported diagram types from the current Mermaid instance\n * @param mermaid - The mermaid library instance\n * @returns Set of supported diagram type names\n */\nexport function detectSupportedDiagramTypes(mermaid: any): Set<string> {\n if (supportedDiagramTypes && mermaidInstance === mermaid) {\n return supportedDiagramTypes;\n }\n\n const supportedTypes = new Set<string>();\n \n // Don't run detection if mermaid is not properly initialized\n if (!mermaid || !mermaid.parse) {\n console.warn('Mermaid not properly initialized for type detection');\n return supportedTypes;\n }\n \n // Test diagram types with minimal valid syntax\n const testCases = [\n // Stable diagram types\n { type: 'flowchart', def: 'flowchart TD\\n A --> B' },\n { type: 'graph', def: 'graph TD\\n A --> B' },\n { type: 'sequenceDiagram', def: 'sequenceDiagram\\n A->>B: message' },\n { type: 'classDiagram', def: 'classDiagram\\n class A' },\n { type: 'stateDiagram', def: 'stateDiagram-v2\\n [*] --> A' },\n { type: 'erDiagram', def: 'erDiagram\\n A { int id }' },\n { type: 'journey', def: 'journey\\n title Test\\n section A\\n Task: 5: User' },\n { type: 'gantt', def: 'gantt\\n title Test\\n dateFormat YYYY-MM-DD\\n Task: 2024-01-01, 1d' },\n { type: 'pie', def: 'pie title Test\\n \"A\": 50\\n \"B\": 50' },\n { type: 'gitgraph', def: 'gitgraph\\n commit id: \"Initial\"' },\n { type: 'requirementDiagram', def: 'requirementDiagram\\n requirement test {\\n id: 1\\n text: test\\n risk: low\\n verifymethod: test\\n }' },\n { type: 'timeline', def: 'timeline\\n title Test\\n 2024: Event' },\n { type: 'mindmap', def: 'mindmap\\n root\\n A\\n B' },\n { type: 'quadrantChart', def: 'quadrantChart\\n title Test\\n x-axis Low --> High\\n y-axis Low --> High\\n \"A\": [0.5, 0.5]' },\n \n // Beta diagram types - test both with and without -beta suffix\n { type: 'xychart', def: 'xychart-beta\\n title Test\\n x-axis [A, B]\\n y-axis Test 0 --> 10\\n line Test [1, 2]' },\n { type: 'xychart-beta', def: 'xychart-beta\\n title Test\\n x-axis [A, B]\\n y-axis Test 0 --> 10\\n line Test [1, 2]' },\n { type: 'sankey', def: 'sankey-beta\\n A,B,10' },\n { type: 'sankey-beta', def: 'sankey-beta\\n A,B,10' },\n { type: 'block', def: 'block-beta\\n A[Test]' },\n { type: 'block-beta', def: 'block-beta\\n A[Test]' },\n { type: 'packet', def: 'packet-beta\\n title Test\\n 0-7: Test' },\n { type: 'packet-beta', def: 'packet-beta\\n title Test\\n 0-7: Test' },\n { type: 'architecture', def: 'architecture-beta\\n service test[Test]' },\n { type: 'architecture-beta', def: 'architecture-beta\\n service test[Test]' }\n ];\n\n for (const testCase of testCases) {\n try {\n mermaid.parse(testCase.def);\n supportedTypes.add(testCase.type);\n } catch (error) {\n // Type not supported - this is expected for beta types\n }\n }\n\n supportedDiagramTypes = supportedTypes;\n mermaidInstance = mermaid;\n \n console.log('Detected supported diagram types:', Array.from(supportedTypes));\n return supportedTypes;\n}\n\n/**\n * Normalize diagram type name by checking for beta promotion\n * @param diagramType - The diagram type to normalize\n * @param mermaid - The mermaid library instance\n * @returns The correct diagram type name to use\n */\nexport function normalizeDiagramType(diagramType: string, mermaid: any): string {\n const supportedTypes = detectSupportedDiagramTypes(mermaid);\n \n // If the exact type is supported, use it\n if (supportedTypes.has(diagramType)) {\n return diagramType;\n }\n \n // Check for beta promotion (beta type promoted to stable)\n if (diagramType.endsWith('-beta')) {\n const stableType = diagramType.replace('-beta', '');\n if (supportedTypes.has(stableType)) {\n return stableType;\n }\n }\n \n // Check for beta demotion (stable type needs beta suffix)\n if (!diagramType.endsWith('-beta')) {\n const betaType = diagramType + '-beta';\n if (supportedTypes.has(betaType)) {\n return betaType;\n }\n }\n \n // Return original if no alternative found\n return diagramType;\n}\n\n/**\n * Preprocess diagram definition with automatic type normalization\n * @param definition - The diagram definition\n * @param diagramType - The diagram type (will be normalized)\n * @param mermaid - The mermaid library instance\n * @returns Object with normalized type and processed definition\n */\nexport function preprocessWithTypeNormalization(\n definition: string, \n diagramType: string, \n mermaid: any\n): { normalizedType: string; processedDefinition: string } {\n const normalizedType = normalizeDiagramType(diagramType, mermaid);\n \n // Update the definition if the type changed\n let processedDefinition = definition;\n if (normalizedType !== diagramType) {\n // Replace the first line if it contains the diagram type\n const lines = definition.split('\\n');\n if (lines[0].trim().startsWith(diagramType)) {\n lines[0] = lines[0].replace(diagramType, normalizedType);\n processedDefinition = lines.join('\\n');\n }\n }\n \n // Apply standard preprocessing\n processedDefinition = preprocessDefinition(processedDefinition, normalizedType);\n \n return {\n normalizedType,\n processedDefinition\n };\n}\n\n/**\n * Register a preprocessor function\n * @param fn - Function that takes diagram text and returns processed text\n * @param options - Options including priority and diagram types to target\n */\nexport function registerPreprocessor(\n fn: (definition: string, diagramType: string) => string,\n options: PreprocessorOptions = {}\n): () => void {\n const processor: Preprocessor = {\n process: fn,\n priority: options.priority || 10,\n diagramTypes: options.diagramTypes || ['*'], // '*' means all diagram types\n name: options.name || `preprocessor-${preprocessors.length}`\n };\n\n preprocessors.push(processor);\n // Sort by priority (higher numbers run first)\n preprocessors.sort((a, b) => b.priority - a.priority);\n\n return () => {\n // Return function to unregister this preprocessor\n const index = preprocessors.findIndex(p => p === processor);\n if (index !== -1) {\n preprocessors.splice(index, 1);\n }\n };\n}\n\n/**\n * Register an error handler function\n * @param fn - Function that takes error and context and returns boolean (true if handled)\n * @param options - Options including priority and error types to target\n */\nexport function registerErrorHandler(\n fn: (error: Error, context: ErrorContext) => boolean,\n options: ErrorHandlerOptions = {}\n): () => void {\n const handler: ErrorHandler = {\n handle: fn,\n priority: options.priority || 10,\n errorTypes: options.errorTypes || ['*'], // '*' means all error types\n name: options.name || `error-handler-${errorHandlers.length}`\n };\n\n errorHandlers.push(handler);\n // Sort by priority (higher numbers run first)\n errorHandlers.sort((a, b) => b.priority - a.priority);\n\n return () => {\n // Return function to unregister this handler\n const index = errorHandlers.findIndex(h => h === handler);\n if (index !== -1) {\n errorHandlers.splice(index, 1);\n }\n };\n}\n\n/**\n * Process a diagram definition through all applicable preprocessors\n * @param definition - The original diagram definition\n * @param diagramType - The type of diagram (e.g., 'sequence', 'state')\n * @returns - The processed definition\n */\nexport function preprocessDefinition(definition: string, diagramType?: string, mermaid?: any): string {\n let processedDef = definition;\n\n // Extract diagram type if not provided\n if (!diagramType) {\n const firstLine = definition.trim().split('\\n')[0];\n diagramType = firstLine.trim().replace(/^(\\w+).*$/, '$1');\n }\n\n // Normalize diagram type if mermaid instance is available\n let normalizedType = diagramType;\n if (mermaid) {\n normalizedType = normalizeDiagramType(diagramType, mermaid);\n \n // Update the definition if the type changed\n if (normalizedType !== diagramType) {\n const lines = processedDef.split('\\n');\n if (lines[0].trim().startsWith(diagramType)) {\n lines[0] = lines[0].replace(diagramType, normalizedType);\n processedDef = lines.join('\\n');\n }\n }\n }\n\n // Apply each preprocessor in order\n for (const processor of preprocessors) {\n if (processor.diagramTypes.includes('*') || processor.diagramTypes.includes(normalizedType)) {\n try {\n const result = processor.process(processedDef, normalizedType);\n if (result) {\n processedDef = result;\n }\n } catch (error) {\n console.warn(`Preprocessor ${processor.name} failed:`, error);\n }\n }\n }\n\n return processedDef;\n}\n\n/**\n * Handle rendering errors by passing through registered error handlers\n * @param error - The error that occurred\n * @param context - Context including diagram definition, type, and container\n * @returns - True if the error was handled, false otherwise\n */\nexport function handleRenderError(error: Error, context: ErrorContext): boolean {\n const errorType = error.name || 'Error';\n let handled = false;\n\n // Try each handler in order until one handles the error\n for (const handler of errorHandlers) {\n if (handler.errorTypes.includes('*') || handler.errorTypes.includes(errorType)) {\n try {\n if (handler.handle(error, context)) {\n handled = true;\n break;\n }\n } catch (handlerError) {\n console.warn(`Error handler ${handler.name} failed:`, handlerError);\n }\n }\n }\n return handled;\n}\n\n/*\n * Initialize the Mermaid enhancer with default preprocessors and error handlers\n */\nexport function initMermaidEnhancer(): void {\n // Register default preprocessors\n\n // Add a preprocessor to fix quotes and parentheses in node labels - HIGHEST PRIORITY\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n console.log('🔍 NODE-QUOTE-FIX: Processing node labels with quotes and parentheses');\n\n // Fix node labels that contain quotes and parentheses that cause parsing errors\n // Pattern: B{My \"Brain\" (Gemini LLM)} -> B{My Brain - Gemini LLM}\n let result = definition.replace(/(\\w+)(\\{|\\[)([^}\\]]*?)(\\}|\\])/g, (match, nodeId, openBracket, content, closeBracket) => {\n let processedContent = content;\n \n // Remove quotes and replace with safe alternatives\n processedContent = processedContent.replace(/\"/g, '');\n \n // Replace parentheses with dashes for better readability\n processedContent = processedContent.replace(/\\(/g, '- ').replace(/\\)/g, '');\n \n // Clean up extra spaces\n processedContent = processedContent.replace(/\\s+/g, ' ').trim();\n \n console.log(`🔍 NODE-QUOTE-FIX: Fixed node ${nodeId}: \"${content}\" -> \"${processedContent}\"`);\n return `${nodeId}${openBracket}${processedContent}${closeBracket}`;\n });\n\n // Also remove semicolons at the end of lines that cause parsing issues\n result = result.replace(/;(\\s*$)/gm, '$1');\n\n console.log('🔍 NODE-QUOTE-FIX: Processing complete');\n return result;\n }, {\n name: 'node-quote-parentheses-fix',\n priority: 600, // Very high priority to run before other fixes\n diagramTypes: ['flowchart', 'graph']\n });\n\n // CRITICAL: Fix sankey diagram format - HIGHEST PRIORITY \n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (!definition.trim().startsWith('sankey')) {\n return definition;\n }\n\n const lines = definition.split('\\n').map(line => line.trim()).filter(line => line);\n if (lines.length === 0) return definition;\n const result: string[] = [];\n result.push(lines[0]); // Keep the sankey-beta header\n\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i];\n\n // Skip empty lines and comments\n if (!line || line.startsWith('%%')) continue;\n\n // Process data lines - must have exactly 3 comma-separated values\n if (line.includes(',')) {\n const parts = line.split(',').map(p => p.trim());\n if (parts.length >= 3) {\n result.push(`${parts[0]},${parts[1]},${parts[2]}`);\n }\n }\n }\n\n console.log('🔍 CRITICAL-SANKEY-FORMAT-FIX: Processing complete');\n return result.join('\\n');\n }, {\n name: 'sankey-format-fix',\n priority: 700, // Very high priority\n diagramTypes: ['sankey']\n });\n\n // CRITICAL: Single comprehensive requirement diagram preprocessor\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'requirementdiagram' && !definition.trim().startsWith('requirementDiagram')) {\n return definition;\n }\n\n console.log('🔍 REQUIREMENT-MASTER-FIX: Processing requirement diagram');\n\n let result = definition;\n \n // Step 1: Ensure we have the proper header\n if (!result.trim().startsWith('requirementDiagram')) {\n result = 'requirementDiagram\\n' + result;\n }\n \n // Step 2: Parse and rebuild the entire structure properly\n const lines = result.split('\\n');\n const output: string[] = [];\n let inRequirementBlock = false;\n \n for (const line of lines) {\n const trimmed = line.trim();\n \n // Skip empty lines in blocks\n if (!trimmed && inRequirementBlock) continue;\n \n // Add the header\n if (trimmed.startsWith('requirementDiagram')) {\n output.push(trimmed);\n continue;\n }\n \n // Handle requirement block start\n if (trimmed.match(/^(requirement|functionalreq|performancereq|interfacereq|physicalreq|designconstraint)\\s+\\w+\\s*\\{/)) {\n if (inRequirementBlock) {\n output.push(' }'); // Close previous block\n }\n inRequirementBlock = true;\n output.push(' ' + trimmed);\n continue;\n }\n \n // Handle requirement block end\n if (trimmed === '}' && inRequirementBlock) {\n output.push(' }');\n inRequirementBlock = false;\n continue;\n }\n \n // Handle properties inside blocks\n if (inRequirementBlock && trimmed.match(/^(id|text|risk|verifymethod):/)) {\n const match = trimmed.match(/^(\\w+):\\s*(.+)$/);\n if (match) {\n const [, prop, value] = match;\n // Clean the value and apply proper quoting rules\n const cleanValue = value.replace(/^[\"']|[\"']$/g, '');\n const shouldQuote = ['id', 'text'].includes(prop);\n output.push(` ${prop}: ${shouldQuote ? `\"${cleanValue}\"` : cleanValue}`);\n }\n continue;\n }\n \n // Handle element definitions and relationships\n if (!inRequirementBlock && (trimmed.startsWith('element ') || trimmed.includes(' - ') || trimmed.includes(' -> '))) {\n output.push(' ' + trimmed);\n continue;\n }\n \n // Handle other lines\n if (trimmed && !inRequirementBlock) {\n output.push(' ' + trimmed);\n }\n }\n \n // Close any remaining block\n if (inRequirementBlock) {\n output.push(' }');\n }\n \n console.log('🔍 REQUIREMENT-MASTER-FIX: Processing complete');\n return output.join('\\n');\n }, {\n name: 'requirement-master-fix',\n priority: 650, // Single high priority\n diagramTypes: ['requirementdiagram']\n });\n\n // Fix requirementDiagram ID and property syntax\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (!definition.trim().startsWith('requirementDiagram')) {\n return definition;\n }\n\n console.log('🔍 REQUIREMENT-ID-FIX: Fixing ID format and properties');\n\n let result = definition;\n \n // Fix ID format - remove hyphens and make alphanumeric\n result = result.replace(/(\\s+id:\\s*)([A-Z]+-\\d+)/g, (match, prefix, id) => {\n const cleanId = id.replace(/-/g, '');\n return `${prefix}${cleanId}`;\n });\n \n // Fix verifymethod property name\n result = result.replace(/verifymethod:/g, 'verifyMethod:');\n \n console.log('🔍 REQUIREMENT-ID-FIX: Processing complete');\n return result;\n }, {\n name: 'requirement-id-fix',\n priority: 500,\n diagramTypes: ['requirementDiagram']\n });\n\n // Fix sequence diagram break statements (invalid syntax)\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (!definition.trim().startsWith('sequenceDiagram')) {\n return definition;\n }\n\n console.log('🔍 SEQUENCE-BREAK-FIX: Removing invalid break statements');\n\n let result = definition;\n \n // Remove break statements completely as they're not valid in Mermaid sequence diagrams\n result = result.replace(/^(\\s*)break\\s+.*$/gm, '');\n \n // Clean up any resulting empty lines\n result = result.replace(/\\n\\s*\\n\\s*\\n/g, '\\n\\n');\n \n console.log('🔍 SEQUENCE-BREAK-FIX: Processing complete');\n return result;\n }, {\n name: 'sequence-break-fix',\n priority: 500,\n diagramTypes: ['sequenceDiagram']\n });\n\n // Fix packet diagram syntax - add missing quotes\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (!definition.trim().startsWith('packet') && !definition.trim().startsWith('packet-beta')) {\n return definition;\n }\n\n console.log('🔍 PACKET-SYNTAX-FIX: Adding quotes to packet fields');\n\n let result = definition;\n \n // Add quotes around field descriptions if missing\n result = result.replace(/^(\\d+(-\\d+)?): ([^\"\\n].*)$/gm, '$1: \"$3\"');\n \n // Add quotes around title if missing\n result = result.replace(/^title ([^\"\\n].*)$/gm, 'title \"$1\"');\n \n console.log('🔍 PACKET-SYNTAX-FIX: Processing complete');\n return result;\n }, {\n name: 'packet-syntax-fix',\n priority: 500,\n diagramTypes: ['packet', 'packet-beta']\n });\n\n // Fix gitgraph syntax issues\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (!definition.trim().startsWith('gitgraph')) {\n return definition;\n }\n\n console.log('🔍 GITGRAPH-FIX: Processing gitgraph syntax');\n\n let result = definition;\n \n // Ensure proper gitgraph syntax\n if (!result.includes('gitgraph:')) {\n result = result.replace('gitgraph', 'gitgraph:');\n }\n \n console.log('🔍 GITGRAPH-FIX: Processing complete');\n return result;\n }, {\n name: 'gitgraph-fix',\n priority: 500,\n diagramTypes: ['gitgraph']\n });\n\n // CRITICAL: Fix block diagram double quotes - HIGHEST PRIORITY \n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (!definition.trim().startsWith('block-beta') && !definition.trim().startsWith('block')) {\n return definition;\n }\n\n console.log('🔍 BLOCK-QUOTE-FIX: Fixing double quotes and complex labels');\n\n let result = definition;\n\n // Fix double quote patterns that cause lexical errors\n result = result.replace(/(\\w+)\\[\"\"([^\"]*)\"\"\\]/g, '$1[\"$2\"]');\n \n // Fix complex parentheses patterns like M[\"(\"PostgreSQL<br/>Primary DB\")\"]\n result = result.replace(/\\[\"?\\(\"([^\"]*?)(?:<br\\/?>([^\"]*?))?\"?\\)?\"?\\]/g, '[\"$1$2\"]');\n \n console.log('🔍 BLOCK-QUOTE-FIX: Processing complete');\n return result;\n }, {\n name: 'block-quote-fix',\n priority: 600,\n diagramTypes: ['block-beta', 'block']\n });\n\n // CRITICAL: Fix sequence diagram structural issues\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (!definition.trim().startsWith('sequenceDiagram')) {\n return definition;\n }\n\n console.log('🔍 SEQUENCE-FIX: Processing sequence diagram');\n\n let result = definition;\n \n // Fix bullet characters\n result = result.replace(/•/g, '-');\n \n // Remove invalid option statements from alt blocks\n // Remove quotes from risk and verifymethod values\n result = result.replace(/(critical[\\s\\S]*?)option\\s+[^\\n]*\\n([\\s\\S]*?)end/g, (match, criticalPart, rest) => {\n // Keep option statements only in critical blocks\n return match;\n });\n \n // Remove option statements from alt blocks\n result = result.replace(/(alt[\\s\\S]*?)option\\s+[^\\n]*\\n/g, '$1');\n\n console.log('🔍 SEQUENCE-FIX: Processing complete');\n return result;\n }, {\n name: 'sequence-fix',\n priority: 550,\n diagramTypes: ['sequencediagram']\n });\n\n // Fix state diagram divider syntax\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'statediagram' && diagramType !== 'statediagram-v2' &&\n !definition.trim().startsWith('stateDiagram')) {\n return definition;\n }\n\n console.log('🔍 CRITICAL-STATE-FIX: Fixing divider syntax errors');\n\n let result = definition;\n // Remove problematic -- dividers that cause \"No such shape: divider\" errors\n result = result.replace(/^\\s*--\\s*$/gm, '');\n\n console.log('🔍 CRITICAL-STATE-FIX: Processing complete');\n return result;\n }, {\n name: 'critical-state-divider-fix',\n priority: 555, // High priority\n diagramTypes: ['statediagram', 'statediagram-v2']\n });\n\n // Add a preprocessor to fix quoted style references - HIGHEST PRIORITY \n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n console.log('🔍 QUOTED-STYLE-FIX: Removing invalid quoted style statements');\n\n // Simply remove all style statements that reference quoted names\n // These are invalid in Mermaid and cause parse errors\n let result = definition;\n\n // Remove style statements with quoted subgraph references\n // Pattern: style \"Subgraph Name\" fill:#color\n const removedStyles: string[] = [];\n result = result.replace(/style\\s+\"([^\"]+)\"\\s+fill:[^;\\n]*/g, (match, quotedName) => {\n removedStyles.push(quotedName);\n console.log(`🔍 QUOTED-STYLE-FIX: Removing invalid style statement: ${match}`);\n return ''; // Remove the entire invalid style statement\n });\n\n if (removedStyles.length > 0) {\n console.log(`🔍 QUOTED-STYLE-FIX: Removed ${removedStyles.length} invalid style statements`);\n }\n console.log('🔍 QUOTED-STYLE-FIX: Processing complete');\n return result;\n }, {\n name: 'quoted-style-fix',\n priority: 500, // Highest priority to run before all other fixes\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix naming conflicts between subgraphs and nodes\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n console.log('🔍 NAMING-CONFLICT-FIX: Checking for subgraph/node naming conflicts');\n\n // Extract subgraph names\n const subgraphNames = new Set<string>();\n // Handle both old format: subgraph \"Name\" and new format: subgraph Identifier [\"Name\"]\n const quotedSubgraphMatches = definition.matchAll(/subgraph\\s+\"([^\"]+)\"/g);\n const identifierSubgraphMatches = definition.matchAll(/subgraph\\s+(\\w+)\\s*(?:\\[\"[^\"]+\"\\])?/g);\n\n for (const match of quotedSubgraphMatches) {\n subgraphNames.add(match[1]);\n }\n for (const match of identifierSubgraphMatches) {\n subgraphNames.add(match[1]); // Add the identifier (e.g., \"Integration\")\n }\n\n // Extract node IDs\n const nodeIds = new Set<string>();\n const nodeMatches = definition.matchAll(/(\\w+)\\[/g);\n for (const match of nodeMatches) {\n nodeIds.add(match[1]);\n }\n\n console.log('🔍 NAMING-CONFLICT-FIX: Found subgraphs:', Array.from(subgraphNames));\n console.log('🔍 NAMING-CONFLICT-FIX: Found node IDs:', Array.from(nodeIds));\n\n // Check for conflicts and fix them\n let result = definition;\n for (const subgraphName of subgraphNames) {\n // Check if there's a node with the same ID as the subgraph name\n if (nodeIds.has(subgraphName)) {\n console.log(`🔍 NAMING-CONFLICT-FIX: Found conflict - subgraph \"${subgraphName}\" has node with same ID`);\n\n // Create a unique new node ID\n const newNodeId = `${subgraphName}Node`;\n\n // Replace node definition: TRI[...] -> TRINode[...]\n const nodeDefRegex = new RegExp(`\\\\b${subgraphName}\\\\[`, 'g');\n result = result.replace(nodeDefRegex, `${newNodeId}[`);\n\n // Replace all references to this node in connections, but NOT in subgraph declarations\n // This regex matches the node ID when it's used in connections but not in subgraph declarations\n const nodeRefRegex = new RegExp(`\\\\b${subgraphName}\\\\b(?!\\\\s*\\\\[|\"\\\\s*$)`, 'g');\n result = result.replace(nodeRefRegex, (match, offset) => {\n // Don't replace if this is part of a subgraph declaration\n const beforeMatch = result.substring(Math.max(0, offset - 20), offset);\n return beforeMatch.includes('subgraph') ? match : newNodeId;\n });\n\n console.log(`🔍 NAMING-CONFLICT-FIX: Renamed conflicting node from \"${subgraphName}\" to \"${newNodeId}\"`);\n }\n }\n\n console.log('🔍 NAMING-CONFLICT-FIX: Processing complete');\n return result;\n }, {\n name: 'naming-conflict-fix',\n priority: 480, // Very high priority to run before other fixes\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix numbered list syntax in node labels\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n console.log('🔍 NODE-LABEL-FIX: Processing node labels with numbered lists');\n\n // Fix node labels that contain numbered list syntax\n // This regex matches node definitions like: NodeId[1. Some text...]\n const result = definition.replace(/(\\w+)\\[([^\\]]*?)\\]/gs, (match, nodeId, content) => {\n // Check if content starts with numbered list syntax\n if (content.match(/^\\s*\\d+\\.\\s/)) {\n console.log('🔍 NODE-LABEL-FIX: Fixing numbered list in node:', nodeId);\n\n // Process the content to escape numbered list syntax\n const fixedContent = content\n .split('\\n')\n .map(line => {\n // Escape numbered list syntax at the beginning of lines\n return line.replace(/^(\\s*)(\\d+)\\.\\s*(.*)$/, '$1$2\\\\. $3');\n })\n .join('<br/>'); // Also convert newlines to <br/>\n\n return `${nodeId}[${fixedContent}]`;\n }\n return match;\n });\n\n console.log('🔍 NODE-LABEL-FIX: Processing complete');\n return result;\n }, {\n name: 'node-label-numbered-list-fix',\n priority: 470, // Higher priority to run before other fixes\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix multi-line node labels\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n console.log('🔍 MULTILINE-NODE-FIX: Processing multi-line node labels');\n\n // Fix multi-line node labels by replacing newlines with <br/>\n // This regex matches node definitions like: NodeId[text with\n // newlines\n // more text]\n const result = definition.replace(/(\\w+)\\[([^\\]]*?)\\]/gs, (match, nodeId, content) => {\n // Check if content contains actual newlines (not <br/> tags)\n if (content.includes('\\n') && !content.includes('<br/>')) {\n console.log('🔍 MULTILINE-NODE-FIX: Fixing node:', nodeId);\n // Replace newlines with <br/> tags, preserving leading whitespace as single spaces\n const fixedContent = content\n .split('\\n')\n .map(line => line.trim())\n .filter(line => line.length > 0)\n .join('<br/>');\n return `${nodeId}[${fixedContent}]`;\n }\n return match;\n });\n\n console.log('🔍 MULTILINE-NODE-FIX: Processing complete');\n return result;\n }, {\n name: 'multiline-node-fix',\n priority: 460, // High priority to run before linkstyle-fix\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix invalid linkStyle references\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n console.log('🔍 LINKSTYLE-FIX: Checking for invalid linkStyle references');\n\n // Count the actual number of links in the definition\n const linkPatterns = [\n /-->/g, // solid arrows\n /---/g, // solid lines \n /-\\.->/g, // dashed arrows\n /--[xo]>/g, // arrows with markers\n /->>|-->>|<--|<<-/g // other arrow types\n ];\n\n // More comprehensive approach: find all arrow-like patterns\n const allArrowPattern = /(-->|---|-.->|--[xo]>|->>|-->>|<--|<<-)/g;\n const arrowMatches = definition.match(allArrowPattern);\n const totalLinks = arrowMatches ? arrowMatches.length : 0;\n\n console.log('🔍 LINKSTYLE-FIX: Found', totalLinks, 'links in definition');\n if (arrowMatches) {\n console.log('🔍 LINKSTYLE-FIX: Arrow types found:', arrowMatches);\n }\n\n // Process linkStyle commands and remove invalid ones\n const lines = definition.split('\\n');\n const processedLines = lines.map(line => {\n const linkStyleMatch = line.match(/^\\s*linkStyle\\s+(\\d+(?:,\\d+)*)/);\n if (linkStyleMatch) {\n const linkNumbers = linkStyleMatch[1].split(',').map(n => parseInt(n.trim()));\n const validLinks = linkNumbers.filter(n => n < totalLinks);\n\n if (validLinks.length !== linkNumbers.length) {\n console.log('🔍 LINKSTYLE-FIX: Removing invalid link references:',\n linkNumbers.filter(n => n >= totalLinks));\n }\n\n if (validLinks.length === 0) {\n console.log('🔍 LINKSTYLE-FIX: Removing entire linkStyle line (no valid links)');\n return ''; // Remove the entire line\n }\n\n const newLinkStyle = `linkStyle ${validLinks.join(',')}`;\n return line.replace(/linkStyle\\s+\\d+(?:,\\d+)*/, newLinkStyle);\n }\n return line;\n });\n\n const result = processedLines.filter(line => line !== '').join('\\n');\n console.log('🔍 LINKSTYLE-FIX: Processing complete');\n return result;\n }, {\n name: 'linkstyle-fix',\n priority: 450, // High priority to run early\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix pipe syntax in flowcharts - higher priority\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n // Fix pipe syntax - convert A |label| B to A -->|label| B\n return definition.replace(/(\\w+)\\s*\\|([^|]+)\\|\\s*(\\w+)/g, '$1 -->|$2| $3');\n }, {\n name: 'pipe-syntax-fix',\n priority: 300,\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix node IDs containing colons, which are invalid\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'flowchart' && !def.trim().startsWith('flowchart') && !def.trim().startsWith('graph')) {\n return def;\n }\n\n const idsToQuote = new Set<string>();\n // Find node definitions with unquoted IDs that contain a colon.\n // e.g., `My Node: with details[Label text]`\n const nodeDefRegex = /([a-zA-Z0-9][^\\[\\(\\n]*:[^\\[\\(\\n]*?)(\\[|\\()/g;\n let match;\n while ((match = nodeDefRegex.exec(def)) !== null) {\n const id = match[1].trim();\n // Only add if it's not already quoted\n if (!id.startsWith('\"') && !id.endsWith('\"')) {\n idsToQuote.add(id);\n }\n }\n\n if (idsToQuote.size === 0) {\n return def;\n }\n\n let newDef = def;\n idsToQuote.forEach(id => {\n // Escape special characters in ID for use in regex\n const escapedId = id.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n // Regex to find the unquoted ID as a whole \"word\".\n const findIdRegex = new RegExp(`(?<=^|\\\\s)(${escapedId})(?=[\\\\s;\\\\[\\\\(]|$)`, 'g');\n newDef = newDef.replace(findIdRegex, `\"${id}\"`);\n });\n\n return newDef;\n }, {\n name: 'colon-in-node-id-fix',\n priority: 155, // High priority to fix structural errors first\n diagramTypes: ['flowchart', 'graph']\n });\n\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n console.log('🔍 LINK-LABEL-SANITIZER: Skipping non-flowchart diagram type:', diagramType);\n return definition;\n }\n\n console.log('🔍 LINK-LABEL-SANITIZER: Processing flowchart/graph');\n console.log('🔍 LINK-LABEL-SANITIZER: Input definition (first 500 chars):', definition.substring(0, 500));\n\n // This regex finds link labels and is non-greedy to handle multiple links on one line.\n const result = definition.replace(/(-->|-\\.->|--[xo]>|---|->>|-->>)\\s*\\|([^|]*?)\\|/g, (match, arrow, label) => {\n console.log('🔍 LINK-LABEL-SANITIZER: Found match:', { match, arrow, label });\n let processedLabel = label.trim();\n\n // If the label is already properly quoted, do nothing.\n if (processedLabel.startsWith('\"') && processedLabel.endsWith('\"')) {\n console.log('🔍 LINK-LABEL-SANITIZER: Label already quoted, skipping:', processedLabel);\n return match;\n }\n\n // If the label (cleaned or original) is empty after processing, just return the arrow without a label.\n if (!processedLabel) {\n console.log('🔍 LINK-LABEL-SANITIZER: Empty label, returning arrow only');\n return arrow;\n }\n\n // Always quote the label to prevent parsing errors with special characters (like \"1. ...\").\n let newLabel = processedLabel\n .replace(/\"/g, '#quot;')\n // CRITICAL: Escape numbered list syntax to prevent Mermaid markdown interpretation\n .replace(/^(\\d+)\\.\\s*(.*)$/, '$1\\\\. $2') // Escape the period with backslash\n // Alternative: Replace period with HTML entity\n // .replace(/^(\\d+)\\.\\s*(.*)$/, '$1. $2')\n // Handle bullet points by escaping them too\n .replace(/^[-*]\\s*(.*)$/, '\\\\$1 $2'); // Escape the bullet character\n\n // Also, replace brackets with parentheses to avoid parsing errors with node-like syntax in labels.\n newLabel = newLabel.replace(/\\[/g, '(').replace(/\\]/g, ')');\n const finalResult = `${arrow}|\"${newLabel}\"|`;\n console.log('🔍 LINK-LABEL-SANITIZER: Transformed:', { original: match, result: finalResult });\n return finalResult;\n });\n\n console.log('🔍 LINK-LABEL-SANITIZER: Processing complete');\n console.log('🔍 LINK-LABEL-SANITIZER: Final result (first 500 chars):', result.substring(0, 500));\n return result;\n }, {\n name: 'link-label-sanitizer',\n priority: 350, // Very high priority to run before other fixes\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add preprocessor to fix bullet characters and other problematic Unicode\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n console.log('🔍 UNICODE-FIX: Processing problematic Unicode characters');\n\n let result = definition;\n\n // Replace bullet characters with hyphens\n result = result.replace(/•/g, '-');\n\n // Replace other problematic Unicode characters\n result = result.replace(/[\\u2022\\u2023\\u2043]/g, '-'); // Various bullet chars\n result = result.replace(/[\\u2013\\u2014]/g, '-'); // En dash, Em dash\n result = result.replace(/[\\u201C\\u201D]/g, '\"'); // Smart quotes\n result = result.replace(/[\\u2018\\u2019]/g, \"'\"); // Smart single quotes\n\n // Fix incomplete connections that end abruptly\n const lines = result.split('\\n');\n const fixedLines = lines.map(line => {\n // Check for lines that end with arrows pointing nowhere\n if (line.trim().match(/-->\\s*$|--->\\s*$|\\|\\s*$/) && !line.includes('subgraph')) {\n console.log('🔍 UNICODE-FIX: Removing incomplete connection:', line.trim());\n return ''; // Remove incomplete connections\n }\n return line;\n }).filter(line => line !== '');\n\n result = fixedLines.join('\\n');\n\n console.log('🔍 UNICODE-FIX: Processing complete');\n return result;\n }, {\n name: 'unicode-and-incomplete-connection-fix',\n priority: 490, // Very high priority\n diagramTypes: ['*']\n });\n\n // Add a preprocessor to clean arrow characters from edge labels\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n console.log('🔍 ARROW-LABEL-CLEANER: Processing edge labels with arrow characters');\n\n // This regex finds edge labels and removes arrow characters from them\n const result = definition.replace(/(==>|-->|-\\.->|--[xo]>|---|->>|-->>)\\s*\\|([^|]*?)\\|/g, (match, arrow, label) => {\n console.log('🔍 ARROW-LABEL-CLEANER: Found match:', { match, arrow, label });\n\n let processedLabel = label.trim();\n\n // If the label is already properly quoted, don't add more quotes\n if (processedLabel.startsWith('\"') && processedLabel.endsWith('\"')) {\n console.log('🔍 ARROW-LABEL-CLEANER: Label already quoted, skipping:', processedLabel);\n return match;\n }\n\n // Clean arrow characters from the label\n let cleanedLabel = processedLabel\n .replace(/-->/g, '') // Remove -->\n .replace(/<--/g, '') // Remove <--\n .replace(/==>/g, '') // Remove ==>\n .replace(/<=/g, '') // Remove <==\n .replace(/-\\.->/g, '') // Remove -.->\n .replace(/<-\\.-/g, '') // Remove <-.-\n .trim();\n\n const finalResult = `${arrow}|\"${cleanedLabel}\"|`;\n console.log('🔍 ARROW-LABEL-CLEANER: Cleaned:', { original: match, result: finalResult });\n return finalResult;\n });\n\n console.log('🔍 ARROW-LABEL-CLEANER: Processing complete');\n return result;\n }, {\n name: 'arrow-label-cleaner',\n priority: 360, // Higher priority to run before other label fixes\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix links where the target is a node definition\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'flowchart' && !def.trim().startsWith('flowchart') && !def.trim().startsWith('graph')) {\n return def;\n }\n\n // Preserve the original diagram type declaration\n const lines = def.split('\\n');\n let diagramTypeLine = '';\n if (lines[0].trim().startsWith('graph') || lines[0].trim().startsWith('flowchart')) {\n diagramTypeLine = lines[0] + '\\n';\n lines.shift(); // Remove the diagram type line from processing\n }\n\n // Enhanced regex to handle links with labels containing brackets\n const linkWithTargetDefRegex = /^(\\s*)(\\w+)\\s*(--+>?)\\s*(\\|.*?\\|)?\\s*(\\w+)(\\[[^\\]]*\\])(\\s*)$/gm;\n\n // Process remaining lines\n const processedLines = lines.join('\\n').replace(linkWithTargetDefRegex, (match, indent, source, link, label, targetId, targetLabel) => {\n // Extract optional label\n const linkLabel = label ? ` ${label}` : '';\n\n return [\n `${indent}${targetId}${targetLabel}`, // Node definition\n `${indent}${source} ${link}${linkLabel} ${targetId}` // Link statement with label\n ].join('\\n');\n });\n\n // Combine diagram type with processed content\n return diagramTypeLine + processedLines;\n }, {\n name: 'link-target-definition-fix',\n priority: 255, // High priority to run before other link/node fixes\n diagramTypes: ['flowchart', 'graph']\n });\n\n // // Add a preprocessor to fix multi-line node labels that cause parsing errors\n // registerPreprocessor(\n // (definition: string, diagramType: string): string => {\n // if (diagramType !== 'flowchart' && diagramType !== 'graph' && !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n // return definition;\n // }\n // // This regex finds nodeId[...] and captures the content.\n // return definition.replace(/(\\w+)\\[([\\s\\S]+?)\\]/g, (match, nodeId, content) => {\n // // If content is already properly quoted, do nothing.\n // if (content.startsWith('\"') && content.endsWith('\"')) {\n // return match;\n // }\n // // If content contains newlines or quotes that need escaping, quote the whole thing.\n // if (content.includes('\\n') || content.includes('\"')) {\n // const escapedContent = content.replace(/\"/g, '#quot;'); // Mermaid's way of escaping quotes inside labels\n // return `${nodeId}[\"${escapedContent}\"]`;\n // }\n // return match;\n // });\n // }, {\n // name: 'multiline-node-label-fix',\n // priority: 250,\n // diagramTypes: ['flowchart', 'graph']\n // });\n\n // Add a preprocessor to fix class diagram syntax issues\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'classdiagram' && !definition.trim().startsWith('classDiagram')) {\n return definition;\n }\n\n let processedDef = definition;\n\n // Fix invalid inheritance syntax like \"User > OrderStatus\"\n processedDef = processedDef.replace(/^(\\s*)(\\w+)\\s*>\\s*(\\w+)\\s*$/gm, '$1$2 --|> $3');\n\n // Fix class body with standalone \">\" - remove it\n processedDef = processedDef.replace(/(class\\s+\\w+\\s*{\\s*)>\\s*/g, '$1');\n\n // Fix the specific \"} > OrderStatus {\" error pattern\n processedDef = processedDef.replace(/}\\s*>\\s*(\\w+)\\s*{/g, '}\\n $1 --|> ');\n\n // Fix invalid \">\" syntax in class definitions\n processedDef = processedDef.replace(/}\\s*(\\w+)\\s*{/g, '}\\n\\n class $1 {');\n\n return processedDef;\n }, {\n name: 'class-diagram-inheritance-fix',\n priority: 190,\n diagramTypes: ['classdiagram']\n });\n\n // Add a preprocessor to fix single-quoted link labels that cause SQS errors\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'flowchart' && !def.trim().startsWith('flowchart') && !def.trim().startsWith('graph')) {\n return def;\n }\n // Replaces single-quoted labels with double-quoted ones, e.g., -->|'text'| becomes -->|\"text\"|\n return def.replace(/\\|'([^']*)'\\|/g, '|\"$1\"|');\n }, {\n name: 'link-label-single-quote-fix',\n priority: 145,\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix class diagram syntax issues\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'classDiagram' && !definition.trim().startsWith('classDiagram')) {\n return definition;\n }\n\n let processedDef = definition;\n\n // Fix class inheritance syntax - replace \">\" with \"--|>\"\n processedDef = processedDef.replace(/(\\s+)>\\s*(\\w+)/g, '$1--|> $2');\n\n // Fix invalid standalone \">\" syntax in class definitions\n processedDef = processedDef.replace(/^\\s*>\\s*$/gm, '');\n\n // Fix the specific \"} > OrderStatus {\" error pattern\n processedDef = processedDef.replace(/}\\s*>\\s*(\\w+)\\s*{/g, '}\\n $1 --|> ');\n\n // Fix class body with standalone \">\" - remove it\n processedDef = processedDef.replace(/(class\\s+\\w+\\s*{\\s*)>\\s*/g, '$1');\n\n // Fix enum syntax issues\n processedDef = processedDef.replace(/(\\w+)\\s*{\\s*<<enumeration>>/g, '$1 {\\n <<enumeration>>');\n\n // Fix method syntax with asterisk\n processedDef = processedDef.replace(/\\+(\\w+)\\([^)]*\\)\\s*(\\w+)\\*/g, '+$1() $2');\n\n // Fix invalid \">\" syntax in class definitions\n processedDef = processedDef.replace(/}\\s*(\\w+)\\s*{/g, '}\\n\\n class $1 {');\n\n return processedDef;\n }, {\n name: 'class-diagram-syntax-fix',\n priority: 180,\n diagramTypes: ['classdiagram']\n });\n\n // Add a quote cleanup preprocessor that runs first to fix quote multiplication\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' && !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n const lines = definition.split('\\n');\n const fixedLines: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n let currentLine = lines[i];\n // Regex to capture:\n // 1: leading whitespace, 2: nodeId, 3: openBracket (paren or square),\n // 4: opening quote (optional), 5: content, 6: closing quote (matches opening),\n // 7: closeBracket (matches openBracket), 8: any trailing characters on the line\n\n // Skip subgraph lines - they don't need node termination fixes\n if (currentLine.trim().startsWith('subgraph') || currentLine.trim() === 'end') {\n fixedLines.push(currentLine);\n continue;\n }\n\n const nodeDefRegex = /^(\\s*)(\\w+)\\s*(\\[|\\()([\"']?)([\\s\\S]*?)(\\4)(\\]|\\))(\\s*.*)$/;\n const nodeDefMatch = currentLine.match(nodeDefRegex);\n\n if (nodeDefMatch) {\n const [,\n leadingSpace,\n nodeId,\n openBracketOrParen,\n openingQuote,\n nodeContent,\n closingQuote, // This should match openingQuote due to \\4 in regex\n closeBracketOrParen,\n trailingCharacters // All characters after the closing bracket/paren\n ] = nodeDefMatch;\n\n let mainPart = `${leadingSpace}${nodeId}${openBracketOrParen}`;\n let contentPart = nodeContent;\n\n if (openingQuote && closingQuote) { // If it was quoted\n if (contentPart.trim() === \"\") {\n contentPart = \" \"; // Replace \"\" or '' with \" \"\n }\n mainPart += `${openingQuote}${contentPart}${closingQuote}`;\n } else { // Unquoted content\n mainPart += contentPart;\n }\n mainPart += `${closeBracketOrParen}`;\n\n let finalLine = mainPart;\n const originalTrailingSyntax = trailingCharacters.trim();\n\n if (originalTrailingSyntax) {\n finalLine += trailingCharacters;\n }\n\n const needsTerminationFix = !originalTrailingSyntax ||\n (!originalTrailingSyntax.startsWith(':::') &&\n !originalTrailingSyntax.match(/^(-->|---|~~~|\\.-|\\.\\.-|o--|--o|x--)/));\n\n fixedLines.push(finalLine);\n } else {\n fixedLines.push(currentLine);\n }\n }\n return fixedLines.join('\\n');\n }, {\n name: 'flowchart-node-termination-fix',\n priority: 185,\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix gitgraph diagrams\n registerPreprocessor((def: string, type: string) => {\n // This preprocessor is specific to gitgraph/gitGraph types.\n // We need to replace `gitgraph` with `gitGraph` if it's present after frontmatter.\n const lines = def.split('\\n');\n\n let inFrontmatter = false;\n let diagramTypeLineProcessed = false; // Flag to ensure we only process the first 'gitgraph' after frontmatter\n\n if (lines.length > 0 && lines[0].trim() === '---') {\n inFrontmatter = true;\n }\n\n let finalDef = lines.map((line) => {\n if (inFrontmatter) {\n if (line.trim() === '---') {\n inFrontmatter = false; // End of frontmatter\n }\n return line; // Keep frontmatter lines as is\n }\n\n // After frontmatter (or if no frontmatter)\n if (!diagramTypeLineProcessed && line.trim().startsWith('gitgraph')) {\n diagramTypeLineProcessed = true; // Mark that we've processed the diagram type line\n return line.replace('gitgraph', 'gitGraph');\n }\n return line;\n }).join('\\n');\n return finalDef;\n }, {\n name: 'gitgraph-syntax-fix',\n priority: 140,\n diagramTypes: ['gitgraph'] // This is correct - gitgraph becomes 'gitgraph' in lowercase\n });\n\n // Add a preprocessor to fix XYChart excessive quotes\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'xychart' && !def.trim().startsWith('xychart')) {\n return def;\n }\n\n // Fix excessive quotes in xychart syntax\n return def.replace(/\"{2,}/g, '\"');\n }, {\n name: 'xychart-quotes-fix',\n priority: 140,\n diagramTypes: ['xychart']\n });\n\n // Add a preprocessor to fix flowchart line break issues\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n // Fix incomplete node definitions that end with newlines\n let processedDef = definition;\n\n // Fix nodes that have incomplete label definitions - ensure proper closing\n // processedDef = processedDef.replace(/(\\w+)\\[(?!\")([^\\]]*)\\n/g, '$1[\"$2\"]');\n\n // Ensure proper spacing around arrows\n processedDef = processedDef.replace(/(\\w+)-->/g, '$1 -->');\n processedDef = processedDef.replace(/-->(\\w+)/g, '--> $1');\n\n return processedDef;\n }, {\n name: 'flowchart-arrow-spacing-fix',\n priority: 195, // Slightly different priority to avoid conflicts\n diagramTypes: ['flowchart', 'graph']\n });\n // Add a quote cleanup preprocessor that runs first to fix quote multiplication\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'flowchart' && !def.startsWith('flowchart ') && !def.startsWith('graph ')) {\n return def;\n }\n\n let finalDef = def;\n\n // Fix malformed edge labels that cause parsing errors\n // Pattern: \"D --> E{Attempts -->|Yes| F[\" should be \"D --> E{Attempts < 3?}\\n E -->|Yes| F[\"\n finalDef = finalDef.replace(/(\\w+)\\s*-->\\s*(\\w+)\\{([^}]*?)-->\\|([^|]+)\\|\\s*(\\w+)\\[/g,\n '$1 --> $2{$3}\\n $2 -->|$4| $5[');\n\n // Fix diamond nodes with embedded arrows: \"E{Attempts -->|Yes|\" \n finalDef = finalDef.replace(/(\\w+)\\{([^}]*?)-->\\|([^|]+)\\|/g, '$1{$2}\\n $1 -->|$3|');\n\n // Fix incomplete diamond syntax\n finalDef = finalDef.replace(/(\\w+)\\{([^}]*?)\\s+\\|([^|]+)\\|\\s*(\\w+)\\[/g, '$1{$2}\\n $1 -->|$3| $4[');\n\n return finalDef;\n }, {\n name: 'flowchart-edge-label-fix',\n priority: 210,\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a quote cleanup preprocessor that runs first to fix quote multiplication\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'flowchart' && !def.startsWith('flowchart ') && !def.startsWith('graph ')) {\n return def;\n }\n\n let finalDef = def;\n console.log('Quote cleanup - before:', finalDef.substring(0, 200));\n\n // Fix quote multiplication by cleaning up malformed quotes\n finalDef = finalDef.replace(/(\\w+)(\\s*)\\[([\\s\\S]*?)\\]/g, (match, nodeId, spacing, content) => {\n // Skip subgraph display names - they should be handled by style-subgraph-fix\n // Pattern: subgraph Identifier [\"Display Name\"]\n const beforeMatch = finalDef.substring(Math.max(0, finalDef.indexOf(match) - 50), finalDef.indexOf(match));\n if (beforeMatch.includes('subgraph') && spacing.length === 1) {\n console.log(`Skipping subgraph display name: ${nodeId}${spacing}[${content}]`);\n return match; // Don't process subgraph display names\n }\n\n // Only process actual node definitions, not subgraph display names\n const actualNodeId = nodeId + spacing;\n\n // Skip if this is already properly quoted\n if (content.match(/^\"[^\"]*\"$/)) {\n return match;\n }\n\n // If content has multiple quotes, excessive quotes, or malformed quotes, clean it up\n if (content.includes('\"\"') || content.match(/\"{2,}/) || content.includes('\\\\\"') || content.match(/^\".*\".*\"/)) {\n // Extract the actual text content by removing all quote variations and trailing backslashes\n const cleanContent = content.replace(/^\"+|\"+$/g, '').replace(/\\\\\"/g, '\"').replace(/\"{2,}/g, '\"').replace(/\\\\+$/g, '');\n console.log(`Cleaning quotes for ${actualNodeId}: \"${content}\" -> \"${cleanContent}\"`);\n return `${actualNodeId}[\"${cleanContent}\"]`;\n }\n return match;\n });\n\n console.log('Quote cleanup - after:', finalDef.substring(0, 200));\n return finalDef;\n }, {\n name: 'quote-cleanup-flowchart',\n priority: 200, // High priority to run first\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor specifically for subgraph syntax\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'flowchart' && !def.startsWith('flowchart') && !def.startsWith('graph')) {\n return def;\n }\n\n let finalDef = def;\n\n // Fix class assignments that use subgraph-* syntax\n // Change from: class ServerStartup subgraph-blue\n // To: class ServerStartup subgraph_blue\n finalDef = finalDef.replace(/class\\s+(\\w+)\\s+subgraph-(\\w+)/g, 'class $1 subgraph_$2');\n\n // Also fix classDef with subgraph prefix\n finalDef = finalDef.replace(/classDef\\s+subgraph-(\\w+)/g, 'classDef style_$1');\n\n // Ensure subgraph declarations are properly formatted\n // Make sure there's a space between subgraph and the ID\n finalDef = finalDef.replace(/subgraph(\\w+)/g, 'subgraph $1');\n\n return finalDef;\n }, {\n name: 'subgraph-syntax-fix',\n priority: 130,\n diagramTypes: ['flowchart', 'graph']\n });\n\n registerPreprocessor((def: string, type: string): string => {\n if (type !== 'flowchart' && !def.startsWith('flowchart') && !def.startsWith('graph')) {\n return def;\n }\n\n let finalDef = def;\n\n console.log('Mixed node shapes - processing:', finalDef.substring(0, 200));\n finalDef = finalDef.replace(/(\\w+)(\\[|\\()([\\s\\S]*?)(\\]|\\))/g, (match, nodeId, open, content, close) => {\n // Skip subgraph display names - they should not be modified\n // Pattern: subgraph Identifier [\"Display Name\"]\n const beforeMatch = finalDef.substring(Math.max(0, finalDef.indexOf(match) - 50), finalDef.indexOf(match));\n if (beforeMatch.includes('subgraph')) {\n console.log(`Skipping subgraph display name in special-char fix: ${nodeId}${open}${content}${close}`);\n return match; // Don't process subgraph display names\n }\n\n // Ensure open and close brackets match\n if ((open === '[' && close !== ']') || (open === '(' && close !== ')')) {\n console.log(`Malformed brackets in special-char fix: ${match}`);\n return match; // Malformed, skip\n }\n\n // Skip if already properly quoted\n if (content.match(/^\"[\\s\\S]*\"$/)) {\n return match;\n }\n\n // Quote if content has special characters, newlines, or <br>\n if (/[()\\/\\n<>&:\\.,']/.test(content) || content.includes('<br>')) {\n const escapedContent = content.replace(/\"/g, '#quot;').replace(/\\n/g, '<br/>');\n console.log(`Adding quotes for special chars: ${nodeId}${open}${content}${close} -> ${nodeId}${open}\"${escapedContent}\"${close}`);\n return `${nodeId}${open}\"${escapedContent}\"${close}`;\n }\n return match;\n });\n\n console.log('Mixed node shapes - result:', finalDef.substring(0, 200));\n console.log('Final processed definition length:', finalDef.length);\n return finalDef;\n }, {\n name: 'special-char-in-node-label-fix',\n priority: 135,\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to fix spacing issues between subgraph end and style statements\n registerPreprocessor(\n (definition: string, diagramType: string): string => {\n if (diagramType !== 'flowchart' && diagramType !== 'graph' &&\n !definition.trim().startsWith('flowchart') && !definition.trim().startsWith('graph')) {\n return definition;\n }\n\n console.log('🔍 SUBGRAPH-STYLE-SPACING: Fixing spacing between subgraph end and style statements');\n\n // Fix subgraph syntax - replace } with end and ensure proper spacing\n let result = definition;\n\n // Replace closing braces with 'end' for subgraphs\n result = result.replace(/(\\s+)}\\s*\\n/g, '$1end\\n');\n result = result.replace(/(\\s+)}\\s*$/g, '$1end');\n\n // Ensure proper line breaks between subgraph end and style statements\n result = result.replace(/(end\\s*)(style\\s+)/g, '$1\\n $2');\n\n console.log('🔍 SUBGRAPH-STYLE-SPACING: Processing complete');\n return result;\n }, {\n name: 'subgraph-style-spacing-fix',\n priority: 160, // Run after other structural fixes\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor to clean arrow characters from edge labels\n registerPreprocessor(\n (def: string, type: string) => {\n let finalDef = def;\n\n // Fix nodes with \"DONE\" text by replacing quotes with escaped quotes\n finalDef = finalDef.replace(/\\[([^\"\\]]*)\"([^\"\\]]*)\"([^\"\\]]*)\\]/g, (match, before, quoted, after) => {\n // Replace with HTML entity quotes to avoid parsing issues\n return `[${before}\"${quoted}\"${after}]`;\n });\n\n return finalDef;\n }, {\n name: 'quoted-text-fix',\n priority: 125,\n diagramTypes: ['*']\n });\n\n // Add a specific preprocessor for complex flowcharts\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'flowchart' && !def.startsWith('flowchart') && !def.startsWith('graph')) {\n return def;\n }\n\n let finalDef = def;\n\n // Convert flowchart to graph LR if needed for better compatibility\n finalDef = finalDef.replace(/^flowchart\\s+/m, 'graph ');\n\n // IMPORTANT: Remove any \"note on link:\" text that causes parsing errors\n finalDef = finalDef.replace(/note\\s+on\\s+link.*?:/gi, '%%note removed:');\n\n // Fix \"Send DONE Marker\" nodes that cause parsing errors\n finalDef = finalDef.replace(/\\[Send\\s+\"DONE\"\\s+Marker\\]/g, '[Send DONE Marker]');\n\n // Fix issues like `class X,Y,Z style --> class`\n // 1. Ensure `class` as a node ID is quoted.\n finalDef = finalDef.replace(/(\\s+-->\\s+)class(\\s*;|\\s*\\[|\\s*$|\\s+-->)/gm, '$1\"class\"$2');\n // 2. Address `class X,Y,Z somenode` potentially being misparsed before `-->`\n // This is complex; a simpler fix is to ensure `class` keyword is not misinterpreted.\n // The main issue seems to be `--> class`.\n\n // Fix node references that cause parsing errors\n finalDef = finalDef.replace(/(\\w+)\\s*-->\\s*(\\w+)\\[([^\\]]+)\\]/g, (match, source, target, label) => {\n // If label contains special characters, quote it\n if (/[\\/\\[\\]]/.test(label)) {\n return `${source} --> ${target}[\"${label}\"]`;\n }\n return `${source} --> ${target}[${label}]`;\n });\n\n // Fix end nodes that cause parsing errors\n finalDef = finalDef.replace(/end\\[([^\\]]+)\\]/g, 'endNode[\"$1\"]');\n\n // Fix SendDone nodes that cause parsing errors\n finalDef = finalDef.replace(/SendDone\\[([^\\]]+)\\]/g, 'sendDoneNode[\"$1\"]');\n\n return finalDef;\n }, {\n name: 'flowchart-fix',\n priority: 120,\n diagramTypes: ['flowchart', 'graph']\n });\n\n // Add a preprocessor for requirement diagrams\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'requirement') {\n return def;\n }\n\n // Fix common syntax issues in requirement diagrams\n let lines = def.split('\\n');\n let result: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i].trim();\n\n // Fix ID format\n if (line.match(/^\\s*id:/i)) {\n line = line.replace(/id:\\s*([^,]+)/, 'id: \"$1\"');\n }\n\n // Fix text format\n if (line.match(/^\\s*text:/i)) {\n line = line.replace(/text:\\s*([^,]+)/, 'text: \"$1\"');\n }\n\n result.push(line);\n }\n\n return result.join('\\n');\n }, {\n name: 'requirement-diagram-fix',\n priority: 110,\n diagramTypes: ['requirement']\n });\n\n // Add a preprocessor for xychart diagrams\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'xychart') {\n return def;\n }\n\n // Fix common syntax issues in xychart diagrams\n let lines = def.split('\\n');\n let result: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i].trim();\n\n // Fix array format\n if (line.includes('[') && line.includes(']')) {\n line = line.replace(/\\[(.*?)\\]/, '\"[$1]\"');\n }\n\n result.push(line);\n }\n\n return result.join('\\n');\n }, {\n name: 'xychart-array-format-fix', // Rename to avoid duplicate\n priority: 110,\n diagramTypes: ['xychart']\n });\n\n // Add a preprocessor to fix Gantt diagram task definition issues\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'gantt' && !def.trim().startsWith('gantt')) {\n return def;\n }\n\n console.log('🔍 GANTT-FIX: Processing gantt diagram task definitions');\n\n let processedDef = def;\n\n // CRITICAL FIX: Mermaid's gantt parser expects very specific task format\n // The error \"Cannot read properties of undefined (reading 'type')\" happens when\n // the task object structure is malformed. Let's ensure proper task format.\n\n // First, ensure we have proper section structure\n if (!processedDef.includes('section ')) {\n console.log('🔍 GANTT-FIX: Adding missing section structure');\n const lines = processedDef.split('\\n');\n const hasTitle = lines.some(line => line.trim().startsWith('title'));\n const titleIndex = hasTitle ? lines.findIndex(line => line.trim().startsWith('title')) : 0;\n\n // Insert a default section after title/dateFormat lines\n const insertIndex = Math.max(titleIndex + 1, 3);\n lines.splice(insertIndex, 0, ' section Tasks');\n processedDef = lines.join('\\n');\n }\n\n // CRITICAL FIX: Replace dateFormat X with a standard date format\n // But handle different types of data appropriately\n if (processedDef.includes('dateFormat X') || processedDef.includes('dateFormat X')) {\n\n // Check if this uses hour/minute formats (like \"1h\", \"30m\") \n const usesTimeFormat = processedDef.match(/:\\s*\\w+,\\s*\\w+,\\s*\\d*[hm]/);\n\n if (usesTimeFormat) {\n console.log('🔍 GANTT-FIX: Detected time-based gantt chart, using appropriate format');\n // For hour/minute based charts, convert to a format Mermaid can actually parse\n // dateFormat X with time strings like \"1h\" doesn't work - convert to numeric minutes\n processedDef = processedDef.replace(/dateFormat\\s+X/g, 'dateFormat X');\n\n // Keep the time axis format but we'll convert the times to minutes\n // This allows Mermaid to parse the timeline as minute offsets\n console.log('🔍 GANTT-FIX: Converting time strings to minute numbers for Mermaid compatibility');\n } else {\n // For large timestamp charts, convert to date format\n console.log('🔍 GANTT-FIX: Replacing Unix timestamp dateFormat with YYYY-MM-DD');\n processedDef = processedDef.replace(/dateFormat\\s+X/g, 'dateFormat YYYY-MM-DD');\n\n // Also update axisFormat to match\n if (processedDef.includes('axisFormat %s')) {\n processedDef = processedDef.replace(/axisFormat %s/g, 'axisFormat %Y-%m-%d');\n }\n }\n }\n\n // CRITICAL: Convert all tasks to use simple relative format\n // This avoids the complex date parsing that's causing the \"type\" error\n const lines = processedDef.split('\\n');\n const fixedLines: string[] = [];\n let taskCounter = 1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n // Skip non-task lines\n if (!trimmed || trimmed.startsWith('gantt') || trimmed.startsWith('title') ||\n trimmed.startsWith('dateFormat') || trimmed.startsWith('axisFormat') ||\n trimmed.startsWith('section') || trimmed.startsWith('%%')) {\n fixedLines.push(line);\n continue;\n }\n\n // Process task lines\n if (trimmed.includes(':')) {\n const colonIndex = trimmed.indexOf(':');\n const taskName = trimmed.substring(0, colonIndex).trim();\n const taskDef = trimmed.substring(colonIndex + 1).trim();\n\n // Parse task definition\n const taskDefParts = taskDef.split(',').map(p => p.trim());\n\n // Handle simplified format: TaskName: start, end (only 2 parameters)\n if (taskDefParts.length === 2 && !isNaN(parseInt(taskDefParts[0])) && !isNaN(parseInt(taskDefParts[1]))) {\n console.log(`🔍 GANTT-FIX: Converting simple numeric format for task: ${taskName}`);\n\n const startNum = parseInt(taskDefParts[0]);\n const endNum = parseInt(taskDefParts[1]);\n const duration = Math.max(1, endNum - startNum);\n\n if (taskCounter === 1) {\n fixedLines.push(` ${taskName} :done, t${taskCounter}, 2024-01-01, ${duration}d`);\n } else {\n fixedLines.push(` ${taskName} :done, t${taskCounter}, after t${taskCounter - 1}, ${duration}d`);\n }\n taskCounter++;\n continue;\n }\n\n if (taskDefParts.length >= 3) {\n // ... rest of the existing logic\n } else {\n // Handle incomplete tasks\n console.log(`🔍 GANTT-FIX: Adding default format for incomplete task: ${taskName}`);\n const id = `t${taskCounter}`;\n fixedLines.push(` ${taskName} :done, ${id}, 2024-01-01, 1d`);\n taskCounter++;\n }\n } else {\n fixedLines.push(line);\n }\n }\n\n const result = fixedLines.join('\\n');\n console.log('🔍 GANTT-FIX: Processing complete');\n return result;\n }, {\n name: 'gantt-task-definition-fix',\n diagramTypes: ['gantt']\n });\n\n // Add a preprocessor to fix line break issues in sankey diagrams \n registerPreprocessor((def: string, type: string) => {\n if (!def.trim().startsWith('sankey')) {\n return def;\n }\n\n console.log('🔍 SANKEY-FIX: Processing sankey diagram');\n\n // Fix line break issues in sankey diagrams\n let lines = def.split('\\n');\n let result: string[] = [];\n\n for (let line of lines) {\n let trimmedLine = line.trim();\n\n // Skip empty lines\n if (!trimmedLine) {\n continue;\n }\n\n // Keep the sankey-beta header as is\n if (trimmedLine.startsWith('sankey')) {\n result.push(trimmedLine);\n } else if (trimmedLine.includes(',')) {\n // Ensure each data line has proper comma separation and no extra whitespace\n // Also ensure all data lines have exactly 3 parts: source,target,value\n const parts = trimmedLine.split(',').map(p => p.trim());\n if (parts.length >= 3) {\n result.push(` ${parts[0]},${parts[1]},${parts[2]}`);\n }\n }\n }\n\n console.log('🔍 SANKEY-FIX: Processing complete');\n return result.join('\\n');\n }, {\n name: 'sankey-format-fix',\n priority: 315, // Higher priority\n diagramTypes: ['sankey']\n });\n\n // Add comprehensive block diagram node label fixer\n registerPreprocessor((def: string, type: string) => {\n if (!def.trim().startsWith('block')) {\n return def;\n }\n\n console.log('🔍 BLOCK-COMPREHENSIVE-FIX: Processing block diagram node labels');\n\n let result = def;\n\n // Fix the exact pattern causing lexical error: M[\"(\"PostgreSQL<br/>Primary DB\")\"]\n result = result.replace(/(\\w+)\\[\"?\\(\"([^\"]+?)<br\\/>([^\"]+?)\"\\)/g, '$1[\"$2 $3\"]');\n\n // Fix other malformed patterns\n result = result.replace(/\\[\"?\\(\"([^\"]+)\"\\)/g, '[\"$1\"]');\n result = result.replace(/\\[\"\"([^\"]+)\"\"\\]/g, '[\"$1\"]');\n\n console.log('🔍 BLOCK-COMPREHENSIVE-FIX: Processing complete');\n return result;\n }, {\n name: 'block-advanced-node-fix', // Rename duplicate\n priority: 325, // Higher than existing block fix\n diagramTypes: ['block']\n });\n\n // Add a preprocessor to fix block diagram node label issues\n registerPreprocessor((def: string, type: string) => {\n if (!def.trim().startsWith('block')) {\n return def;\n }\n\n console.log('🔍 BLOCK-DIAGRAM-FIX: Processing block diagram node labels');\n\n let result = def;\n\n // Fix problematic parentheses in node labels like [\"(\"PostgreSQL...]\n // Replace with proper format: [\"PostgreSQL\"]\n result = result.replace(/\\[\"?\\([\"`]([^\"`)]+)[\"`]([^\"]*)[\"`]\\]/g, '[\"$1$2\"]');\n\n // Fix malformed parentheses in labels\n result = result.replace(/\\[\"?\\(\"([^\"]+)\"([^\"]*?)\"\\]/g, '[\"$1$2\"]');\n\n // Fix double quotes and parentheses combinations\n result = result.replace(/\\[\"\\(\"([^\"]+)<br\\/>([^\"]+)\"\\)/g, '[\"$1 $2\"]');\n\n console.log('🔍 BLOCK-DIAGRAM-FIX: Processing complete');\n return result;\n }, {\n name: 'block-basic-node-label-fix', // Rename to be more specific\n priority: 320,\n diagramTypes: ['block']\n });\n\n // Add a more comprehensive class diagram relationship fixer\n registerPreprocessor((def: string, type: string) => {\n if (!def.trim().startsWith('classDiagram')) {\n return def;\n }\n\n console.log('🔍 CLASS-CARDINALITY-FIX: Processing class diagram cardinality relationships');\n\n let result = def;\n\n // CRITICAL: Fix cardinality relationships like ||--o{ that cause lexical errors\n const cardinalityPatterns = [\n { pattern: /\\|\\|--o\\{/g, replacement: '||--o{' }, // This pattern is actually valid, need to check context\n { pattern: /(\\w+)\\s+\\|\\|--o\\{\\s+(\\w+)\\s*:\\s*(.+)/g, replacement: '$1 ||--o{ $2 : $3' },\n { pattern: /(\\w+)\\s+\\|\\|--\\|\\|\\s*\\{\\s+(\\w+)/g, replacement: '$1 ||--o{ $2' },\n { pattern: /\\|\\|--\\|\\|\\{/g, replacement: '||--o{' },\n { pattern: /\\|\\|--\\|\\|/g, replacement: '-->' }, // Fallback for invalid double pipes\n ];\n\n cardinalityPatterns.forEach(({ pattern, replacement }) => {\n const beforeCount = (result.match(pattern) || []).length;\n if (beforeCount > 0) {\n result = result.replace(pattern, replacement);\n console.log(`🔍 CLASS-CARDINALITY-FIX: Fixed ${beforeCount} instances of ${pattern.source}`);\n }\n });\n\n // Fix the specific \"User ||--o{ Role : has\" error by ensuring proper spacing\n result = result.replace(/(\\w+)\\s+\\|\\|--o\\{\\s+(\\w+)\\s*:\\s*(.+?)(\\s*)$/gm, '$1 ||--o{ $2 : $3$4');\n\n console.log('🔍 CLASS-CARDINALITY-FIX: Processing complete');\n return result;\n }, {\n name: 'class-cardinality-relationship-fix',\n priority: 510, // Highest priority to fix before other class processors\n diagramTypes: ['classdiagram']\n });\n\n // Add a more comprehensive class diagram relationship fixer \n registerPreprocessor((def: string, type: string) => {\n if (!def.trim().startsWith('classDiagram')) {\n return def;\n }\n\n console.log('🔍 CLASS-COMPREHENSIVE-FIX: Processing class diagram relationships');\n\n let result = def;\n\n // CRITICAL: Fix all invalid relationship patterns\n const invalidPatterns = [\n { pattern: /\\|\\|--\\|\\|/g, replacement: '-->' },\n { pattern: /\\|\\|\\s*--\\s*\\|\\|/g, replacement: '-->' },\n { pattern: /\\|\\|-->/g, replacement: '-->' },\n { pattern: /--\\|\\|/g, replacement: '-->' },\n { pattern: /<\\|\\|--\\|\\|>/g, replacement: '<-->' },\n { pattern: /\\|\\|==\\|\\|/g, replacement: '-->' },\n { pattern: /\\|\\|\\.\\.>\\|\\|/g, replacement: '..>' },\n { pattern: /\\|\\|<\\.\\.\\|\\|/g, replacement: '<..' },\n ];\n\n invalidPatterns.forEach(({ pattern, replacement }) => {\n const beforeCount = (result.match(pattern) || []).length;\n if (beforeCount > 0) {\n result = result.replace(pattern, replacement);\n console.log(`🔍 CLASS-COMPREHENSIVE-FIX: Fixed ${beforeCount} instances of ${pattern.source}`);\n }\n });\n\n // Fix relationship lines that have extra syntax\n result = result.replace(/(\\w+)\\s+(\\|\\|--\\|\\||\\|\\|-\\|\\||--\\|\\|--)\\s+(\\w+)/g, '$1 --> $3');\n\n console.log('🔍 CLASS-COMPREHENSIVE-FIX: Processing complete');\n return result;\n }, {\n name: 'class-invalid-relationship-fix',\n priority: 500, // Highest priority to fix before other processors\n diagramTypes: ['classdiagram']\n });\n\n // Add a comprehensive sequence diagram alt/else block fixer\n registerPreprocessor(\n (def: string, type: string) => {\n if (!def.trim().startsWith('sequenceDiagram')) {\n return def;\n }\n\n console.log('🔍 CRITICAL-SEQUENCE-FIX: Processing comprehensive sequence diagram alt/else/critical structure');\n\n const lines = def.split('\\n');\n const result: string[] = [];\n let inAltBlock = false;\n let inCriticalBlock = false;\n let inParBlock = false;\n let blockDepth = 0;\n let hasElseInCurrentBlock = false;\n let hasBreakInCurrentBlock = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n // CRITICAL: Handle option statements - they can only be in critical blocks, not alt blocks\n if (trimmed.startsWith('option ')) {\n if (inCriticalBlock) {\n result.push(line); // Valid option in critical block\n continue;\n } else {\n // Convert invalid option to else in alt blocks\n console.log(`🔍 CRITICAL-SEQUENCE-FIX: Converting invalid option to else: \"${trimmed}\"`);\n const indentation = line.match(/^\\s*/)?.[0] || '';\n if (inAltBlock && !hasElseInCurrentBlock) {\n result.push(`${indentation}else`);\n hasElseInCurrentBlock = true;\n }\n continue;\n }\n }\n\n // Track block starts\n if (trimmed.startsWith('alt ')) {\n inAltBlock = true;\n blockDepth++;\n hasElseInCurrentBlock = false;\n hasBreakInCurrentBlock = false;\n result.push(line);\n continue;\n }\n\n if (trimmed.startsWith('critical ')) {\n inCriticalBlock = true;\n blockDepth++;\n hasElseInCurrentBlock = false;\n hasBreakInCurrentBlock = false;\n result.push(line);\n continue;\n }\n\n if (trimmed.startsWith('par ')) {\n inParBlock = true;\n blockDepth++;\n result.push(line);\n continue;\n }\n\n // Track block ends\n if (trimmed === 'end' && blockDepth > 0) {\n blockDepth--;\n if (blockDepth === 0) {\n inAltBlock = false;\n inCriticalBlock = false;\n inParBlock = false;\n hasElseInCurrentBlock = false;\n }\n hasBreakInCurrentBlock = false;\n result.push(line);\n continue;\n }\n\n // Handle 'and' in par blocks\n if (inParBlock && trimmed === 'and') {\n result.push(line);\n continue;\n }\n\n // Handle 'option' in critical blocks\n if (inCriticalBlock && trimmed.startsWith('option ')) {\n result.push(line);\n continue;\n }\n\n // Handle break statements - they terminate the current alt path\n if (inAltBlock && trimmed.startsWith('break ')) {\n hasBreakInCurrentBlock = true;\n result.push(line);\n continue;\n }\n\n // CRITICAL: Fix problematic 'else' statements\n if (inAltBlock && trimmed.startsWith('else ')) {\n // For \"else Stock available\" or \"else Some condition\", convert to just \"else\"\n console.log(`🔍 CRITICAL-SEQUENCE-FIX: Converting \"${trimmed}\" -> \"else\"`);\n const indentation = line.match(/^\\s*/)?.[0] || '';\n\n if (hasBreakInCurrentBlock) {\n // Cannot have else after break - skip it entirely\n console.log(`🔍 CRITICAL-SEQUENCE-FIX: Skipping else after break: \"${trimmed}\"`);\n continue;\n } else if (!hasElseInCurrentBlock) {\n result.push(`${indentation}else`);\n hasElseInCurrentBlock = true;\n } else {\n // Convert additional else to a note to preserve logic\n result.push(`${indentation}Note over DB: Alternative path`);\n }\n continue;\n }\n\n // Handle standalone 'else' in alt blocks - ensure proper indentation\n if (inAltBlock && trimmed === 'else') {\n if (hasBreakInCurrentBlock) {\n // Cannot have else after break - convert to a note\n const indentation = line.match(/^\\s*/)?.[0] || '';\n result.push(`${indentation}Note over DB: Break terminated this path`);\n } else if (!hasElseInCurrentBlock) {\n const indentation = line.match(/^\\s*/)?.[0] || '';\n // Ensure proper indentation (at least 4 spaces for sequence diagrams)\n if (indentation.length < 4) {\n result.push(' else');\n } else {\n result.push(line);\n }\n hasElseInCurrentBlock = true;\n } else {\n // Skip duplicate else, convert to note\n const indentation = line.match(/^\\s*/)?.[0] || '';\n result.push(`${indentation}Note over DB: Alternative path`);\n }\n continue;\n }\n\n // Default: add the line as-is\n result.push(line);\n }\n\n console.log('🔍 CRITICAL-SEQUENCE-FIX: Processing complete');\n return result.join('\\n');\n }, {\n name: 'sequence-comprehensive-else-fix',\n priority: 590, // Very high priority\n diagramTypes: ['sequencediagram']\n });\n\n // Add a preprocessor to fix Timeline diagram syntax issues\n registerPreprocessor((def: string, type: string) => {\n if (!def.trim().startsWith('timeline')) {\n return def;\n }\n\n // Fix timeline diagram syntax issues\n let lines = def.split('\\n');\n let result: string[] = [];\n let inSection = false;\n\n for (let line of lines) {\n let trimmedLine = line.trim();\n\n // Skip empty lines\n if (!trimmedLine) {\n continue;\n }\n\n // Handle timeline header\n if (trimmedLine.startsWith('timeline')) {\n result.push(trimmedLine);\n continue;\n }\n\n // Handle title\n if (trimmedLine.startsWith('title ')) {\n result.push(' ' + trimmedLine);\n continue;\n }\n\n // Handle sections\n if (trimmedLine.startsWith('section ')) {\n result.push(' ' + trimmedLine);\n inSection = true;\n continue;\n }\n\n // Handle events within sections\n if (inSection && trimmedLine.includes(' : ')) {\n result.push(' ' + trimmedLine);\n continue;\n }\n\n // Default case - preserve line with proper indentation\n if (trimmedLine) {\n result.push(' ' + trimmedLine);\n }\n }\n\n return result.join('\\n');\n }, {\n name: 'timeline-syntax-fix',\n priority: 120,\n diagramTypes: ['timeline']\n });\n\n // Add a preprocessor to fix Gantt diagram date format issues\n registerPreprocessor((def: string, type: string) => {\n if (type !== 'gantt' && !def.trim().startsWith('gantt')) {\n return def;\n }\n\n // Fix gantt diagram date format issues\n let processedDef = def;\n\n // Fix date format - convert \"50s\" style dates to proper format\n processedDef = processedDef.replace(/(\\d+)s/g, '$1');\n\n // Ensure proper date format is set\n if (!processedDef.includes('dateFormat')) {\n processedDef = processedDef.replace(/^gantt/, 'gantt\\n dateFormat YYYY-MM-DD');\n }\n\n // Fix axis format\n if (!processedDef.includes('axisFormat')) {\n processedDef = processedDef.replace(/dateFormat[^\\n]*/, '$&\\n axisFormat %Y-%m-%d');\n }\n\n return processedDef;\n }, {\n name: 'gantt-date-format-fix',\n priority: 120,\n diagramTypes: ['gantt']\n });\n\n // Add a preprocessor specifically for sequence diagram note formatting\n registerPreprocessor(\n (definition: string, diagramType: string) => {\n if (diagramType.toLowerCase() !== 'sequencediagram' && !definition.trim().startsWith('sequenceDiagram')) return definition;\n\n console.log('Running sequence diagram note formatter');\n\n const lines = definition.split('\\n');\n const fixedLines: string[] = [];\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n const trimmedLine = line.trim();\n\n // Check if this is a note line\n if (trimmedLine.startsWith('Note over ') || trimmedLine.startsWith('Note left of ') || trimmedLine.startsWith('Note right of ')) {\n // Extract the note declaration and content\n const noteMatch = trimmedLine.match(/^(Note (?:over|left of|right of) [^:]+):\\s*(.*)$/);\n\n if (noteMatch) {\n const [, noteDeclaration, firstLineContent] = noteMatch;\n let noteContent = firstLineContent;\n let j = i + 1;\n\n // Collect all subsequent lines that are part of this note (indented or continuation)\n while (j < lines.length) {\n const nextLine = lines[j];\n const nextTrimmed = nextLine.trim();\n\n // Stop if we hit another Mermaid command or empty line followed by command\n if (nextTrimmed.match(/^(participant|Note|activate|deactivate|\\w+->>|\\w+-->>|loop|alt|opt|par|and|else|end)/) ||\n nextTrimmed === '' && j + 1 < lines.length && lines[j + 1].trim().match(/^(participant|Note|activate|deactivate|\\w+->>|\\w+-->>|loop|alt|opt|par|and|else|end)/)) {\n break;\n }\n\n // If it's not empty, add it to note content\n if (nextTrimmed !== '') {\n noteContent += '<br/>' + nextTrimmed;\n }\n j++;\n }\n\n // Clean up the note content\n if (noteContent) {\n noteContent = noteContent\n // First, normalize line breaks and clean up whitespace\n .replace(/\\r\\n/g, '\\n')\n .replace(/\\r/g, '\\n')\n // Split into lines, preserve all lines (including empty ones for spacing)\n .split('\\n')\n .map(line => {\n const trimmed = line.trim();\n // Keep empty lines for spacing, but convert to a single space\n return trimmed.length === 0 ? ' ' : trimmed;\n })\n .join('<br/>')\n // Remove problematic HTML tags but keep <br/> for line breaks\n .replace(/<(?!br\\/?>)[^>]*>/g, '')\n // Escape only the most problematic characters, keep others readable\n .replace(/\"/g, \"'\")\n .replace(/\\{/g, '(')\n .replace(/\\}/g, ')')\n // Handle numbered lists\n .replace(/(\\d+)\\.\\s*/g, '$1. ')\n // Handle bullet points\n .replace(/-\\s*/g, '• ')\n .trim();\n }\n\n // Reconstruct the note with proper formatting\n fixedLines.push(` ${noteDeclaration}: ${noteContent}`);\n i = j;\n } else {\n // Malformed note, just add as-is\n fixedLines.push(line);\n i++;\n }\n } else {\n // Not a note line, add as-is\n fixedLines.push(line);\n i++;\n }\n }\n\n return fixedLines.join('\\n');\n },\n {\n name: 'sequence-diagram-note-formatter',\n priority: 300, // Higher priority to run before other fixes\n diagramTypes: ['sequencediagram']\n }\n );\n\n // Add a preprocessor for state diagram notes to fix markdown list errors\n registerPreprocessor(\n (definition: string, diagramType: string) => {\n if (!diagramType.toLowerCase().startsWith('statediagram') && !definition.trim().startsWith('stateDiagram')) {\n return definition;\n }\n\n const lines = definition.split('\\n');\n const fixedLines: string[] = [];\n let inNote = false;\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n\n if (trimmedLine.match(/^note\\s+(right of|left of|over)\\s+\\w+/)) {\n inNote = true;\n fixedLines.push(line);\n continue;\n }\n\n if (trimmedLine === 'end note') {\n inNote = false;\n fixedLines.push(line);\n continue;\n }\n\n if (inNote) {\n // Replace leading hyphens with a bullet to avoid markdown list parsing issues\n const processedLine = line.replace(/^(\\s*)-\\s+/, '$1• ');\n fixedLines.push(processedLine);\n } else {\n fixedLines.push(line);\n }\n }\n return fixedLines.join('\\n');\n }\n\n );\n\n // Add a preprocessor to handle participant names with special characters\n registerPreprocessor(\n (definition: string, diagramType: string) => {\n if (diagramType.toLowerCase() !== 'sequencediagram' && !definition.trim().startsWith('sequenceDiagram')) return definition;\n\n console.log('Running sequence diagram participant name fixer');\n\n const lines = definition.split('\\n');\n const fixedLines: string[] = [];\n\n for (const line of lines) {\n let fixedLine = line;\n const trimmedLine = line.trim();\n\n // Fix participant declarations with special characters\n if (trimmedLine.startsWith('participant ')) {\n const participantMatch = trimmedLine.match(/^participant\\s+(.+)$/);\n if (participantMatch) {\n const participantName = participantMatch[1];\n // If participant name contains spaces or special chars, don't quote it\n // Mermaid handles this automatically in most cases\n fixedLine = ` participant ${participantName}`;\n }\n }\n\n fixedLines.push(fixedLine);\n }\n\n return fixedLines.join('\\n');\n },\n {\n name: 'sequence-diagram-participant-fixer',\n priority: 290,\n diagramTypes: ['sequencediagram']\n });\n\n // Add preprocessor for beta diagram types\n registerPreprocessor((def: string, type: string) => {\n // Remove old beta diagram fallbacks - now handled by dynamic type normalization\n return def;\n }, {\n name: 'beta-diagram-fallback',\n priority: 290, // Lower priority than the comprehensive one\n diagramTypes: ['*']\n });\n\n // Add a specific preprocessor to handle the exact parsing errors we're seeing\n registerPreprocessor((def: string, type: string) => {\n // Fix incomplete flowchart connections that cause \"NODE_STRING\" errors\n let processedDef = def;\n\n // Fix patterns like \"F H G I\" (incomplete connections)\n processedDef = processedDef.replace(/(\\w+)\\s+(\\w+)\\s+(\\w+)\\s+(\\w+)\\s*$/gm,\n '$1 --> $2\\n $2 --> $3\\n $3 --> $4');\n\n return processedDef;\n }, {\n name: 'incomplete-connection-fix',\n priority: 90,\n diagramTypes: ['flowchart', 'graph']\n });\n\n registerPreprocessor((def: string, type: string) => {\n // Handle all diagram types that might have parsing issues\n let processedDef = def;\n\n // Fix the specific \"Load User Profil\" truncation error\n processedDef = processedDef.replace(/C\\[\"Load User Profil$/m, 'C[\"Load User Profile\"]');\n processedDef = processedDef.replace(/(\\w+)\\[\"([^\"]*?)$/gm, '$1[\"$2\"]');\n\n // Fix class diagram \">\" dependency syntax\n processedDef = processedDef.replace(/}\\s*>\\s*(\\w+)\\s*{/g, '}\\n $1 --|> ');\n processedDef = processedDef.replace(/(class\\s+\\w+\\s*{\\s*)>\\s*/g, '$1');\n\n // Fix for `OrderStatus --|> PENDING` where PENDING is not a class\n // If Y in X --|> Y is all caps and not defined as a class, comment it out.\n processedDef = processedDef.replace(/^(\\s*)(\\w+)\\s*--\\|>\\s*([A-Z_]+)\\s*$/gm, (match, indent, classX, classY) => {\n if (!processedDef.match(new RegExp(`class\\\\s+${classY}\\\\s*\\\\{`, 'm'))) {\n return `${indent}%% ${match.trim()}`;\n }\n return match;\n });\n\n return processedDef;\n }, {\n name: 'parsing-error-fix',\n priority: 85,\n diagramTypes: ['*']\n });\n\n // Register a preprocessor to handle color values in classDef statements\n registerPreprocessor((def: string, type: string) => {\n // Ensure color values in classDef statements are properly formatted\n return def.replace(/classDef\\s+(\\w+)\\s+([^:]+):([^,]+),([^:]+):([^,\\n]+)/g,\n (match, className, attr1, val1, attr2, val2) => `classDef ${className} ${attr1}:${val1},${attr2}:${val2}`);\n }, {\n name: 'classdef-color-fix',\n priority: 100,\n diagramTypes: ['*']\n });\n\n // Register a preprocessor to fix classDef statements with quotes\n registerPreprocessor((def: string, type: string) => {\n // Fix classDef statements with quoted attributes\n // Change from: classDef primary fill:\"#f94144\",color:\"white\"\n // To: classDef primary fill:#f94144,color:white\n return def.replace(/classDef\\s+(\\w+)\\s+((?:[a-zA-Z]+:\"[^\"]+\",?)+)/g, (match, className, attributes) => {\n // Remove quotes from attribute values\n const fixedAttributes = attributes.replace(/:\"/g, ':').replace(/\"/g, '');\n return `classDef ${className} ${fixedAttributes}`;\n });\n }, {\n name: 'classdef-quotes-fix',\n priority: 110,\n diagramTypes: ['*']\n });\n\n // Register a preprocessor to handle slashes in node labels\n registerPreprocessor((def: string, type: string) => {\n // Handle slashes in node labels by adding quotes\n let finalDef = def;\n\n // Fix nodes with slashes by adding quotes\n finalDef = finalDef.replace(/\\[([^\\]]*\\/[^\\]]*)\\]/g, '[\"$1\"]');\n\n return finalDef;\n }, {\n name: 'node-slash-fix',\n priority: 95,\n diagramTypes: ['*']\n });\n\n registerPreprocessor((def: string, type: string) => {\n // Add explicit shape definitions for states that might be causing issues\n const lines = def.split('\\n');\n const states = new Set<string>();\n\n // First pass: collect all state names\n for (const line of lines) {\n // Skip if not a state diagram type, but allow processing if it looks like one\n if (type && type !== 'stateDiagram' && type !== 'stateDiagram-v2' && !line.match(/^\\s*stateDiagram/i)) {\n continue;\n }\n // Match state definitions and transitions\n const stateMatches = line.match(/\\b(\\w+)\\b\\s*:/g) || [];\n const transitionMatches = line.match(/\\b(\\w+)\\b\\s*-->/g) || [];\n\n stateMatches.forEach(match => {\n const state = match.replace(/\\s*:$/, '').trim();\n states.add(state);\n });\n\n transitionMatches.forEach(match => {\n const state = match.replace(/\\s*-->$/, '').trim();\n states.add(state);\n });\n }\n\n // Second pass: ensure all states have a shape definition\n const result = [...lines];\n const stateDefSection = lines.findIndex(line =>\n line.trim().match(/^stateDiagram(?:-v2)?/i)\n );\n\n if (stateDefSection !== -1) {\n // Add state style definitions after the diagram type declaration\n const stateStyles = Array.from(states)\n .map(state => ` ${state}: ${state}`)\n .join('\\n');\n\n if (stateStyles) {\n result.splice(stateDefSection + 1, 0, stateStyles);\n }\n }\n\n return result.join('\\n');\n }, {\n name: 'state-shape-fix',\n priority: 90,\n diagramTypes: ['statediagram', 'statediagram-v2']\n });\n\n // Generic syntax validator and fixer\n registerPreprocessor((def: string) => {\n // Fix common syntax issues\n let processed = def;\n\n // Ensure proper line breaks between sections\n processed = processed.replace(/(\\w+)(\\s*\\n\\s*[A-Z])/g, '$1\\n$2');\n\n // Fix missing spaces in arrows\n processed = processed.replace(/(\\w+)-->/g, '$1 -->');\n processed = processed.replace(/-->(\\w+)/g, '--> $1');\n\n // Fix missing spaces in notes\n processed = processed.replace(/Note(\\w+):/g, 'Note $1:');\n\n // Specifically handle [DONE] text which causes parsing issues\n processed = processed.replace(/\\[DONE\\]/g, '\"DONE\"');\n\n // Fix issues with square brackets in node text\n processed = processed.replace(/(\\w+)\\[([^\\]]+)\\]/g, (match, nodeName, nodeText) => {\n // Only add quotes if not already quoted\n return nodeText.includes('\"') ? `${nodeName}[${nodeText}]` : `${nodeName}[\"${nodeText}\"]`;\n });\n\n return processed;\n }, {\n name: 'syntax-fixer',\n priority: 50,\n diagramTypes: ['*']\n });\n\n // Register a preprocessor to improve dark mode text visibility by using stroke colors for text\n registerPreprocessor((def: string, type: string) => {\n // Only apply to diagrams that might have classDef or style statements\n if (!def.includes('classDef') && !def.includes('style ')) {\n return def;\n }\n\n let processedDef = def;\n\n // Extract classDef statements and modify them for better dark mode visibility\n // Pattern: classDef className fill:#lightcolor,stroke:#darkcolor,stroke-width:2px\n processedDef = processedDef.replace(\n /classDef\\s+(\\w+)\\s+fill:(#[a-fA-F0-9]{6}),stroke:(#[a-fA-F0-9]{6}),stroke-width:(\\d+px)/g,\n (match, className, fillColor, strokeColor, strokeWidth) => {\n // Add color property using the stroke color for better text visibility\n return `classDef ${className} fill:${fillColor},stroke:${strokeColor},stroke-width:${strokeWidth},color:${strokeColor}`;\n }\n );\n\n // Handle style statements for individual nodes\n // Pattern: style NodeName fill:#color,stroke:#color,stroke-width:3px\n processedDef = processedDef.replace(\n /style\\s+(\\w+)\\s+fill:(#[a-fA-F0-9]{6}),stroke:(#[a-fA-F0-9]{6}),stroke-width:(\\d+px)/g,\n (match, nodeName, fillColor, strokeColor, strokeWidth) => {\n // Add color property using the stroke color, or a high-contrast color if stroke is too light\n const contrastColor = getContrastColor(strokeColor, fillColor);\n return `style ${nodeName} fill:${fillColor},stroke:${strokeColor},stroke-width:${strokeWidth},color:${contrastColor}`;\n }\n );\n\n // Handle cases where stroke color might be too light (like #333 which is common)\n // Replace #333 strokes with darker colors for better text contrast\n processedDef = processedDef.replace(\n /(stroke:#333)/g,\n 'stroke:#000000'\n );\n\n return processedDef;\n }, {\n name: 'dark-mode-text-visibility-fix',\n priority: 105,\n diagramTypes: ['*']\n });\n\n // Default error handler (lowest priority)\n registerErrorHandler((error: Error, context: ErrorContext) => {\n const { container, definition, diagramType } = context;\n\n // This handler should only run if no other handler has dealt with the error\n // and if a container is provided to display the error.\n if (!container) return false;\n\n // Create a fallback visualization\n container.innerHTML = `\n <div class=\"mermaid-error-recovery\" style=\"\n border: 1px solid #f0ad4e;\n border-radius: 4px;\n padding: 15px;\n margin: 10px 0;\n background-color: #fcf8e3;\n \">\n <div style=\"margin-bottom: 10px; color: #8a6d3b;\">\n <strong>Diagram Rendering Error:</strong> ${error.message || 'Unknown error'}\n </div>\n <div style=\"margin-bottom: 15px;\">\n <button id=\"toggle-source-${Date.now()}\" style=\"\n background-color: #f0ad4e;\n color: white;\n border: none;\n padding: 5px 10px;\n border-radius: 3px;\n cursor: pointer;\n \">Show Source</button>\n </div>\n <div id=\"source-container-${Date.now()}\" style=\"display: none;\">\n <pre style=\"\n background-color: #f5f5f5;\n padding: 10px;\n border-radius: 4px;\n overflow: auto;\n max-height: 300px;\n \"><code>${definition.replace(/</g, '<').replace(/>/g, '>')}</code></pre>\n </div>\n </div>\n `;\n\n // Add toggle functionality\n const toggleBtn = container.querySelector(`#toggle-source-${Date.now()}`) as HTMLButtonElement;\n const sourceContainer = container.querySelector(`#source-container-${Date.now()}`) as HTMLDivElement;\n\n if (toggleBtn && sourceContainer) {\n toggleBtn.addEventListener('click', () => {\n const isHidden = sourceContainer.style.display === 'none';\n sourceContainer.style.display = isHidden ? 'block' : 'none';\n toggleBtn.textContent = isHidden ? 'Hide Source' : 'Show Source';\n });\n }\n\n return true;\n }, {\n name: 'fallback-renderer',\n priority: 0, // Lowest priority, runs if nothing else handled it\n errorTypes: ['*']\n });\n\n console.log('Mermaid enhancer initialized with default preprocessors and error handlers');\n}\n\n/**\n * Get a high-contrast color for text based on fill and stroke colors\n * @param strokeColor - The stroke color (hex)\n * @param fillColor - The fill color (hex)\n * @returns - A color that provides good contrast\n */\nfunction getContrastColor(strokeColor: string, fillColor: string): string {\n // Convert hex to RGB for luminance calculation\n const hexToRgb = (hex: string) => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n };\n\n const strokeRgb = hexToRgb(strokeColor);\n if (!strokeRgb) return strokeColor;\n\n // Calculate relative luminance using proper sRGB formula\n const luminance = (0.299 * strokeRgb.r + 0.587 * strokeRgb.g + 0.114 * strokeRgb.b) / 255;\n\n // If stroke color is too light (luminance > 0.5), use a darker version or black\n return luminance > 0.5 ? '#000000' : strokeColor;\n}\n\n/**\n * Get optimal text color based on background color with special handling for problematic colors\n * @param backgroundColor - The background color (hex)\n * @returns - The best contrasting text color\n */\nfunction getOptimalTextColor(backgroundColor: string): string {\n // Convert hex to RGB\n const hexToRgb = (hex: string) => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n };\n\n const rgb = hexToRgb(backgroundColor);\n if (!rgb) return '#000000';\n\n // Special handling for yellow and yellow-ish colors\n // Yellow has high luminance but white text on yellow is terrible\n if (rgb.r > 180 && rgb.g > 180 && rgb.b < 120) {\n return '#000000'; // Always use black on yellow/yellow-ish\n }\n\n // Special handling for beige/cream colors (high R, G, moderate B)\n if (rgb.r > 200 && rgb.g > 180 && rgb.b > 140) {\n return '#000000'; // Always use black on beige/cream\n }\n\n // Special handling for light gray colors\n if (Math.abs(rgb.r - rgb.g) < 30 && Math.abs(rgb.g - rgb.b) < 30 && rgb.r > 180) {\n return '#000000'; // Use black on light grays\n }\n\n // Calculate relative luminance using proper sRGB formula\n const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;\n\n // Use a more conservative threshold - prefer black text unless background is quite dark\n return luminance > 0.35 ? '#000000' : '#ffffff';\n}\n\n/**\n * Enhance the mermaid object with preprocessing and error handling\n * @param mermaid - The mermaid library instance\n */\nexport function enhanceMermaid(mermaid: any): void {\n if (!mermaid) {\n console.error('Mermaid library not provided');\n return;\n }\n\n // Store the original render function\n const originalRender = mermaid.render;\n\n // Replace with enhanced version\n mermaid.render = async function(id: string, definition: string, ...args: any[]): Promise<any> {\n try {\n // Determine diagram type\n let diagramType: string;\n const lines = definition.trim().split('\\n');\n let typeLine = lines[0]?.trim() || '';\n if (typeLine === '---' && lines.length > 1) {\n let inFrontmatterDetect = true;\n let diagramDeclarationLine = '';\n for (let i = 1; i < lines.length; i++) {\n const currentLineTrimmed = lines[i].trim();\n if (inFrontmatterDetect) {\n if (currentLineTrimmed === '---') {\n inFrontmatterDetect = false;\n }\n } else {\n if (currentLineTrimmed) { // First non-empty line after frontmatter\n diagramDeclarationLine = currentLineTrimmed;\n break;\n }\n }\n }\n typeLine = diagramDeclarationLine || lines[0]?.trim() || ''; // Fallback if no declaration found\n }\n diagramType = typeLine.split(' ')[0].toLowerCase(); // Get the first word as type\n \n // Debug logging for type normalization\n console.log('Mermaid preprocessing debug:', {\n originalType: diagramType,\n definition: definition.substring(0, 100) + '...'\n });\n \n // Preprocess the definition with type normalization\n const processedDef = preprocessDefinition(definition, diagramType, mermaid);\n \n console.log('After preprocessing:', {\n originalType: diagramType,\n processedLength: processedDef.length,\n processedStart: processedDef.substring(0, 100) + '...'\n });\n\n // Final validation before sending to Mermaid\n if (!processedDef || processedDef.trim().length === 0) {\n throw new Error('Empty definition after preprocessing');\n }\n\n // Check for obvious syntax issues that would cause parsing errors\n if (processedDef.includes('• ') || processedDef.includes('•')) {\n console.warn('Definition still contains bullet characters after preprocessing');\n }\n\n // Add a unique marker to verify this exact definition is being used\n // Only add marker if definition doesn't end with incomplete syntax\n const markedDef = processedDef.trim() + `\\n%% PROCESSED-${Date.now()}`;\n\n // DEBUG: Log the final processed definition to see what's actually being sent to Mermaid\n console.log('🔍 FINAL-DEF: About to render with processed definition:');\n console.log('🔍 FINAL-DEF: Length:', markedDef.length);\n console.log('🔍 FINAL-DEF: Content:', markedDef);\n\n // CRITICAL: Try to bypass Mermaid's internal preprocessing that might be corrupting definitions\n // Instead of using the high-level render() function, try the lower-level API\n if (mermaid.mermaidAPI && typeof mermaid.mermaidAPI.render === 'function') {\n console.log('🔍 BYPASS: Using mermaidAPI.render directly to avoid internal preprocessing');\n try {\n const directResult = await mermaid.mermaidAPI.render(id, markedDef);\n // mermaidAPI.render returns SVG string directly, not wrapped in an object\n const svg = typeof directResult === 'string' ? directResult : directResult.svg || '';\n console.log('🔍 BYPASS: Direct API render successful, SVG length:', svg.length);\n return {\n svg: svg,\n bindFunctions: () => { }\n };\n } catch (directError) {\n console.log('🔍 BYPASS: Direct API render failed, falling back to original method:', directError instanceof Error ? directError.message : String(directError));\n }\n }\n\n console.log('🔍 FALLBACK: Using original render method');\n // Call the original render with processed definition\n const result = await originalRender.call(this, id, markedDef, ...args);\n\n console.log('🔍 RENDER-RESULT: Mermaid render completed, result type:', typeof result);\n\n // Handle case where result doesn't have svg property\n if (!result || typeof result !== 'object' || !result.svg) {\n console.warn('Mermaid render returned unexpected result:', result);\n return { svg: '', bindFunctions: () => { } };\n }\n\n return result;\n } catch (error: any) {\n console.error('Mermaid rendering error:', error);\n\n // Try to handle the error\n const container = document.getElementById(id);\n const context: ErrorContext = {\n container: container || undefined,\n definition,\n diagramType: definition.trim().split('\\n')[0].trim(),\n error\n };\n\n const handled = handleRenderError(error, context);\n\n if (!handled) {\n // If not handled by any handler, rethrow\n throw error;\n }\n\n // Return a minimal valid result to prevent destructuring errors\n return { svg: '', bindFunctions: () => { } };\n }\n };\n}\n\nexport default function initMermaidSupport(mermaidInstance?: any): void {\n initMermaidEnhancer();\n\n if (mermaidInstance) {\n enhanceMermaid(mermaidInstance);\n } else if (typeof window !== 'undefined') {\n // Wait for mermaid to be available on window\n const checkInterval = setInterval(() => {\n if (window.mermaid) {\n enhanceMermaid(window.mermaid);\n clearInterval(checkInterval);\n }\n }, 100);\n\n // Stop checking after 10 seconds\n setTimeout(() => {\n clearInterval(checkInterval);\n }, 10000);\n }\n\n // Add a preprocessor for class diagram relationship syntax issues\n // CONSOLIDATED: Remove duplicate class diagram relationship fixes and create one comprehensive one\n registerPreprocessor((def: string, type: string) => {\n if (!def.trim().startsWith('classDiagram')) {\n return def;\n }\n\n console.log('🔍 CLASS-CONSOLIDATED-FIX: Processing all class diagram relationship issues');\n\n let result = def;\n\n // Fix 1: Invalid cardinality syntax that causes lexical errors\n result = result.replace(/(\\w+)\\s+\\|\\|--o\\{\\s+(\\w+)\\s*:\\s*(.+)/g, '$1 --> $2 : $3');\n result = result.replace(/(\\w+)\\s+\\}\\|--\\|\\{\\s+(\\w+)\\s*:\\s*(.+)/g, '$1 --> $2 : $3');\n\n // Fix 2: All invalid double-pipe patterns \n const invalidPatterns = [\n { pattern: /\\|\\|--\\|\\|/g, replacement: '-->' },\n { pattern: /\\|\\|\\s*--\\s*\\|\\|/g, replacement: '-->' },\n { pattern: /\\|\\|-->/g, replacement: '-->' },\n { pattern: /--\\|\\|/g, replacement: '-->' },\n { pattern: /<\\|\\|--\\|\\|>/g, replacement: '<-->' },\n { pattern: /\\|\\|==\\|\\|/g, replacement: '-->' },\n { pattern: /\\|\\|\\.\\.>\\|\\|/g, replacement: '..>' },\n { pattern: /\\|\\|<\\.\\.\\|\\|/g, replacement: '<..' },\n ];\n\n invalidPatterns.forEach(({ pattern, replacement }) => {\n const beforeCount = (result.match(pattern) || []).length;\n if (beforeCount > 0) {\n result = result.replace(pattern, replacement);\n console.log(`🔍 CLASS-CONSOLIDATED-FIX: Fixed ${beforeCount} instances of ${pattern.source}`);\n }\n });\n\n // Fix 3: Remove incomplete relationship lines\n result = result.replace(/(\\w+)\\s+(-->|<--|<\\|--|-->\\||<\\|--\\|>)\\s*$/gm, '');\n result = result.replace(/^\\s*(-->|<--|<\\|--|-->\\||<\\|--\\|>)\\s*$/gm, '');\n\n console.log('🔍 CLASS-CONSOLIDATED-FIX: Processing complete');\n return result;\n }, {\n name: 'class-consolidated-relationship-fix',\n priority: 520, // Highest priority\n diagramTypes: ['classdiagram']\n });\n\n // Remove the old duplicate preprocessors by commenting them out\n /*\n registerPreprocessor(\n (definition: string, diagramType: string) => {\n if (diagramType.toLowerCase() !== 'classdiagram' && !definition.trim().startsWith('classDiagram')) {\n return definition;\n }\n\n console.log('🔍 CLASS-DIAGRAM-CLEANUP: Fixing malformed relationships');\n\n let result = definition;\n\n // Fix incomplete relationship lines that end abruptly\n // Pattern: \"SomeClass --> \" followed by newline or end of string\n result = result.replace(/(\\w+)\\s+(-->|<--|<\\|--|-->\\||<\\|--\\|>)\\s*$/gm, '');\n\n // Remove lines that have only arrows without proper class references\n result = result.replace(/^\\s*(-->|<--|<\\|--|-->\\||<\\|--\\|>)\\s*$/gm, '');\n\n console.log('🔍 CLASS-DIAGRAM-CLEANUP: Processing complete');\n return result;\n }, {\n name: 'class-diagram-cleanup',\n priority: 400, // High priority to clean up before other class diagram fixes\n diagramTypes: ['classDiagram']\n }); \n */\n\n // Remove duplicate - this is the same as above\n /*\n registerPreprocessor(\n (definition: string, diagramType: string) => {\n if (diagramType.toLowerCase() !== 'classdiagram' && !definition.trim().startsWith('classDiagram')) {\n return definition;\n }\n\n console.log('🔍 CLASS-RELATIONSHIP-FIX: Starting class diagram relationship syntax fixes');\n\n let result = definition;\n\n // Log before changes for debugging\n const beforeCount = (result.match(/\\|\\|--\\|\\|/g) || []).length;\n console.log(`🔍 CLASS-RELATIONSHIP-FIX: Found ${beforeCount} instances of ||--||`);\n\n // CRITICAL FIX: Replace all invalid double-pipe relationships\n // Use global replacement with explicit escaping\n result = result.replace(/\\|\\|--\\|\\|/g, '-->');\n\n // Also handle variations with spaces\n result = result.replace(/\\|\\|\\s*--\\s*\\|\\|/g, '-->');\n\n // Fix other invalid relationship patterns\n result = result.replace(/\\|\\|-->/g, '-->'); // Invalid to association \n result = result.replace(/--\\|\\|/g, '-->'); // Invalid to association\n result = result.replace(/<\\|\\|--\\|\\|>/g, '<-->'); // Invalid bidirectional\n result = result.replace(/\\|\\|==\\|\\|/g, '-->'); // Convert to simple association\n result = result.replace(/\\|\\|\\.\\.>\\|\\|/g, '..>'); // Invalid to dependency\n result = result.replace(/\\|\\|<\\.\\.\\|\\|/g, '<..'); // Invalid to dependency\n\n // Log after changes for debugging\n const afterCount = (result.match(/\\|\\|--\\|\\|/g) || []).length;\n console.log(`🔍 CLASS-RELATIONSHIP-FIX: After replacement: ${afterCount} instances remaining`);\n\n // Additional safety check - if replacements didn't work, try a different approach\n if (afterCount > 0) {\n console.log('🔍 CLASS-RELATIONSHIP-FIX: Standard replacement failed, trying line-by-line approach');\n const lines = result.split('\\n');\n result = lines.map(line => {\n if (line.includes('||--||')) {\n console.log('🔍 CLASS-RELATIONSHIP-FIX: Fixing line:', line);\n return line.replace(/\\|\\|--\\|\\|/g, '-->');\n }\n return line;\n }).join('\\n');\n }\n\n // Fix other invalid relationship patterns that cause parsing errors\n console.log('🔍 CLASS-RELATIONSHIP-FIX: Processing complete');\n\n // Ensure relationships are on separate lines\n const lines = result.split('\\n');\n const processedLines = lines.map(line => {\n const trimmed = line.trim();\n // If line contains relationship syntax, ensure proper spacing\n if (trimmed.match(/\\w+\\s*(--|\\.\\.>|<\\.\\.|-->|<--|==|<==|\\|>|<\\|)\\s*\\w+/)) {\n return ` ${trimmed}`;\n }\n return line;\n });\n\n result = processedLines.join('\\n');\n console.log('🔍 CLASS-RELATIONSHIP-FIX: Processing complete');\n return result;\n }, {\n name: 'class-relationship-syntax-fix-1',\n priority: 450, // Higher priority to run before other class diagram fixes\n diagramTypes: ['classdiagram']\n });\n */\n\n registerPreprocessor(\n (definition: string, diagramType: string) => {\n if (diagramType.toLowerCase() !== 'classdiagram' && !definition.trim().startsWith('classDiagram')) {\n return definition;\n }\n\n console.log('🔍 CLASS-RELATIONSHIP-FIX: Running class diagram relationship fixer (priority 85)');\n\n let result = definition;\n\n // CRITICAL FIX: Replace invalid ||--|| syntax FIRST\n result = result.replace(/\\|\\|--\\|\\|/g, '-->');\n result = result.replace(/\\|\\|\\s*--\\s*\\|\\|/g, '-->');\n\n // Fix other invalid relationship patterns\n result = result.replace(/\\|\\|-->/g, '-->');\n result = result.replace(/--\\|\\|/g, '-->');\n result = result.replace(/<\\|\\|--\\|\\|>/g, '<-->');\n\n console.log('🔍 CLASS-RELATIONSHIP-FIX: Processing complete');\n return result;\n }, {\n name: 'class-relationship-syntax-fix-2', // Rename duplicate\n priority: 440, // Slightly lower priority to avoid duplicate\n diagramTypes: ['classdiagram']\n });\n\n registerPreprocessor(\n (definition: string, diagramType: string) => {\n if (diagramType.toLowerCase() !== 'classdiagram' && !definition.trim().startsWith('classDiagram')) {\n return definition;\n }\n\n console.log('🔍 CLASS-RELATIONSHIP-FIX: Running class diagram relationship fixer (priority 85)');\n\n // CRITICAL FIX: Replace invalid ||--|| syntax FIRST\n let result = definition;\n\n // Log before changes for debugging\n const beforeCount = (result.match(/\\|\\|--\\|\\|/g) || []).length;\n console.log(`🔍 CLASS-RELATIONSHIP-FIX: Found ${beforeCount} instances of ||--||`);\n\n // Replace all invalid double-pipe relationships\n result = result.replace(/\\|\\|--\\|\\|/g, '-->');\n result = result.replace(/\\|\\|\\s*--\\s*\\|\\|/g, '-->');\n\n // Log after changes\n const afterCount = (result.match(/\\|\\|--\\|\\|/g) || []).length;\n console.log(`🔍 CLASS-RELATIONSHIP-FIX: After replacement: ${afterCount} instances remaining`);\n\n const lines = result.split('\\n'); // Use the fixed result\n const fixedLines: string[] = [];\n let inClassDefinition = false;\n\n for (const line of lines) {\n let fixedLine = line;\n const trimmedLine = line.trim();\n\n // Check if we're entering or exiting a class definition block\n if (trimmedLine.match(/class\\s+\\w+\\s*{/)) {\n inClassDefinition = true;\n } else if (inClassDefinition && trimmedLine === '}') {\n inClassDefinition = false;\n }\n\n // Only process relationship lines outside of class definitions\n if (!inClassDefinition) {\n // Fix incorrect relationship syntax (e.g., \"User > OrderStatus\" should be \"User --> OrderStatus\")\n const incorrectRelationMatch = trimmedLine.match(/^(\\w+)\\s+([<>])\\s+(\\w+)$/);\n if (incorrectRelationMatch) {\n const [, class1, relation, class2] = incorrectRelationMatch;\n const fixedRelation = relation === '>' ? '-->' : '<--';\n fixedLine = `${class1} ${fixedRelation} ${class2}`;\n console.log(`Fixed relationship syntax: \"${trimmedLine}\" -> \"${fixedLine}\"`);\n }\n\n // Fix missing relationship type (e.g., \"User -- Order\" should be \"User --> Order\")\n const missingArrowMatch = trimmedLine.match(/^(\\w+)\\s+--\\s+(\\w+)$/);\n if (missingArrowMatch) {\n const [, class1, class2] = missingArrowMatch;\n fixedLine = `${class1} --> ${class2}`;\n console.log(`Fixed missing arrow: \"${trimmedLine}\" -> \"${fixedLine}\"`);\n }\n }\n\n fixedLines.push(fixedLine);\n }\n\n return result; // Return the preprocessed result with ||--|| fixed\n },\n {\n name: 'class-diagram-legacy-relationship-fixer',\n priority: 85,\n diagramTypes: ['classdiagram']\n }\n );\n // Add a simple preprocessor for sequence diagram activation/deactivation issues\n registerPreprocessor((definition: string, diagramType: string) => {\n if (diagramType.toLowerCase() !== 'sequencediagram' && !definition.trim().startsWith('sequenceDiagram')) {\n return definition;\n }\n\n // This is a targeted fix for participant names that are also Mermaid keywords (e.g., 'opt', 'loop').\n // It finds message lines where a keyword is used as a participant and quotes it.\n const keywords = ['opt', 'alt', 'loop', 'par', 'and', 'else', 'end'];\n let processedDef = definition;\n\n keywords.forEach(keyword => {\n // Regex for keyword as target: e.g., A->>opt: message\n const targetRegex = new RegExp(`(->>|-->>|->>\\\\+|-->>\\\\+|->>-|-->>-)(\\\\s*)${keyword}\\\\b`, 'gi');\n processedDef = processedDef.replace(targetRegex, (match, arrow, space) => `${arrow}${space}\"${keyword}\"`);\n\n // Regex for keyword as source: e.g., opt->>A: message\n const sourceRegex = new RegExp(`^(\\\\s*)${keyword}\\\\b(\\\\s*)(->>|-->>|->>\\\\+|-->>\\\\+|->>-|-->>-)`, 'gim');\n processedDef = processedDef.replace(sourceRegex, (match, pre, post, arrow) => `${pre}\"${keyword}\"${post}${arrow}`);\n });\n\n return processedDef;\n }, {\n name: 'sequence-diagram-keyword-participant-fix',\n priority: 285,\n diagramTypes: ['sequencediagram']\n });\n}\n"],"names":["isNetworkDiagramSpec","spec","type","Array","isArray","nodes","links","length","every","n","id","l","source","target","networkDiagramPlugin","name","priority","sizingConfig","sizingStrategy","needsDynamicHeight","needsOverflowVisible","observeResize","containerStyles","height","overflow","canHandle","render","container","d3","_spec$groups","console","debug","Error","nodeCount","linkCount","groupCount","groups","_spec$groups2","svg","select","selectAll","remove","append","attr","width","boards","data","enter","d","text","label","error","defaultMargin","top","right","bottom","left","basicChartPlugin","margin","concat","x","scaleBand","range","domain","map","padding","y","scaleLinear","max","value","call","axisBottom","axisLeft","join","bandwidth","color","line","datum","size","extractDefinitionFromYAML","definition","diagramType","typePattern","includes","log","lines","split","inDefinition","contentLines","trim","startsWith","cleanedLine","replace","push","extractedContent","substring","isDiagramDefinitionComplete","actualDefinition","toLowerCase","firstLine","endsWith","isMermaidDefinitionComplete","openBraces","closeBraces","isGraphvizDefinitionComplete","parsed","JSON","parse","hasData","undefined","hasVisualization","mark","layer","facet","repeat","isVegaLiteDefinitionComplete","SCALE_CONFIG","renderQueue","constructor","queue","isProcessing","enqueue","renderFn","Promise","resolve","reject","this","async","result","processQueue","shift","initMermaidSupport","mermaid","window","mermaidPlugin","isMermaidSpec","isDefinitionComplete","isDarkMode","renderSuccessful","innerHTML","loadingSpinner","document","createElement","className","style","cssText","appendChild","isStreaming","isMarkdownBlockClosed","forceRender","e","warn","rawDefinition","containerId","mermaidId","Date","now","Math","random","toString","initialize","startOnLoad","theme","securityLevel","fontFamily","fontSize","themeVariables","primaryColor","primaryTextColor","primaryBorderColor","lineColor","secondaryColor","tertiaryColor","textColor","loopTextColor","mainBkg","secondBkg","nodeBorder","edgeLabelBackground","altBackground","nodeBkg","clusterBkg","titleColor","classText","labelColor","actorBkg","actorBorder","activationBkg","sectionBkgColor","altSectionBkgColor","gridColor","todayLineColor","flowchart","htmlLabels","curve","nodeSpacing","rankSpacing","diagramPadding","sequence","diagramMarginX","diagramMarginY","actorMargin","boxMargin","boxTextMargin","noteMargin","messageMargin","mirrorActors","bottomMarginAdj","useMaxWidth","gantt","titleTopMargin","barHeight","barGap","topPadding","leftPadding","gridLineStartPadding","sectionFontSize","numberSectionStyles","axisFormat","topAxis","renderError","String","message","stack","querySelector","keyframes","textContent","head","wrapper","parentNode","removeChild","svgElement","applyCustomStyles","querySelectorAll","forEach","styleEl","match","rule","classMatch","styleMatch","styles","el","prop","s","setProperty","enhanceDarkModeTextVisibility","textEl","parentElement","classList","contains","shapeElement","stroke","getAttribute","fill","setAttribute","contrastColor","backgroundColor","rgb","hex","exec","r","parseInt","g","b","hexToRgb","getTextContrastColor","currentFill","_textEl$closest","parentRect","closest","bgColor","optimalColor","getOptimalTextColor","requestAnimationFrame","getColorLuminance","val","pow","calculateContrastRatio","textLum","bgLum","min","setTimeout","foreignObjects","fixCount","totalTextElements","elementsWithBackground","foreignObj","foreignIndex","textElements","_textEl$textContent","content","getComputedStyle","currentElement","depth","tagName","parentGroup","shapeElements","shape","computedFill","allShapes","allColors","Set","i","add","from","isProblematic","normalizedColor","rgbMatch","padStart","toUpperCase","isProblematicBackground","contrastRatio","toFixed","computedStyle","currentFontSize","parseFloat","scale","finalScale","transform","transformOrigin","svgStyleAttr","newStyleAttr","actionsContainer","openButton","onclick","svgGraphics","bbox","getBBox","svgData","XMLSerializer","serializeToString","htmlContent","blob","Blob","url","URL","createObjectURL","popupWindow","open","focus","revokeObjectURL","saveButton","svgDoc","link","href","download","body","click","showingSource","originalContent","sourceButton","insertBefore","_lines$","spinner","errorTitle","errorMessage","errorMsg","detectSupportedDiagramTypes","normalizeDiagramType","supportedTypes","normalizedType","supportedTypesSize","hasOriginal","has","hasNormalized","detectionError","viewSourceButton","retryButton","buttonContainer","textAlign","backButton","renderSingleDiagram","containerThemes","WeakMap","graphvizPlugin","hasExistingContent","set","themeColors","light","nodeFill","edgeColor","background","labelText","clusterBg","clusterBorder","dark","nodeColors","colors","vizInstance","Viz","processedDefinition","escapedForHtml","themedDot","defaultTextColor","labelMatch","originalLabel","element","renderSVGElement","elements","getElementsByTagName","nodeIndex","nodeBackgroundColors","Map","clusterBackgroundColors","originalFill","isLightColor","darkColor","getDarkVersionOfColor","getBrightness","colorIndex","parent","nodeShape","isLightBackground","themeButton","some","c","colorMap","floor","isVegaLiteObject","obj","$schema","encoding","vconcat","hconcat","sanitizeSpec","filter","v","newObj","key","Object","prototype","hasOwnProperty","trimmed","vegaLitePlugin","_unused","isVegaLiteSpec","existingView","_vegaView","finalize","embed","shouldWaitForComplete","isCompleteVegaLiteObject","datasets","stringify","isComplete","definitionLength","definitionPreview","waitingContainer","forceSpec","_objectSpread","sourceDefinition","forceRenderBtn","expandBtn","pre","isExpanded","maxHeight","vegaSpec","preprocessVegaSpec","rawSpec","_spec$encoding","_spec$data3","_spec$data","_shapeEnc$scale","_shapeEnc$scale$range","_spec$data2","shapeEnc","shouldRemoveShape","values","fieldValues","field","availableFields","keys","channel","channelSpec","_spec$encoding2","_spec$encoding2$chann","_spec$encoding2$chann2","cleanDomain","parseError","_vegaSpec$encoding","_vegaSpec$encoding$x","_vegaSpec$data","_vegaSpec$encoding2","_vegaSpec$data3","_vegaSpec$encoding4","_vegaSpec$encoding4$x","_vegaSpec$encoding4$x2","_vegaSpec$encoding5","_vegaSpec$encoding6","_vegaSpec$data4","_vegaSpec$data$values","_vegaSpec$data$values2","_vegaSpec$encoding7","_vegaSpec$data5","_vegaSpec$data$values3","_vegaSpec$data$values4","_vegaSpec$data6","_vegaSpec$data7","_vegaSpec$encoding8","_vegaSpec$encoding9","_vegaSpec$data8","_vegaSpec$encoding10","_vegaSpec$encoding11","_vegaSpec$transform","_vegaSpec$encoding12","_vegaSpec$encoding13","_vegaSpec$encoding14","_vegaSpec$transform2","_vegaSpec$encoding15","slice","_vegaSpec$data2","shapeEncoding","_shapeEncoding$scale","validShapes","_vegaSpec$encoding3","_vegaSpec$encoding3$c","_vegaSpec$encoding3$c2","cleanedValues","row","axis","labelLimit","specStringForColorFix","containerRect","getBoundingClientRect","availableWidth","availableHeight","autosize","_layer$encoding","_layer$encoding2","labelAngle","labelFontSize","theta","radius","innerRadius","outerRadius","tooltip","title","t","density","_vegaSpec$transform$f","_vegaSpec$transform$f2","_vegaSpec$encoding$y","groupField","find","groupby","column","opacity","removeInvalidSignals","cleaned","entries","_vegaSpec$encoding$x2","_vegaSpec$encoding$y2","params","p","bind","input","aggregate","lat","lon","calculate","stop","expr","sequenceIndex","findIndex","sequenceTransform","flatten","as","splice","index","newCalculate","arrayStr","items","item","conditions","idx","strokeDash","hasWindowTransform","hasCalculateUsingSkillIndex","windowTransforms","otherTransforms","fold","format","bin","scheme","xOffset","_layer$encoding3","_layer$encoding3$colo","theta2","firstRow","fields","categoricalField","f","quantitativeField","charAt","numericFields","dateField","numericField","_vegaSpec$data9","_vegaSpec$data9$value","categoricalFields","detail","w","op","y2","_vegaSpec$transform3","_vegaSpec$transform3$","flowField","yField","_vegaSpec$data10","selectionParams","param","modifiedSpec","otherProps","_objectWithoutProperties","_excluded","correctedSpec","facetConfig","_excluded2","correctedEncoding","optimizeLegendLayout","_spec$data4","chartHeight","maxLegendHeight","maxItemsPerColumn","applyLegendWrapping","fieldName","uniqueCount","countUniqueValues","uniqueValues","neededColumns","ceil","columns","legend","symbolLimit","titleLimit","orient","offset","rowPadding","columnPadding","mainData","layerIndex","_layer$data","layerData","embedOptions","actions","renderer","scaleFactor","config","view","continuousWidth","continuousHeight","minHeight","renderContainer","maxWidth","boxSizing","sanitizedSpec","finalSpec","_finalSpec$data","_finalSpec$data2","dataFields","validationError","vegaEmbed","vegaEmbedDiv","vegaHeight","offsetHeight","offsetWidth","parentEl","setupVegaLiteResizing","vegaSvg","targetElement","ResizeObserver","entry","actualHeight","contentRect","actualWidth","currentHeight","observe","mutationObserver","MutationObserver","mutations","mutation","addedNodes","node","nodeType","Node","ELEMENT_NODE","childList","subtree","disconnect","vegaRect","vegaContainer","position","alert","originalVegaContainer","display","sourceView","firstChild","addEventListener","embedDiv","svgRect","scaleX","scaleY","svgEl","embedContainer","removeAttribute","hasExplicitWidth","hasExplicitHeight","svgWidth","containerWidth","debugVegaLite","getSVGActualSize","rect","viewBox","vbX","vbY","vbWidth","vbHeight","Number","viewBoxWidth","viewBoxHeight","scaleRatio","inspect","svgBottom","containerBottom","isOverflowing","overflowAmount","level","computedHeight","svgHeight","aspectRatio","neededHeight","forceContainerResize","isStreamingError","isIncompleteDefinition","_suppressedErrorConta","_suppressedErrorConta2","suppressedErrorContainer","forceRetryId","debugSourceId","forceRetryButton","getElementById","debugSourceButton","showVegaLiteDebugView","kde","hasTransform","hasMark","transformTypes","forceButton","showVegaLiteErrorView","errorDiv","errorRect","debugDiv","debugRect","pluginRegistry","plugin","d3RenderPlugins","freeze","ContainerSizingManager","resizeObservers","cleanupFunctions","applySizingConfig","assign","minWidth","updateParentOverflow","setupResizeObserver","observer","adjustParentContainers","contentElement","cleanup","clear","addCleanupFunction","findPlugin","visualizationType","exactMatch","matchingPlugins","sort","a","D3Renderer","_ref","onLoad","onError","useTheme","vegaContainerRef","useRef","d3ContainerRef","vegaViewRef","isLoading","setIsLoading","useState","setRenderError","displayWaitingMessage","setDisplayWaitingMessage","hasAttemptedRender","setHasAttemptedRender","errorDetails","setErrorDetails","cleanupRef","simulationRef","isSourceModalVisible","setIsSourceModalVisible","renderIdRef","mounted","lastSpecRef","streamingContentRef","lastUsedPluginRef","lastValidSpecRef","renderingStarted","setRenderingStarted","initialThemeRef","hasSuccessfulRenderRef","cleanupFunctionsRef","reservedSize","setReservedSize","sizingManagerRef","useEffect","current","estimated","defaults","avgCharsPerLine","estimateDiagramSize","on","initializeVisualization","useCallback","arguments","specLines","attemptRender","localShouldShowWaitingPlaceholder","cleanSpec","specType","_sizingManagerRef$cur","tempContainer","sanitizedParsed","pluginCleanup","currentRender","isD3Render","useMemo","currentPlugin","_plugin$sizingConfig","baseStyles","outerContainerStyle","_jsxs","children","_jsx","_Fragment","border","borderRadius","ref","flexDirection","alignItems","justifyContent","Spin","marginTop","whiteSpace","wordWrap","overflowY","lineHeight","Modal","onCancel","footer","preprocessors","errorHandlers","supportedDiagramTypes","mermaidInstance","testCases","def","testCase","stableType","betaType","registerPreprocessor","fn","options","processor","process","diagramTypes","preprocessDefinition","processedDef","initMermaidEnhancer","nodeId","openBracket","closeBracket","processedContent","parts","output","inRequirementBlock","cleanValue","shouldQuote","prefix","cleanId","criticalPart","rest","removedStyles","quotedName","subgraphNames","quotedSubgraphMatches","matchAll","identifierSubgraphMatches","nodeIds","nodeMatches","subgraphName","newNodeId","nodeDefRegex","RegExp","nodeRefRegex","fixedContent","arrowMatches","totalLinks","linkStyleMatch","linkNumbers","validLinks","newLinkStyle","idsToQuote","newDef","escapedId","findIdRegex","arrow","processedLabel","newLabel","finalResult","original","cleanedLabel","diagramTypeLine","indent","targetId","targetLabel","linkLabel","fixedLines","currentLine","nodeDefMatch","leadingSpace","openBracketOrParen","openingQuote","nodeContent","closingQuote","closeBracketOrParen","trailingCharacters","mainPart","contentPart","finalLine","originalTrailingSyntax","inFrontmatter","diagramTypeLineProcessed","finalDef","spacing","indexOf","actualNodeId","cleanContent","close","test","escapedContent","before","quoted","after","titleIndex","insertIndex","taskCounter","colonIndex","taskName","taskDefParts","isNaN","startNum","endNum","duration","trimmedLine","pattern","replacement","beforeCount","_ref2","inAltBlock","inCriticalBlock","inParBlock","blockDepth","hasElseInCurrentBlock","hasBreakInCurrentBlock","_line$match","indentation","_line$match2","_line$match3","_line$match5","_line$match4","inSection","noteMatch","noteDeclaration","firstLineContent","noteContent","j","nextTrimmed","inNote","processedLine","fixedLine","participantMatch","participantName","classX","classY","attr1","val1","attr2","val2","attributes","fixedAttributes","states","stateMatches","transitionMatches","state","stateDefSection","stateStyles","processed","nodeName","nodeText","fillColor","strokeColor","strokeWidth","strokeRgb","getContrastColor","handler","handle","errorTypes","registerErrorHandler","context","toggleBtn","sourceContainer","isHidden","enhanceMermaid","originalRender","typeLine","_lines$2","inFrontmatterDetect","diagramDeclarationLine","currentLineTrimmed","originalType","processedLength","processedStart","markedDef","mermaidAPI","directResult","bindFunctions","directError","_len","args","_key","handled","errorType","handlerError","handleRenderError","checkInterval","setInterval","clearInterval","_ref3","afterCount","inClassDefinition","incorrectRelationMatch","class1","relation","class2","fixedRelation","missingArrowMatch","keyword","targetRegex","space","sourceRegex","post"],"sourceRoot":""}
|