velo-plot 2.20.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -8
- package/dist/{ChartCore-ivzLqxVb.js → ChartCore-BpzRvN4Y.js} +978 -861
- package/dist/ChartCore-BpzRvN4Y.js.map +1 -0
- package/dist/a11y-Bw6urYpr.js +105 -0
- package/dist/a11y-Bw6urYpr.js.map +1 -0
- package/dist/angular/hooks-entry.d.ts +1 -0
- package/dist/angular/hooks.d.ts +26 -0
- package/dist/angular/index.d.ts +8 -0
- package/dist/angular/velo-plot.component.d.ts +46 -0
- package/dist/angular-hooks.d.ts +1 -0
- package/dist/angular-hooks.js +9 -0
- package/dist/angular-hooks.js.map +1 -0
- package/dist/angular.d.ts +1 -0
- package/dist/angular.js +166 -0
- package/dist/angular.js.map +1 -0
- package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -1
- package/dist/astro/StackedPlot.astro +19 -0
- package/dist/astro/VeloPlot.astro +23 -0
- package/dist/bindings/shared/a11y.d.ts +26 -0
- package/dist/bindings/shared/chartLifecycle.d.ts +16 -0
- package/dist/bindings/shared/chartSyncBridge.d.ts +8 -0
- package/dist/bindings/shared/dimensions.d.ts +1 -0
- package/dist/bindings/shared/index.d.ts +9 -0
- package/dist/bindings/shared/indicatorBridge.d.ts +11 -0
- package/dist/bindings/shared/optionsSync.d.ts +7 -0
- package/dist/bindings/shared/seriesDiff.d.ts +8 -0
- package/dist/bindings/shared/stackedSync.d.ts +9 -0
- package/dist/bindings/shared/types.d.ts +46 -0
- package/dist/bindings/test-utils/index.d.ts +35 -0
- package/dist/bindings/test-utils/mockLifecycle.d.ts +120 -0
- package/dist/bindings/test-utils/vitestSveltePlugin.d.ts +3 -0
- package/dist/chartSyncBridge-DbWrwtyP.js +57 -0
- package/dist/chartSyncBridge-DbWrwtyP.js.map +1 -0
- package/dist/core/Chart.d.ts +1 -1
- package/dist/core/InteractionManager.d.ts +7 -1
- package/dist/core/OverlayRenderer.d.ts +5 -0
- package/dist/core/annotations/types.d.ts +1 -1
- package/dist/core/chart/ChartCore.d.ts +2 -2
- package/dist/core/chart/types.d.ts +1 -1
- package/dist/core/clipboard/index.d.ts +1 -1
- package/dist/core/debug/index.d.ts +1 -1
- package/dist/core/keybindings/index.d.ts +1 -1
- package/dist/core/loading/index.d.ts +1 -1
- package/dist/core/locale/index.d.ts +1 -1
- package/dist/core/stacked/paneResize.d.ts +3 -0
- package/dist/core/stacked/types.d.ts +10 -0
- package/dist/core/theme-editor/index.d.ts +1 -1
- package/dist/createStackedChart-Dm-YqUT7.js +756 -0
- package/dist/createStackedChart-Dm-YqUT7.js.map +1 -0
- package/dist/examples/PluginDemonstration.d.ts +1 -1
- package/dist/gpuRenderer-BpaMYz-k.js.map +1 -1
- package/dist/hooks-CYPCxoZx.js +69 -0
- package/dist/hooks-CYPCxoZx.js.map +1 -0
- package/dist/{index-BBpJwOct.js → index-0InEyj0q.js} +119 -121
- package/dist/index-0InEyj0q.js.map +1 -0
- package/dist/index-BMiZoKmm.js.map +1 -1
- package/dist/{index-DoYxf1cV.js → index-CWxIHdwX.js} +38 -98
- package/dist/index-CWxIHdwX.js.map +1 -0
- package/dist/index-CaXWSOTk.js.map +1 -1
- package/dist/index-Dag88bW4.js.map +1 -1
- package/dist/index-qhscKTDy.js.map +1 -1
- package/dist/index-qunX30Xu.js.map +1 -1
- package/dist/index-x4stH3jD.js.map +1 -1
- package/dist/{index.core-COREBDNq.js → index.core-BmZe2jRQ.js} +9 -9
- package/dist/index.core-BmZe2jRQ.js.map +1 -0
- package/dist/index.core.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/indicators--eJGmVox.js.map +1 -1
- package/dist/{mockDatafeed-927foCM4.js → mockDatafeed-DHIDPcpX.js} +150 -146
- package/dist/mockDatafeed-DHIDPcpX.js.map +1 -0
- package/dist/optionsSync-QUiN4Inw.js +119 -0
- package/dist/optionsSync-QUiN4Inw.js.map +1 -0
- package/dist/plugins/3d/index.d.ts +2 -2
- package/dist/plugins/3d.d.ts +2 -2
- package/dist/plugins/3d.js.map +1 -1
- package/dist/plugins/analysis/index.d.ts +1 -1
- package/dist/plugins/analysis/indicators.d.ts +1 -1
- package/dist/plugins/analysis.d.ts +2 -2
- package/dist/plugins/analysis.js +2 -2
- package/dist/plugins/analysis.js.map +1 -1
- package/dist/plugins/annotations/index.d.ts +1 -1
- package/dist/plugins/annotations.d.ts +2 -2
- package/dist/plugins/annotations.js.map +1 -1
- package/dist/plugins/anomaly-detection.js +1 -1
- package/dist/plugins/anomaly-detection.js.map +1 -1
- package/dist/plugins/broken-axis.d.ts +2 -2
- package/dist/plugins/builtins/crosshair/CrosshairPlugin.d.ts +1 -1
- package/dist/plugins/builtins/index.d.ts +1 -1
- package/dist/plugins/caching.d.ts +2 -2
- package/dist/plugins/clipboard/index.d.ts +2 -2
- package/dist/plugins/clipboard.d.ts +2 -2
- package/dist/plugins/clipboard.js.map +1 -1
- package/dist/plugins/context-menu/index.d.ts +1 -1
- package/dist/plugins/context-menu.d.ts +2 -2
- package/dist/plugins/context-menu.js +1 -1
- package/dist/plugins/context-menu.js.map +1 -1
- package/dist/plugins/data-export/index.d.ts +1 -1
- package/dist/plugins/data-export.d.ts +2 -2
- package/dist/plugins/data-export.js +2 -2
- package/dist/plugins/data-export.js.map +1 -1
- package/dist/plugins/data-transform.d.ts +2 -2
- package/dist/plugins/data-transform.js +19 -19
- package/dist/plugins/data-transform.js.map +1 -1
- package/dist/plugins/debug/index.d.ts +2 -2
- package/dist/plugins/debug.d.ts +2 -2
- package/dist/plugins/debug.js +2 -2
- package/dist/plugins/debug.js.map +1 -1
- package/dist/plugins/forecasting/index.d.ts +1 -1
- package/dist/plugins/forecasting.js.map +1 -1
- package/dist/plugins/gpu/index.d.ts +2 -2
- package/dist/plugins/gpu.d.ts +2 -2
- package/dist/plugins/gpu.js.map +1 -1
- package/dist/plugins/i18n/index.d.ts +2 -2
- package/dist/plugins/i18n.d.ts +2 -2
- package/dist/plugins/i18n.js.map +1 -1
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/keyboard.d.ts +2 -2
- package/dist/plugins/keyboard.js +65 -5
- package/dist/plugins/keyboard.js.map +1 -1
- package/dist/plugins/latex.js.map +1 -1
- package/dist/plugins/lazy-load.d.ts +2 -2
- package/dist/plugins/loading/index.d.ts +1 -1
- package/dist/plugins/loading.d.ts +2 -2
- package/dist/plugins/ml-integration.d.ts +2 -2
- package/dist/plugins/ml-integration.js +5 -5
- package/dist/plugins/ml-integration.js.map +1 -1
- package/dist/plugins/offscreen.d.ts +2 -2
- package/dist/plugins/pattern-recognition.d.ts +2 -2
- package/dist/plugins/pattern-recognition.js +1 -1
- package/dist/plugins/pattern-recognition.js.map +1 -1
- package/dist/plugins/radar.d.ts +2 -2
- package/dist/plugins/regression.d.ts +2 -2
- package/dist/plugins/regression.js +1 -1
- package/dist/plugins/regression.js.map +1 -1
- package/dist/plugins/roi.js +9 -9
- package/dist/plugins/roi.js.map +1 -1
- package/dist/plugins/snapshot/index.d.ts +1 -1
- package/dist/plugins/snapshot/types.d.ts +1 -1
- package/dist/plugins/snapshot.d.ts +2 -2
- package/dist/plugins/snapshot.js.map +1 -1
- package/dist/plugins/streaming/index.d.ts +2 -2
- package/dist/plugins/streaming.d.ts +2 -2
- package/dist/plugins/sync/index.d.ts +3 -2
- package/dist/plugins/sync.d.ts +2 -2
- package/dist/plugins/sync.js.map +1 -1
- package/dist/plugins/theme-editor/index.d.ts +1 -1
- package/dist/plugins/theme-editor.d.ts +2 -2
- package/dist/plugins/tools/index.d.ts +1 -1
- package/dist/plugins/tools/tooltip/index.d.ts +1 -1
- package/dist/plugins/tools.d.ts +2 -2
- package/dist/plugins/types.d.ts +1 -1
- package/dist/plugins/video-recorder.d.ts +2 -2
- package/dist/plugins/virtualization.d.ts +2 -2
- package/dist/plugins/virtualization.js +1 -1
- package/dist/pool-DZ8shSqv.js +109 -0
- package/dist/pool-DZ8shSqv.js.map +1 -0
- package/dist/react/StackedPlot.d.ts +31 -0
- package/dist/react/VeloPlot.d.ts +29 -0
- package/dist/react/index.d.ts +25 -3
- package/dist/react/useChartSync.d.ts +8 -0
- package/dist/react/useIndicator.d.ts +12 -0
- package/dist/react/useVeloPlot.d.ts +19 -0
- package/dist/react.js +328 -24
- package/dist/react.js.map +1 -1
- package/dist/scientific/index.d.ts +48 -0
- package/dist/scientific.d.ts +1 -0
- package/dist/scientific.js +91 -0
- package/dist/scientific.js.map +1 -0
- package/dist/solid/VeloPlot.d.ts +16 -0
- package/dist/solid/index.d.ts +13 -0
- package/dist/solid/useChartSync.d.ts +6 -0
- package/dist/solid/useIndicator.d.ts +11 -0
- package/dist/solid/useStackedPlot.d.ts +14 -0
- package/dist/solid/useVeloPlot.d.ts +18 -0
- package/dist/solid.d.ts +1 -0
- package/dist/solid.js +172 -0
- package/dist/solid.js.map +1 -0
- package/dist/stackedSync-tnrunZMt.js +100 -0
- package/dist/stackedSync-tnrunZMt.js.map +1 -0
- package/dist/svelte/StackedPlot.svelte +29 -0
- package/dist/svelte/StackedPlot.test.ts +114 -0
- package/dist/svelte/VeloPlot.svelte +44 -0
- package/dist/svelte/VeloPlot.test.ts +105 -0
- package/dist/svelte/index.d.ts +11 -0
- package/dist/svelte/index.test.ts +20 -0
- package/dist/svelte/index.ts +15 -0
- package/dist/svelte/useChartSync.d.ts +8 -0
- package/dist/svelte/useChartSync.test.ts +49 -0
- package/dist/svelte/useChartSync.ts +29 -0
- package/dist/svelte/useIndicator.d.ts +13 -0
- package/dist/svelte/useIndicator.test.ts +67 -0
- package/dist/svelte/useIndicator.ts +43 -0
- package/dist/svelte/useStackedPlot.d.ts +16 -0
- package/dist/svelte/useStackedPlot.test.ts +76 -0
- package/dist/svelte/useStackedPlot.ts +54 -0
- package/dist/svelte/useVeloPlot.d.ts +21 -0
- package/dist/svelte/useVeloPlot.test.ts +100 -0
- package/dist/svelte/useVeloPlot.ts +81 -0
- package/dist/svelte.d.ts +1 -0
- package/dist/svelte.js +143 -0
- package/dist/svelte.js.map +1 -0
- package/dist/testing/index.d.ts +1 -1
- package/dist/theme/index.d.ts +2 -1
- package/dist/trading.js +6 -6
- package/dist/types.d.ts +1 -1
- package/dist/{utils-BK5UUXxj.js → utils-Dx0h0bgQ.js} +9 -9
- package/dist/{utils-BK5UUXxj.js.map → utils-Dx0h0bgQ.js.map} +1 -1
- package/dist/velo-plot.full.js +452 -443
- package/dist/velo-plot.full.js.map +1 -1
- package/dist/velo-plot.js +15 -15
- package/dist/vue/StackedPlot.vue.d.ts +48 -0
- package/dist/vue/VeloPlot.vue.d.ts +64 -0
- package/dist/vue/index.d.ts +250 -0
- package/dist/vue/useChartSync.d.ts +52 -0
- package/dist/vue/useIndicator.d.ts +23 -0
- package/dist/vue/useStackedPlot.d.ts +15 -0
- package/dist/vue/useVeloPlot.d.ts +20 -0
- package/dist/vue.d.ts +1 -0
- package/dist/vue.js +312 -0
- package/dist/vue.js.map +1 -0
- package/dist/workers/indicatorsAsync.d.ts +2 -0
- package/dist/workers/pool.d.ts +9 -0
- package/package.json +88 -10
- package/dist/ChartCore-ivzLqxVb.js.map +0 -1
- package/dist/SciPlot-CEU4ApgD.js +0 -463
- package/dist/SciPlot-CEU4ApgD.js.map +0 -1
- package/dist/createStackedChart-DxNW0VkF.js +0 -705
- package/dist/createStackedChart-DxNW0VkF.js.map +0 -1
- package/dist/index-BBpJwOct.js.map +0 -1
- package/dist/index-DoYxf1cV.js.map +0 -1
- package/dist/index.core-COREBDNq.js.map +0 -1
- package/dist/mockDatafeed-927foCM4.js.map +0 -1
- package/dist/pool-15HMCNv8.js +0 -88
- package/dist/pool-15HMCNv8.js.map +0 -1
- package/dist/react/SciPlot.d.ts +0 -60
- package/dist/react/useSciPlot.d.ts +0 -56
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"latex.js","sources":["../../src/plugins/latex/parser.ts","../../src/plugins/latex/renderer.ts","../../src/plugins/latex/index.ts"],"sourcesContent":["/**\n * @fileoverview Simple LaTeX parser for mathematical expressions\n * @module plugins/latex/parser\n */\n\nimport { LaTeXNode } from './types';\nimport { getSymbol, isSymbol, BLACKBOARD, CALLIGRAPHIC, FRAKTUR } from './symbols';\n\n/** Delimiters for supported matrix environments. */\nconst MATRIX_DELIMITERS: Record<string, [string, string]> = {\n matrix: ['', ''],\n pmatrix: ['(', ')'],\n bmatrix: ['[', ']'],\n Bmatrix: ['{', '}'],\n vmatrix: ['|', '|'],\n Vmatrix: ['‖', '‖'],\n};\n\n/** Alphabet transforms for math font commands. */\nconst ALPHABET_MAPS: Record<string, Record<string, string>> = {\n mathbb: BLACKBOARD,\n mathcal: CALLIGRAPHIC,\n mathfrak: FRAKTUR,\n};\n\n/**\n * Parse LaTeX string into an abstract syntax tree\n */\nexport function parseLaTeX(latex: string): LaTeXNode[] {\n const tokens = tokenize(latex);\n return parseTokens(tokens);\n}\n\n/**\n * Extract text content from nodes recursively\n */\nfunction extractTextContent(nodes: LaTeXNode[]): string {\n let result = '';\n for (const node of nodes) {\n if (node.type === 'text' || node.type === 'textgroup') {\n result += node.content || '';\n } else if (node.type === 'symbol') {\n result += node.content || '';\n } else if (node.children) {\n result += extractTextContent(node.children);\n }\n }\n return result;\n}\n\n/**\n * Tokenize LaTeX string\n */\nfunction tokenize(latex: string): string[] {\n const tokens: string[] = [];\n let i = 0;\n\n while (i < latex.length) {\n const char = latex[i];\n\n // Backslash indicates a command\n if (char === '\\\\') {\n let command = '';\n i++;\n // Read command name (letters only)\n while (i < latex.length && /[a-zA-Z]/.test(latex[i])) {\n command += latex[i];\n i++;\n }\n if (command) {\n tokens.push('\\\\' + command);\n } else {\n // Single character command like \\{\n if (i < latex.length) {\n tokens.push('\\\\' + latex[i]);\n i++;\n }\n }\n }\n // Special characters that should be separate tokens\n else if (char === '{' || char === '}' || char === '^' || char === '_') {\n tokens.push(char);\n i++;\n }\n // Whitespace: preserve as single space token for text commands\n else if (/\\s/.test(char)) {\n tokens.push(' ');\n i++;\n // Skip additional whitespace\n while (i < latex.length && /\\s/.test(latex[i])) {\n i++;\n }\n }\n // Single characters: keep separate for proper subscript/superscript handling\n else {\n // Group text only if we're in a \"text\" context (not math/chemistry)\n // For chemistry formulas, keep each letter/digit separate\n tokens.push(char);\n i++;\n }\n }\n\n return tokens;\n}\n\n/**\n * Parse tokens into AST nodes\n */\nfunction parseTokens(tokens: string[]): LaTeXNode[] {\n const nodes: LaTeXNode[] = [];\n let i = 0;\n\n while (i < tokens.length) {\n const token = tokens[i];\n\n // Superscript\n if (token === '^') {\n i++;\n const content = parseGroup(tokens, i);\n nodes.push({\n type: 'superscript',\n children: content.nodes,\n });\n i = content.nextIndex;\n }\n // Subscript\n else if (token === '_') {\n i++;\n const content = parseGroup(tokens, i);\n nodes.push({\n type: 'subscript',\n children: content.nodes,\n });\n i = content.nextIndex;\n }\n // Commands\n else if (token.startsWith('\\\\')) {\n const command = token.substring(1);\n\n // Fraction\n if (command === 'frac') {\n i++;\n const numerator = parseGroup(tokens, i);\n i = numerator.nextIndex;\n const denominator = parseGroup(tokens, i);\n i = denominator.nextIndex;\n nodes.push({\n type: 'fraction',\n numerator: numerator.nodes,\n denominator: denominator.nodes,\n });\n }\n // Square root\n else if (command === 'sqrt') {\n i++;\n const content = parseGroup(tokens, i);\n nodes.push({\n type: 'sqrt',\n children: content.nodes,\n });\n i = content.nextIndex;\n }\n // Text command - render as a single grouped string for proper kerning\n else if (command === 'text' || command === 'mathrm' || command === 'mathbf' || command === 'mathit' || command === 'operatorname') {\n i++;\n const content = parseGroup(tokens, i);\n // Concatenate all text content from the group into a single string\n const textContent = extractTextContent(content.nodes);\n nodes.push({\n type: 'textgroup',\n content: textContent,\n });\n i = content.nextIndex;\n }\n // Math alphabets: map each letter to its Unicode variant\n else if (command in ALPHABET_MAPS) {\n i++;\n const content = parseGroup(tokens, i);\n i = content.nextIndex;\n const map = ALPHABET_MAPS[command];\n const raw = extractTextContent(content.nodes);\n let mapped = '';\n for (const ch of raw) mapped += map[ch] ?? ch;\n nodes.push({ type: 'text', content: mapped });\n }\n // Matrix environments: \\begin{pmatrix} a & b \\\\ c & d \\end{pmatrix}\n else if (command === 'begin') {\n i = parseMatrix(tokens, i, nodes);\n }\n // Symbol\n else if (isSymbol(command)) {\n nodes.push({\n type: 'symbol',\n content: getSymbol(command),\n });\n i++;\n }\n // Common operators that might be commands\n else if (command === 'times' || command === 'cdot' || command === 'pm' || command === 'mp') {\n nodes.push({\n type: 'symbol',\n content: getSymbol(command),\n });\n i++;\n }\n // Unknown command - treat as text\n else {\n nodes.push({\n type: 'text',\n content: token,\n });\n i++;\n }\n }\n // Group start\n else if (token === '{') {\n const content = parseGroup(tokens, i);\n nodes.push({\n type: 'group',\n children: content.nodes,\n });\n i = content.nextIndex;\n }\n // Regular text\n else {\n nodes.push({\n type: 'text',\n content: token,\n });\n i++;\n }\n }\n\n return nodes;\n}\n\n/**\n * Parse a matrix environment starting at the `\\begin` token.\n * Returns the index immediately after the matching `\\end{...}`.\n */\nfunction parseMatrix(tokens: string[], startIndex: number, nodes: LaTeXNode[]): number {\n let i = startIndex + 1; // skip \\begin\n\n // Read environment name inside the following {...}\n let envName = '';\n if (tokens[i] === '{') {\n i++;\n while (i < tokens.length && tokens[i] !== '}') {\n envName += tokens[i];\n i++;\n }\n if (tokens[i] === '}') i++;\n }\n\n // Collect tokens until the matching \\end (supporting nesting)\n const inner: string[] = [];\n let depth = 1;\n while (i < tokens.length && depth > 0) {\n const t = tokens[i];\n if (t === '\\\\begin') {\n depth++;\n inner.push(t);\n i++;\n } else if (t === '\\\\end') {\n depth--;\n if (depth === 0) {\n i++; // consume \\end\n if (tokens[i] === '{') {\n i++;\n while (i < tokens.length && tokens[i] !== '}') i++;\n if (tokens[i] === '}') i++;\n }\n } else {\n inner.push(t);\n i++;\n }\n } else {\n inner.push(t);\n i++;\n }\n }\n\n // Split inner tokens into rows (\\\\) and cells (&)\n const matrixRows: LaTeXNode[][][] = [];\n let rowCells: LaTeXNode[][] = [];\n let cellTokens: string[] = [];\n const flushCell = () => {\n rowCells.push(parseTokens(cellTokens));\n cellTokens = [];\n };\n const flushRow = () => {\n flushCell();\n matrixRows.push(rowCells);\n rowCells = [];\n };\n\n for (const t of inner) {\n if (t === '&') {\n flushCell();\n } else if (t === '\\\\\\\\') {\n flushRow();\n } else {\n cellTokens.push(t);\n }\n }\n if (cellTokens.length > 0 || rowCells.length > 0) {\n flushRow();\n }\n\n const delimiters = MATRIX_DELIMITERS[envName] ?? ['', ''];\n nodes.push({ type: 'matrix', rows: matrixRows, delimiters });\n\n return i;\n}\n\n/**\n * Parse a grouped expression (inside braces)\n */\nfunction parseGroup(\n tokens: string[],\n startIndex: number\n): { nodes: LaTeXNode[]; nextIndex: number } {\n // If next token is not a brace, treat single token as group\n if (tokens[startIndex] !== '{') {\n return {\n nodes: [\n {\n type: 'text',\n content: tokens[startIndex] || '',\n },\n ],\n nextIndex: startIndex + 1,\n };\n }\n\n // Skip opening brace\n let i = startIndex + 1;\n const groupTokens: string[] = [];\n let braceDepth = 1;\n\n // Collect tokens until matching closing brace\n while (i < tokens.length && braceDepth > 0) {\n const token = tokens[i];\n if (token === '{') {\n braceDepth++;\n groupTokens.push(token);\n } else if (token === '}') {\n braceDepth--;\n if (braceDepth > 0) {\n groupTokens.push(token);\n }\n } else {\n groupTokens.push(token);\n }\n i++;\n }\n\n return {\n nodes: parseTokens(groupTokens),\n nextIndex: i,\n };\n}\n","/**\n * @fileoverview LaTeX renderer using native Canvas API\n * @module plugins/latex/renderer\n */\n\nimport { LaTeXNode, LaTeXRenderContext, LaTeXDimensions } from './types';\n\n/**\n * Render a list of LaTeX nodes to canvas\n */\nexport function renderNodes(\n nodes: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n let currentX = ctx.x;\n let maxAscent = 0;\n let maxDescent = 0;\n\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n // Check if we have adjacent subscript and superscript (stacking)\n const isSub = node.type === 'subscript';\n const isSuper = node.type === 'superscript';\n const nextNode = nodes[i + 1];\n const isNextSub = nextNode?.type === 'subscript';\n const isNextSuper = nextNode?.type === 'superscript';\n\n if ((isSub && isNextSuper) || (isSuper && isNextSub)) {\n // Stack subscript and superscript at the same X coordinate\n const dims1 = renderNode(node, { ...ctx, x: currentX });\n const dims2 = renderNode(nextNode, { ...ctx, x: currentX });\n\n const width = Math.max(dims1.width, dims2.width);\n currentX += width + (ctx.fontSize * 0.15); // Scaled padding after scripts\n\n maxAscent = Math.max(maxAscent, dims1.baseline, dims2.baseline);\n maxDescent = Math.max(maxDescent, dims1.height - dims1.baseline, dims2.height - dims2.baseline);\n i++; // Skip next node\n } else {\n const dims = renderNode(node, { ...ctx, x: currentX });\n currentX += dims.width;\n\n // Add a small gap after scripts to prevent overlap with next character (Chemistry fix)\n if (isSub || isSuper) {\n currentX += ctx.fontSize * 0.12;\n }\n\n maxAscent = Math.max(maxAscent, dims.baseline);\n maxDescent = Math.max(maxDescent, dims.height - dims.baseline);\n }\n }\n\n return {\n width: currentX - ctx.x,\n height: maxAscent + maxDescent,\n baseline: maxAscent,\n };\n}\n\n/**\n * Render a single LaTeX node\n */\nfunction renderNode(node: LaTeXNode, ctx: LaTeXRenderContext): LaTeXDimensions {\n switch (node.type) {\n case 'text':\n return renderText(node.content || '', ctx);\n\n case 'textgroup':\n return renderText(node.content || '', ctx);\n\n case 'symbol':\n return renderSymbol(node.content || '', ctx);\n\n case 'superscript':\n return renderSuperscript(node.children || [], ctx);\n\n case 'subscript':\n return renderSubscript(node.children || [], ctx);\n\n case 'fraction':\n return renderFraction(\n node.numerator || [],\n node.denominator || [],\n ctx\n );\n\n case 'sqrt':\n return renderSqrt(node.children || [], ctx);\n\n case 'group':\n return renderNodes(node.children || [], ctx);\n\n case 'matrix':\n return renderMatrix(node.rows || [], node.delimiters || ['', ''], ctx);\n\n default:\n return { width: 0, height: 0, baseline: 0 };\n }\n}\n\n/**\n * Render a matrix environment (\\begin{pmatrix}...\\end{pmatrix}).\n * The matrix is vertically centered on the current baseline.\n */\nfunction renderMatrix(\n rows: LaTeXNode[][][],\n delimiters: [string, string],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n const nRows = rows.length;\n const nCols = rows.reduce((m, r) => Math.max(m, r.length), 0);\n if (nRows === 0 || nCols === 0) {\n return { width: 0, height: 0, baseline: 0 };\n }\n\n const cellPadX = ctx.fontSize * 0.35;\n const cellPadY = ctx.fontSize * 0.25;\n const delimW = ctx.fontSize * 0.35;\n\n // Measure every cell\n const cellDims: LaTeXDimensions[][] = rows.map((r) => r.map((cell) => measureNodes(cell, ctx)));\n\n const colW = new Array(nCols).fill(0);\n const rowAsc = new Array(nRows).fill(0);\n const rowDesc = new Array(nRows).fill(0);\n\n for (let r = 0; r < nRows; r++) {\n for (let c = 0; c < rows[r].length; c++) {\n const d = cellDims[r][c];\n colW[c] = Math.max(colW[c], d.width);\n rowAsc[r] = Math.max(rowAsc[r], d.baseline);\n rowDesc[r] = Math.max(rowDesc[r], d.height - d.baseline);\n }\n }\n const rowH = rowAsc.map((a, i) => a + rowDesc[i]);\n\n const totalH = rowH.reduce((s, h) => s + h, 0) + cellPadY * 2 * nRows;\n const contentW = colW.reduce((s, w) => s + w, 0) + cellPadX * 2 * nCols;\n const totalW = contentW + delimW * 2;\n\n const top = ctx.y - totalH / 2;\n\n // Delimiters\n drawDelimiter(ctx, delimiters[0], ctx.x, top, totalH, delimW, 'left');\n drawDelimiter(ctx, delimiters[1], ctx.x + totalW - delimW, top, totalH, delimW, 'right');\n\n // Cells\n let cellTop = top + cellPadY;\n for (let r = 0; r < nRows; r++) {\n let cellX = ctx.x + delimW + cellPadX;\n for (let c = 0; c < nCols; c++) {\n const cell = rows[r][c];\n if (cell) {\n const d = cellDims[r][c];\n const x = cellX + (colW[c] - d.width) / 2;\n const baselineY = cellTop + rowAsc[r];\n renderNodes(cell, { ...ctx, x, y: baselineY });\n }\n cellX += colW[c] + cellPadX * 2;\n }\n cellTop += rowH[r] + cellPadY * 2;\n }\n\n return { width: totalW, height: totalH, baseline: totalH / 2 };\n}\n\n/**\n * Draw a stretchable matrix delimiter using geometric strokes.\n */\nfunction drawDelimiter(\n ctx: LaTeXRenderContext,\n ch: string,\n x: number,\n top: number,\n height: number,\n width: number,\n side: 'left' | 'right'\n): void {\n if (!ch) return;\n const c = ctx.ctx;\n c.save();\n c.strokeStyle = ctx.color;\n c.lineWidth = Math.max(1, ctx.fontSize * 0.05);\n c.lineCap = 'round';\n c.lineJoin = 'round';\n\n const bottom = top + height;\n const tipInset = width * 0.7;\n\n const drawParen = (open: boolean) => {\n c.beginPath();\n if (open) {\n c.moveTo(x + width, top);\n c.quadraticCurveTo(x, (top + bottom) / 2, x + width, bottom);\n } else {\n c.moveTo(x, top);\n c.quadraticCurveTo(x + width, (top + bottom) / 2, x, bottom);\n }\n c.stroke();\n };\n\n const drawBracket = (open: boolean) => {\n c.beginPath();\n if (open) {\n c.moveTo(x + tipInset, top);\n c.lineTo(x, top);\n c.lineTo(x, bottom);\n c.lineTo(x + tipInset, bottom);\n } else {\n c.moveTo(x + width - tipInset, top);\n c.lineTo(x + width, top);\n c.lineTo(x + width, bottom);\n c.lineTo(x + width - tipInset, bottom);\n }\n c.stroke();\n };\n\n const drawBar = (offset: number) => {\n c.beginPath();\n c.moveTo(x + offset, top);\n c.lineTo(x + offset, bottom);\n c.stroke();\n };\n\n const drawBrace = (open: boolean) => {\n const midY = (top + bottom) / 2;\n const bx = open ? x + width : x;\n const tx = open ? x : x + width;\n c.beginPath();\n c.moveTo(bx, top);\n c.quadraticCurveTo(tx, top + height * 0.25, (bx + tx) / 2, top + height * 0.4);\n c.quadraticCurveTo(tx, midY - 1, tx, midY);\n c.quadraticCurveTo(tx, midY + 1, (bx + tx) / 2, bottom - height * 0.4);\n c.quadraticCurveTo(tx, bottom - height * 0.25, bx, bottom);\n c.stroke();\n };\n\n switch (ch) {\n case '(':\n drawParen(true);\n break;\n case ')':\n drawParen(false);\n break;\n case '[':\n drawBracket(true);\n break;\n case ']':\n drawBracket(false);\n break;\n case '{':\n drawBrace(true);\n break;\n case '}':\n drawBrace(false);\n break;\n case '|':\n drawBar(side === 'left' ? width * 0.5 : width * 0.5);\n break;\n case '‖':\n drawBar(width * 0.3);\n drawBar(width * 0.7);\n break;\n default:\n break;\n }\n\n c.restore();\n}\n\n/**\n * Render plain text\n */\nfunction renderText(text: string, ctx: LaTeXRenderContext): LaTeXDimensions {\n ctx.ctx.save();\n ctx.ctx.font = `${ctx.fontSize}px ${ctx.fontFamily}`;\n ctx.ctx.fillStyle = ctx.color;\n ctx.ctx.textAlign = 'left';\n ctx.ctx.textBaseline = 'alphabetic';\n\n const metrics = ctx.ctx.measureText(text);\n ctx.ctx.fillText(text, ctx.x, ctx.y);\n\n ctx.ctx.restore();\n\n const height = ctx.fontSize;\n const baseline = height * 0.75; // Approximate baseline\n\n return {\n width: metrics.width,\n height,\n baseline,\n };\n}\n\n/**\n * Render mathematical symbol\n */\nfunction renderSymbol(symbol: string, ctx: LaTeXRenderContext): LaTeXDimensions {\n // Use larger font size for symbols\n ctx.ctx.save();\n ctx.ctx.font = `${ctx.fontSize * 1.1}px ${ctx.fontFamily}`;\n ctx.ctx.fillStyle = ctx.color;\n ctx.ctx.textAlign = 'left';\n ctx.ctx.textBaseline = 'alphabetic';\n\n const metrics = ctx.ctx.measureText(symbol);\n ctx.ctx.fillText(symbol, ctx.x, ctx.y);\n\n ctx.ctx.restore();\n\n const height = ctx.fontSize * 1.1;\n const baseline = height * 0.75;\n\n return {\n width: metrics.width,\n height,\n baseline,\n };\n}\n\n/**\n * Render superscript (exponent)\n */\nfunction renderSuperscript(\n nodes: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n const scaledFontSize = ctx.fontSize * 0.7;\n const yOffset = -ctx.fontSize * 0.4;\n\n const dims = renderNodes(nodes, {\n ...ctx,\n fontSize: scaledFontSize,\n y: ctx.y + yOffset,\n });\n\n const subAscent = dims.baseline;\n const subDescent = dims.height - dims.baseline;\n\n return {\n width: dims.width,\n height: (subAscent - yOffset) + (subDescent + yOffset),\n baseline: subAscent - yOffset,\n };\n}\n\n/**\n * Render subscript\n */\nfunction renderSubscript(\n nodes: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n const scaledFontSize = ctx.fontSize * 0.7;\n const yOffset = ctx.fontSize * 0.3;\n\n const dims = renderNodes(nodes, {\n ...ctx,\n fontSize: scaledFontSize,\n y: ctx.y + yOffset,\n });\n\n const subAscent = dims.baseline;\n const subDescent = dims.height - dims.baseline;\n\n return {\n width: dims.width,\n height: (subAscent - yOffset) + (subDescent + yOffset),\n baseline: subAscent - yOffset,\n };\n}\n\n/**\n * Render fraction\n */\nfunction renderFraction(\n numerator: LaTeXNode[],\n denominator: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n const scaledFontSize = ctx.fontSize * 0.85;\n const lineThickness = Math.max(1, ctx.fontSize * 0.05);\n const padding = ctx.fontSize * 0.1;\n\n // Measure both parts\n const numDims = measureNodes(numerator, {\n ...ctx,\n fontSize: scaledFontSize,\n });\n const denDims = measureNodes(denominator, {\n ...ctx,\n fontSize: scaledFontSize,\n });\n\n const maxWidth = Math.max(numDims.width, denDims.width);\n const totalHeight = numDims.height + denDims.height + padding * 2 + lineThickness;\n\n // Render numerator (centered)\n const numX = ctx.x + (maxWidth - numDims.width) / 2;\n const numY = ctx.y - padding - lineThickness / 2;\n renderNodes(numerator, {\n ...ctx,\n x: numX,\n y: numY,\n fontSize: scaledFontSize,\n });\n\n // Draw fraction line\n ctx.ctx.fillStyle = ctx.color;\n ctx.ctx.fillRect(\n ctx.x,\n ctx.y - lineThickness / 2,\n maxWidth,\n lineThickness\n );\n\n // Render denominator (centered)\n const denX = ctx.x + (maxWidth - denDims.width) / 2;\n const denY = ctx.y + denDims.baseline + padding + lineThickness / 2;\n renderNodes(denominator, {\n ...ctx,\n x: denX,\n y: denY,\n fontSize: scaledFontSize,\n });\n\n return {\n width: maxWidth,\n height: totalHeight,\n baseline: totalHeight / 2,\n };\n}\n\n/**\n * Render square root\n */\nfunction renderSqrt(nodes: LaTeXNode[], ctx: LaTeXRenderContext): LaTeXDimensions {\n const contentDims = renderNodes(nodes, {\n ...ctx,\n x: ctx.x + ctx.fontSize * 0.4,\n });\n\n const totalWidth = contentDims.width + ctx.fontSize * 0.5;\n const totalHeight = contentDims.height * 1.1;\n\n // Draw radical symbol\n ctx.ctx.save();\n ctx.ctx.strokeStyle = ctx.color;\n ctx.ctx.lineWidth = Math.max(1, ctx.fontSize * 0.05);\n ctx.ctx.lineCap = 'round';\n ctx.ctx.lineJoin = 'miter';\n\n ctx.ctx.beginPath();\n // Left tick\n ctx.ctx.moveTo(ctx.x, ctx.y - totalHeight * 0.3);\n ctx.ctx.lineTo(ctx.x + ctx.fontSize * 0.15, ctx.y);\n // Down stroke\n ctx.ctx.lineTo(ctx.x + ctx.fontSize * 0.3, ctx.y - totalHeight * 0.9);\n // Top bar\n ctx.ctx.lineTo(ctx.x + totalWidth, ctx.y - totalHeight * 0.9);\n ctx.ctx.stroke();\n\n ctx.ctx.restore();\n\n return {\n width: totalWidth,\n height: totalHeight,\n baseline: contentDims.baseline,\n };\n}\n\n/**\n * Measure nodes without rendering\n */\nfunction measureNodes(\n nodes: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n // Create an offscreen canvas for measurement\n const canvas = document.createElement('canvas');\n const measureCtx = canvas.getContext('2d');\n if (!measureCtx) {\n return { width: 0, height: 0, baseline: 0 };\n }\n\n return renderNodes(nodes, { ...ctx, ctx: measureCtx, x: 0, y: 0 });\n}\n","/**\n * @fileoverview LaTeX rendering plugin for Sci Plot\n * @module plugins/latex\n *\n * This plugin provides native LaTeX rendering without external dependencies.\n * It supports common mathematical notation including:\n * - Greek letters (\\alpha, \\beta, \\gamma, etc.)\n * - Superscripts and subscripts (x^2, H_2O)\n * - Fractions (\\frac{a}{b})\n * - Square roots (\\sqrt{x})\n * - Mathematical operators (\\sum, \\int, \\partial, etc.)\n *\n * @example\n * ```typescript\n * import { PluginLaTeX } from 'velo-plot/plugins';\n *\n * const latex = PluginLaTeX({\n * fontSize: 16,\n * fontFamily: 'serif',\n * color: '#000000'\n * });\n *\n * await chart.use(latex);\n *\n * // Use with axis labels\n * chart.xAxis.label = '\\\\Delta E = mc^2';\n * chart.yAxis.label = '\\\\frac{\\\\partial^2 y}{\\\\partial x^2}';\n *\n * // Use with annotations\n * chart.addAnnotation({\n * type: 'text',\n * text: '\\\\sum_{i=1}^{n} x_i',\n * latex: true\n * });\n * ```\n */\n\nimport type { ChartPlugin, PluginContext } from '../types';\nimport type {\n PluginLaTeXConfig,\n LaTeXPluginAPI,\n LaTeXDimensions,\n} from './types';\nimport { parseLaTeX } from './parser';\nimport { renderNodes } from './renderer';\n\n/**\n * LaTeX rendering plugin\n */\nexport function PluginLaTeX(config: PluginLaTeXConfig = {}): ChartPlugin<PluginLaTeXConfig> {\n const defaultConfig: Required<PluginLaTeXConfig> = {\n fontSize: 14,\n fontFamily: 'serif',\n color: '#000000',\n enableCache: true,\n customSymbols: {},\n };\n\n const finalConfig = { ...defaultConfig, ...config };\n\n // Bounded caches prevent unbounded memory growth when many distinct\n // expressions are rendered over the lifetime of a chart (task 3.11).\n const MAX_CACHE_ENTRIES = 1000;\n\n /** Evict the oldest entry once the cache exceeds its cap (FIFO). */\n function capCache<K, V>(cache: Map<K, V>): void {\n if (cache.size > MAX_CACHE_ENTRIES) {\n const oldest = cache.keys().next().value;\n if (oldest !== undefined) cache.delete(oldest);\n }\n }\n\n // Cache for parsed LaTeX\n const parseCache = new Map<string, ReturnType<typeof parseLaTeX>>();\n // Cache for measured dimensions\n const measureCache = new Map<string, LaTeXDimensions>();\n\n /**\n * Clear all caches\n */\n function clearCache(): void {\n parseCache.clear();\n measureCache.clear();\n }\n\n /**\n * Get parsed AST for LaTeX string (with caching)\n */\n function getParsed(latex: string): ReturnType<typeof parseLaTeX> {\n if (!finalConfig.enableCache) {\n return parseLaTeX(latex);\n }\n\n let parsed = parseCache.get(latex);\n if (!parsed) {\n parsed = parseLaTeX(latex);\n parseCache.set(latex, parsed);\n capCache(parseCache);\n }\n return parsed;\n }\n\n /**\n * Render LaTeX to canvas\n */\n function render(\n latex: string,\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n options: Partial<PluginLaTeXConfig> = {}\n ): LaTeXDimensions {\n const renderConfig = { ...finalConfig, ...options };\n const nodes = getParsed(latex);\n\n const dims = renderNodes(nodes, {\n ctx,\n x,\n y,\n fontSize: renderConfig.fontSize,\n fontFamily: renderConfig.fontFamily,\n color: renderConfig.color,\n scale: 1,\n });\n\n return dims;\n }\n\n /**\n * Measure LaTeX dimensions without rendering\n */\n function measure(\n latex: string,\n options: Partial<PluginLaTeXConfig> = {}\n ): LaTeXDimensions {\n const cacheKey = `${latex}:${options.fontSize || finalConfig.fontSize}`;\n\n if (finalConfig.enableCache && measureCache.has(cacheKey)) {\n return measureCache.get(cacheKey)!;\n }\n\n const renderConfig = { ...finalConfig, ...options };\n const nodes = getParsed(latex);\n\n // Create offscreen canvas for measurement\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return { width: 0, height: 0, baseline: 0 };\n }\n\n const dims = renderNodes(nodes, {\n ctx,\n x: 0,\n y: 0,\n fontSize: renderConfig.fontSize,\n fontFamily: renderConfig.fontFamily,\n color: renderConfig.color,\n scale: 1,\n });\n\n if (finalConfig.enableCache) {\n measureCache.set(cacheKey, dims);\n capCache(measureCache);\n }\n\n return dims;\n }\n\n /** Expose cache sizes for leak verification / diagnostics. */\n function getCacheStats(): { parseCache: number; measureCache: number; maxEntries: number } {\n return {\n parseCache: parseCache.size,\n measureCache: measureCache.size,\n maxEntries: MAX_CACHE_ENTRIES,\n };\n }\n\n // API exposed to chart\n const api: LaTeXPluginAPI = {\n render,\n measure,\n clearCache,\n getCacheStats,\n };\n\n return {\n manifest: {\n name: 'velo-plot-latex',\n version: '1.0.0',\n description: 'Native LaTeX rendering for mathematical expressions',\n provides: ['latex'],\n tags: ['latex', 'math', 'typography'],\n },\n\n onInit(ctx: PluginContext) {\n // API is accessed via plugin bridge, no need to set property on chart which has only a getter\n ctx.log.info('LaTeX plugin initialized');\n },\n\n onDestroy(ctx: PluginContext) {\n clearCache();\n ctx.log.info('LaTeX plugin destroyed');\n },\n\n api,\n };\n}\n\n// Type exports\nexport type { PluginLaTeXConfig, LaTeXPluginAPI, LaTeXDimensions };\n\n"],"names":["MATRIX_DELIMITERS","ALPHABET_MAPS","BLACKBOARD","CALLIGRAPHIC","FRAKTUR","parseLaTeX","latex","tokens","tokenize","parseTokens","extractTextContent","nodes","result","node","i","char","command","token","content","parseGroup","numerator","denominator","textContent","map","raw","mapped","ch","parseMatrix","isSymbol","getSymbol","startIndex","envName","inner","depth","t","matrixRows","rowCells","cellTokens","flushCell","flushRow","delimiters","groupTokens","braceDepth","renderNodes","ctx","currentX","maxAscent","maxDescent","isSub","isSuper","nextNode","isNextSub","isNextSuper","dims1","renderNode","dims2","width","dims","renderText","renderSymbol","renderSuperscript","renderSubscript","renderFraction","renderSqrt","renderMatrix","rows","nRows","nCols","m","r","cellPadX","cellPadY","delimW","cellDims","cell","measureNodes","colW","rowAsc","rowDesc","c","d","rowH","a","totalH","s","h","totalW","w","top","drawDelimiter","cellTop","cellX","x","baselineY","height","side","bottom","tipInset","drawParen","open","drawBracket","drawBar","offset","drawBrace","midY","bx","tx","text","metrics","baseline","symbol","scaledFontSize","yOffset","subAscent","subDescent","lineThickness","padding","numDims","denDims","maxWidth","totalHeight","numX","numY","denX","denY","contentDims","totalWidth","measureCtx","PluginLaTeX","config","finalConfig","MAX_CACHE_ENTRIES","capCache","cache","oldest","parseCache","measureCache","clearCache","getParsed","parsed","render","options","renderConfig","measure","cacheKey","getCacheStats"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"latex.js","sources":["../../src/plugins/latex/parser.ts","../../src/plugins/latex/renderer.ts","../../src/plugins/latex/index.ts"],"sourcesContent":["/**\n * @fileoverview Simple LaTeX parser for mathematical expressions\n * @module plugins/latex/parser\n */\n\nimport { LaTeXNode } from './types';\nimport { getSymbol, isSymbol, BLACKBOARD, CALLIGRAPHIC, FRAKTUR } from './symbols';\n\n/** Delimiters for supported matrix environments. */\nconst MATRIX_DELIMITERS: Record<string, [string, string]> = {\n matrix: ['', ''],\n pmatrix: ['(', ')'],\n bmatrix: ['[', ']'],\n Bmatrix: ['{', '}'],\n vmatrix: ['|', '|'],\n Vmatrix: ['‖', '‖'],\n};\n\n/** Alphabet transforms for math font commands. */\nconst ALPHABET_MAPS: Record<string, Record<string, string>> = {\n mathbb: BLACKBOARD,\n mathcal: CALLIGRAPHIC,\n mathfrak: FRAKTUR,\n};\n\n/**\n * Parse LaTeX string into an abstract syntax tree\n */\nexport function parseLaTeX(latex: string): LaTeXNode[] {\n const tokens = tokenize(latex);\n return parseTokens(tokens);\n}\n\n/**\n * Extract text content from nodes recursively\n */\nfunction extractTextContent(nodes: LaTeXNode[]): string {\n let result = '';\n for (const node of nodes) {\n if (node.type === 'text' || node.type === 'textgroup') {\n result += node.content || '';\n } else if (node.type === 'symbol') {\n result += node.content || '';\n } else if (node.children) {\n result += extractTextContent(node.children);\n }\n }\n return result;\n}\n\n/**\n * Tokenize LaTeX string\n */\nfunction tokenize(latex: string): string[] {\n const tokens: string[] = [];\n let i = 0;\n\n while (i < latex.length) {\n const char = latex[i];\n\n // Backslash indicates a command\n if (char === '\\\\') {\n let command = '';\n i++;\n // Read command name (letters only)\n while (i < latex.length && /[a-zA-Z]/.test(latex[i])) {\n command += latex[i];\n i++;\n }\n if (command) {\n tokens.push('\\\\' + command);\n } else {\n // Single character command like \\{\n if (i < latex.length) {\n tokens.push('\\\\' + latex[i]);\n i++;\n }\n }\n }\n // Special characters that should be separate tokens\n else if (char === '{' || char === '}' || char === '^' || char === '_') {\n tokens.push(char);\n i++;\n }\n // Whitespace: preserve as single space token for text commands\n else if (/\\s/.test(char)) {\n tokens.push(' ');\n i++;\n // Skip additional whitespace\n while (i < latex.length && /\\s/.test(latex[i])) {\n i++;\n }\n }\n // Single characters: keep separate for proper subscript/superscript handling\n else {\n // Group text only if we're in a \"text\" context (not math/chemistry)\n // For chemistry formulas, keep each letter/digit separate\n tokens.push(char);\n i++;\n }\n }\n\n return tokens;\n}\n\n/**\n * Parse tokens into AST nodes\n */\nfunction parseTokens(tokens: string[]): LaTeXNode[] {\n const nodes: LaTeXNode[] = [];\n let i = 0;\n\n while (i < tokens.length) {\n const token = tokens[i];\n\n // Superscript\n if (token === '^') {\n i++;\n const content = parseGroup(tokens, i);\n nodes.push({\n type: 'superscript',\n children: content.nodes,\n });\n i = content.nextIndex;\n }\n // Subscript\n else if (token === '_') {\n i++;\n const content = parseGroup(tokens, i);\n nodes.push({\n type: 'subscript',\n children: content.nodes,\n });\n i = content.nextIndex;\n }\n // Commands\n else if (token.startsWith('\\\\')) {\n const command = token.substring(1);\n\n // Fraction\n if (command === 'frac') {\n i++;\n const numerator = parseGroup(tokens, i);\n i = numerator.nextIndex;\n const denominator = parseGroup(tokens, i);\n i = denominator.nextIndex;\n nodes.push({\n type: 'fraction',\n numerator: numerator.nodes,\n denominator: denominator.nodes,\n });\n }\n // Square root\n else if (command === 'sqrt') {\n i++;\n const content = parseGroup(tokens, i);\n nodes.push({\n type: 'sqrt',\n children: content.nodes,\n });\n i = content.nextIndex;\n }\n // Text command - render as a single grouped string for proper kerning\n else if (command === 'text' || command === 'mathrm' || command === 'mathbf' || command === 'mathit' || command === 'operatorname') {\n i++;\n const content = parseGroup(tokens, i);\n // Concatenate all text content from the group into a single string\n const textContent = extractTextContent(content.nodes);\n nodes.push({\n type: 'textgroup',\n content: textContent,\n });\n i = content.nextIndex;\n }\n // Math alphabets: map each letter to its Unicode variant\n else if (command in ALPHABET_MAPS) {\n i++;\n const content = parseGroup(tokens, i);\n i = content.nextIndex;\n const map = ALPHABET_MAPS[command];\n const raw = extractTextContent(content.nodes);\n let mapped = '';\n for (const ch of raw) mapped += map[ch] ?? ch;\n nodes.push({ type: 'text', content: mapped });\n }\n // Matrix environments: \\begin{pmatrix} a & b \\\\ c & d \\end{pmatrix}\n else if (command === 'begin') {\n i = parseMatrix(tokens, i, nodes);\n }\n // Symbol\n else if (isSymbol(command)) {\n nodes.push({\n type: 'symbol',\n content: getSymbol(command),\n });\n i++;\n }\n // Common operators that might be commands\n else if (command === 'times' || command === 'cdot' || command === 'pm' || command === 'mp') {\n nodes.push({\n type: 'symbol',\n content: getSymbol(command),\n });\n i++;\n }\n // Unknown command - treat as text\n else {\n nodes.push({\n type: 'text',\n content: token,\n });\n i++;\n }\n }\n // Group start\n else if (token === '{') {\n const content = parseGroup(tokens, i);\n nodes.push({\n type: 'group',\n children: content.nodes,\n });\n i = content.nextIndex;\n }\n // Regular text\n else {\n nodes.push({\n type: 'text',\n content: token,\n });\n i++;\n }\n }\n\n return nodes;\n}\n\n/**\n * Parse a matrix environment starting at the `\\begin` token.\n * Returns the index immediately after the matching `\\end{...}`.\n */\nfunction parseMatrix(tokens: string[], startIndex: number, nodes: LaTeXNode[]): number {\n let i = startIndex + 1; // skip \\begin\n\n // Read environment name inside the following {...}\n let envName = '';\n if (tokens[i] === '{') {\n i++;\n while (i < tokens.length && tokens[i] !== '}') {\n envName += tokens[i];\n i++;\n }\n if (tokens[i] === '}') i++;\n }\n\n // Collect tokens until the matching \\end (supporting nesting)\n const inner: string[] = [];\n let depth = 1;\n while (i < tokens.length && depth > 0) {\n const t = tokens[i];\n if (t === '\\\\begin') {\n depth++;\n inner.push(t);\n i++;\n } else if (t === '\\\\end') {\n depth--;\n if (depth === 0) {\n i++; // consume \\end\n if (tokens[i] === '{') {\n i++;\n while (i < tokens.length && tokens[i] !== '}') i++;\n if (tokens[i] === '}') i++;\n }\n } else {\n inner.push(t);\n i++;\n }\n } else {\n inner.push(t);\n i++;\n }\n }\n\n // Split inner tokens into rows (\\\\) and cells (&)\n const matrixRows: LaTeXNode[][][] = [];\n let rowCells: LaTeXNode[][] = [];\n let cellTokens: string[] = [];\n const flushCell = () => {\n rowCells.push(parseTokens(cellTokens));\n cellTokens = [];\n };\n const flushRow = () => {\n flushCell();\n matrixRows.push(rowCells);\n rowCells = [];\n };\n\n for (const t of inner) {\n if (t === '&') {\n flushCell();\n } else if (t === '\\\\\\\\') {\n flushRow();\n } else {\n cellTokens.push(t);\n }\n }\n if (cellTokens.length > 0 || rowCells.length > 0) {\n flushRow();\n }\n\n const delimiters = MATRIX_DELIMITERS[envName] ?? ['', ''];\n nodes.push({ type: 'matrix', rows: matrixRows, delimiters });\n\n return i;\n}\n\n/**\n * Parse a grouped expression (inside braces)\n */\nfunction parseGroup(\n tokens: string[],\n startIndex: number\n): { nodes: LaTeXNode[]; nextIndex: number } {\n // If next token is not a brace, treat single token as group\n if (tokens[startIndex] !== '{') {\n return {\n nodes: [\n {\n type: 'text',\n content: tokens[startIndex] || '',\n },\n ],\n nextIndex: startIndex + 1,\n };\n }\n\n // Skip opening brace\n let i = startIndex + 1;\n const groupTokens: string[] = [];\n let braceDepth = 1;\n\n // Collect tokens until matching closing brace\n while (i < tokens.length && braceDepth > 0) {\n const token = tokens[i];\n if (token === '{') {\n braceDepth++;\n groupTokens.push(token);\n } else if (token === '}') {\n braceDepth--;\n if (braceDepth > 0) {\n groupTokens.push(token);\n }\n } else {\n groupTokens.push(token);\n }\n i++;\n }\n\n return {\n nodes: parseTokens(groupTokens),\n nextIndex: i,\n };\n}\n","/**\n * @fileoverview LaTeX renderer using native Canvas API\n * @module plugins/latex/renderer\n */\n\nimport { LaTeXNode, LaTeXRenderContext, LaTeXDimensions } from './types';\n\n/**\n * Render a list of LaTeX nodes to canvas\n */\nexport function renderNodes(\n nodes: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n let currentX = ctx.x;\n let maxAscent = 0;\n let maxDescent = 0;\n\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n // Check if we have adjacent subscript and superscript (stacking)\n const isSub = node.type === 'subscript';\n const isSuper = node.type === 'superscript';\n const nextNode = nodes[i + 1];\n const isNextSub = nextNode?.type === 'subscript';\n const isNextSuper = nextNode?.type === 'superscript';\n\n if ((isSub && isNextSuper) || (isSuper && isNextSub)) {\n // Stack subscript and superscript at the same X coordinate\n const dims1 = renderNode(node, { ...ctx, x: currentX });\n const dims2 = renderNode(nextNode, { ...ctx, x: currentX });\n\n const width = Math.max(dims1.width, dims2.width);\n currentX += width + (ctx.fontSize * 0.15); // Scaled padding after scripts\n\n maxAscent = Math.max(maxAscent, dims1.baseline, dims2.baseline);\n maxDescent = Math.max(maxDescent, dims1.height - dims1.baseline, dims2.height - dims2.baseline);\n i++; // Skip next node\n } else {\n const dims = renderNode(node, { ...ctx, x: currentX });\n currentX += dims.width;\n\n // Add a small gap after scripts to prevent overlap with next character (Chemistry fix)\n if (isSub || isSuper) {\n currentX += ctx.fontSize * 0.12;\n }\n\n maxAscent = Math.max(maxAscent, dims.baseline);\n maxDescent = Math.max(maxDescent, dims.height - dims.baseline);\n }\n }\n\n return {\n width: currentX - ctx.x,\n height: maxAscent + maxDescent,\n baseline: maxAscent,\n };\n}\n\n/**\n * Render a single LaTeX node\n */\nfunction renderNode(node: LaTeXNode, ctx: LaTeXRenderContext): LaTeXDimensions {\n switch (node.type) {\n case 'text':\n return renderText(node.content || '', ctx);\n\n case 'textgroup':\n return renderText(node.content || '', ctx);\n\n case 'symbol':\n return renderSymbol(node.content || '', ctx);\n\n case 'superscript':\n return renderSuperscript(node.children || [], ctx);\n\n case 'subscript':\n return renderSubscript(node.children || [], ctx);\n\n case 'fraction':\n return renderFraction(\n node.numerator || [],\n node.denominator || [],\n ctx\n );\n\n case 'sqrt':\n return renderSqrt(node.children || [], ctx);\n\n case 'group':\n return renderNodes(node.children || [], ctx);\n\n case 'matrix':\n return renderMatrix(node.rows || [], node.delimiters || ['', ''], ctx);\n\n default:\n return { width: 0, height: 0, baseline: 0 };\n }\n}\n\n/**\n * Render a matrix environment (\\begin{pmatrix}...\\end{pmatrix}).\n * The matrix is vertically centered on the current baseline.\n */\nfunction renderMatrix(\n rows: LaTeXNode[][][],\n delimiters: [string, string],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n const nRows = rows.length;\n const nCols = rows.reduce((m, r) => Math.max(m, r.length), 0);\n if (nRows === 0 || nCols === 0) {\n return { width: 0, height: 0, baseline: 0 };\n }\n\n const cellPadX = ctx.fontSize * 0.35;\n const cellPadY = ctx.fontSize * 0.25;\n const delimW = ctx.fontSize * 0.35;\n\n // Measure every cell\n const cellDims: LaTeXDimensions[][] = rows.map((r) => r.map((cell) => measureNodes(cell, ctx)));\n\n const colW = new Array(nCols).fill(0);\n const rowAsc = new Array(nRows).fill(0);\n const rowDesc = new Array(nRows).fill(0);\n\n for (let r = 0; r < nRows; r++) {\n for (let c = 0; c < rows[r].length; c++) {\n const d = cellDims[r][c];\n colW[c] = Math.max(colW[c], d.width);\n rowAsc[r] = Math.max(rowAsc[r], d.baseline);\n rowDesc[r] = Math.max(rowDesc[r], d.height - d.baseline);\n }\n }\n const rowH = rowAsc.map((a, i) => a + rowDesc[i]);\n\n const totalH = rowH.reduce((s, h) => s + h, 0) + cellPadY * 2 * nRows;\n const contentW = colW.reduce((s, w) => s + w, 0) + cellPadX * 2 * nCols;\n const totalW = contentW + delimW * 2;\n\n const top = ctx.y - totalH / 2;\n\n // Delimiters\n drawDelimiter(ctx, delimiters[0], ctx.x, top, totalH, delimW, 'left');\n drawDelimiter(ctx, delimiters[1], ctx.x + totalW - delimW, top, totalH, delimW, 'right');\n\n // Cells\n let cellTop = top + cellPadY;\n for (let r = 0; r < nRows; r++) {\n let cellX = ctx.x + delimW + cellPadX;\n for (let c = 0; c < nCols; c++) {\n const cell = rows[r][c];\n if (cell) {\n const d = cellDims[r][c];\n const x = cellX + (colW[c] - d.width) / 2;\n const baselineY = cellTop + rowAsc[r];\n renderNodes(cell, { ...ctx, x, y: baselineY });\n }\n cellX += colW[c] + cellPadX * 2;\n }\n cellTop += rowH[r] + cellPadY * 2;\n }\n\n return { width: totalW, height: totalH, baseline: totalH / 2 };\n}\n\n/**\n * Draw a stretchable matrix delimiter using geometric strokes.\n */\nfunction drawDelimiter(\n ctx: LaTeXRenderContext,\n ch: string,\n x: number,\n top: number,\n height: number,\n width: number,\n side: 'left' | 'right'\n): void {\n if (!ch) return;\n const c = ctx.ctx;\n c.save();\n c.strokeStyle = ctx.color;\n c.lineWidth = Math.max(1, ctx.fontSize * 0.05);\n c.lineCap = 'round';\n c.lineJoin = 'round';\n\n const bottom = top + height;\n const tipInset = width * 0.7;\n\n const drawParen = (open: boolean) => {\n c.beginPath();\n if (open) {\n c.moveTo(x + width, top);\n c.quadraticCurveTo(x, (top + bottom) / 2, x + width, bottom);\n } else {\n c.moveTo(x, top);\n c.quadraticCurveTo(x + width, (top + bottom) / 2, x, bottom);\n }\n c.stroke();\n };\n\n const drawBracket = (open: boolean) => {\n c.beginPath();\n if (open) {\n c.moveTo(x + tipInset, top);\n c.lineTo(x, top);\n c.lineTo(x, bottom);\n c.lineTo(x + tipInset, bottom);\n } else {\n c.moveTo(x + width - tipInset, top);\n c.lineTo(x + width, top);\n c.lineTo(x + width, bottom);\n c.lineTo(x + width - tipInset, bottom);\n }\n c.stroke();\n };\n\n const drawBar = (offset: number) => {\n c.beginPath();\n c.moveTo(x + offset, top);\n c.lineTo(x + offset, bottom);\n c.stroke();\n };\n\n const drawBrace = (open: boolean) => {\n const midY = (top + bottom) / 2;\n const bx = open ? x + width : x;\n const tx = open ? x : x + width;\n c.beginPath();\n c.moveTo(bx, top);\n c.quadraticCurveTo(tx, top + height * 0.25, (bx + tx) / 2, top + height * 0.4);\n c.quadraticCurveTo(tx, midY - 1, tx, midY);\n c.quadraticCurveTo(tx, midY + 1, (bx + tx) / 2, bottom - height * 0.4);\n c.quadraticCurveTo(tx, bottom - height * 0.25, bx, bottom);\n c.stroke();\n };\n\n switch (ch) {\n case '(':\n drawParen(true);\n break;\n case ')':\n drawParen(false);\n break;\n case '[':\n drawBracket(true);\n break;\n case ']':\n drawBracket(false);\n break;\n case '{':\n drawBrace(true);\n break;\n case '}':\n drawBrace(false);\n break;\n case '|':\n drawBar(side === 'left' ? width * 0.5 : width * 0.5);\n break;\n case '‖':\n drawBar(width * 0.3);\n drawBar(width * 0.7);\n break;\n default:\n break;\n }\n\n c.restore();\n}\n\n/**\n * Render plain text\n */\nfunction renderText(text: string, ctx: LaTeXRenderContext): LaTeXDimensions {\n ctx.ctx.save();\n ctx.ctx.font = `${ctx.fontSize}px ${ctx.fontFamily}`;\n ctx.ctx.fillStyle = ctx.color;\n ctx.ctx.textAlign = 'left';\n ctx.ctx.textBaseline = 'alphabetic';\n\n const metrics = ctx.ctx.measureText(text);\n ctx.ctx.fillText(text, ctx.x, ctx.y);\n\n ctx.ctx.restore();\n\n const height = ctx.fontSize;\n const baseline = height * 0.75; // Approximate baseline\n\n return {\n width: metrics.width,\n height,\n baseline,\n };\n}\n\n/**\n * Render mathematical symbol\n */\nfunction renderSymbol(symbol: string, ctx: LaTeXRenderContext): LaTeXDimensions {\n // Use larger font size for symbols\n ctx.ctx.save();\n ctx.ctx.font = `${ctx.fontSize * 1.1}px ${ctx.fontFamily}`;\n ctx.ctx.fillStyle = ctx.color;\n ctx.ctx.textAlign = 'left';\n ctx.ctx.textBaseline = 'alphabetic';\n\n const metrics = ctx.ctx.measureText(symbol);\n ctx.ctx.fillText(symbol, ctx.x, ctx.y);\n\n ctx.ctx.restore();\n\n const height = ctx.fontSize * 1.1;\n const baseline = height * 0.75;\n\n return {\n width: metrics.width,\n height,\n baseline,\n };\n}\n\n/**\n * Render superscript (exponent)\n */\nfunction renderSuperscript(\n nodes: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n const scaledFontSize = ctx.fontSize * 0.7;\n const yOffset = -ctx.fontSize * 0.4;\n\n const dims = renderNodes(nodes, {\n ...ctx,\n fontSize: scaledFontSize,\n y: ctx.y + yOffset,\n });\n\n const subAscent = dims.baseline;\n const subDescent = dims.height - dims.baseline;\n\n return {\n width: dims.width,\n height: (subAscent - yOffset) + (subDescent + yOffset),\n baseline: subAscent - yOffset,\n };\n}\n\n/**\n * Render subscript\n */\nfunction renderSubscript(\n nodes: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n const scaledFontSize = ctx.fontSize * 0.7;\n const yOffset = ctx.fontSize * 0.3;\n\n const dims = renderNodes(nodes, {\n ...ctx,\n fontSize: scaledFontSize,\n y: ctx.y + yOffset,\n });\n\n const subAscent = dims.baseline;\n const subDescent = dims.height - dims.baseline;\n\n return {\n width: dims.width,\n height: (subAscent - yOffset) + (subDescent + yOffset),\n baseline: subAscent - yOffset,\n };\n}\n\n/**\n * Render fraction\n */\nfunction renderFraction(\n numerator: LaTeXNode[],\n denominator: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n const scaledFontSize = ctx.fontSize * 0.85;\n const lineThickness = Math.max(1, ctx.fontSize * 0.05);\n const padding = ctx.fontSize * 0.1;\n\n // Measure both parts\n const numDims = measureNodes(numerator, {\n ...ctx,\n fontSize: scaledFontSize,\n });\n const denDims = measureNodes(denominator, {\n ...ctx,\n fontSize: scaledFontSize,\n });\n\n const maxWidth = Math.max(numDims.width, denDims.width);\n const totalHeight = numDims.height + denDims.height + padding * 2 + lineThickness;\n\n // Render numerator (centered)\n const numX = ctx.x + (maxWidth - numDims.width) / 2;\n const numY = ctx.y - padding - lineThickness / 2;\n renderNodes(numerator, {\n ...ctx,\n x: numX,\n y: numY,\n fontSize: scaledFontSize,\n });\n\n // Draw fraction line\n ctx.ctx.fillStyle = ctx.color;\n ctx.ctx.fillRect(\n ctx.x,\n ctx.y - lineThickness / 2,\n maxWidth,\n lineThickness\n );\n\n // Render denominator (centered)\n const denX = ctx.x + (maxWidth - denDims.width) / 2;\n const denY = ctx.y + denDims.baseline + padding + lineThickness / 2;\n renderNodes(denominator, {\n ...ctx,\n x: denX,\n y: denY,\n fontSize: scaledFontSize,\n });\n\n return {\n width: maxWidth,\n height: totalHeight,\n baseline: totalHeight / 2,\n };\n}\n\n/**\n * Render square root\n */\nfunction renderSqrt(nodes: LaTeXNode[], ctx: LaTeXRenderContext): LaTeXDimensions {\n const contentDims = renderNodes(nodes, {\n ...ctx,\n x: ctx.x + ctx.fontSize * 0.4,\n });\n\n const totalWidth = contentDims.width + ctx.fontSize * 0.5;\n const totalHeight = contentDims.height * 1.1;\n\n // Draw radical symbol\n ctx.ctx.save();\n ctx.ctx.strokeStyle = ctx.color;\n ctx.ctx.lineWidth = Math.max(1, ctx.fontSize * 0.05);\n ctx.ctx.lineCap = 'round';\n ctx.ctx.lineJoin = 'miter';\n\n ctx.ctx.beginPath();\n // Left tick\n ctx.ctx.moveTo(ctx.x, ctx.y - totalHeight * 0.3);\n ctx.ctx.lineTo(ctx.x + ctx.fontSize * 0.15, ctx.y);\n // Down stroke\n ctx.ctx.lineTo(ctx.x + ctx.fontSize * 0.3, ctx.y - totalHeight * 0.9);\n // Top bar\n ctx.ctx.lineTo(ctx.x + totalWidth, ctx.y - totalHeight * 0.9);\n ctx.ctx.stroke();\n\n ctx.ctx.restore();\n\n return {\n width: totalWidth,\n height: totalHeight,\n baseline: contentDims.baseline,\n };\n}\n\n/**\n * Measure nodes without rendering\n */\nfunction measureNodes(\n nodes: LaTeXNode[],\n ctx: LaTeXRenderContext\n): LaTeXDimensions {\n // Create an offscreen canvas for measurement\n const canvas = document.createElement('canvas');\n const measureCtx = canvas.getContext('2d');\n if (!measureCtx) {\n return { width: 0, height: 0, baseline: 0 };\n }\n\n return renderNodes(nodes, { ...ctx, ctx: measureCtx, x: 0, y: 0 });\n}\n","/**\n * @fileoverview LaTeX rendering plugin for Velo Plot\n * @module plugins/latex\n *\n * This plugin provides native LaTeX rendering without external dependencies.\n * It supports common mathematical notation including:\n * - Greek letters (\\alpha, \\beta, \\gamma, etc.)\n * - Superscripts and subscripts (x^2, H_2O)\n * - Fractions (\\frac{a}{b})\n * - Square roots (\\sqrt{x})\n * - Mathematical operators (\\sum, \\int, \\partial, etc.)\n *\n * @example\n * ```typescript\n * import { PluginLaTeX } from 'velo-plot/plugins';\n *\n * const latex = PluginLaTeX({\n * fontSize: 16,\n * fontFamily: 'serif',\n * color: '#000000'\n * });\n *\n * await chart.use(latex);\n *\n * // Use with axis labels\n * chart.xAxis.label = '\\\\Delta E = mc^2';\n * chart.yAxis.label = '\\\\frac{\\\\partial^2 y}{\\\\partial x^2}';\n *\n * // Use with annotations\n * chart.addAnnotation({\n * type: 'text',\n * text: '\\\\sum_{i=1}^{n} x_i',\n * latex: true\n * });\n * ```\n */\n\nimport type { ChartPlugin, PluginContext } from '../types';\nimport type {\n PluginLaTeXConfig,\n LaTeXPluginAPI,\n LaTeXDimensions,\n} from './types';\nimport { parseLaTeX } from './parser';\nimport { renderNodes } from './renderer';\n\n/**\n * LaTeX rendering plugin\n */\nexport function PluginLaTeX(config: PluginLaTeXConfig = {}): ChartPlugin<PluginLaTeXConfig> {\n const defaultConfig: Required<PluginLaTeXConfig> = {\n fontSize: 14,\n fontFamily: 'serif',\n color: '#000000',\n enableCache: true,\n customSymbols: {},\n };\n\n const finalConfig = { ...defaultConfig, ...config };\n\n // Bounded caches prevent unbounded memory growth when many distinct\n // expressions are rendered over the lifetime of a chart (task 3.11).\n const MAX_CACHE_ENTRIES = 1000;\n\n /** Evict the oldest entry once the cache exceeds its cap (FIFO). */\n function capCache<K, V>(cache: Map<K, V>): void {\n if (cache.size > MAX_CACHE_ENTRIES) {\n const oldest = cache.keys().next().value;\n if (oldest !== undefined) cache.delete(oldest);\n }\n }\n\n // Cache for parsed LaTeX\n const parseCache = new Map<string, ReturnType<typeof parseLaTeX>>();\n // Cache for measured dimensions\n const measureCache = new Map<string, LaTeXDimensions>();\n\n /**\n * Clear all caches\n */\n function clearCache(): void {\n parseCache.clear();\n measureCache.clear();\n }\n\n /**\n * Get parsed AST for LaTeX string (with caching)\n */\n function getParsed(latex: string): ReturnType<typeof parseLaTeX> {\n if (!finalConfig.enableCache) {\n return parseLaTeX(latex);\n }\n\n let parsed = parseCache.get(latex);\n if (!parsed) {\n parsed = parseLaTeX(latex);\n parseCache.set(latex, parsed);\n capCache(parseCache);\n }\n return parsed;\n }\n\n /**\n * Render LaTeX to canvas\n */\n function render(\n latex: string,\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n options: Partial<PluginLaTeXConfig> = {}\n ): LaTeXDimensions {\n const renderConfig = { ...finalConfig, ...options };\n const nodes = getParsed(latex);\n\n const dims = renderNodes(nodes, {\n ctx,\n x,\n y,\n fontSize: renderConfig.fontSize,\n fontFamily: renderConfig.fontFamily,\n color: renderConfig.color,\n scale: 1,\n });\n\n return dims;\n }\n\n /**\n * Measure LaTeX dimensions without rendering\n */\n function measure(\n latex: string,\n options: Partial<PluginLaTeXConfig> = {}\n ): LaTeXDimensions {\n const cacheKey = `${latex}:${options.fontSize || finalConfig.fontSize}`;\n\n if (finalConfig.enableCache && measureCache.has(cacheKey)) {\n return measureCache.get(cacheKey)!;\n }\n\n const renderConfig = { ...finalConfig, ...options };\n const nodes = getParsed(latex);\n\n // Create offscreen canvas for measurement\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return { width: 0, height: 0, baseline: 0 };\n }\n\n const dims = renderNodes(nodes, {\n ctx,\n x: 0,\n y: 0,\n fontSize: renderConfig.fontSize,\n fontFamily: renderConfig.fontFamily,\n color: renderConfig.color,\n scale: 1,\n });\n\n if (finalConfig.enableCache) {\n measureCache.set(cacheKey, dims);\n capCache(measureCache);\n }\n\n return dims;\n }\n\n /** Expose cache sizes for leak verification / diagnostics. */\n function getCacheStats(): { parseCache: number; measureCache: number; maxEntries: number } {\n return {\n parseCache: parseCache.size,\n measureCache: measureCache.size,\n maxEntries: MAX_CACHE_ENTRIES,\n };\n }\n\n // API exposed to chart\n const api: LaTeXPluginAPI = {\n render,\n measure,\n clearCache,\n getCacheStats,\n };\n\n return {\n manifest: {\n name: 'velo-plot-latex',\n version: '1.0.0',\n description: 'Native LaTeX rendering for mathematical expressions',\n provides: ['latex'],\n tags: ['latex', 'math', 'typography'],\n },\n\n onInit(ctx: PluginContext) {\n // API is accessed via plugin bridge, no need to set property on chart which has only a getter\n ctx.log.info('LaTeX plugin initialized');\n },\n\n onDestroy(ctx: PluginContext) {\n clearCache();\n ctx.log.info('LaTeX plugin destroyed');\n },\n\n api,\n };\n}\n\n// Type exports\nexport type { PluginLaTeXConfig, LaTeXPluginAPI, LaTeXDimensions };\n\n"],"names":["MATRIX_DELIMITERS","ALPHABET_MAPS","BLACKBOARD","CALLIGRAPHIC","FRAKTUR","parseLaTeX","latex","tokens","tokenize","parseTokens","extractTextContent","nodes","result","node","i","char","command","token","content","parseGroup","numerator","denominator","textContent","map","raw","mapped","ch","parseMatrix","isSymbol","getSymbol","startIndex","envName","inner","depth","t","matrixRows","rowCells","cellTokens","flushCell","flushRow","delimiters","groupTokens","braceDepth","renderNodes","ctx","currentX","maxAscent","maxDescent","isSub","isSuper","nextNode","isNextSub","isNextSuper","dims1","renderNode","dims2","width","dims","renderText","renderSymbol","renderSuperscript","renderSubscript","renderFraction","renderSqrt","renderMatrix","rows","nRows","nCols","m","r","cellPadX","cellPadY","delimW","cellDims","cell","measureNodes","colW","rowAsc","rowDesc","c","d","rowH","a","totalH","s","h","totalW","w","top","drawDelimiter","cellTop","cellX","x","baselineY","height","side","bottom","tipInset","drawParen","open","drawBracket","drawBar","offset","drawBrace","midY","bx","tx","text","metrics","baseline","symbol","scaledFontSize","yOffset","subAscent","subDescent","lineThickness","padding","numDims","denDims","maxWidth","totalHeight","numX","numY","denX","denY","contentDims","totalWidth","measureCtx","PluginLaTeX","config","finalConfig","MAX_CACHE_ENTRIES","capCache","cache","oldest","parseCache","measureCache","clearCache","getParsed","parsed","render","options","renderConfig","measure","cacheKey","getCacheStats"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './lazy-load/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './lazy-load/index'
|
|
3
|
+
export default VeloPlot
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './loading/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './loading/index'
|
|
3
|
+
export default VeloPlot
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './ml-integration/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './ml-integration/index'
|
|
3
|
+
export default VeloPlot
|
|
@@ -259,7 +259,7 @@ function X(i) {
|
|
|
259
259
|
return new I(i);
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
|
-
function
|
|
262
|
+
function V(i) {
|
|
263
263
|
const t = i.length, n = new Array(t), e = new Array(t);
|
|
264
264
|
for (let s = 0; s < t; s++) {
|
|
265
265
|
let l = 0, r = 0;
|
|
@@ -274,7 +274,7 @@ function Y(i) {
|
|
|
274
274
|
function R(i) {
|
|
275
275
|
return i.reduce((t, n) => t + n, 0) / i.length;
|
|
276
276
|
}
|
|
277
|
-
function
|
|
277
|
+
function Y(i) {
|
|
278
278
|
const t = R(i), n = i.reduce((e, s) => e + Math.pow(s - t, 2), 0) / i.length;
|
|
279
279
|
return Math.sqrt(n);
|
|
280
280
|
}
|
|
@@ -290,7 +290,7 @@ function $(i, t) {
|
|
|
290
290
|
const E = {
|
|
291
291
|
name: "velo-plot-ml-integration",
|
|
292
292
|
version: "1.0.0",
|
|
293
|
-
description: "Machine Learning Integration Bridge for
|
|
293
|
+
description: "Machine Learning Integration Bridge for Velo Plot",
|
|
294
294
|
provides: ["ml", "prediction", "inference"],
|
|
295
295
|
tags: ["ml", "ai", "analysis"]
|
|
296
296
|
};
|
|
@@ -353,9 +353,9 @@ function _(i = {}) {
|
|
|
353
353
|
return Array.from(n.values()).map((r) => r.getInfo());
|
|
354
354
|
},
|
|
355
355
|
stats: {
|
|
356
|
-
fft:
|
|
356
|
+
fft: V,
|
|
357
357
|
mean: R,
|
|
358
|
-
standardDeviation:
|
|
358
|
+
standardDeviation: Y,
|
|
359
359
|
correlation: $
|
|
360
360
|
}
|
|
361
361
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ml-integration.js","sources":["../../src/plugins/ml-integration/native-algorithms.ts","../../src/plugins/ml-integration/index.ts"],"sourcesContent":["/**\n * Native ML Integration Plugin - Core Algorithms\n * \n * Implements machine learning algorithms natively without third-party dependencies.\n * Includes simple neural networks, statistical models, and signal processing.\n * \n * @packageDocumentation\n * @module plugins/ml-integration\n */\n\nimport type {\n MLModelAPI,\n ModelConfig,\n PredictionInput,\n PredictionResult\n} from './types';\n\n// ============================================\n// Native Neural Network Implementation\n// ============================================\n\ninterface NativeNeuralNetwork {\n layers: NeuralLayer[];\n learningRate: number;\n epochs: number;\n}\n\ninterface NeuralLayer {\n type: 'dense' | 'activation';\n weights: number[][];\n biases: number[];\n activation?: 'relu' | 'sigmoid' | 'tanh' | 'linear';\n}\n\nexport class SimpleNeuralNetwork implements MLModelAPI {\n private network: NativeNeuralNetwork;\n private config: ModelConfig;\n private ready = false;\n\n constructor(config: ModelConfig) {\n this.config = config;\n this.network = {\n layers: [],\n learningRate: 0.01,\n epochs: 100\n };\n }\n\n get id(): string { return this.config.id; }\n get name(): string { return this.config.name; }\n get type(): string { return this.config.type; }\n\n async predict(input: PredictionInput): Promise<PredictionResult> {\n const startTime = performance.now();\n \n const inputData = Array.from(input.data as number[]);\n const outputData = this.forwardPass(inputData);\n \n const processingTime = performance.now() - startTime;\n\n return {\n modelId: this.config.id,\n output: new Float32Array(outputData),\n outputShape: [outputData.length],\n timestamp: Date.now(),\n processingTime\n };\n }\n\n private forwardPass(input: number[]): number[] {\n let activations = input;\n \n for (const layer of this.network.layers) {\n if (layer.type === 'dense') {\n activations = this.denseLayer(activations, layer.weights, layer.biases);\n }\n \n if (layer.activation) {\n activations = this.applyActivation(activations, layer.activation);\n }\n }\n \n return activations;\n }\n\n private denseLayer(input: number[], weights: number[][], biases: number[]): number[] {\n const output: number[] = [];\n for (let i = 0; i < weights.length; i++) {\n let sum = biases[i];\n for (let j = 0; j < input.length; j++) {\n sum += input[j] * weights[i][j];\n }\n output.push(sum);\n }\n return output;\n }\n\n private applyActivation(input: number[], activation: string): number[] {\n switch (activation) {\n case 'relu':\n return input.map(x => Math.max(0, x));\n case 'sigmoid':\n return input.map(x => 1 / (1 + Math.exp(-x)));\n case 'tanh':\n return input.map(x => Math.tanh(x));\n default:\n return input;\n }\n }\n\n getInfo(): ModelConfig {\n return { ...this.config };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n async warmup(): Promise<void> {\n const dummyInput = new Array(10).fill(0.1);\n await this.predict({ data: dummyInput });\n this.ready = true;\n }\n\n dispose(): void {\n this.ready = false;\n }\n}\n\n// ============================================\n// Native Statistical Models\n// ============================================\n\n/** Result returned when training a small on-chart model (task 3.17). */\nexport interface TrainingResult {\n coefficients: number[];\n intercept: number;\n /** Fitted values for the training inputs. */\n fitted: number[];\n /** Residuals (observed - fitted), suitable for a residual plot. */\n residuals: number[];\n /** Coefficient of determination on the training set. */\n r2: number;\n /** Root mean squared error on the training set. */\n rmse: number;\n}\n\nexport class NativeLinearRegression implements MLModelAPI {\n private config: ModelConfig;\n private coefficients: number[] = [];\n private intercept = 0;\n private ready = false;\n private lastTraining: TrainingResult | null = null;\n\n constructor(config: ModelConfig) {\n this.config = config;\n }\n\n get id(): string { return this.config.id; }\n get name(): string { return this.config.name; }\n get type(): string { return this.config.type; }\n\n async predict(input: PredictionInput): Promise<PredictionResult> {\n const startTime = performance.now();\n\n // Each input entry is treated as a single-feature observation.\n const inputData = Array.from(input.data);\n const predictions = inputData.map((x) => {\n const feat = x as number;\n let result = this.intercept;\n // Univariate: only the first coefficient multiplies the scalar input.\n // Multivariate models should call `predictRows`.\n if (this.coefficients.length > 0) {\n result += this.coefficients[0] * feat;\n }\n return result;\n });\n\n const processingTime = performance.now() - startTime;\n\n return {\n modelId: this.config.id,\n output: new Float32Array(predictions),\n outputShape: [predictions.length],\n timestamp: Date.now(),\n processingTime\n };\n }\n\n /** Predict from full feature rows (multivariate). */\n predictRows(rows: number[][]): number[] {\n return rows.map((row) => {\n let result = this.intercept;\n for (let i = 0; i < this.coefficients.length && i < row.length; i++) {\n result += this.coefficients[i] * row[i];\n }\n return result;\n });\n }\n\n train(data: { x: number[][], y: number[] }): TrainingResult {\n const n = data.x.length;\n\n // Design matrix with an intercept column.\n const X: number[][] = [];\n for (let i = 0; i < n; i++) {\n X.push([1, ...data.x[i]]);\n }\n\n // Normal equation: β = (XᵀX)⁻¹ Xᵀy\n const XtX = matrixMultiply(transpose(X), X);\n const XtY = matrixMultiply(transpose(X), data.y.map((y) => [y]));\n\n const XtXInv = matrixInverse(XtX);\n const beta = matrixMultiply(XtXInv, XtY);\n\n this.intercept = beta[0][0];\n this.coefficients = beta.slice(1).map((row) => row[0]);\n this.ready = true;\n\n // Fit diagnostics for a residual plot.\n const fitted = this.predictRows(data.x);\n const residuals = data.y.map((y, i) => y - fitted[i]);\n const meanY = data.y.reduce((s, v) => s + v, 0) / (n || 1);\n const sse = residuals.reduce((s, r) => s + r * r, 0);\n const sst = data.y.reduce((s, y) => s + (y - meanY) ** 2, 0);\n const r2 = sst > 0 ? 1 - sse / sst : 0;\n const rmse = Math.sqrt(sse / (n || 1));\n\n this.lastTraining = { coefficients: this.coefficients, intercept: this.intercept, fitted, residuals, r2, rmse };\n return this.lastTraining;\n }\n\n getTrainingResult(): TrainingResult | null {\n return this.lastTraining;\n }\n\n getInfo(): ModelConfig {\n return { ...this.config };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n async warmup(): Promise<void> {\n this.coefficients = [1.0];\n this.intercept = 0.0;\n this.ready = true;\n }\n\n dispose(): void {\n this.ready = false;\n this.lastTraining = null;\n }\n}\n\n// ============================================\n// Matrix utilities (general purpose)\n// ============================================\n\nfunction transpose(matrix: number[][]): number[][] {\n return matrix[0].map((_, colIndex) => matrix.map((row) => row[colIndex]));\n}\n\nfunction matrixMultiply(a: number[][], b: number[][]): number[][] {\n const result: number[][] = [];\n for (let i = 0; i < a.length; i++) {\n result[i] = [];\n for (let j = 0; j < b[0].length; j++) {\n let sum = 0;\n for (let k = 0; k < b.length; k++) {\n sum += a[i][k] * b[k][j];\n }\n result[i][j] = sum;\n }\n }\n return result;\n}\n\n/**\n * General square-matrix inverse via Gauss-Jordan elimination with partial\n * pivoting. Falls back to the identity for singular matrices so callers never\n * receive NaNs. Replaces the previous 2x2-only stub (task 3.17 fix).\n */\nexport function matrixInverse(matrix: number[][]): number[][] {\n const n = matrix.length;\n // Augment [A | I]\n const M = matrix.map((row, i) => [\n ...row,\n ...Array.from({ length: n }, (_, j) => (i === j ? 1 : 0)),\n ]);\n\n for (let col = 0; col < n; col++) {\n // Partial pivot\n let pivot = col;\n for (let r = col + 1; r < n; r++) {\n if (Math.abs(M[r][col]) > Math.abs(M[pivot][col])) pivot = r;\n }\n if (Math.abs(M[pivot][col]) < 1e-12) {\n // Singular - return identity as a safe fallback.\n return matrix.map((row, i) => row.map((_, j) => (i === j ? 1 : 0)));\n }\n [M[col], M[pivot]] = [M[pivot], M[col]];\n\n const pivotVal = M[col][col];\n for (let c = 0; c < 2 * n; c++) M[col][c] /= pivotVal;\n\n for (let r = 0; r < n; r++) {\n if (r === col) continue;\n const factor = M[r][col];\n for (let c = 0; c < 2 * n; c++) M[r][c] -= factor * M[col][c];\n }\n }\n\n return M.map((row) => row.slice(n));\n}\n\n// ============================================\n// Native Signal Processing\n// ============================================\n\nexport class NativeSignalProcessor implements MLModelAPI {\n private config: ModelConfig;\n private filterType: 'lowpass' | 'highpass' | 'bandpass';\n private cutoffFrequency: number;\n private sampleRate: number;\n private ready = false;\n\n constructor(config: ModelConfig) {\n this.config = config;\n // Extract parameters from metadata\n this.filterType = (config.metadata?.filterType as any) || 'lowpass';\n this.cutoffFrequency = config.metadata?.cutoffFrequency || 1000;\n this.sampleRate = config.metadata?.sampleRate || 44100;\n }\n\n get id(): string { return this.config.id; }\n get name(): string { return this.config.name; }\n get type(): string { return this.config.type; }\n\n async predict(input: PredictionInput): Promise<PredictionResult> {\n const startTime = performance.now();\n \n const inputData = Array.from(input.data as number[]);\n const filteredData = this.applyFilter(inputData);\n \n const processingTime = performance.now() - startTime;\n\n return {\n modelId: this.config.id,\n output: new Float32Array(filteredData),\n outputShape: [filteredData.length],\n timestamp: Date.now(),\n processingTime\n };\n }\n\n private applyFilter(data: number[]): number[] {\n switch (this.filterType) {\n case 'lowpass':\n return this.lowpassFilter(data);\n case 'highpass':\n return this.highpassFilter(data);\n case 'bandpass':\n return this.bandpassFilter(data);\n default:\n return data;\n }\n }\n\n private lowpassFilter(data: number[]): number[] {\n // Simple exponential moving average low-pass filter\n const alpha = 2 * Math.PI * this.cutoffFrequency / this.sampleRate;\n const smoothedAlpha = alpha / (1 + alpha);\n \n const filtered: number[] = [data[0]];\n for (let i = 1; i < data.length; i++) {\n filtered.push(smoothedAlpha * data[i] + (1 - smoothedAlpha) * filtered[i - 1]);\n }\n return filtered;\n }\n\n private highpassFilter(data: number[]): number[] {\n // High-pass filter using difference\n const filtered: number[] = [];\n for (let i = 1; i < data.length; i++) {\n filtered.push(data[i] - data[i - 1]);\n }\n return filtered;\n }\n\n private bandpassFilter(data: number[]): number[] {\n // Band-pass filter using combination of low-pass and high-pass\n const lowpass = this.lowpassFilter(data);\n return this.highpassFilter(lowpass);\n }\n\n getInfo(): ModelConfig {\n return { ...this.config };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n async warmup(): Promise<void> {\n this.ready = true;\n }\n\n dispose(): void {\n this.ready = false;\n }\n}\n\n// ============================================\n// Native Model Factory\n// ============================================\n\nexport function createNativeModel(config: ModelConfig): MLModelAPI {\n switch (config.type) {\n case 'neural-network':\n return new SimpleNeuralNetwork(config);\n case 'linear-regression':\n return new NativeLinearRegression(config);\n case 'signal-processor':\n return new NativeSignalProcessor(config);\n default:\n // Default to simple linear model\n return new NativeLinearRegression(config);\n }\n}\n\n// ============================================\n// Native FFT Implementation\n// ============================================\n\nexport function nativeFFT(data: number[]): { real: number[]; imag: number[] } {\n const n = data.length;\n const real: number[] = new Array(n);\n const imag: number[] = new Array(n);\n \n // Simplified DFT (not optimized FFT)\n for (let k = 0; k < n; k++) {\n let sumReal = 0;\n let sumImag = 0;\n \n for (let t = 0; t < n; t++) {\n const angle = -2 * Math.PI * k * t / n;\n sumReal += data[t] * Math.cos(angle);\n sumImag += data[t] * Math.sin(angle);\n }\n \n real[k] = sumReal;\n imag[k] = sumImag;\n }\n \n return { real, imag };\n}\n\n// ============================================\n// Native Statistical Functions\n// ============================================\n\nexport function nativeMean(data: number[]): number {\n return data.reduce((sum, val) => sum + val, 0) / data.length;\n}\n\nexport function nativeStandardDeviation(data: number[]): number {\n const mean = nativeMean(data);\n const variance = data.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / data.length;\n return Math.sqrt(variance);\n}\n\nexport function nativeCorrelation(x: number[], y: number[]): number {\n const n = x.length;\n const meanX = nativeMean(x);\n const meanY = nativeMean(y);\n \n let numerator = 0;\n let denomX = 0;\n let denomY = 0;\n \n for (let i = 0; i < n; i++) {\n const dx = x[i] - meanX;\n const dy = y[i] - meanY;\n numerator += dx * dy;\n denomX += dx * dx;\n denomY += dy * dy;\n }\n \n return numerator / Math.sqrt(denomX * denomY);\n}","import type { \n PluginMLIntegrationConfig, \n MLIntegrationAPI, \n MLModelAPI, \n PredictionResult, \n VisualizationConfig\n} from './types';\nimport { \n createNativeModel,\n nativeFFT, \n nativeMean, \n nativeStandardDeviation, \n nativeCorrelation \n} from './native-algorithms';\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n AfterRenderEvent\n} from '../types';\n\nconst manifestML: PluginManifest = {\n name: \"velo-plot-ml-integration\",\n version: \"1.0.0\",\n description: \"Machine Learning Integration Bridge for Sci Plot\",\n provides: [\"ml\", \"prediction\", \"inference\"],\n tags: [\"ml\", \"ai\", \"analysis\"],\n};\n\nexport function PluginMLIntegration(\n userConfig: Partial<PluginMLIntegrationConfig> = {}\n): ChartPlugin<PluginMLIntegrationConfig> {\n let ctx: PluginContext | null = null;\n const models = new Map<string, MLModelAPI>();\n const activeVisualizations = new Map<string, { result: PredictionResult, config: VisualizationConfig }>();\n\n // Register initial models from config\n if (userConfig.models) {\n userConfig.models.forEach(m => models.set(m.id, createNativeModel(m)));\n }\n\n const api: MLIntegrationAPI & Record<string, unknown> = {\n registerModel(model: MLModelAPI) {\n if (!model.id) {\n ctx?.log.error(\"Cannot register model without id\");\n return;\n }\n models.set(model.id, model);\n ctx?.log.info(`Model registered: ${model.name || 'Unnamed'} (${model.id})`);\n },\n\n async runInference(modelId: string, seriesId: string) {\n const model = models.get(modelId);\n if (!model) throw new Error(`Model not found: ${modelId}`);\n\n const seriesData = ctx?.data.getSeriesData(seriesId);\n if (!seriesData) throw new Error(`Series not found: ${seriesId}`);\n\n // Convert to Float32Array for model compatibility\n const data = new Float32Array(seriesData.y);\n\n const result = await model.predict({ data });\n // Attach X values for visualization\n result.xValues = seriesData.x;\n return result;\n },\n\n visualizeResults(result: PredictionResult, config: VisualizationConfig = {}) {\n const vizId = `ml-viz-${Math.random().toString(36).substr(2, 9)}`;\n activeVisualizations.set(vizId, { \n result, \n config: { ...userConfig.defaultVisualization, ...config } \n });\n ctx?.requestRender();\n return vizId;\n },\n\n clearResults(visualizationId?: string) {\n if (visualizationId) {\n activeVisualizations.delete(visualizationId);\n } else {\n activeVisualizations.clear();\n }\n ctx?.requestRender();\n },\n\n /**\n * Alias for {@link visualizeResults} that reads as an intent-revealing\n * name for the prediction-overlay use case (task 3.18).\n */\n visualizePredictions(result: PredictionResult, config: VisualizationConfig = {}) {\n return api.visualizeResults(result, config);\n },\n\n /**\n * Train a small regression model on the fly (task 3.17). Creates a native\n * linear-regression model when the id does not yet exist. Returns fit\n * diagnostics including residuals for a residual plot.\n */\n trainModel(modelId: string, data: { x: number[][]; y: number[] }) {\n let model = models.get(modelId) as any;\n if (!model) {\n model = createNativeModel({ id: modelId, name: modelId, type: 'linear-regression' });\n models.set(modelId, model);\n }\n if (typeof model.train !== 'function') {\n throw new Error(`Model '${modelId}' does not support training`);\n }\n return model.train(data);\n },\n\n /** Retrieve the last training diagnostics for a model, if any. */\n getTrainingResult(modelId: string) {\n const model = models.get(modelId) as any;\n return model?.getTrainingResult?.() ?? null;\n },\n\n /** List registered model descriptors (for the ML audit / introspection). */\n listModels() {\n return Array.from(models.values()).map((m) => m.getInfo());\n },\n\n stats: {\n fft: nativeFFT,\n mean: nativeMean,\n standardDeviation: nativeStandardDeviation,\n correlation: nativeCorrelation\n }\n };\n\n function drawMLVisualizations(pCtx: PluginContext) {\n const { render, coords } = pCtx;\n const { ctx2d } = render;\n if (!ctx2d) return;\n\n activeVisualizations.forEach((viz) => {\n const { result, config } = viz;\n const { output, xValues, confidence } = result;\n if (!xValues) return;\n\n const n = Math.min(xValues.length, output.length);\n\n ctx2d.save();\n\n // 1. Draw Confidence Interval (as filled area)\n if (config.showConfidenceInterval && confidence && confidence.length === n) {\n ctx2d.beginPath();\n const opacity = config.intervalOpacity ?? 0.2;\n ctx2d.fillStyle = (config.lineStyle?.color || '#3b82f6') + Math.floor(opacity * 255).toString(16).padStart(2, '0');\n \n // Forward: upper bound\n for (let i = 0; i < n; i++) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(output[i] + confidence[i]);\n if (i === 0) ctx2d.moveTo(px, py);\n else ctx2d.lineTo(px, py);\n }\n \n // Backward: lower bound\n for (let i = n - 1; i >= 0; i--) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(output[i] - confidence[i]);\n ctx2d.lineTo(px, py);\n }\n \n ctx2d.closePath();\n ctx2d.fill();\n }\n\n // 2. Draw Prediction Line\n ctx2d.beginPath();\n ctx2d.strokeStyle = config.lineStyle?.color || '#3b82f6';\n ctx2d.lineWidth = config.lineStyle?.width || 2;\n if (config.lineStyle?.dash) ctx2d.setLineDash(config.lineStyle.dash);\n\n for (let i = 0; i < n; i++) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(output[i]);\n if (i === 0) ctx2d.moveTo(px, py);\n else ctx2d.lineTo(px, py);\n }\n ctx2d.stroke();\n\n ctx2d.restore();\n });\n }\n\n return {\n manifest: manifestML,\n\n onInit(c: PluginContext) {\n ctx = c;\n },\n\n onRenderOverlay(pCtx: PluginContext, _event: AfterRenderEvent) {\n drawMLVisualizations(pCtx);\n },\n\n api\n };\n}\n\nexport default PluginMLIntegration;\n\nexport type { \n PluginMLIntegrationConfig, \n MLIntegrationAPI, \n MLModelAPI, \n PredictionResult, \n VisualizationConfig \n} from './types';"],"names":["SimpleNeuralNetwork","config","__publicField","input","startTime","inputData","outputData","processingTime","activations","layer","weights","biases","output","i","sum","j","activation","x","dummyInput","NativeLinearRegression","predictions","feat","result","rows","row","data","X","XtX","matrixMultiply","transpose","XtY","y","XtXInv","matrixInverse","beta","fitted","residuals","meanY","s","v","sse","r","sst","r2","rmse","matrix","_","colIndex","a","b","k","n","M","col","pivot","pivotVal","c","factor","NativeSignalProcessor","_a","_b","_c","filteredData","alpha","smoothedAlpha","filtered","lowpass","createNativeModel","nativeFFT","real","imag","sumReal","sumImag","t","angle","nativeMean","val","nativeStandardDeviation","mean","variance","nativeCorrelation","meanX","numerator","denomX","denomY","dx","dy","manifestML","PluginMLIntegration","userConfig","ctx","models","activeVisualizations","m","api","model","modelId","seriesId","seriesData","vizId","visualizationId","drawMLVisualizations","pCtx","render","coords","ctx2d","viz","_d","xValues","confidence","opacity","px","py","_event"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ml-integration.js","sources":["../../src/plugins/ml-integration/native-algorithms.ts","../../src/plugins/ml-integration/index.ts"],"sourcesContent":["/**\n * Native ML Integration Plugin - Core Algorithms\n * \n * Implements machine learning algorithms natively without third-party dependencies.\n * Includes simple neural networks, statistical models, and signal processing.\n * \n * @packageDocumentation\n * @module plugins/ml-integration\n */\n\nimport type {\n MLModelAPI,\n ModelConfig,\n PredictionInput,\n PredictionResult\n} from './types';\n\n// ============================================\n// Native Neural Network Implementation\n// ============================================\n\ninterface NativeNeuralNetwork {\n layers: NeuralLayer[];\n learningRate: number;\n epochs: number;\n}\n\ninterface NeuralLayer {\n type: 'dense' | 'activation';\n weights: number[][];\n biases: number[];\n activation?: 'relu' | 'sigmoid' | 'tanh' | 'linear';\n}\n\nexport class SimpleNeuralNetwork implements MLModelAPI {\n private network: NativeNeuralNetwork;\n private config: ModelConfig;\n private ready = false;\n\n constructor(config: ModelConfig) {\n this.config = config;\n this.network = {\n layers: [],\n learningRate: 0.01,\n epochs: 100\n };\n }\n\n get id(): string { return this.config.id; }\n get name(): string { return this.config.name; }\n get type(): string { return this.config.type; }\n\n async predict(input: PredictionInput): Promise<PredictionResult> {\n const startTime = performance.now();\n \n const inputData = Array.from(input.data as number[]);\n const outputData = this.forwardPass(inputData);\n \n const processingTime = performance.now() - startTime;\n\n return {\n modelId: this.config.id,\n output: new Float32Array(outputData),\n outputShape: [outputData.length],\n timestamp: Date.now(),\n processingTime\n };\n }\n\n private forwardPass(input: number[]): number[] {\n let activations = input;\n \n for (const layer of this.network.layers) {\n if (layer.type === 'dense') {\n activations = this.denseLayer(activations, layer.weights, layer.biases);\n }\n \n if (layer.activation) {\n activations = this.applyActivation(activations, layer.activation);\n }\n }\n \n return activations;\n }\n\n private denseLayer(input: number[], weights: number[][], biases: number[]): number[] {\n const output: number[] = [];\n for (let i = 0; i < weights.length; i++) {\n let sum = biases[i];\n for (let j = 0; j < input.length; j++) {\n sum += input[j] * weights[i][j];\n }\n output.push(sum);\n }\n return output;\n }\n\n private applyActivation(input: number[], activation: string): number[] {\n switch (activation) {\n case 'relu':\n return input.map(x => Math.max(0, x));\n case 'sigmoid':\n return input.map(x => 1 / (1 + Math.exp(-x)));\n case 'tanh':\n return input.map(x => Math.tanh(x));\n default:\n return input;\n }\n }\n\n getInfo(): ModelConfig {\n return { ...this.config };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n async warmup(): Promise<void> {\n const dummyInput = new Array(10).fill(0.1);\n await this.predict({ data: dummyInput });\n this.ready = true;\n }\n\n dispose(): void {\n this.ready = false;\n }\n}\n\n// ============================================\n// Native Statistical Models\n// ============================================\n\n/** Result returned when training a small on-chart model (task 3.17). */\nexport interface TrainingResult {\n coefficients: number[];\n intercept: number;\n /** Fitted values for the training inputs. */\n fitted: number[];\n /** Residuals (observed - fitted), suitable for a residual plot. */\n residuals: number[];\n /** Coefficient of determination on the training set. */\n r2: number;\n /** Root mean squared error on the training set. */\n rmse: number;\n}\n\nexport class NativeLinearRegression implements MLModelAPI {\n private config: ModelConfig;\n private coefficients: number[] = [];\n private intercept = 0;\n private ready = false;\n private lastTraining: TrainingResult | null = null;\n\n constructor(config: ModelConfig) {\n this.config = config;\n }\n\n get id(): string { return this.config.id; }\n get name(): string { return this.config.name; }\n get type(): string { return this.config.type; }\n\n async predict(input: PredictionInput): Promise<PredictionResult> {\n const startTime = performance.now();\n\n // Each input entry is treated as a single-feature observation.\n const inputData = Array.from(input.data);\n const predictions = inputData.map((x) => {\n const feat = x as number;\n let result = this.intercept;\n // Univariate: only the first coefficient multiplies the scalar input.\n // Multivariate models should call `predictRows`.\n if (this.coefficients.length > 0) {\n result += this.coefficients[0] * feat;\n }\n return result;\n });\n\n const processingTime = performance.now() - startTime;\n\n return {\n modelId: this.config.id,\n output: new Float32Array(predictions),\n outputShape: [predictions.length],\n timestamp: Date.now(),\n processingTime\n };\n }\n\n /** Predict from full feature rows (multivariate). */\n predictRows(rows: number[][]): number[] {\n return rows.map((row) => {\n let result = this.intercept;\n for (let i = 0; i < this.coefficients.length && i < row.length; i++) {\n result += this.coefficients[i] * row[i];\n }\n return result;\n });\n }\n\n train(data: { x: number[][], y: number[] }): TrainingResult {\n const n = data.x.length;\n\n // Design matrix with an intercept column.\n const X: number[][] = [];\n for (let i = 0; i < n; i++) {\n X.push([1, ...data.x[i]]);\n }\n\n // Normal equation: β = (XᵀX)⁻¹ Xᵀy\n const XtX = matrixMultiply(transpose(X), X);\n const XtY = matrixMultiply(transpose(X), data.y.map((y) => [y]));\n\n const XtXInv = matrixInverse(XtX);\n const beta = matrixMultiply(XtXInv, XtY);\n\n this.intercept = beta[0][0];\n this.coefficients = beta.slice(1).map((row) => row[0]);\n this.ready = true;\n\n // Fit diagnostics for a residual plot.\n const fitted = this.predictRows(data.x);\n const residuals = data.y.map((y, i) => y - fitted[i]);\n const meanY = data.y.reduce((s, v) => s + v, 0) / (n || 1);\n const sse = residuals.reduce((s, r) => s + r * r, 0);\n const sst = data.y.reduce((s, y) => s + (y - meanY) ** 2, 0);\n const r2 = sst > 0 ? 1 - sse / sst : 0;\n const rmse = Math.sqrt(sse / (n || 1));\n\n this.lastTraining = { coefficients: this.coefficients, intercept: this.intercept, fitted, residuals, r2, rmse };\n return this.lastTraining;\n }\n\n getTrainingResult(): TrainingResult | null {\n return this.lastTraining;\n }\n\n getInfo(): ModelConfig {\n return { ...this.config };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n async warmup(): Promise<void> {\n this.coefficients = [1.0];\n this.intercept = 0.0;\n this.ready = true;\n }\n\n dispose(): void {\n this.ready = false;\n this.lastTraining = null;\n }\n}\n\n// ============================================\n// Matrix utilities (general purpose)\n// ============================================\n\nfunction transpose(matrix: number[][]): number[][] {\n return matrix[0].map((_, colIndex) => matrix.map((row) => row[colIndex]));\n}\n\nfunction matrixMultiply(a: number[][], b: number[][]): number[][] {\n const result: number[][] = [];\n for (let i = 0; i < a.length; i++) {\n result[i] = [];\n for (let j = 0; j < b[0].length; j++) {\n let sum = 0;\n for (let k = 0; k < b.length; k++) {\n sum += a[i][k] * b[k][j];\n }\n result[i][j] = sum;\n }\n }\n return result;\n}\n\n/**\n * General square-matrix inverse via Gauss-Jordan elimination with partial\n * pivoting. Falls back to the identity for singular matrices so callers never\n * receive NaNs. Replaces the previous 2x2-only stub (task 3.17 fix).\n */\nexport function matrixInverse(matrix: number[][]): number[][] {\n const n = matrix.length;\n // Augment [A | I]\n const M = matrix.map((row, i) => [\n ...row,\n ...Array.from({ length: n }, (_, j) => (i === j ? 1 : 0)),\n ]);\n\n for (let col = 0; col < n; col++) {\n // Partial pivot\n let pivot = col;\n for (let r = col + 1; r < n; r++) {\n if (Math.abs(M[r][col]) > Math.abs(M[pivot][col])) pivot = r;\n }\n if (Math.abs(M[pivot][col]) < 1e-12) {\n // Singular - return identity as a safe fallback.\n return matrix.map((row, i) => row.map((_, j) => (i === j ? 1 : 0)));\n }\n [M[col], M[pivot]] = [M[pivot], M[col]];\n\n const pivotVal = M[col][col];\n for (let c = 0; c < 2 * n; c++) M[col][c] /= pivotVal;\n\n for (let r = 0; r < n; r++) {\n if (r === col) continue;\n const factor = M[r][col];\n for (let c = 0; c < 2 * n; c++) M[r][c] -= factor * M[col][c];\n }\n }\n\n return M.map((row) => row.slice(n));\n}\n\n// ============================================\n// Native Signal Processing\n// ============================================\n\nexport class NativeSignalProcessor implements MLModelAPI {\n private config: ModelConfig;\n private filterType: 'lowpass' | 'highpass' | 'bandpass';\n private cutoffFrequency: number;\n private sampleRate: number;\n private ready = false;\n\n constructor(config: ModelConfig) {\n this.config = config;\n // Extract parameters from metadata\n this.filterType = (config.metadata?.filterType as any) || 'lowpass';\n this.cutoffFrequency = config.metadata?.cutoffFrequency || 1000;\n this.sampleRate = config.metadata?.sampleRate || 44100;\n }\n\n get id(): string { return this.config.id; }\n get name(): string { return this.config.name; }\n get type(): string { return this.config.type; }\n\n async predict(input: PredictionInput): Promise<PredictionResult> {\n const startTime = performance.now();\n \n const inputData = Array.from(input.data as number[]);\n const filteredData = this.applyFilter(inputData);\n \n const processingTime = performance.now() - startTime;\n\n return {\n modelId: this.config.id,\n output: new Float32Array(filteredData),\n outputShape: [filteredData.length],\n timestamp: Date.now(),\n processingTime\n };\n }\n\n private applyFilter(data: number[]): number[] {\n switch (this.filterType) {\n case 'lowpass':\n return this.lowpassFilter(data);\n case 'highpass':\n return this.highpassFilter(data);\n case 'bandpass':\n return this.bandpassFilter(data);\n default:\n return data;\n }\n }\n\n private lowpassFilter(data: number[]): number[] {\n // Simple exponential moving average low-pass filter\n const alpha = 2 * Math.PI * this.cutoffFrequency / this.sampleRate;\n const smoothedAlpha = alpha / (1 + alpha);\n \n const filtered: number[] = [data[0]];\n for (let i = 1; i < data.length; i++) {\n filtered.push(smoothedAlpha * data[i] + (1 - smoothedAlpha) * filtered[i - 1]);\n }\n return filtered;\n }\n\n private highpassFilter(data: number[]): number[] {\n // High-pass filter using difference\n const filtered: number[] = [];\n for (let i = 1; i < data.length; i++) {\n filtered.push(data[i] - data[i - 1]);\n }\n return filtered;\n }\n\n private bandpassFilter(data: number[]): number[] {\n // Band-pass filter using combination of low-pass and high-pass\n const lowpass = this.lowpassFilter(data);\n return this.highpassFilter(lowpass);\n }\n\n getInfo(): ModelConfig {\n return { ...this.config };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n async warmup(): Promise<void> {\n this.ready = true;\n }\n\n dispose(): void {\n this.ready = false;\n }\n}\n\n// ============================================\n// Native Model Factory\n// ============================================\n\nexport function createNativeModel(config: ModelConfig): MLModelAPI {\n switch (config.type) {\n case 'neural-network':\n return new SimpleNeuralNetwork(config);\n case 'linear-regression':\n return new NativeLinearRegression(config);\n case 'signal-processor':\n return new NativeSignalProcessor(config);\n default:\n // Default to simple linear model\n return new NativeLinearRegression(config);\n }\n}\n\n// ============================================\n// Native FFT Implementation\n// ============================================\n\nexport function nativeFFT(data: number[]): { real: number[]; imag: number[] } {\n const n = data.length;\n const real: number[] = new Array(n);\n const imag: number[] = new Array(n);\n \n // Simplified DFT (not optimized FFT)\n for (let k = 0; k < n; k++) {\n let sumReal = 0;\n let sumImag = 0;\n \n for (let t = 0; t < n; t++) {\n const angle = -2 * Math.PI * k * t / n;\n sumReal += data[t] * Math.cos(angle);\n sumImag += data[t] * Math.sin(angle);\n }\n \n real[k] = sumReal;\n imag[k] = sumImag;\n }\n \n return { real, imag };\n}\n\n// ============================================\n// Native Statistical Functions\n// ============================================\n\nexport function nativeMean(data: number[]): number {\n return data.reduce((sum, val) => sum + val, 0) / data.length;\n}\n\nexport function nativeStandardDeviation(data: number[]): number {\n const mean = nativeMean(data);\n const variance = data.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / data.length;\n return Math.sqrt(variance);\n}\n\nexport function nativeCorrelation(x: number[], y: number[]): number {\n const n = x.length;\n const meanX = nativeMean(x);\n const meanY = nativeMean(y);\n \n let numerator = 0;\n let denomX = 0;\n let denomY = 0;\n \n for (let i = 0; i < n; i++) {\n const dx = x[i] - meanX;\n const dy = y[i] - meanY;\n numerator += dx * dy;\n denomX += dx * dx;\n denomY += dy * dy;\n }\n \n return numerator / Math.sqrt(denomX * denomY);\n}","import type { \n PluginMLIntegrationConfig, \n MLIntegrationAPI, \n MLModelAPI, \n PredictionResult, \n VisualizationConfig\n} from './types';\nimport { \n createNativeModel,\n nativeFFT, \n nativeMean, \n nativeStandardDeviation, \n nativeCorrelation \n} from './native-algorithms';\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n AfterRenderEvent\n} from '../types';\n\nconst manifestML: PluginManifest = {\n name: \"velo-plot-ml-integration\",\n version: \"1.0.0\",\n description: \"Machine Learning Integration Bridge for Velo Plot\",\n provides: [\"ml\", \"prediction\", \"inference\"],\n tags: [\"ml\", \"ai\", \"analysis\"],\n};\n\nexport function PluginMLIntegration(\n userConfig: Partial<PluginMLIntegrationConfig> = {}\n): ChartPlugin<PluginMLIntegrationConfig> {\n let ctx: PluginContext | null = null;\n const models = new Map<string, MLModelAPI>();\n const activeVisualizations = new Map<string, { result: PredictionResult, config: VisualizationConfig }>();\n\n // Register initial models from config\n if (userConfig.models) {\n userConfig.models.forEach(m => models.set(m.id, createNativeModel(m)));\n }\n\n const api: MLIntegrationAPI & Record<string, unknown> = {\n registerModel(model: MLModelAPI) {\n if (!model.id) {\n ctx?.log.error(\"Cannot register model without id\");\n return;\n }\n models.set(model.id, model);\n ctx?.log.info(`Model registered: ${model.name || 'Unnamed'} (${model.id})`);\n },\n\n async runInference(modelId: string, seriesId: string) {\n const model = models.get(modelId);\n if (!model) throw new Error(`Model not found: ${modelId}`);\n\n const seriesData = ctx?.data.getSeriesData(seriesId);\n if (!seriesData) throw new Error(`Series not found: ${seriesId}`);\n\n // Convert to Float32Array for model compatibility\n const data = new Float32Array(seriesData.y);\n\n const result = await model.predict({ data });\n // Attach X values for visualization\n result.xValues = seriesData.x;\n return result;\n },\n\n visualizeResults(result: PredictionResult, config: VisualizationConfig = {}) {\n const vizId = `ml-viz-${Math.random().toString(36).substr(2, 9)}`;\n activeVisualizations.set(vizId, { \n result, \n config: { ...userConfig.defaultVisualization, ...config } \n });\n ctx?.requestRender();\n return vizId;\n },\n\n clearResults(visualizationId?: string) {\n if (visualizationId) {\n activeVisualizations.delete(visualizationId);\n } else {\n activeVisualizations.clear();\n }\n ctx?.requestRender();\n },\n\n /**\n * Alias for {@link visualizeResults} that reads as an intent-revealing\n * name for the prediction-overlay use case (task 3.18).\n */\n visualizePredictions(result: PredictionResult, config: VisualizationConfig = {}) {\n return api.visualizeResults(result, config);\n },\n\n /**\n * Train a small regression model on the fly (task 3.17). Creates a native\n * linear-regression model when the id does not yet exist. Returns fit\n * diagnostics including residuals for a residual plot.\n */\n trainModel(modelId: string, data: { x: number[][]; y: number[] }) {\n let model = models.get(modelId) as any;\n if (!model) {\n model = createNativeModel({ id: modelId, name: modelId, type: 'linear-regression' });\n models.set(modelId, model);\n }\n if (typeof model.train !== 'function') {\n throw new Error(`Model '${modelId}' does not support training`);\n }\n return model.train(data);\n },\n\n /** Retrieve the last training diagnostics for a model, if any. */\n getTrainingResult(modelId: string) {\n const model = models.get(modelId) as any;\n return model?.getTrainingResult?.() ?? null;\n },\n\n /** List registered model descriptors (for the ML audit / introspection). */\n listModels() {\n return Array.from(models.values()).map((m) => m.getInfo());\n },\n\n stats: {\n fft: nativeFFT,\n mean: nativeMean,\n standardDeviation: nativeStandardDeviation,\n correlation: nativeCorrelation\n }\n };\n\n function drawMLVisualizations(pCtx: PluginContext) {\n const { render, coords } = pCtx;\n const { ctx2d } = render;\n if (!ctx2d) return;\n\n activeVisualizations.forEach((viz) => {\n const { result, config } = viz;\n const { output, xValues, confidence } = result;\n if (!xValues) return;\n\n const n = Math.min(xValues.length, output.length);\n\n ctx2d.save();\n\n // 1. Draw Confidence Interval (as filled area)\n if (config.showConfidenceInterval && confidence && confidence.length === n) {\n ctx2d.beginPath();\n const opacity = config.intervalOpacity ?? 0.2;\n ctx2d.fillStyle = (config.lineStyle?.color || '#3b82f6') + Math.floor(opacity * 255).toString(16).padStart(2, '0');\n \n // Forward: upper bound\n for (let i = 0; i < n; i++) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(output[i] + confidence[i]);\n if (i === 0) ctx2d.moveTo(px, py);\n else ctx2d.lineTo(px, py);\n }\n \n // Backward: lower bound\n for (let i = n - 1; i >= 0; i--) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(output[i] - confidence[i]);\n ctx2d.lineTo(px, py);\n }\n \n ctx2d.closePath();\n ctx2d.fill();\n }\n\n // 2. Draw Prediction Line\n ctx2d.beginPath();\n ctx2d.strokeStyle = config.lineStyle?.color || '#3b82f6';\n ctx2d.lineWidth = config.lineStyle?.width || 2;\n if (config.lineStyle?.dash) ctx2d.setLineDash(config.lineStyle.dash);\n\n for (let i = 0; i < n; i++) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(output[i]);\n if (i === 0) ctx2d.moveTo(px, py);\n else ctx2d.lineTo(px, py);\n }\n ctx2d.stroke();\n\n ctx2d.restore();\n });\n }\n\n return {\n manifest: manifestML,\n\n onInit(c: PluginContext) {\n ctx = c;\n },\n\n onRenderOverlay(pCtx: PluginContext, _event: AfterRenderEvent) {\n drawMLVisualizations(pCtx);\n },\n\n api\n };\n}\n\nexport default PluginMLIntegration;\n\nexport type { \n PluginMLIntegrationConfig, \n MLIntegrationAPI, \n MLModelAPI, \n PredictionResult, \n VisualizationConfig \n} from './types';"],"names":["SimpleNeuralNetwork","config","__publicField","input","startTime","inputData","outputData","processingTime","activations","layer","weights","biases","output","i","sum","j","activation","x","dummyInput","NativeLinearRegression","predictions","feat","result","rows","row","data","X","XtX","matrixMultiply","transpose","XtY","y","XtXInv","matrixInverse","beta","fitted","residuals","meanY","s","v","sse","r","sst","r2","rmse","matrix","_","colIndex","a","b","k","n","M","col","pivot","pivotVal","c","factor","NativeSignalProcessor","_a","_b","_c","filteredData","alpha","smoothedAlpha","filtered","lowpass","createNativeModel","nativeFFT","real","imag","sumReal","sumImag","t","angle","nativeMean","val","nativeStandardDeviation","mean","variance","nativeCorrelation","meanX","numerator","denomX","denomY","dx","dy","manifestML","PluginMLIntegration","userConfig","ctx","models","activeVisualizations","m","api","model","modelId","seriesId","seriesData","vizId","visualizationId","drawMLVisualizations","pCtx","render","coords","ctx2d","viz","_d","xValues","confidence","opacity","px","py","_event"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './offscreen/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './offscreen/index'
|
|
3
|
+
export default VeloPlot
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './pattern-recognition/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './pattern-recognition/index'
|
|
3
|
+
export default VeloPlot
|
|
@@ -363,7 +363,7 @@ const A = {
|
|
|
363
363
|
name: "pattern-recognition",
|
|
364
364
|
version: "1.0.0",
|
|
365
365
|
description: "Technical pattern recognition for financial and scientific data",
|
|
366
|
-
author: "
|
|
366
|
+
author: "Velo Plot Team",
|
|
367
367
|
provides: ["patterns", "technical-analysis", "chart-patterns"]
|
|
368
368
|
}, H = {
|
|
369
369
|
defaultParameters: {
|