velo-plot 3.1.0 → 4.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ChartCore-AnR_3Xkb.js → ChartCore-KYG2HTcK.js} +1349 -1213
- package/dist/ChartCore-KYG2HTcK.js.map +1 -0
- package/dist/{PluginRegistry-CzMHebYP.js → PluginRegistry-CDf_jcnp.js} +2 -2
- package/dist/{PluginRegistry-CzMHebYP.js.map → PluginRegistry-CDf_jcnp.js.map} +1 -1
- package/dist/SVGDocumentBuilder-C-uLkcFW.js +83 -0
- package/dist/SVGDocumentBuilder-C-uLkcFW.js.map +1 -0
- package/dist/angular-hooks.js +1 -1
- package/dist/angular.js +4 -4
- package/dist/{chartSyncBridge-D_rCtbFq.js → chartSyncBridge-C1uRy0ZS.js} +3 -3
- package/dist/{chartSyncBridge-D_rCtbFq.js.map → chartSyncBridge-C1uRy0ZS.js.map} +1 -1
- package/dist/core/chart/ChartCore.d.ts +7 -3
- package/dist/core/chart/ChartRenderLoop.d.ts +5 -0
- package/dist/core/chart/ChartRenderer.d.ts +9 -0
- package/dist/core/chart/ChartSetup.d.ts +1 -0
- package/dist/core/chart/exporter/SVGExporter.d.ts +9 -7
- package/dist/core/chart/exporter/svg/SVGDocumentBuilder.d.ts +27 -0
- package/dist/core/chart/exporter/svg/SVGExportContext.d.ts +147 -0
- package/dist/core/chart/exporter/svg/SVGOrchestrator.d.ts +3 -0
- package/dist/core/chart/exporter/svg/SVGThemeAdapter.d.ts +22 -0
- package/dist/core/chart/exporter/svg/__tests__/testFixtures.d.ts +46 -0
- package/dist/core/chart/exporter/svg/__tests__/visualTestUtils.d.ts +12 -0
- package/dist/core/chart/exporter/svg/overlay/axes.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/border.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/errorBars.d.ts +7 -0
- package/dist/core/chart/exporter/svg/overlay/grid.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/index.d.ts +12 -0
- package/dist/core/chart/exporter/svg/overlay/legend.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/pluginCharts.d.ts +6 -0
- package/dist/core/chart/exporter/svg/overlay/polarGrid.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/specialChart.d.ts +15 -0
- package/dist/core/chart/exporter/svg/overlay/title.d.ts +4 -0
- package/dist/core/chart/exporter/svg/plugins/annotations.d.ts +5 -0
- package/dist/core/chart/exporter/svg/plugins/brokenAxis.d.ts +20 -0
- package/dist/core/chart/exporter/svg/plugins/latex.d.ts +9 -0
- package/dist/core/chart/exporter/svg/plugins/register.d.ts +8 -0
- package/dist/core/chart/exporter/svg/plugins/regression.d.ts +33 -0
- package/dist/core/chart/exporter/svg/plugins/roi.d.ts +12 -0
- package/dist/core/chart/exporter/svg/plugins/tradeMarkers.d.ts +3 -0
- package/dist/core/chart/exporter/svg/plugins/types.d.ts +28 -0
- package/dist/core/chart/exporter/svg/plugins/watermark.d.ts +13 -0
- package/dist/core/chart/exporter/svg/series/band.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/bar.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/boxplot.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/candlestick.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/finitePoints.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/gauge.d.ts +5 -0
- package/dist/core/chart/exporter/svg/series/heatmap.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/indicator.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/line.d.ts +12 -0
- package/dist/core/chart/exporter/svg/series/polar.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/radar.d.ts +5 -0
- package/dist/core/chart/exporter/svg/series/registry.d.ts +10 -0
- package/dist/core/chart/exporter/svg/series/sankey.d.ts +5 -0
- package/dist/core/chart/exporter/svg/series/scatter.d.ts +1 -0
- package/dist/core/chart/exporter/svg/series/ternary.d.ts +7 -0
- package/dist/core/chart/exporter/svg/series/waterfall.d.ts +6 -0
- package/dist/core/chart/exporter/svg/seriesAtTimestamp.d.ts +4 -0
- package/dist/core/chart/exporter/svg/seriesUtils.d.ts +3 -0
- package/dist/core/chart/exporter/svg/symbols.d.ts +5 -0
- package/dist/core/chart/exporter/svg/tickUtils.d.ts +9 -0
- package/dist/core/chart/mountSVGString.d.ts +5 -0
- package/dist/core/chart/types.d.ts +2 -2
- package/dist/core/stacked/StackSVGComposer.d.ts +14 -0
- package/dist/core/stacked/index.d.ts +3 -2
- package/dist/core/stacked/types.d.ts +12 -4
- package/dist/createStackedChart-DjA3aJAu.js +2761 -0
- package/dist/createStackedChart-DjA3aJAu.js.map +1 -0
- package/dist/{hooks-DH-3bewj.js → hooks-4wQH27r9.js} +3 -3
- package/dist/{hooks-DH-3bewj.js.map → hooks-4wQH27r9.js.map} +1 -1
- package/dist/index-Bj-xyXY6.js +582 -0
- package/dist/index-Bj-xyXY6.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +5 -0
- package/dist/plugins/annotations.js +8 -7
- package/dist/plugins/annotations.js.map +1 -1
- package/dist/plugins/broken-axis.js +198 -152
- package/dist/plugins/broken-axis.js.map +1 -1
- package/dist/plugins/forecasting.js +273 -258
- package/dist/plugins/forecasting.js.map +1 -1
- package/dist/plugins/ml-integration.js +107 -93
- package/dist/plugins/ml-integration.js.map +1 -1
- package/dist/plugins/radar/types.d.ts +11 -0
- package/dist/plugins/radar.js +64 -53
- package/dist/plugins/radar.js.map +1 -1
- package/dist/plugins/roi/index.d.ts +2 -0
- package/dist/plugins/roi.js +184 -145
- package/dist/plugins/roi.js.map +1 -1
- package/dist/plugins/snapshot.js +20 -15
- package/dist/plugins/snapshot.js.map +1 -1
- package/dist/plugins/types.d.ts +4 -0
- package/dist/react.js +2 -2
- package/dist/regression-HNdyk1Dm.js +28 -0
- package/dist/regression-HNdyk1Dm.js.map +1 -0
- package/dist/renderer/ChartSeriesRenderer.d.ts +3 -2
- package/dist/renderer/SVGChartRenderer.d.ts +15 -0
- package/dist/renderer/SankeyRenderer.d.ts +1 -0
- package/dist/renderer/registerSVG.d.ts +5 -0
- package/dist/renderer/sankeyLayout.d.ts +29 -0
- package/dist/scientific.js +2 -2
- package/dist/solid.js +2 -2
- package/dist/svelte.js +2 -2
- package/dist/tickUtils-B_X-ha13.js +41 -0
- package/dist/tickUtils-B_X-ha13.js.map +1 -0
- package/dist/trading.js +3 -3
- package/dist/types.d.ts +2 -1
- package/dist/velo-plot.full.js +1107 -1292
- package/dist/velo-plot.full.js.map +1 -1
- package/dist/velo-plot.js +2 -2
- package/dist/vue/VeloPlot.vue.d.ts +1 -1
- package/dist/vue/index.d.ts +33 -33
- package/dist/vue.js +2 -2
- package/package.json +6 -1
- package/dist/ChartCore-AnR_3Xkb.js.map +0 -1
- package/dist/createStackedChart-DqcLCFGS.js +0 -1338
- package/dist/createStackedChart-DqcLCFGS.js.map +0 -1
- package/dist/index-Cv6ZDLWf.js +0 -521
- package/dist/index-Cv6ZDLWf.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"velo-plot.full.js","sources":["../src/renderer/native/utilsExtended.ts","../src/renderer/BarRenderer.ts","../src/renderer/HeatmapRenderer.ts","../src/renderer/CandlestickRenderer.ts","../src/renderer/seriesBufferExtended.ts","../src/renderer/native/drawExtended.ts","../src/renderer/native/frameRenderExtended.ts","../src/renderer/GaugeRenderer.ts","../src/renderer/SankeyRenderer.ts","../src/renderer/overlaySeriesExtended.ts","../src/renderer/native/programFactoryExtended.ts","../src/renderer/registerWebGPU.ts","../src/renderer/registerExtendedSeries.ts","../src/core/chart/exporter/SVGExporter.ts","../src/core/chart/chartExportPatch.ts","../src/core/chart/ChartAlerts.ts","../src/core/chart/positionLines.ts","../src/trading/registerTrading.ts","../src/renderer/WebGPURenderer.ts","../src/renderer/spike/WebGLGridSpike.ts","../src/testing/gridSpikeBenchmark.ts","../src/testing/stage1BrowserBench.ts","../src/testing/rendererBenchmark.ts","../src/testing/index.ts","../src/plugins/builtins/crosshair/CrosshairPlugin.ts","../src/plugins/builtins/stats/StatsPlugin.ts","../src/plugins/builtins/watermark/WatermarkPlugin.ts","../src/plugins/builtins/grid-highlight/GridHighlightPlugin.ts","../src/plugins/builtins/data-logger/DataLoggerPlugin.ts","../src/plugins/builtins/direction-indicator/DirectionIndicatorPlugin.ts","../src/plugins/builtins/index.ts","../src/plugins/drag-edit/index.ts","../src/plugins/index.ts","../src/index.ts"],"sourcesContent":["export function interleaveBoxPlotData(\n x: Float32Array | Float64Array | number[],\n min: Float32Array | Float64Array | number[],\n q1: Float32Array | Float64Array | number[],\n median: Float32Array | Float64Array | number[],\n q3: Float32Array | Float64Array | number[],\n max: Float32Array | Float64Array | number[],\n width: number\n): { lines: Float32Array; boxes: Float32Array } {\n const n = x.length;\n const w = width / 2;\n \n // Lines: 5 segments per box: 14 points per box if we use separate lines\n // Actually, let's use 10 points (5 lines x 2 points)\n const lineData = new Float32Array(n * 20);\n \n // Boxes: 1 rectangle (2 triangles) per box = 6 vertices * 2 floats = 12 floats per box\n const boxData = new Float32Array(n * 12);\n \n let lIdx = 0;\n let bIdx = 0;\n \n for (let i = 0; i < n; i++) {\n const xi = x[i];\n const mi = min[i];\n const q1i = q1[i];\n const medi = median[i];\n const q3i = q3[i];\n const maxti = max[i];\n \n // Lines\n // 1. Lower whisker\n lineData[lIdx++] = xi; lineData[lIdx++] = mi;\n lineData[lIdx++] = xi; lineData[lIdx++] = q1i;\n // 2. Upper whisker\n lineData[lIdx++] = xi; lineData[lIdx++] = q3i;\n lineData[lIdx++] = xi; lineData[lIdx++] = maxti;\n // 3. Median\n lineData[lIdx++] = xi - w; lineData[lIdx++] = medi;\n lineData[lIdx++] = xi + w; lineData[lIdx++] = medi;\n // 4. Q1 bottom cap\n lineData[lIdx++] = xi - w; lineData[lIdx++] = q1i;\n lineData[lIdx++] = xi + w; lineData[lIdx++] = q1i;\n // 5. Q3 top cap\n lineData[lIdx++] = xi - w; lineData[lIdx++] = q3i;\n lineData[lIdx++] = xi + w; lineData[lIdx++] = q3i;\n \n // Rectangle (Box)\n boxData[bIdx++] = xi - w; boxData[bIdx++] = q1i;\n boxData[bIdx++] = xi + w; boxData[bIdx++] = q1i;\n boxData[bIdx++] = xi + w; boxData[bIdx++] = q3i;\n boxData[bIdx++] = xi - w; boxData[bIdx++] = q1i;\n boxData[bIdx++] = xi + w; boxData[bIdx++] = q3i;\n boxData[bIdx++] = xi - w; boxData[bIdx++] = q3i;\n }\n \n return { lines: lineData, boxes: boxData };\n}\n\n/**\n * Interleave data for Waterfall charts\n * Creates rectangles that show cumulative changes from a running total\n */\nexport function interleaveWaterfallData(\n x: Float32Array | Float64Array | number[],\n y: Float32Array | Float64Array | number[],\n width: number,\n isSubtotal?: boolean[]\n): { \n positiveData: Float32Array; \n negativeData: Float32Array; \n subtotalData: Float32Array;\n connectorData: Float32Array;\n positiveCount: number;\n negativeCount: number;\n subtotalCount: number;\n} {\n const n = x.length;\n const w = width / 2;\n \n // Each bar is 2 triangles = 6 vertices\n const positiveData = new Float32Array(n * 12);\n const negativeData = new Float32Array(n * 12);\n const subtotalData = new Float32Array(n * 12);\n const connectorData = new Float32Array((n - 1) * 4); // Horizontal lines connecting bars\n \n let pIdx = 0, nIdx = 0, sIdx = 0, cIdx = 0;\n let runningTotal = 0;\n \n for (let i = 0; i < n; i++) {\n const xi = x[i];\n const yi = y[i];\n const isSub = isSubtotal?.[i] ?? false;\n \n let barBottom: number, barTop: number;\n \n if (isSub) {\n // Subtotal bar: from 0 to current running total\n barBottom = 0;\n barTop = runningTotal;\n \n // Draw subtotal bar\n subtotalData[sIdx++] = xi - w; subtotalData[sIdx++] = barBottom;\n subtotalData[sIdx++] = xi + w; subtotalData[sIdx++] = barBottom;\n subtotalData[sIdx++] = xi + w; subtotalData[sIdx++] = barTop;\n subtotalData[sIdx++] = xi - w; subtotalData[sIdx++] = barBottom;\n subtotalData[sIdx++] = xi + w; subtotalData[sIdx++] = barTop;\n subtotalData[sIdx++] = xi - w; subtotalData[sIdx++] = barTop;\n } else {\n // Regular bar: from running total to running total + value\n barBottom = runningTotal;\n barTop = runningTotal + yi;\n runningTotal = barTop;\n \n if (yi >= 0) {\n // Positive bar\n positiveData[pIdx++] = xi - w; positiveData[pIdx++] = barBottom;\n positiveData[pIdx++] = xi + w; positiveData[pIdx++] = barBottom;\n positiveData[pIdx++] = xi + w; positiveData[pIdx++] = barTop;\n positiveData[pIdx++] = xi - w; positiveData[pIdx++] = barBottom;\n positiveData[pIdx++] = xi + w; positiveData[pIdx++] = barTop;\n positiveData[pIdx++] = xi - w; positiveData[pIdx++] = barTop;\n } else {\n // Negative bar (barTop < barBottom)\n negativeData[nIdx++] = xi - w; negativeData[nIdx++] = barTop;\n negativeData[nIdx++] = xi + w; negativeData[nIdx++] = barTop;\n negativeData[nIdx++] = xi + w; negativeData[nIdx++] = barBottom;\n negativeData[nIdx++] = xi - w; negativeData[nIdx++] = barTop;\n negativeData[nIdx++] = xi + w; negativeData[nIdx++] = barBottom;\n negativeData[nIdx++] = xi - w; negativeData[nIdx++] = barBottom;\n }\n }\n \n // Connector line to next bar (if not last)\n if (i < n - 1) {\n const nextX = x[i + 1];\n connectorData[cIdx++] = xi + w;\n connectorData[cIdx++] = barTop;\n connectorData[cIdx++] = nextX - w;\n connectorData[cIdx++] = barTop;\n }\n }\n \n return {\n positiveData: positiveData.subarray(0, pIdx),\n negativeData: negativeData.subarray(0, nIdx),\n subtotalData: subtotalData.subarray(0, sIdx),\n connectorData: connectorData.subarray(0, cIdx),\n positiveCount: pIdx / 2,\n negativeCount: nIdx / 2,\n subtotalCount: sIdx / 2\n };\n}\n","/**\n * Prepare bar chart data for WebGL rendering\n * Creates rectangle vertices for each bar (2 triangles per bar = 6 vertices)\n * \n * @param x - X positions of bar centers\n * @param y - Y heights of bars\n * @param barWidth - Width of each bar in data units\n * @returns Interleaved vertex data ready for gl.TRIANGLES\n */\nexport function interleaveBarData(\n x: Float32Array | Float64Array | number[],\n y: Float32Array | Float64Array | number[],\n barWidth: number\n): Float32Array {\n const n = Math.min(x.length, y.length);\n // Each bar = 2 triangles = 6 vertices, 2 floats per vertex\n const result = new Float32Array(n * 6 * 2);\n \n const halfWidth = barWidth * 0.5;\n \n for (let i = 0; i < n; i++) {\n const xi = x[i];\n const yi = y[i];\n const base = i * 12; // 6 vertices * 2 floats\n \n // Define bar corners\n const x0 = xi - halfWidth; // Left\n const x1 = xi + halfWidth; // Right\n const y0 = 0; // Bottom\n const y1 = yi; // Top\n \n // First triangle (bottom-left, bottom-right, top-left)\n result[base + 0] = x0;\n result[base + 1] = y0;\n result[base + 2] = x1;\n result[base + 3] = y0;\n result[base + 4] = x0;\n result[base + 5] = y1;\n \n // Second triangle (top-left, bottom-right, top-right)\n result[base + 6] = x0;\n result[base + 7] = y1;\n result[base + 8] = x1;\n result[base + 9] = y0;\n result[base + 10] = x1;\n result[base + 11] = y1;\n }\n \n return result;\n}\n\n/**\n * Calculate automatic bar width based on data spacing\n */\nexport function calculateBarWidth(x: Float32Array | Float64Array | number[]): number {\n if (x.length < 2) return 1.0;\n \n // Find minimum spacing between consecutive bars\n let minSpacing = Infinity;\n for (let i = 1; i < x.length; i++) {\n const spacing = Math.abs(x[i] - x[i - 1]);\n if (spacing > 0 && spacing < minSpacing) {\n minSpacing = spacing;\n }\n }\n \n // Bar width is 80% of minimum spacing (20% gap)\n return minSpacing === Infinity ? 1.0 : minSpacing * 0.8;\n}\n","/**\n * Prepare Heatmap data for WebGL rendering\n * Creates a mesh of triangles for the grid.\n * \n * @param x - X coordinates of grid columns\n * @param y - Y coordinates of grid rows\n * @param z - Z values (matrix flattened in row-major order: width=x.length, height=y.length)\n * @returns Interleaved data [x, y, value, ...] ready for gl.TRIANGLES\n */\nexport function interleaveHeatmapData(\n x: Float32Array | Float64Array | number[],\n y: Float32Array | Float64Array | number[],\n z: Float32Array | Float64Array | number[]\n): Float32Array {\n const width = x.length;\n const height = y.length;\n \n if (width * height > z.length) {\n console.warn(\"[Heatmap] Z array is too small for the specified grid dimensions\");\n }\n\n // Each cell is 2 triangles = 6 vertices\n // Each vertex has 3 floats: [x, y, value]\n const numCells = (width - 1) * (height - 1);\n const result = new Float32Array(numCells * 6 * 3);\n \n let idx = 0;\n for (let j = 0; j < height - 1; j++) {\n for (let i = 0; i < width - 1; i++) {\n // Corners\n const x0 = x[i];\n const x1 = x[i+1];\n const y0 = y[j];\n const y1 = y[j+1];\n \n const v00 = z[j * width + i];\n const v10 = z[j * width + (i + 1)];\n const v01 = z[(j + 1) * width + i];\n const v11 = z[(j + 1) * width + (i + 1)];\n \n // Triangle 1 (BL, BR, TL)\n result[idx++] = x0; result[idx++] = y0; result[idx++] = v00;\n result[idx++] = x1; result[idx++] = y0; result[idx++] = v10;\n result[idx++] = x0; result[idx++] = y1; result[idx++] = v01;\n \n // Triangle 2 (TL, BR, TR)\n result[idx++] = x0; result[idx++] = y1; result[idx++] = v01;\n result[idx++] = x1; result[idx++] = y0; result[idx++] = v10;\n result[idx++] = x1; result[idx++] = y1; result[idx++] = v11;\n }\n }\n \n return result;\n}\n\n/**\n * Generates a colormap texture data\n * Viridis approximation\n */\nexport function getColormap(name: string = 'viridis'): Uint8Array {\n const size = 256;\n const data = new Uint8Array(size * 4);\n \n for (let i = 0; i < size; i++) {\n const t = i / (size - 1);\n let r, g, b;\n \n if (name === 'jet') {\n r = Math.min(Math.max(1.5 - Math.abs(t * 4 - 3), 0), 1);\n g = Math.min(Math.max(1.5 - Math.abs(t * 4 - 2), 0), 1);\n b = Math.min(Math.max(1.5 - Math.abs(t * 4 - 1), 0), 1);\n } else if (name === 'grayscale') {\n r = g = b = t;\n } else if (name === 'plasma') {\n r = 0.5 + 0.5 * Math.sin(Math.PI * (t - 0.5));\n g = 0.5 + 0.5 * Math.sin(Math.PI * t);\n b = 0.8;\n } else { // default viridis approx\n r = 0.267 * (1 - t) + 0.993 * t;\n g = 0.005 * (1 - t) + 0.906 * t;\n b = 0.337 * (1 - t) + 0.144 * t;\n // More accurate viridis constants could be used\n }\n \n data[i * 4 + 0] = r * 255;\n data[i * 4 + 1] = g * 255;\n data[i * 4 + 2] = b * 255;\n data[i * 4 + 3] = 255;\n }\n \n return data;\n}\n","/**\n * Candlestick Renderer Utilities\n */\n\n/**\n * Interleave data for candlestick rendering\n * Each candle is represented by a body (box) and a wick (line/thin box)\n * Returns a Float32Array of interleaved [x, y] coordinates for TRIANGLES\n */\nexport function interleaveCandlestickData(\n x: Float32Array | Float64Array,\n open: Float32Array | Float64Array,\n high: Float32Array | Float64Array,\n low: Float32Array | Float64Array,\n close: Float32Array | Float64Array,\n width: number,\n hollow = false,\n): { bullish: Float32Array; bearish: Float32Array } {\n const n = x.length;\n const bullishBody: number[] = [];\n const bearishBody: number[] = [];\n \n const halfWidth = width / 2;\n const wickWidth = width / 10;\n const halfWick = wickWidth / 2;\n\n for (let i = 0; i < n; i++) {\n if (!Number.isFinite(x[i])) continue;\n const isBullish = close[i] >= open[i];\n const target = isBullish ? bullishBody : bearishBody;\n \n const bodyTop = Math.max(open[i], close[i]);\n const bodyBottom = Math.min(open[i], close[i]);\n \n // Body (skip filled body for hollow bullish candles)\n if (!(hollow && isBullish)) {\n appendRect(target, x[i] - halfWidth, bodyBottom, x[i] + halfWidth, bodyTop);\n }\n \n // Wick (Rectangle as 2 triangles, thin)\n appendRect(target, x[i] - halfWick, low[i], x[i] + halfWick, high[i]);\n }\n\n return {\n bullish: new Float32Array(bullishBody),\n bearish: new Float32Array(bearishBody)\n };\n}\n\nfunction appendRect(arr: number[], x1: number, y1: number, x2: number, y2: number) {\n // Triangle 1\n arr.push(x1, y1, x2, y1, x1, y2);\n // Triangle 2\n arr.push(x2, y1, x2, y2, x1, y2);\n}\n","/**\n * Extended series buffer handlers (bar, heatmap, candlestick, polar, boxplot, waterfall).\n */\nimport { Series } from \"../core/Series\";\nimport { interleaveBarData, calculateBarWidth } from \"./BarRenderer\";\nimport { interleaveHeatmapData, getColormap } from \"./HeatmapRenderer\";\nimport { interleaveCandlestickData } from \"./CandlestickRenderer\";\nimport {\n interleavePolarFillData,\n interleavePolarLineData,\n} from \"./PolarRenderer\";\nimport {\n interleaveBoxPlotData,\n interleaveWaterfallData,\n} from \"./native/utilsExtended\";\nimport {\n interleaveBandData,\n interleaveData,\n interleaveErrorData,\n interleaveStepData,\n} from \"./native/utilsCore\";\nimport { registerSeriesBufferHandler } from \"../core/chart/series/seriesTypeRegistry\";\n\nconst CORE_LITE_TYPES = new Set([\n \"line\",\n \"scatter\",\n \"line+scatter\",\n \"step\",\n \"step+scatter\",\n \"band\",\n \"area\",\n]);\n\nfunction updateErrorAndStepBuffers(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesId = s.getId();\n const seriesType = s.getType();\n\n if (s.hasErrorData()) {\n const errData = interleaveErrorData(\n d.x,\n d.y,\n {\n yError: d.yError,\n yErrorMinus: d.yErrorMinus,\n yErrorPlus: d.yErrorPlus,\n },\n {\n xError: d.xError,\n xErrorMinus: d.xErrorMinus,\n xErrorPlus: d.xErrorPlus,\n },\n );\n ctx.renderer.createBuffer(`${seriesId}_errors`, errData);\n }\n\n if (seriesType === \"step\" || seriesType === \"step+scatter\") {\n const stepMode = s.getStyle().stepMode ?? \"after\";\n ctx.renderer.createBuffer(\n `${seriesId}_step`,\n interleaveStepData(d.x, d.y, stepMode),\n );\n }\n}\n\nfunction updateBarBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const barWidth = (s.getStyle() as any).barWidth ?? calculateBarWidth(d.x);\n ctx.renderer.createBuffer(\n s.getId(),\n interleaveBarData(d.x, d.y, barWidth),\n );\n updateErrorAndStepBuffers(ctx, s);\n s.resetLastAppendCount();\n}\n\nfunction updateHeatmapBuffer(ctx: any, s: Series): void {\n ctx.renderer?.installHeatmapProgram?.();\n const hData = s.getHeatmapData();\n const hStyle = s.getHeatmapStyle();\n if (!hData || hData.xValues.length < 2) return;\n ctx.renderer.createBuffer(\n s.getId(),\n interleaveHeatmapData(hData.xValues, hData.yValues, hData.zValues),\n );\n const colormapName = hStyle?.colorScale?.name || \"viridis\";\n ctx.renderer.createColormapTexture(\n `${s.getId()}_colormap`,\n getColormap(colormapName),\n );\n s.resetLastAppendCount();\n}\n\nfunction updateCandlestickBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesId = s.getId();\n if (d.open && d.high && d.low && d.close) {\n const barWidth = (s.getStyle() as any).barWidth ?? calculateBarWidth(d.x);\n const hollow = Boolean((s.getStyle() as any).hollow);\n const { bullish, bearish } = interleaveCandlestickData(\n d.x,\n d.open,\n d.high,\n d.low,\n d.close,\n barWidth,\n hollow,\n );\n ctx.renderer.createBuffer(`${seriesId}_bullish`, bullish);\n ctx.renderer.createBuffer(`${seriesId}_bearish`, bearish);\n s.bullishCount = bullish.length / 2;\n s.bearishCount = bearish.length / 2;\n }\n s.resetLastAppendCount();\n}\n\nfunction updateBoxplotBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesId = s.getId();\n if (d.low && d.open && d.median && d.close && d.high) {\n const barWidth = (s.getStyle() as any).barWidth ?? calculateBarWidth(d.x);\n const { lines, boxes } = interleaveBoxPlotData(\n d.x,\n d.low,\n d.open,\n d.median,\n d.close,\n d.high,\n barWidth,\n );\n ctx.renderer.createBuffer(`${seriesId}_box_lines`, lines);\n ctx.renderer.createBuffer(`${seriesId}_box_faces`, boxes);\n }\n s.resetLastAppendCount();\n}\n\nfunction updateWaterfallBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesId = s.getId();\n const barWidth = (s.getStyle() as any).barWidth ?? calculateBarWidth(d.x);\n const isSubtotal = (s.getStyle() as any).isSubtotal;\n const wfData = interleaveWaterfallData(d.x, d.y, barWidth, isSubtotal);\n ctx.renderer.createBuffer(`${seriesId}_wf_positive`, wfData.positiveData);\n ctx.renderer.createBuffer(`${seriesId}_wf_negative`, wfData.negativeData);\n ctx.renderer.createBuffer(`${seriesId}_wf_subtotal`, wfData.subtotalData);\n ctx.renderer.createBuffer(`${seriesId}_wf_connectors`, wfData.connectorData);\n s.waterfallCounts = {\n positive: wfData.positiveCount,\n negative: wfData.negativeCount,\n subtotal: wfData.subtotalCount,\n connectors: wfData.connectorData.length / 2,\n };\n s.resetLastAppendCount();\n}\n\nfunction updatePolarBuffer(ctx: any, s: Series): void {\n const polarData = s.getPolarData();\n if (!polarData || polarData.r.length === 0) return;\n\n const style = s.getStyle() as any;\n const angleMode = style.angleMode || \"degrees\";\n const closePath = style.closePath !== false;\n const fill = style.fill || false;\n\n if (fill) {\n const fillData = interleavePolarFillData(polarData, angleMode, closePath);\n ctx.renderer.createBuffer(s.getId(), fillData);\n } else {\n const lineData = interleavePolarLineData(polarData, angleMode, closePath);\n ctx.renderer.createBuffer(s.getId(), lineData);\n }\n s.resetLastAppendCount();\n}\n\nfunction updateBandOrAreaBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesType = s.getType();\n const y2 =\n seriesType === \"area\"\n ? new Float32Array(d.x.length).fill(0)\n : d.y2 || new Float32Array(d.x.length).fill(0);\n ctx.renderer.createBuffer(s.getId(), interleaveBandData(d.x, d.y, y2));\n updateErrorAndStepBuffers(ctx, s);\n s.resetLastAppendCount();\n}\n\nfunction updateDefaultBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n ctx.renderer.createBuffer(s.getId(), interleaveData(d.x, d.y));\n updateErrorAndStepBuffers(ctx, s);\n s.resetLastAppendCount();\n}\n\nlet registered = false;\n\n/** Register extended series buffer handlers (call from trading/scientific/full entries). */\nexport function registerExtendedSeriesBuffers(): void {\n if (registered) return;\n registered = true;\n\n registerSeriesBufferHandler(\"bar\", updateBarBuffer);\n registerSeriesBufferHandler(\"heatmap\", updateHeatmapBuffer);\n registerSeriesBufferHandler(\"candlestick\", updateCandlestickBuffer);\n registerSeriesBufferHandler(\"boxplot\", updateBoxplotBuffer);\n registerSeriesBufferHandler(\"waterfall\", updateWaterfallBuffer);\n registerSeriesBufferHandler(\"polar\", updatePolarBuffer);\n registerSeriesBufferHandler(\"band\", updateBandOrAreaBuffer);\n registerSeriesBufferHandler(\"area\", updateBandOrAreaBuffer);\n registerSeriesBufferHandler(\"heikin-ashi\", (ctx: any, s) => {\n const d = s.getData();\n if (!d?.x?.length) return;\n ctx.renderer.createBuffer(s.getId(), interleaveData(d.x, d.y));\n s.resetLastAppendCount();\n });\n\n for (const type of [\n \"line\",\n \"scatter\",\n \"line+scatter\",\n \"step\",\n \"step+scatter\",\n ]) {\n registerSeriesBufferHandler(type, updateDefaultBuffer);\n }\n}\n\nexport { CORE_LITE_TYPES };\n","import type { ShaderProgram } from \"./types\";\nimport { computeSeriesColor } from \"./drawCore\";\n\nexport function renderHeatmap(\n gl: WebGLRenderingContext,\n prog: ShaderProgram,\n buffer: WebGLBuffer,\n count: number,\n uniforms: { scale: [number, number]; translate: [number, number] },\n zBounds: { min: number; max: number } = { min: 0, max: 1 },\n texture?: WebGLTexture\n): void {\n gl.useProgram(prog.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n\n gl.enableVertexAttribArray(prog.attributes.position);\n gl.vertexAttribPointer(prog.attributes.position, 2, gl.FLOAT, false, 12, 0);\n\n if (prog.attributes.value !== undefined && prog.attributes.value !== -1) {\n gl.enableVertexAttribArray(prog.attributes.value);\n gl.vertexAttribPointer(prog.attributes.value, 1, gl.FLOAT, false, 12, 8);\n }\n\n gl.uniform2f(prog.uniforms.uScale, uniforms.scale[0], uniforms.scale[1]);\n gl.uniform2f(\n prog.uniforms.uTranslate,\n uniforms.translate[0],\n uniforms.translate[1]\n );\n\n if (prog.uniforms.uMinValue)\n gl.uniform1f(prog.uniforms.uMinValue, zBounds.min);\n if (prog.uniforms.uMaxValue)\n gl.uniform1f(prog.uniforms.uMaxValue, zBounds.max);\n\n if (texture && prog.uniforms.uColormap) {\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.uniform1i(prog.uniforms.uColormap, 0);\n } else if (prog.uniforms.uColormap) {\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n\n gl.drawArrays(gl.TRIANGLES, 0, count);\n\n gl.disableVertexAttribArray(prog.attributes.position);\n if (prog.attributes.value !== undefined && prog.attributes.value !== -1) {\n gl.disableVertexAttribArray(prog.attributes.value);\n }\n}\n\nexport function renderBar(\n gl: WebGLRenderingContext,\n prog: ShaderProgram,\n buffer: WebGLBuffer,\n count: number,\n uniforms: { scale: [number, number]; translate: [number, number] },\n color: [number, number, number, number]\n): void {\n gl.useProgram(prog.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(prog.attributes.position);\n gl.vertexAttribPointer(prog.attributes.position, 2, gl.FLOAT, false, 0, 0);\n\n gl.uniform2f(prog.uniforms.uScale, uniforms.scale[0], uniforms.scale[1]);\n gl.uniform2f(\n prog.uniforms.uTranslate,\n uniforms.translate[0],\n uniforms.translate[1]\n );\n gl.uniform4f(prog.uniforms.uColor!, color[0], color[1], color[2], color[3]);\n\n gl.drawArrays(gl.TRIANGLES, 0, count);\n gl.disableVertexAttribArray(prog.attributes.position);\n}\n\nexport function renderBoxPlot(\n gl: WebGLRenderingContext,\n programs: { line: ShaderProgram; point: ShaderProgram },\n data: {\n boxBuffer: WebGLBuffer;\n boxCount: number;\n linesBuffer: WebGLBuffer;\n linesCount: number;\n },\n uniforms: { scale: [number, number]; translate: [number, number] },\n style: { color?: string; opacity?: number; width?: number }\n): void {\n const color = computeSeriesColor(style);\n\n gl.useProgram(programs.line.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, data.boxBuffer);\n gl.enableVertexAttribArray(programs.line.attributes.position);\n gl.vertexAttribPointer(programs.line.attributes.position, 2, gl.FLOAT, false, 0, 0);\n\n gl.uniform2f(programs.line.uniforms.uScale, uniforms.scale[0], uniforms.scale[1]);\n gl.uniform2f(\n programs.line.uniforms.uTranslate,\n uniforms.translate[0],\n uniforms.translate[1]\n );\n\n const fillColor = [...color] as [number, number, number, number];\n fillColor[3] *= 0.5;\n gl.uniform4f(programs.line.uniforms.uColor!, fillColor[0], fillColor[1], fillColor[2], fillColor[3]);\n\n gl.drawArrays(gl.TRIANGLES, 0, data.boxCount);\n\n gl.uniform4f(programs.line.uniforms.uColor!, color[0], color[1], color[2], color[3]);\n gl.lineWidth(style.width || 1);\n gl.bindBuffer(gl.ARRAY_BUFFER, data.linesBuffer);\n gl.vertexAttribPointer(programs.line.attributes.position, 2, gl.FLOAT, false, 0, 0);\n\n gl.drawArrays(gl.LINES, 0, data.linesCount);\n\n gl.disableVertexAttribArray(programs.line.attributes.position);\n}\n","import { parseColor } from \"./utilsCore\";\nimport { renderBar, renderBoxPlot, renderHeatmap } from \"./drawExtended\";\nimport { registerFrameRenderer } from \"./frameRenderRegistry\";\nimport type { FrameRenderContext } from \"./frameRenderRegistry\";\nimport type { NativeSeriesRenderData } from \"./types\";\n\nfunction renderHeatmapSeries(\n ctx: FrameRenderContext,\n s: NativeSeriesRenderData,\n seriesUniforms: { scale: [number, number]; translate: [number, number] },\n): void {\n renderHeatmap(\n ctx.gl,\n ctx.programs.heatmapProgram,\n s.buffer,\n s.count,\n seriesUniforms,\n s.zBounds,\n s.colormapTexture,\n );\n}\n\nfunction renderBarSeries(\n ctx: FrameRenderContext,\n s: NativeSeriesRenderData,\n seriesUniforms: { scale: [number, number]; translate: [number, number] },\n color: [number, number, number, number],\n): void {\n renderBar(\n ctx.gl,\n ctx.programs.lineProgram,\n s.buffer,\n s.count,\n seriesUniforms,\n color,\n );\n}\n\nfunction renderBoxplotSeries(\n ctx: FrameRenderContext,\n s: NativeSeriesRenderData,\n seriesUniforms: { scale: [number, number]; translate: [number, number] },\n): void {\n if (s.boxBuffer && s.boxLinesBuffer) {\n renderBoxPlot(\n ctx.gl,\n { line: ctx.programs.lineProgram, point: ctx.programs.pointProgram },\n {\n boxBuffer: s.boxBuffer,\n boxCount: s.boxCount || 0,\n linesBuffer: s.boxLinesBuffer,\n linesCount: s.boxLinesCount || 0,\n },\n seriesUniforms,\n s.style,\n );\n }\n}\n\nfunction renderWaterfallSeries(\n ctx: FrameRenderContext,\n s: NativeSeriesRenderData,\n seriesUniforms: { scale: [number, number]; translate: [number, number] },\n): void {\n const { gl, programs, dpr } = ctx;\n const positiveColor = parseColor(s.style.positiveColor || \"#22c55e\");\n const negativeColor = parseColor(s.style.negativeColor || \"#ef4444\");\n const subtotalColor = parseColor(s.style.subtotalColor || \"#3b82f6\");\n const connectorColor = parseColor(s.style.connectorColor || \"#64748b\");\n\n if (s.wfPositiveBuffer && s.wfPositiveCount && s.wfPositiveCount > 0) {\n gl.useProgram(programs.lineProgram.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, s.wfPositiveBuffer);\n gl.enableVertexAttribArray(programs.lineProgram.attributes.position);\n gl.vertexAttribPointer(\n programs.lineProgram.attributes.position,\n 2,\n gl.FLOAT,\n false,\n 0,\n 0,\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uScale,\n seriesUniforms.scale[0],\n seriesUniforms.scale[1],\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uTranslate,\n seriesUniforms.translate[0],\n seriesUniforms.translate[1],\n );\n gl.uniform4f(\n programs.lineProgram.uniforms.uColor!,\n positiveColor[0],\n positiveColor[1],\n positiveColor[2],\n 0.9,\n );\n gl.drawArrays(gl.TRIANGLES, 0, s.wfPositiveCount);\n }\n\n if (s.wfNegativeBuffer && s.wfNegativeCount && s.wfNegativeCount > 0) {\n gl.useProgram(programs.lineProgram.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, s.wfNegativeBuffer);\n gl.enableVertexAttribArray(programs.lineProgram.attributes.position);\n gl.vertexAttribPointer(\n programs.lineProgram.attributes.position,\n 2,\n gl.FLOAT,\n false,\n 0,\n 0,\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uScale,\n seriesUniforms.scale[0],\n seriesUniforms.scale[1],\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uTranslate,\n seriesUniforms.translate[0],\n seriesUniforms.translate[1],\n );\n gl.uniform4f(\n programs.lineProgram.uniforms.uColor!,\n negativeColor[0],\n negativeColor[1],\n negativeColor[2],\n 0.9,\n );\n gl.drawArrays(gl.TRIANGLES, 0, s.wfNegativeCount);\n }\n\n if (s.wfSubtotalBuffer && s.wfSubtotalCount && s.wfSubtotalCount > 0) {\n gl.useProgram(programs.lineProgram.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, s.wfSubtotalBuffer);\n gl.enableVertexAttribArray(programs.lineProgram.attributes.position);\n gl.vertexAttribPointer(\n programs.lineProgram.attributes.position,\n 2,\n gl.FLOAT,\n false,\n 0,\n 0,\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uScale,\n seriesUniforms.scale[0],\n seriesUniforms.scale[1],\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uTranslate,\n seriesUniforms.translate[0],\n seriesUniforms.translate[1],\n );\n gl.uniform4f(\n programs.lineProgram.uniforms.uColor!,\n subtotalColor[0],\n subtotalColor[1],\n subtotalColor[2],\n 0.9,\n );\n gl.drawArrays(gl.TRIANGLES, 0, s.wfSubtotalCount);\n }\n\n if (\n s.style.showConnectors !== false &&\n s.wfConnectorBuffer &&\n s.wfConnectorCount &&\n s.wfConnectorCount > 0\n ) {\n gl.useProgram(programs.lineProgram.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, s.wfConnectorBuffer);\n gl.enableVertexAttribArray(programs.lineProgram.attributes.position);\n gl.vertexAttribPointer(\n programs.lineProgram.attributes.position,\n 2,\n gl.FLOAT,\n false,\n 0,\n 0,\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uScale,\n seriesUniforms.scale[0],\n seriesUniforms.scale[1],\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uTranslate,\n seriesUniforms.translate[0],\n seriesUniforms.translate[1],\n );\n gl.uniform4f(\n programs.lineProgram.uniforms.uColor!,\n connectorColor[0],\n connectorColor[1],\n connectorColor[2],\n 0.6,\n );\n gl.lineWidth(1);\n gl.drawArrays(gl.LINES, 0, s.wfConnectorCount);\n }\n\n gl.disableVertexAttribArray(programs.lineProgram.attributes.position);\n void dpr;\n}\n\nlet registered = false;\n\nexport function registerExtendedFrameRenderers(): void {\n if (registered) return;\n registered = true;\n\n registerFrameRenderer(\"heatmap\", (ctx, s, uniforms) =>\n renderHeatmapSeries(ctx, s, uniforms),\n );\n registerFrameRenderer(\"bar\", (ctx, s, uniforms, color) =>\n renderBarSeries(ctx, s, uniforms, color),\n );\n registerFrameRenderer(\"boxplot\", (ctx, s, uniforms) =>\n renderBoxplotSeries(ctx, s, uniforms),\n );\n registerFrameRenderer(\"waterfall\", (ctx, s, uniforms) =>\n renderWaterfallSeries(ctx, s, uniforms),\n );\n}\n","/**\n * Gauge Chart Renderer\n * \n * Renders a dial/gauge with ranges and a needle.\n * Uses Canvas 2D for high-quality decorative elements.\n */\n\nimport type { GaugeData, GaugeStyle, PlotArea } from \"../types\";\n\nexport function drawGauge(\n ctx: CanvasRenderingContext2D,\n data: GaugeData,\n style: GaugeStyle,\n plotArea: PlotArea\n): void {\n const { value, min, max } = data;\n const {\n needleColor = \"#333\",\n needleWidth = 3,\n ranges = [],\n radius: radiusScale = 0.8,\n startAngle = 135,\n endAngle = 405,\n showValue = true,\n valueColor = \"#fff\",\n valueSize = 24,\n label\n } = style;\n\n const centerX = plotArea.x + plotArea.width / 2;\n const centerY = plotArea.y + plotArea.height / 2;\n const maxRadius = (Math.min(plotArea.width, plotArea.height) / 2) * radiusScale;\n\n const totalAngle = endAngle - startAngle;\n const valueRatio = Math.max(0, Math.min(1, (value - min) / (max - min)));\n const currentAngle = (startAngle + valueRatio * totalAngle) * (Math.PI / 180);\n\n ctx.save();\n \n // Draw background arc\n ctx.beginPath();\n ctx.arc(centerX, centerY, maxRadius, startAngle * (Math.PI / 180), endAngle * (Math.PI / 180));\n ctx.strokeStyle = \"rgba(255, 255, 255, 0.1)\";\n ctx.lineWidth = maxRadius * 0.2;\n ctx.lineCap = \"round\";\n ctx.stroke();\n\n // Draw defined ranges\n for (const range of ranges) {\n const rStart = Math.max(0, Math.min(1, (range.from - min) / (max - min)));\n const rEnd = Math.max(0, Math.min(1, (range.to - min) / (max - min)));\n \n ctx.beginPath();\n ctx.arc(\n centerX, \n centerY, \n maxRadius, \n (startAngle + rStart * totalAngle) * (Math.PI / 180), \n (startAngle + rEnd * totalAngle) * (Math.PI / 180)\n );\n ctx.strokeStyle = range.color;\n ctx.lineWidth = maxRadius * 0.2;\n ctx.stroke();\n }\n\n // Draw Ticks\n const numTicks = 11;\n for (let i = 0; i < numTicks; i++) {\n const angle = (startAngle + (i / (numTicks - 1)) * totalAngle) * (Math.PI / 180);\n const innerR = maxRadius * 0.85;\n const outerR = maxRadius * 0.95;\n \n ctx.beginPath();\n ctx.moveTo(centerX + innerR * Math.cos(angle), centerY + innerR * Math.sin(angle));\n ctx.lineTo(centerX + outerR * Math.cos(angle), centerY + outerR * Math.sin(angle));\n ctx.strokeStyle = \"rgba(255, 255, 255, 0.5)\";\n ctx.lineWidth = 2;\n ctx.stroke();\n }\n\n // Draw Needle\n ctx.beginPath();\n ctx.moveTo(centerX, centerY);\n ctx.lineTo(centerX + maxRadius * 0.9 * Math.cos(currentAngle), centerY + maxRadius * 0.9 * Math.sin(currentAngle));\n ctx.strokeStyle = needleColor;\n ctx.lineWidth = needleWidth;\n ctx.lineCap = \"round\";\n \n // Needle shadow/glow\n ctx.shadowColor = needleColor;\n ctx.shadowBlur = 10;\n ctx.stroke();\n ctx.shadowBlur = 0;\n\n // Center hub\n ctx.beginPath();\n ctx.arc(centerX, centerY, 8, 0, Math.PI * 2);\n ctx.fillStyle = needleColor;\n ctx.fill();\n ctx.strokeStyle = \"#fff\";\n ctx.lineWidth = 2;\n ctx.stroke();\n\n // Value text\n if (showValue) {\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.font = `bold ${valueSize}px Inter, sans-serif`;\n ctx.fillStyle = valueColor;\n ctx.fillText(value.toFixed(1), centerX, centerY + maxRadius * 0.4);\n \n if (label) {\n ctx.font = `${valueSize * 0.5}px Inter, sans-serif`;\n ctx.fillStyle = \"rgba(255, 255, 255, 0.6)\";\n ctx.fillText(label, centerX, centerY + maxRadius * 0.6);\n }\n }\n\n ctx.restore();\n}\n","import type { SankeyData, SankeyStyle, PlotArea, SankeyNode, SankeyLink } from \"../types\";\n\nexport function drawSankey(\n ctx: CanvasRenderingContext2D,\n data: SankeyData,\n style: SankeyStyle,\n plotArea: PlotArea\n): void {\n const { nodes, links } = data;\n const {\n nodeWidth = 18,\n nodePadding = 12,\n palette = [\"#6366f1\", \"#10b981\", \"#3b82f6\", \"#f43f5e\", \"#f59e0b\"],\n linkOpacity = 0.4,\n showLabels = true\n } = style;\n\n if (!links.length) return;\n\n // Apply zoom out factor to reduce the diagram size\n const zoomFactor = 1.8;\n const effectiveWidth = plotArea.width / zoomFactor;\n const effectiveHeight = plotArea.height / zoomFactor;\n const offsetX = (plotArea.width - effectiveWidth) / 2;\n const offsetY = (plotArea.height - effectiveHeight) / 2;\n \n const scaledPlotArea = {\n x: plotArea.x + offsetX,\n y: plotArea.y + offsetY,\n width: effectiveWidth,\n height: effectiveHeight\n };\n\n // Use scaledPlotArea for all calculations below\n const workingArea = scaledPlotArea;\n\n // 1. Build node ID set\n const allNodeIds = new Set<string | number>();\n links.forEach((l: SankeyLink) => {\n allNodeIds.add(l.source);\n allNodeIds.add(l.target);\n });\n const nodeIds = Array.from(allNodeIds);\n\n // 2. Calculate layers (depth-first from sources)\n const nodeLevels = new Map<string | number, number>();\n const targets = new Set(links.map((l: SankeyLink) => l.target));\n const roots = nodeIds.filter(id => !targets.has(id));\n \n roots.forEach(id => nodeLevels.set(id, 0));\n \n let changed = true;\n while (changed) {\n changed = false;\n links.forEach((l: SankeyLink) => {\n const srcLevel = nodeLevels.get(l.source);\n if (srcLevel !== undefined) {\n const currentDstLevel = nodeLevels.get(l.target);\n const newDstLevel = srcLevel + 1;\n if (currentDstLevel === undefined || newDstLevel > currentDstLevel) {\n nodeLevels.set(l.target, newDstLevel);\n changed = true;\n }\n }\n });\n }\n\n nodeIds.forEach(id => {\n if (nodeLevels.get(id) === undefined) nodeLevels.set(id, 0);\n });\n\n const maxLevel = Math.max(...Array.from(nodeLevels.values()));\n const layers: (string | number)[][] = Array.from({ length: maxLevel + 1 }, () => []);\n nodeIds.forEach(id => layers[nodeLevels.get(id)!].push(id));\n\n // 3. Calculate node values (max of in/out)\n const nodeInValue = new Map<string | number, number>();\n const nodeOutValue = new Map<string | number, number>();\n \n links.forEach((l: SankeyLink) => {\n nodeOutValue.set(l.source, (nodeOutValue.get(l.source) || 0) + l.value);\n nodeInValue.set(l.target, (nodeInValue.get(l.target) || 0) + l.value);\n });\n\n const getNodeValue = (id: string | number) => Math.max(nodeInValue.get(id) || 0, nodeOutValue.get(id) || 0);\n\n // 4. Calculate global scale\n let maxLayerTotal = 0;\n layers.forEach(layerNodes => {\n let layerTotal = 0;\n layerNodes.forEach(id => layerTotal += getNodeValue(id));\n if (layerTotal > maxLayerTotal) maxLayerTotal = layerTotal;\n });\n\n // 5. Position nodes\n type NodeLayout = { x: number; y: number; width: number; height: number; color: string; value: number };\n const nodeRegistry = new Map<string | number, NodeLayout>();\n \n const numLayers = layers.length;\n const horizontalSpacing = (workingArea.width - nodeWidth) / Math.max(1, numLayers - 1);\n\n layers.forEach((layerNodes, lIdx) => {\n const x = workingArea.x + (lIdx * horizontalSpacing);\n \n // Calculate all node heights first\n const nodeHeights: number[] = [];\n let layerHeightSum = 0;\n layerNodes.forEach(id => {\n const val = getNodeValue(id);\n const h = maxLayerTotal > 0 ? (val / maxLayerTotal) * (workingArea.height * 0.9) : 20;\n nodeHeights.push(h);\n layerHeightSum += h;\n });\n\n // Center nodes vertically\n const totalPadding = (layerNodes.length - 1) * nodePadding;\n const totalContentHeight = layerHeightSum + totalPadding;\n let currentY = workingArea.y + (workingArea.height - totalContentHeight) / 2;\n\n layerNodes.forEach((id, nIdx) => {\n const height = nodeHeights[nIdx];\n \n let color = palette[nIdx % palette.length];\n if (nodes.length > 0) {\n const found = (nodes as SankeyNode[]).find(n => n.id === id);\n if (found?.color) color = found.color;\n }\n \n nodeRegistry.set(id, { x, y: currentY, width: nodeWidth, height, color, value: getNodeValue(id) });\n currentY += height + nodePadding;\n });\n });\n\n // 6. Draw flow bands FIRST (behind nodes)\n ctx.save();\n \n const sourceOffsets = new Map<string | number, number>();\n const targetOffsets = new Map<string | number, number>();\n\n links.forEach((link: SankeyLink) => {\n const src = nodeRegistry.get(link.source);\n const dst = nodeRegistry.get(link.target);\n if (!src || !dst) return;\n\n const sOffset = sourceOffsets.get(link.source) || 0;\n const tOffset = targetOffsets.get(link.target) || 0;\n \n const sValue = nodeOutValue.get(link.source) || 1;\n const tValue = nodeInValue.get(link.target) || 1;\n\n const srcFlowHeight = (link.value / sValue) * src.height;\n const dstFlowHeight = (link.value / tValue) * dst.height;\n\n // Coordinates\n const x0 = src.x + src.width;\n const y0 = src.y + sOffset;\n const y1 = y0 + srcFlowHeight;\n\n const x2 = dst.x;\n const y2 = dst.y + tOffset;\n const y3 = y2 + dstFlowHeight;\n\n const cpOffset = (x2 - x0) * 0.5;\n\n // Create gradient for the flow\n const gradient = ctx.createLinearGradient(x0, (y0 + y1) / 2, x2, (y2 + y3) / 2);\n gradient.addColorStop(0, src.color);\n gradient.addColorStop(1, dst.color);\n\n // Draw filled flow band\n ctx.beginPath();\n ctx.moveTo(x0, y0);\n ctx.bezierCurveTo(x0 + cpOffset, y0, x2 - cpOffset, y2, x2, y2);\n ctx.lineTo(x2, y3);\n ctx.bezierCurveTo(x2 - cpOffset, y3, x0 + cpOffset, y1, x0, y1);\n ctx.closePath();\n\n ctx.fillStyle = gradient;\n ctx.globalAlpha = linkOpacity;\n ctx.fill();\n \n // Optional: Add a subtle stroke for definition\n ctx.strokeStyle = src.color;\n ctx.globalAlpha = linkOpacity * 0.3;\n ctx.lineWidth = 0.5;\n ctx.stroke();\n \n sourceOffsets.set(link.source, sOffset + srcFlowHeight);\n targetOffsets.set(link.target, tOffset + dstFlowHeight);\n });\n \n ctx.restore();\n\n // 7. Draw nodes ON TOP\n ctx.save();\n ctx.globalAlpha = 1.0;\n \n nodeRegistry.forEach((node) => {\n // Main node rectangle\n ctx.fillStyle = node.color;\n ctx.fillRect(node.x, node.y, node.width, node.height);\n \n // Optional: Add slight gradient for depth\n const grad = ctx.createLinearGradient(node.x, node.y, node.x + node.width, node.y);\n grad.addColorStop(0, \"rgba(255, 255, 255, 0.15)\");\n grad.addColorStop(1, \"rgba(0, 0, 0, 0.15)\");\n ctx.fillStyle = grad;\n ctx.fillRect(node.x, node.y, node.width, node.height);\n });\n \n ctx.restore();\n\n // 8. Draw labels LAST\n if (showLabels) {\n ctx.save();\n ctx.font = \"bold 11px Inter, -apple-system, sans-serif\";\n ctx.textBaseline = \"middle\";\n \n nodeRegistry.forEach((node, id) => {\n let nodeName = String(id);\n const found = (nodes as SankeyNode[]).find(n => n.id === id);\n if (found?.name) nodeName = found.name;\n\n const isFirstLayer = node.x <= workingArea.x + 5;\n const isLastLayer = node.x >= workingArea.x + workingArea.width - nodeWidth - 5;\n \n // White text with dark shadow for contrast\n ctx.shadowBlur = 3;\n ctx.shadowColor = \"rgba(0, 0, 0, 0.7)\";\n ctx.fillStyle = \"#ffffff\";\n\n if (isFirstLayer) {\n ctx.textAlign = \"right\";\n ctx.fillText(nodeName, node.x - 10, node.y + node.height / 2);\n } else if (isLastLayer) {\n ctx.textAlign = \"left\";\n ctx.fillText(nodeName, node.x + node.width + 10, node.y + node.height / 2);\n } else {\n // Middle layers: label above\n ctx.textAlign = \"center\";\n ctx.fillText(nodeName, node.x + node.width / 2, node.y - 10);\n }\n });\n \n ctx.restore();\n }\n}\n","import { drawGauge } from \"./GaugeRenderer\";\nimport { drawSankey } from \"./SankeyRenderer\";\nimport { registerOverlaySeriesDrawer } from \"../core/chart/overlaySeriesRegistry\";\n\nlet registered = false;\n\nexport function registerExtendedOverlayDrawers(): void {\n if (registered) return;\n registered = true;\n\n registerOverlaySeriesDrawer(\"gauge\", (ctx, s, plotArea) => {\n const gData = s.getGaugeData();\n const gStyle = s.getGaugeStyle();\n if (gData && gStyle) drawGauge(ctx, gData, gStyle, plotArea);\n });\n\n registerOverlaySeriesDrawer(\"sankey\", (ctx, s, plotArea) => {\n const sData = s.getSankeyData();\n const sStyle = s.getSankeyStyle();\n if (sData && sStyle) drawSankey(ctx, sData, sStyle, plotArea);\n });\n}\n","import type { ProgramBundle } from \"./types\";\nimport { HEATMAP_FRAG, HEATMAP_VERT } from \"./shaderSources\";\nimport { createProgram } from \"./programFactoryCore\";\n\n/** Compile the heatmap shader program (scientific/trading/full bundles). */\nexport function registerHeatmapProgram(\n gl: WebGLRenderingContext,\n bundle: ProgramBundle,\n): void {\n bundle.heatmapProgram = createProgram(gl, HEATMAP_VERT, HEATMAP_FRAG, \"heatmap\");\n}\n","import { ChartImpl } from \"../core/chart/ChartCore\";\nimport { NativeWebGLRenderer } from \"./NativeWebGLRenderer\";\n\nlet registered = false;\n\n/** Enable `renderer: 'webgpu'` for charts (extended bundles only). */\nexport function registerWebGPURenderer(): void {\n if (registered) return;\n registered = true;\n\n ChartImpl.afterConstruct = (chart, options) => {\n if (options.renderer !== \"webgpu\") return;\n (chart as { _webgpuInitPromise?: Promise<void> })._webgpuInitPromise =\n initWebGPURenderer(chart);\n };\n}\n\nasync function initWebGPURenderer(chart: ChartImpl): Promise<void> {\n const c = chart as any;\n const { createGpuChartRenderer } = await import(\"./GpuChartRenderer\");\n const gpu = await createGpuChartRenderer(c.webglCanvas, {\n backend: \"webgpu\",\n powerPreference: \"high-performance\",\n });\n\n if (gpu) {\n c.renderer = gpu;\n c.activeRendererType = gpu.backend;\n c.renderer.setDPR(c.dpr);\n c.renderLoop?.setRenderer(c.renderer);\n return;\n }\n\n console.warn(\n \"[VeloPlot] WebGPU unavailable — falling back to WebGL2. \" +\n \"See docs/adr/001-webgpu-renderer-strategy.md.\",\n );\n c.renderer = new NativeWebGLRenderer(c.webglCanvas);\n c.activeRendererType = \"webgl\";\n c.renderer.setDPR(c.dpr);\n c.renderLoop?.setRenderer(c.renderer);\n}\n","/**\n * Registers extended series buffers and frame renderers for trading/scientific/full bundles.\n */\nimport { registerExtendedSeriesBuffers } from \"./seriesBufferExtended\";\nimport { registerExtendedFrameRenderers } from \"./native/frameRenderExtended\";\nimport { registerExtendedOverlayDrawers } from \"./overlaySeriesExtended\";\nimport { registerHeatmapProgram } from \"./native/programFactoryExtended\";\nimport { NativeWebGLRenderer } from \"./NativeWebGLRenderer\";\nimport { registerWebGPURenderer } from \"./registerWebGPU\";\n\nlet registered = false;\n\nexport function registerExtendedSeries(): void {\n if (registered) return;\n registered = true;\n NativeWebGLRenderer.heatmapProgramInstaller = registerHeatmapProgram;\n registerWebGPURenderer();\n registerExtendedSeriesBuffers();\n registerExtendedFrameRenderers();\n registerExtendedOverlayDrawers();\n}\n","/**\n * SVG Export Support\n */\nimport { Series } from \"../../Series\";\nimport type { AxisOptions, Bounds, PlotArea } from \"../../../types\";\nimport { Scale } from \"../../../scales\";\nimport { ChartTheme } from \"../../../theme\";\nimport { formatXTickValue, formatYTickValue } from \"../../format/axisFormat\";\nimport { snapLabelCoord, snapLineCoord } from \"../../render/pixelSnap\";\n\nexport interface SVGExportOptions {\n xAxis?: AxisOptions;\n yAxis?: AxisOptions;\n primaryYAxisId?: string;\n}\n\nfunction escapeXml(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\nfunction primaryYScale(yAxes: Map<string, Scale>, primaryYAxisId?: string): Scale | undefined {\n if (primaryYAxisId && yAxes.has(primaryYAxisId)) {\n return yAxes.get(primaryYAxisId);\n }\n return yAxes.get(\"default\") ?? yAxes.values().next().value;\n}\n\nexport function exportToSVG(\n series: Series[],\n _viewBounds: Bounds,\n plotArea: PlotArea,\n xAxis: Scale,\n yAxes: Map<string, Scale>,\n theme: ChartTheme,\n width: number,\n height: number,\n axisOptions: SVGExportOptions = {},\n): string {\n const yScale = primaryYScale(yAxes, axisOptions.primaryYAxisId);\n if (!yScale) {\n throw new Error(\"SVG export requires at least one Y scale\");\n }\n\n const svg = [\n `<svg width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\" xmlns=\"http://www.w3.org/2000/svg\" font-family=\"${theme.xAxis.fontFamily || \"sans-serif\"}\">`,\n `<rect width=\"100%\" height=\"100%\" fill=\"${theme.backgroundColor}\" />`,\n `<g transform=\"translate(0,0)\">`,\n ];\n\n drawSVGGrid(svg, plotArea, xAxis, yScale, theme);\n drawSeriesSVG(svg, series, plotArea, xAxis, yAxes, axisOptions.primaryYAxisId);\n drawSVGAxes(svg, plotArea, xAxis, yScale, theme);\n drawSVGTickLabels(svg, plotArea, xAxis, yScale, theme, axisOptions);\n\n svg.push(\"</g>\");\n svg.push(\"</svg>\");\n return svg.join(\"\\n\");\n}\n\nfunction drawSeriesSVG(\n svg: string[],\n series: Series[],\n plotArea: PlotArea,\n xAxis: Scale,\n yAxes: Map<string, Scale>,\n primaryYAxisId?: string,\n): void {\n for (const s of series) {\n if (!s.isVisible()) continue;\n const yScale =\n yAxes.get(s.getYAxisId() || primaryYAxisId || \"default\") ??\n primaryYScale(yAxes, primaryYAxisId);\n if (!yScale) continue;\n\n const data = s.getData();\n if (!data || data.x.length === 0) continue;\n\n const style = s.getStyle() as Record<string, unknown>;\n const type = s.getType();\n\n if (type === \"line\" || type === \"step\") {\n const points: string[] = [];\n const stepMode = (style.stepMode as string) || \"after\";\n for (let i = 0; i < data.x.length; i++) {\n const px = xAxis.transform(data.x[i]);\n const py = yScale.transform(data.y[i]);\n if (i > 0 && type === \"step\") {\n const prevPx = xAxis.transform(data.x[i - 1]);\n const prevPy = yScale.transform(data.y[i - 1]);\n if (stepMode === \"after\") points.push(`${px.toFixed(1)},${prevPy.toFixed(1)}`);\n else if (stepMode === \"before\") points.push(`${prevPx.toFixed(1)},${py.toFixed(1)}`);\n else if (stepMode === \"center\") {\n const midX = (prevPx + px) / 2;\n points.push(`${midX.toFixed(1)},${prevPy.toFixed(1)}`);\n points.push(`${midX.toFixed(1)},${py.toFixed(1)}`);\n }\n }\n points.push(`${px.toFixed(1)},${py.toFixed(1)}`);\n }\n svg.push(\n `<polyline points=\"${points.join(\" \")}\" fill=\"none\" stroke=\"${style.color}\" stroke-width=\"${style.width || 1.5}\" stroke-opacity=\"${style.opacity || 1}\" stroke-linejoin=\"round\" />`,\n );\n } else if (type === \"scatter\") {\n for (let i = 0; i < data.x.length; i++) {\n const px = xAxis.transform(data.x[i]);\n const py = yScale.transform(data.y[i]);\n svg.push(\n `<circle cx=\"${px.toFixed(1)}\" cy=\"${py.toFixed(1)}\" r=\"${(((style.pointSize as number) || 4) / 2).toFixed(1)}\" fill=\"${style.color}\" fill-opacity=\"${style.opacity || 1}\" />`,\n );\n }\n } else if (type === \"bar\") {\n const barWidth =\n ((style.barWidth as number) || 5) *\n (plotArea.width / (xAxis.domain[1] - xAxis.domain[0]));\n for (let i = 0; i < data.x.length; i++) {\n const px = xAxis.transform(data.x[i]);\n const py = yScale.transform(data.y[i]);\n const p0 = yScale.transform(0);\n const yTop = Math.min(py, p0);\n const yHeight = Math.abs(py - p0);\n svg.push(\n `<rect x=\"${(px - barWidth / 2).toFixed(1)}\" y=\"${yTop.toFixed(1)}\" width=\"${barWidth.toFixed(1)}\" height=\"${yHeight.toFixed(1)}\" fill=\"${style.color}\" fill-opacity=\"${style.opacity || 1}\" />`,\n );\n }\n } else if (type === \"band\" || type === \"area\") {\n const y2 =\n type === \"area\"\n ? new Float32Array(data.x.length).fill(0)\n : data.y2 || new Float32Array(data.x.length).fill(0);\n const points: string[] = [];\n for (let i = 0; i < data.x.length; i++) {\n points.push(\n `${xAxis.transform(data.x[i]).toFixed(1)},${yScale.transform(data.y[i]).toFixed(1)}`,\n );\n }\n for (let i = data.x.length - 1; i >= 0; i--) {\n points.push(\n `${xAxis.transform(data.x[i]).toFixed(1)},${yScale.transform(y2[i]).toFixed(1)}`,\n );\n }\n svg.push(\n `<polygon points=\"${points.join(\" \")}\" fill=\"${style.color}\" fill-opacity=\"${(Number(style.opacity) || 1) * 0.3}\" stroke=\"${style.color}\" stroke-width=\"${style.width || 1}\" />`,\n );\n } else if (type === \"candlestick\") {\n const bw =\n ((style.barWidth as number) || 5) *\n (plotArea.width / (xAxis.domain[1] - xAxis.domain[0]));\n const bullishColor = (style.bullishColor as string) || \"#26a69a\";\n const bearishColor = (style.bearishColor as string) || \"#ef5350\";\n if (data.open && data.high && data.low && data.close) {\n for (let i = 0; i < data.x.length; i++) {\n const isBull = data.close[i] >= data.open[i];\n const px = xAxis.transform(data.x[i]);\n const pyOpen = yScale.transform(data.open[i]);\n const pyClose = yScale.transform(data.close[i]);\n const pyHigh = yScale.transform(data.high[i]);\n const pyLow = yScale.transform(data.low[i]);\n const color = isBull ? bullishColor : bearishColor;\n svg.push(\n `<line x1=\"${px.toFixed(1)}\" y1=\"${pyHigh.toFixed(1)}\" x2=\"${px.toFixed(1)}\" y2=\"${pyLow.toFixed(1)}\" stroke=\"${color}\" stroke-width=\"1\" />`,\n );\n const yTop = Math.min(pyOpen, pyClose);\n const yHeight = Math.max(1, Math.abs(pyOpen - pyClose));\n svg.push(\n `<rect x=\"${(px - bw / 2).toFixed(1)}\" y=\"${yTop.toFixed(1)}\" width=\"${bw.toFixed(1)}\" height=\"${yHeight.toFixed(1)}\" fill=\"${color}\" />`,\n );\n }\n }\n }\n }\n}\n\nfunction drawSVGAxes(\n svg: string[],\n plotArea: PlotArea,\n _xAxis: Scale,\n _yScale: Scale,\n theme: ChartTheme,\n): void {\n const axisY = snapLineCoord(plotArea.y + plotArea.height);\n const axisX = snapLineCoord(plotArea.x);\n svg.push(\n `<line x1=\"${plotArea.x}\" y1=\"${axisY}\" x2=\"${plotArea.x + plotArea.width}\" y2=\"${axisY}\" stroke=\"${theme.xAxis.lineColor}\" stroke-width=\"${theme.xAxis.lineWidth || 2}\" />`,\n );\n svg.push(\n `<line x1=\"${axisX}\" y1=\"${plotArea.y}\" x2=\"${axisX}\" y2=\"${plotArea.y + plotArea.height}\" stroke=\"${theme.yAxis.lineColor}\" stroke-width=\"${theme.yAxis.lineWidth || 2}\" />`,\n );\n}\n\nfunction drawSVGTickLabels(\n svg: string[],\n plotArea: PlotArea,\n xScale: Scale,\n yScale: Scale,\n theme: ChartTheme,\n options: SVGExportOptions,\n): void {\n const xOpts = options.xAxis;\n const yOpts = options.yAxis;\n const xTickCount = xOpts?.tickCount ?? 8;\n const yTickCount = yOpts?.tickCount ?? 6;\n const domainSpan = xScale.domain[1] - xScale.domain[0];\n const axisY = plotArea.y + plotArea.height;\n const axisX = plotArea.x;\n const xFont = theme.xAxis;\n const yFont = theme.yAxis;\n\n if (xOpts?.showLabels !== false) {\n xScale.ticks(xTickCount).forEach((tick) => {\n const x = snapLabelCoord(xScale.transform(tick));\n if (x < plotArea.x || x > plotArea.x + plotArea.width) return;\n const label = formatXTickValue(tick, xOpts, domainSpan);\n const y = axisY + (xFont.tickLength ?? 4) + xFont.labelSize * 0.75;\n svg.push(\n `<text x=\"${x.toFixed(1)}\" y=\"${y.toFixed(1)}\" fill=\"${xFont.labelColor}\" font-size=\"${xFont.labelSize}\" text-anchor=\"middle\">${escapeXml(label)}</text>`,\n );\n });\n }\n\n if (yOpts?.showLabels !== false) {\n yScale.ticks(yTickCount).forEach((tick) => {\n const y = snapLabelCoord(yScale.transform(tick));\n if (y < plotArea.y || y > plotArea.y + plotArea.height) return;\n const label = formatYTickValue(tick, yOpts);\n const x = axisX - (yFont.tickLength ?? 4) - 4;\n svg.push(\n `<text x=\"${x.toFixed(1)}\" y=\"${(y + yFont.labelSize * 0.35).toFixed(1)}\" fill=\"${yFont.labelColor}\" font-size=\"${yFont.labelSize}\" text-anchor=\"end\">${escapeXml(label)}</text>`,\n );\n });\n }\n}\n\nfunction drawSVGGrid(\n svg: string[],\n plotArea: PlotArea,\n xAxis: Scale,\n yScale: Scale,\n theme: ChartTheme,\n): void {\n if (!theme.grid.visible) return;\n xAxis.ticks(10).forEach((tick) => {\n const px = snapLineCoord(xAxis.transform(tick));\n if (px >= plotArea.x && px <= plotArea.x + plotArea.width) {\n svg.push(\n `<line x1=\"${px.toFixed(1)}\" y1=\"${plotArea.y}\" x2=\"${px.toFixed(1)}\" y2=\"${plotArea.y + plotArea.height}\" stroke=\"${theme.grid.majorColor}\" stroke-opacity=\"0.1\" stroke-dasharray=\"2,2\" />`,\n );\n }\n });\n yScale.ticks(10).forEach((tick) => {\n const py = snapLineCoord(yScale.transform(tick));\n if (py >= plotArea.y && py <= plotArea.y + plotArea.height) {\n svg.push(\n `<line x1=\"${plotArea.x}\" y1=\"${py.toFixed(1)}\" x2=\"${plotArea.x + plotArea.width}\" y2=\"${py.toFixed(1)}\" stroke=\"${theme.grid.majorColor}\" stroke-opacity=\"0.1\" stroke-dasharray=\"2,2\" />`,\n );\n }\n });\n}\n","import { ChartImpl } from \"./ChartCore\";\nimport { exportToSVG } from \"./exporter/SVGExporter\";\n\nlet patched = false;\n\n/** Restore sync SVG export on Chart (trading/scientific/full bundles). */\nexport function patchExportSVG(): void {\n if (patched) return;\n patched = true;\n\n ChartImpl.prototype.exportSVG = function (): string {\n const chart = this as any;\n const rect = chart.container.getBoundingClientRect();\n return exportToSVG(\n chart.getAllSeries(),\n chart.viewBounds,\n chart.getPlotArea(),\n chart.xScale,\n chart.yScales,\n chart.theme,\n rect.width || chart.container.clientWidth,\n rect.height || chart.container.clientHeight,\n {\n xAxis: chart.xAxisOptions,\n yAxis: chart.yAxisOptionsMap.get(chart.primaryYAxisId),\n primaryYAxisId: chart.primaryYAxisId,\n },\n );\n };\n}\n","/**\n * Price alert registry (Stage 2.18).\n */\n\nimport type { EventEmitter } from \"../EventEmitter\";\nimport type { ChartEventMap } from \"../../types\";\n\nexport type AlertDirection = \"above\" | \"below\" | \"cross\";\n\nexport interface PriceAlertOptions {\n id?: string;\n price: number;\n direction: AlertDirection;\n seriesId?: string;\n /** Fire once then remove (default true) */\n once?: boolean;\n}\n\nexport interface AlertEvent {\n id: string;\n price: number;\n direction: AlertDirection;\n seriesId?: string;\n triggeredAt: number;\n triggerPrice: number;\n}\n\nexport interface AlertableSeries {\n getId(): string;\n getData(): { x: Float32Array | Float64Array; y?: Float32Array | Float64Array; close?: Float32Array | Float64Array };\n}\n\nexport class ChartAlertManager {\n private alerts = new Map<string, PriceAlertOptions & { id: string }>();\n private idCounter = 0;\n\n constructor(\n private events: EventEmitter<ChartEventMap>,\n private getSeries: (id?: string) => AlertableSeries | undefined,\n ) {}\n\n addAlert(options: PriceAlertOptions): string {\n const id = options.id ?? `alert_${++this.idCounter}`;\n this.alerts.set(id, { ...options, id });\n return id;\n }\n\n removeAlert(id: string): boolean {\n return this.alerts.delete(id);\n }\n\n clearAlerts(): void {\n this.alerts.clear();\n }\n\n getAlerts(): PriceAlertOptions[] {\n return Array.from(this.alerts.values());\n }\n\n /** Call after data updates / render tick. */\n evaluate(): void {\n for (const [id, alert] of [...this.alerts.entries()]) {\n const series = this.getSeries(alert.seriesId);\n if (!series) continue;\n\n const data = series.getData();\n const prices = data.close ?? data.y;\n if (!prices?.length) continue;\n\n const latest = prices[prices.length - 1];\n if (!Number.isFinite(latest)) continue;\n\n const prev = prices.length > 1 ? prices[prices.length - 2] : latest;\n let triggered = false;\n\n switch (alert.direction) {\n case \"above\":\n triggered = latest >= alert.price;\n break;\n case \"below\":\n triggered = latest <= alert.price;\n break;\n case \"cross\":\n triggered =\n (prev < alert.price && latest >= alert.price) ||\n (prev > alert.price && latest <= alert.price);\n break;\n }\n\n if (!triggered) continue;\n\n const payload: AlertEvent = {\n id,\n price: alert.price,\n direction: alert.direction,\n seriesId: alert.seriesId ?? series.getId(),\n triggeredAt: Date.now(),\n triggerPrice: latest,\n };\n\n this.events.emit(\"alert\", payload);\n\n if (alert.once !== false) {\n this.alerts.delete(id);\n }\n }\n }\n\n destroy(): void {\n this.alerts.clear();\n }\n}\n","/**\n * Position lines — entry, stop-loss, take-profit (Stage 2.15).\n */\n\nimport type { Annotation } from \"../annotations/types\";\n\nexport type PositionLineStyle = \"entry\" | \"sl\" | \"tp\";\n\nexport interface PositionLineOptions {\n id?: string;\n price: number;\n label?: string;\n color?: string;\n style?: PositionLineStyle;\n interactive?: boolean;\n}\n\nconst STYLE_COLORS: Record<PositionLineStyle, string> = {\n entry: \"#38bdf8\",\n sl: \"#ef4444\",\n tp: \"#22c55e\",\n};\n\nconst STYLE_LABELS: Record<PositionLineStyle, string> = {\n entry: \"Entry\",\n sl: \"SL\",\n tp: \"TP\",\n};\n\nexport function buildPositionLineAnnotation(\n options: PositionLineOptions,\n id: string,\n): Annotation {\n const style = options.style ?? \"entry\";\n return {\n id,\n type: \"horizontal-line\",\n y: options.price,\n color: options.color ?? STYLE_COLORS[style],\n label: options.label ?? STYLE_LABELS[style],\n labelPosition: \"right\",\n lineDash: style === \"sl\" ? [6, 4] : style === \"tp\" ? [4, 4] : undefined,\n interactive: options.interactive ?? false,\n };\n}\n","/**\n * Trading-specific series preprocessors and chart method extensions.\n */\nimport type { SeriesOptions } from \"../types\";\nimport { computeHeikinAshi } from \"../core/chart/heikinAshi\";\nimport {\n applyBusinessDayX,\n isBusinessDayScaleActive,\n} from \"../core/time/applyTimeScale\";\nimport { buildIndicatorSeries } from \"../core/indicator/buildIndicatorSeries\";\nimport type { IndicatorSeriesOptions } from \"../core/indicator/types\";\nimport {\n registerSeriesOptionsExpander,\n registerSeriesOptionsPreprocessor,\n} from \"../core/chart/series/seriesOptionsRegistry\";\nimport { registerSeriesDataPreprocessor } from \"../core/chart/series/SeriesActions\";\nimport { registerExtendedSeries } from \"../renderer/registerExtendedSeries\";\nimport { patchExportSVG } from \"../core/chart/chartExportPatch\";\nimport { ChartImpl } from \"../core/chart/ChartCore\";\nimport {\n addIndicatorToChart,\n type AddIndicatorOptions,\n type AddIndicatorResult,\n type IndicatorPresetName,\n} from \"../core/indicator/addIndicator\";\nimport {\n ChartAlertManager,\n type PriceAlertOptions,\n} from \"../core/chart/ChartAlerts\";\nimport {\n buildPositionLineAnnotation,\n type PositionLineOptions,\n} from \"../core/chart/positionLines\";\nimport type { DrawingMode } from \"../plugins/drawing-tools\";\n\nlet registered = false;\n\nfunction registerTradingSeriesPreprocessors(): void {\n registerSeriesOptionsPreprocessor((ctx: any, options) => {\n if (options.type === \"heatmap\" || options.type === \"indicator\") {\n return options;\n }\n\n let opts = { ...options } as SeriesOptions;\n\n if ((opts.type as string) === \"heikin-ashi\") {\n const d = opts.data;\n if (d?.open && d.high && d.low && d.close) {\n const ha = computeHeikinAshi({\n open: d.open,\n high: d.high,\n low: d.low,\n close: d.close,\n });\n opts = {\n ...opts,\n type: \"candlestick\",\n data: { ...d, ...ha },\n };\n }\n }\n\n if (isBusinessDayScaleActive(ctx.xAxisOptions) && opts.data?.x?.length) {\n const { displayX, mapping } = applyBusinessDayX(\n opts.data.x,\n ctx.xAxisOptions,\n );\n ctx.setTimeScaleMapping(mapping);\n opts = {\n ...opts,\n data: { ...opts.data, x: displayX },\n };\n }\n\n return opts;\n });\n\n registerSeriesOptionsExpander((options) => {\n if ((options as SeriesOptions).type === \"indicator\") {\n return buildIndicatorSeries(options as IndicatorSeriesOptions);\n }\n return [options];\n });\n\n registerSeriesDataPreprocessor((ctx: any, data: import(\"../types\").SeriesUpdateData) => {\n if (data.x && isBusinessDayScaleActive(ctx.xAxisOptions)) {\n const { displayX, mapping } = applyBusinessDayX(data.x, ctx.xAxisOptions);\n ctx.setTimeScaleMapping(mapping);\n return { ...data, x: displayX };\n }\n return data;\n });\n}\n\nexport function patchChartTradingMethods(): void {\n const proto = ChartImpl.prototype as any;\n\n if (proto._tradingPatched) return;\n proto._tradingPatched = true;\n\n proto.addIndicator = async function (\n this: ChartImpl,\n preset: IndicatorPresetName,\n options?: AddIndicatorOptions,\n ): Promise<AddIndicatorResult> {\n return addIndicatorToChart(this, preset, options);\n };\n\n proto.addAlert = function (\n this: ChartImpl,\n options: PriceAlertOptions,\n ): string {\n return getAlertManager(this).addAlert(options);\n };\n\n proto.removeAlert = function (this: ChartImpl, id: string): boolean {\n return getAlertManager(this).removeAlert(id);\n };\n\n proto.clearAlerts = function (this: ChartImpl): void {\n getAlertManager(this).clearAlerts();\n };\n\n proto.getAlerts = function (this: ChartImpl): PriceAlertOptions[] {\n return getAlertManager(this).getAlerts();\n };\n\n proto.addPositionLine = function (\n this: ChartImpl,\n options: PositionLineOptions,\n ): string {\n const self = this as ChartImpl & { _positionLineCounter?: number };\n if (self._positionLineCounter === undefined) self._positionLineCounter = 0;\n const id = options.id ?? `position-${++self._positionLineCounter}`;\n self.addAnnotation(buildPositionLineAnnotation(options, id));\n return id;\n };\n\n proto.setDrawingMode = function (this: ChartImpl, mode: DrawingMode): void {\n const plugin = this.getPlugin<{ setMode?: (m: DrawingMode) => void }>(\n \"velo-plot-drawing-tools\",\n );\n plugin?.setMode?.(mode);\n };\n\n const originalDestroy = proto.destroy;\n proto.destroy = function (this: ChartImpl) {\n const self = this as any;\n self._alertManager?.destroy();\n self._alertManager = undefined;\n self.setFeatureHooks(null);\n return originalDestroy.call(this);\n };\n}\n\nfunction getAlertManager(chart: ChartImpl): ChartAlertManager {\n const self = chart as any;\n if (!self._alertManager) {\n self._alertManager = new ChartAlertManager(chart.events, (seriesId) => {\n const s = seriesId ? chart.series.get(seriesId) : undefined;\n if (s) return s as import(\"../core/chart/ChartAlerts\").AlertableSeries;\n const first = chart.series.values().next().value;\n return first as import(\"../core/chart/ChartAlerts\").AlertableSeries | undefined;\n });\n chart.setFeatureHooks({\n onDataUpdate: () => self._alertManager?.evaluate(),\n getAlerts: () => self._alertManager?.getAlerts() ?? [],\n destroy: () => self._alertManager?.destroy(),\n });\n }\n return self._alertManager;\n}\n\n/** Register trading extensions (call on `velo-plot/trading` import). */\nexport function registerTradingBundle(): void {\n if (registered) return;\n registered = true;\n registerExtendedSeries();\n registerTradingSeriesPreprocessors();\n patchChartTradingMethods();\n patchExportSVG();\n}\n\n// Auto-register when trading entry is imported\nregisterTradingBundle();\n","export interface WebGPURendererOptions {\n powerPreference?: \"low-power\" | \"high-performance\";\n preferredFormat?: string;\n antialias?: boolean;\n}\n\nexport class WebGPURenderer {\n public readonly available: boolean;\n\n private canvas: HTMLCanvasElement;\n private adapter: any;\n private device: any;\n private context: any;\n\n constructor(canvas: HTMLCanvasElement, opts: WebGPURendererOptions = {}) {\n this.canvas = canvas;\n this.available = WebGPURenderer.isSupported();\n void opts;\n }\n\n static isSupported(): boolean {\n return (\n typeof (globalThis as any).navigator !== \"undefined\" &&\n typeof (globalThis as any).navigator.gpu !== \"undefined\"\n );\n }\n\n async init(opts: WebGPURendererOptions = {}): Promise<void> {\n if (!this.available) {\n throw new Error(\"[VeloPlot] WebGPU is not supported in this environment\");\n }\n\n const gpu = (globalThis as any).navigator.gpu;\n this.adapter = await gpu.requestAdapter({\n powerPreference: opts.powerPreference ?? \"high-performance\",\n });\n\n if (!this.adapter) {\n throw new Error(\"[VeloPlot] Failed to request WebGPU adapter\");\n }\n\n this.device = await this.adapter.requestDevice();\n\n const ctx = (this.canvas as any).getContext(\"webgpu\");\n if (!ctx) {\n throw new Error(\"[VeloPlot] Failed to get WebGPU context\");\n }\n\n this.context = ctx;\n\n const format =\n opts.preferredFormat ??\n (gpu.getPreferredCanvasFormat\n ? gpu.getPreferredCanvasFormat()\n : \"bgra8unorm\");\n\n this.context.configure({\n device: this.device,\n format,\n alphaMode: \"premultiplied\",\n });\n }\n\n destroy(): void {\n this.device = undefined;\n this.adapter = undefined;\n this.context = undefined;\n }\n}\n","/**\n * WebGL grid spike — batched GL_LINES renderer for axis grid lines.\n * Labels remain on Canvas 2D; this spike covers grid lines only.\n * @module renderer/spike/WebGLGridSpike\n */\n\nexport interface GridLineSpec {\n /** Plot area in CSS pixels */\n plotArea: { x: number; y: number; width: number; height: number };\n /** Pixel X positions for vertical grid lines */\n xLines: number[];\n /** Pixel Y positions for horizontal grid lines */\n yLines: number[];\n /** Canvas width (physical pixels) */\n width: number;\n /** Canvas height (physical pixels) */\n height: number;\n /** Line color RGBA 0–1 */\n color?: [number, number, number, number];\n /** Line width in pixels */\n lineWidth?: number;\n}\n\nconst VERT_SRC = `\n attribute vec2 aPosition;\n uniform vec2 uResolution;\n void main() {\n vec2 clip = (aPosition / uResolution) * 2.0 - 1.0;\n gl_Position = vec4(clip.x, -clip.y, 0.0, 1.0);\n }\n`;\n\nconst FRAG_SRC = `\n precision mediump float;\n uniform vec4 uColor;\n void main() {\n gl_FragColor = uColor;\n }\n`;\n\nfunction compileShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type);\n if (!shader) throw new Error(\"createShader failed\");\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n throw new Error(gl.getShaderInfoLog(shader) ?? \"shader compile failed\");\n }\n return shader;\n}\n\nfunction createProgram(gl: WebGLRenderingContext): WebGLProgram {\n const vs = compileShader(gl, gl.VERTEX_SHADER, VERT_SRC);\n const fs = compileShader(gl, gl.FRAGMENT_SHADER, FRAG_SRC);\n const program = gl.createProgram();\n if (!program) throw new Error(\"createProgram failed\");\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error(gl.getProgramInfoLog(program) ?? \"program link failed\");\n }\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n return program;\n}\n\n/** Build interleaved [x,y] vertex pairs for GL_LINES from tick pixel positions */\nexport function buildGridLineVertices(spec: GridLineSpec): Float32Array {\n const { plotArea, xLines, yLines } = spec;\n const y0 = plotArea.y;\n const y1 = plotArea.y + plotArea.height;\n const x0 = plotArea.x;\n const x1 = plotArea.x + plotArea.width;\n\n const vertCount = (xLines.length + yLines.length) * 2;\n const out = new Float32Array(vertCount * 2);\n let o = 0;\n\n for (const x of xLines) {\n out[o++] = x;\n out[o++] = y0;\n out[o++] = x;\n out[o++] = y1;\n }\n\n for (const y of yLines) {\n out[o++] = x0;\n out[o++] = y;\n out[o++] = x1;\n out[o++] = y;\n }\n\n return out;\n}\n\nexport class WebGLGridSpike {\n private gl: WebGLRenderingContext;\n private program: WebGLProgram;\n private buffer: WebGLBuffer;\n private aPosition: number;\n private uResolution: WebGLUniformLocation;\n private uColor: WebGLUniformLocation;\n\n constructor(canvas: HTMLCanvasElement) {\n const gl = canvas.getContext(\"webgl\", {\n alpha: true,\n antialias: false,\n preserveDrawingBuffer: true,\n });\n if (!gl) throw new Error(\"WebGL not available for grid spike\");\n\n this.gl = gl;\n this.program = createProgram(gl);\n this.aPosition = gl.getAttribLocation(this.program, \"aPosition\");\n this.uResolution = gl.getUniformLocation(this.program, \"uResolution\")!;\n this.uColor = gl.getUniformLocation(this.program, \"uColor\")!;\n\n const buf = gl.createBuffer();\n if (!buf) throw new Error(\"createBuffer failed\");\n this.buffer = buf;\n }\n\n /** Upload vertices and draw grid lines */\n draw(spec: GridLineSpec): number {\n const gl = this.gl;\n const vertices = buildGridLineVertices(spec);\n const lineSegments = vertices.length / 4;\n\n gl.viewport(0, 0, spec.width, spec.height);\n gl.clearColor(0.04, 0.05, 0.08, 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n\n gl.useProgram(this.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.DYNAMIC_DRAW);\n gl.enableVertexAttribArray(this.aPosition);\n gl.vertexAttribPointer(this.aPosition, 2, gl.FLOAT, false, 0, 0);\n\n gl.uniform2f(this.uResolution, spec.width, spec.height);\n const c = spec.color ?? [0.2, 0.22, 0.3, 0.6];\n gl.uniform4f(this.uColor, c[0], c[1], c[2], c[3]);\n gl.lineWidth(spec.lineWidth ?? 1);\n\n gl.drawArrays(gl.LINES, 0, vertices.length / 2);\n return lineSegments;\n }\n\n destroy(): void {\n const gl = this.gl;\n gl.deleteBuffer(this.buffer);\n gl.deleteProgram(this.program);\n }\n}\n","/**\n * Grid rendering benchmark — Canvas 2D vs WebGL spike comparison.\n * @module testing/gridSpikeBenchmark\n */\n\nimport { OverlayRenderer } from \"../core/OverlayRenderer\";\nimport { LinearScale } from \"../scales\";\nimport { DARK_THEME } from \"../theme\";\nimport { WebGLGridSpike, buildGridLineVertices, type GridLineSpec } from \"../renderer/spike/WebGLGridSpike\";\nimport { snapLineCoord } from \"../core/render/pixelSnap\";\nimport type { PlotArea } from \"../types\";\n\nexport interface GridBenchmarkResult {\n backend: \"canvas2d\" | \"webgl\";\n dpr: number;\n width: number;\n height: number;\n xTicks: number;\n yTicks: number;\n lineSegments: number;\n avgFrameUs: number;\n p95FrameUs: number;\n frames: number;\n}\n\nexport interface GridCompareResult {\n canvas2d: GridBenchmarkResult;\n webgl: GridBenchmarkResult | null;\n /** Positive = WebGL faster */\n gainPercent: number;\n recommendation: \"implement\" | \"defer\";\n}\n\nfunction createMinimalMock2D(canvas: HTMLCanvasElement): CanvasRenderingContext2D {\n const noop = () => {};\n return {\n canvas,\n strokeStyle: \"\",\n fillStyle: \"\",\n lineWidth: 1,\n font: \"\",\n textAlign: \"left\",\n textBaseline: \"alphabetic\",\n beginPath: noop,\n moveTo: noop,\n lineTo: noop,\n stroke: noop,\n fill: noop,\n clearRect: noop,\n setTransform: noop,\n setLineDash: noop,\n save: noop,\n restore: noop,\n translate: noop,\n rotate: noop,\n fillText: noop,\n measureText: (text: string) => ({ width: text.length * 7 } as TextMetrics),\n } as unknown as CanvasRenderingContext2D;\n}\n\nfunction getCanvas2DContext(width: number, height: number): CanvasRenderingContext2D {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n return canvas.getContext(\"2d\") ?? createMinimalMock2D(canvas);\n}\n\nfunction makePlotArea(width: number, height: number): PlotArea {\n const margin = { top: 40, right: 40, bottom: 50, left: 60 };\n return {\n x: margin.left,\n y: margin.top,\n width: width - margin.left - margin.right,\n height: height - margin.top - margin.bottom,\n };\n}\n\nfunction tickPixelLines(\n _plotArea: PlotArea,\n xScale: LinearScale,\n yScale: LinearScale,\n xTickCount: number,\n yTickCount: number,\n): { xLines: number[]; yLines: number[] } {\n const xLines = xScale.ticks(xTickCount).map((t) => snapLineCoord(xScale.transform(t)));\n const yLines = yScale.ticks(yTickCount).map((t) => snapLineCoord(yScale.transform(t)));\n return { xLines, yLines };\n}\n\nfunction measureFrames(runFrame: () => void, frames: number): { avg: number; p95: number } {\n const samples: number[] = [];\n for (let i = 0; i < frames; i++) {\n const t0 = performance.now();\n runFrame();\n samples.push((performance.now() - t0) * 1000);\n }\n samples.sort((a, b) => a - b);\n const avg = samples.reduce((s, v) => s + v, 0) / samples.length;\n const p95 = samples[Math.floor(samples.length * 0.95)] ?? avg;\n return { avg, p95 };\n}\n\n/** Benchmark Canvas 2D grid via OverlayRenderer.drawGrid */\nexport function benchmarkCanvasGrid(options: {\n width?: number;\n height?: number;\n dpr?: number;\n xTickCount?: number;\n yTickCount?: number;\n frames?: number;\n showMinor?: boolean;\n} = {}): GridBenchmarkResult {\n const width = Math.round((options.width ?? 1920) * (options.dpr ?? 1));\n const height = Math.round((options.height ?? 1080) * (options.dpr ?? 1));\n const xTickCount = options.xTickCount ?? 24;\n const yTickCount = options.yTickCount ?? 16;\n const frames = options.frames ?? 120;\n\n const ctx = getCanvas2DContext(width, height);\n\n const theme = {\n ...DARK_THEME,\n grid: {\n ...DARK_THEME.grid,\n visible: true,\n showMinor: options.showMinor ?? true,\n },\n };\n\n const plotArea = makePlotArea(width, height);\n const xScale = new LinearScale();\n const yScale = new LinearScale();\n xScale.setDomain(0, 1_000_000);\n yScale.setDomain(-1, 1);\n xScale.setRange(plotArea.x, plotArea.x + plotArea.width);\n yScale.setRange(plotArea.y + plotArea.height, plotArea.y);\n\n const renderer = new OverlayRenderer(ctx, theme);\n\n const { avg, p95 } = measureFrames(() => {\n ctx.clearRect(0, 0, width, height);\n renderer.drawGrid(plotArea, xScale, yScale, { tickCount: xTickCount }, { tickCount: yTickCount });\n }, frames);\n\n const { xLines, yLines } = tickPixelLines(plotArea, xScale, yScale, xTickCount, yTickCount);\n\n return {\n backend: \"canvas2d\",\n dpr: options.dpr ?? 1,\n width,\n height,\n xTicks: xTickCount,\n yTicks: yTickCount,\n lineSegments: xLines.length + yLines.length,\n avgFrameUs: Math.round(avg),\n p95FrameUs: Math.round(p95),\n frames,\n };\n}\n\n/** Benchmark WebGL grid spike (returns null if WebGL unavailable) */\nexport function benchmarkWebGLGrid(options: {\n width?: number;\n height?: number;\n dpr?: number;\n xTickCount?: number;\n yTickCount?: number;\n frames?: number;\n} = {}): GridBenchmarkResult | null {\n const width = Math.round((options.width ?? 1920) * (options.dpr ?? 1));\n const height = Math.round((options.height ?? 1080) * (options.dpr ?? 1));\n const xTickCount = options.xTickCount ?? 24;\n const yTickCount = options.yTickCount ?? 16;\n const frames = options.frames ?? 120;\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n let spike: WebGLGridSpike;\n try {\n spike = new WebGLGridSpike(canvas);\n } catch {\n return null;\n }\n\n const plotArea = makePlotArea(width, height);\n const xScale = new LinearScale();\n const yScale = new LinearScale();\n xScale.setDomain(0, 1_000_000);\n yScale.setDomain(-1, 1);\n xScale.setRange(plotArea.x, plotArea.x + plotArea.width);\n yScale.setRange(plotArea.y + plotArea.height, plotArea.y);\n\n const { xLines, yLines } = tickPixelLines(plotArea, xScale, yScale, xTickCount, yTickCount);\n const spec: GridLineSpec = { plotArea, xLines, yLines, width, height };\n\n let lineSegments = 0;\n const { avg, p95 } = measureFrames(() => {\n lineSegments = spike.draw(spec);\n }, frames);\n\n spike.destroy();\n\n return {\n backend: \"webgl\",\n dpr: options.dpr ?? 1,\n width,\n height,\n xTicks: xTickCount,\n yTicks: yTickCount,\n lineSegments,\n avgFrameUs: Math.round(avg),\n p95FrameUs: Math.round(p95),\n frames,\n };\n}\n\n/** Compare backends; recommends implement if WebGL ≥20% faster */\nexport function compareGridBackends(options?: {\n dpr?: number;\n frames?: number;\n}): GridCompareResult {\n const dpr = options?.dpr ?? 2;\n const frames = options?.frames ?? 120;\n\n const canvas2d = benchmarkCanvasGrid({ dpr, frames, showMinor: true });\n const webgl = benchmarkWebGLGrid({ dpr, frames });\n\n if (!webgl) {\n return {\n canvas2d,\n webgl: null,\n gainPercent: 0,\n recommendation: \"defer\",\n };\n }\n\n const gainPercent = ((canvas2d.avgFrameUs - webgl.avgFrameUs) / canvas2d.avgFrameUs) * 100;\n\n return {\n canvas2d,\n webgl,\n gainPercent: Math.round(gainPercent * 10) / 10,\n recommendation: gainPercent >= 20 ? \"implement\" : \"defer\",\n };\n}\n\n/** Vertex builder smoke test (no GL required) */\nexport function countGridVertices(xTickCount: number, yTickCount: number): number {\n const spec: GridLineSpec = {\n plotArea: { x: 60, y: 40, width: 800, height: 400 },\n xLines: Array.from({ length: xTickCount }, (_, i) => 60 + i * 30),\n yLines: Array.from({ length: yTickCount }, (_, i) => 40 + i * 25),\n width: 960,\n height: 540,\n };\n return buildGridLineVertices(spec).length / 2;\n}\n","/**\n * Stage 1 browser benchmark harness — scenarios + baseline comparison.\n * @module testing/stage1BrowserBench\n */\n\nimport type { BenchmarkResult } from \"./index\";\nimport baseline from \"./baselines/v1.15.0.json\";\n\nexport interface Stage1ScenarioResult {\n id: string;\n benchmark: BenchmarkResult;\n passed: boolean;\n failures: string[];\n baselineMinFps?: number;\n}\n\nexport interface Stage1BrowserReport {\n timestamp: number;\n version: string;\n scenarios: Stage1ScenarioResult[];\n allPassed: boolean;\n regressionThreshold: number;\n}\n\nexport interface BaselineScenario {\n minAvgFps?: number;\n maxAvgFrameTimeMs?: number;\n maxAvgFrameUs?: number;\n dpr?: number;\n points?: number;\n description?: string;\n}\n\n/** When wall-clock frame count is below this, headless rAF is unreliable — use renderFps. */\nexport const HEADLESS_LOW_FRAME_THRESHOLD = 30;\n\n/** Headless smoke floors (renderFps or effective FPS). Desktop uses baseline minAvgFps. */\nexport const SMOKE_FLOORS: Record<string, number> = {\n \"line-1m-pan\": 5,\n \"candlestick-500k\": 25,\n \"stack-5pane-resize\": 20,\n \"line-200k-webgl\": 3,\n \"line-200k-webgpu\": 2,\n \"boxplot-5k-webgpu\": 2,\n};\n\n/** Pick wall or render FPS depending on headless throttling artifacts. */\nexport function effectiveBenchmarkFps(\n result: Pick<BenchmarkResult, \"avgFps\" | \"renderFps\" | \"frameCount\">,\n isHeadless: boolean,\n): number {\n const wall = result.avgFps ?? 0;\n const render = result.renderFps ?? 0;\n const frames = result.frameCount ?? 0;\n\n if (!isHeadless) return wall;\n\n if (render > 0 && (frames < HEADLESS_LOW_FRAME_THRESHOLD || wall < 10)) {\n return render;\n }\n return wall;\n}\n\nexport function getBaseline(): typeof baseline {\n return baseline;\n}\n\n/** Compare a benchmark result against v1.15 baseline for a scenario */\nexport function compareScenarioToBaseline(\n scenarioId: string,\n result: BenchmarkResult | { avgFrameUs: number; backend?: string },\n): { passed: boolean; failures: string[] } {\n const spec = (baseline.scenarios as Record<string, BaselineScenario>)[scenarioId];\n if (!spec) {\n return { passed: true, failures: [] };\n }\n\n const failures: string[] = [];\n const threshold = baseline.regressionThreshold ?? 0.1;\n\n if (\"avgFps\" in result && spec.minAvgFps !== undefined) {\n const minAllowed = spec.minAvgFps * (1 - threshold);\n if (result.avgFps < minAllowed) {\n failures.push(\n `FPS ${result.avgFps} < baseline min ${spec.minAvgFps} (allowed ${minAllowed.toFixed(1)} with ${threshold * 100}% slack)`,\n );\n }\n }\n\n if (\"avgFrameTime\" in result && spec.maxAvgFrameTimeMs !== undefined) {\n const maxAllowed = spec.maxAvgFrameTimeMs * (1 + threshold);\n if (result.avgFrameTime > maxAllowed) {\n failures.push(\n `Frame time ${result.avgFrameTime}ms > baseline max ${spec.maxAvgFrameTimeMs}ms`,\n );\n }\n }\n\n if (\"avgFrameUs\" in result && spec.maxAvgFrameUs !== undefined) {\n const maxAllowed = spec.maxAvgFrameUs * (1 + threshold);\n if (result.avgFrameUs > maxAllowed) {\n failures.push(\n `Grid frame ${result.avgFrameUs}µs > baseline max ${spec.maxAvgFrameUs}µs`,\n );\n }\n }\n\n return { passed: failures.length === 0, failures };\n}\n\n/** Build a full Stage 1 report from scenario results */\nexport function buildStage1Report(\n scenarios: Stage1ScenarioResult[],\n): Stage1BrowserReport {\n return {\n timestamp: Date.now(),\n version: baseline.version,\n scenarios,\n allPassed: scenarios.every((s) => s.passed),\n regressionThreshold: baseline.regressionThreshold,\n };\n}\n","/**\n * WebGL vs WebGPU chart renderer comparison helpers.\n * @module testing/rendererBenchmark\n */\n\nimport type { BenchmarkResult } from \"./index\";\n\nexport interface RendererCompareResult {\n webgl: BenchmarkResult;\n webgpu: BenchmarkResult | null;\n webgpuActive: boolean;\n /** webgpuFps / webglFps — ≥1 means WebGPU is faster or equal */\n fpsRatio: number;\n /** Meets ADR target: WebGPU ≥ 95% of WebGL FPS */\n meetsTarget: boolean;\n recommendation: \"webgpu-ready\" | \"webgl-faster\" | \"webgpu-unavailable\";\n}\n\nexport function evaluateRendererCompare(\n webgl: BenchmarkResult,\n webgpu: BenchmarkResult | null,\n webgpuActive: boolean,\n minRatio = 0.95,\n): RendererCompareResult {\n if (!webgpuActive || !webgpu) {\n return {\n webgl,\n webgpu,\n webgpuActive: false,\n fpsRatio: 0,\n meetsTarget: false,\n recommendation: \"webgpu-unavailable\",\n };\n }\n\n const ratio = webgl.avgFps > 0 ? webgpu.avgFps / webgl.avgFps : 0;\n const meetsTarget = ratio >= minRatio;\n\n return {\n webgl,\n webgpu,\n webgpuActive: true,\n fpsRatio: ratio,\n meetsTarget,\n recommendation: meetsTarget ? \"webgpu-ready\" : \"webgl-faster\",\n };\n}\n","/**\n * Velo Plot - Testing Utilities\n * \n * Provides utilities for testing chart applications:\n * - Mock data generators\n * - Chart test harness\n * - Snapshot helpers\n * - Performance benchmarks\n * \n * @module testing\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport interface MockChartOptions {\n /** Canvas width (default: 800) */\n width?: number;\n /** Canvas height (default: 600) */\n height?: number;\n /** Device pixel ratio (default: 1) */\n devicePixelRatio?: number;\n /** Theme (default: 'dark') */\n theme?: string;\n /** Enable WebGL mock (default: true) */\n mockWebGL?: boolean;\n}\n\nexport interface WaveformOptions {\n /** Number of points (default: 1000) */\n pointCount?: number;\n /** Amplitude (default: 1) */\n amplitude?: number;\n /** Frequency in Hz (default: 1) */\n frequency?: number;\n /** Phase offset in radians (default: 0) */\n phase?: number;\n /** Noise level (0-1, default: 0) */\n noise?: number;\n /** X start value (default: 0) */\n xStart?: number;\n /** X end value (default: 10) */\n xEnd?: number;\n /** DC offset (default: 0) */\n offset?: number;\n}\n\nexport interface RandomDataOptions {\n /** Number of points (default: 1000) */\n pointCount?: number;\n /** X range [min, max] (default: [0, 100]) */\n xRange?: [number, number];\n /** Y range [min, max] (default: [-1, 1]) */\n yRange?: [number, number];\n /** Sort by X value (default: true) */\n sorted?: boolean;\n /** Seed for reproducible random (optional) */\n seed?: number;\n}\n\nexport interface BenchmarkResult {\n /** Average frames per second */\n avgFps: number;\n /** Minimum FPS recorded */\n minFps: number;\n /** Maximum FPS recorded */\n maxFps: number;\n /** Average frame time in ms */\n avgFrameTime: number;\n /** Total frames rendered */\n frameCount: number;\n /** Test duration in ms */\n duration: number;\n /** Points per frame */\n pointsRendered: number;\n /** Points per second throughput */\n throughput: number;\n /** Render-only throughput (1000 / avgFrameTime); can exceed wall FPS */\n renderFps?: number;\n}\n\nexport interface BenchmarkOptions {\n /** Duration of benchmark in ms (default: 5000) */\n duration?: number;\n /** Warmup duration in ms (default: 1000) */\n warmup?: number;\n /** Target FPS for assertions (default: 55) */\n targetFps?: number;\n /** Enable console output (default: false) */\n verbose?: boolean;\n}\n\nexport interface SnapshotOptions {\n /** Output format: 'json' | 'png' | 'canvas' (default: 'json') */\n format?: 'json' | 'png' | 'canvas';\n /** Include data in snapshot (default: false for performance) */\n includeData?: boolean;\n /** Include styles in snapshot (default: true) */\n includeStyles?: boolean;\n}\n\nexport interface ChartSnapshot {\n /** Snapshot timestamp */\n timestamp: number;\n /** Chart configuration */\n config: Record<string, unknown>;\n /** Series metadata (without data by default) */\n series: {\n id: string;\n type: string;\n pointCount: number;\n style?: Record<string, unknown>;\n }[];\n /** View bounds */\n bounds: {\n xMin: number;\n xMax: number;\n yMin: number;\n yMax: number;\n };\n /** Canvas data URL (if format is 'png') */\n image?: string;\n}\n\n// ============================================\n// Seeded Random Number Generator\n// ============================================\n\nclass SeededRandom {\n private seed: number;\n\n constructor(seed: number) {\n this.seed = seed;\n }\n\n next(): number {\n // Mulberry32 PRNG\n let t = (this.seed += 0x6d2b79f5);\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n }\n\n nextRange(min: number, max: number): number {\n return min + this.next() * (max - min);\n }\n}\n\n// ============================================\n// Data Generators\n// ============================================\n\n/**\n * Generate a sine wave\n */\nexport function generateSineWave(options?: WaveformOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<WaveformOptions> = {\n pointCount: 1000,\n amplitude: 1,\n frequency: 1,\n phase: 0,\n noise: 0,\n xStart: 0,\n xEnd: 10,\n offset: 0,\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n const dx = (opts.xEnd - opts.xStart) / (opts.pointCount - 1);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = opts.xStart + i * dx;\n const baseValue =\n opts.amplitude * Math.sin(2 * Math.PI * opts.frequency * x[i] + opts.phase);\n const noiseValue = opts.noise > 0 ? (Math.random() - 0.5) * 2 * opts.noise : 0;\n y[i] = baseValue + noiseValue + opts.offset;\n }\n\n return { x, y };\n}\n\n/**\n * Generate a square wave\n */\nexport function generateSquareWave(options?: WaveformOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<WaveformOptions> = {\n pointCount: 1000,\n amplitude: 1,\n frequency: 1,\n phase: 0,\n noise: 0,\n xStart: 0,\n xEnd: 10,\n offset: 0,\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n const dx = (opts.xEnd - opts.xStart) / (opts.pointCount - 1);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = opts.xStart + i * dx;\n const t = x[i] * opts.frequency + opts.phase / (2 * Math.PI);\n const baseValue = Math.sign(Math.sin(2 * Math.PI * t)) * opts.amplitude;\n const noiseValue = opts.noise > 0 ? (Math.random() - 0.5) * 2 * opts.noise : 0;\n y[i] = baseValue + noiseValue + opts.offset;\n }\n\n return { x, y };\n}\n\n/**\n * Generate a sawtooth wave\n */\nexport function generateSawtoothWave(options?: WaveformOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<WaveformOptions> = {\n pointCount: 1000,\n amplitude: 1,\n frequency: 1,\n phase: 0,\n noise: 0,\n xStart: 0,\n xEnd: 10,\n offset: 0,\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n const dx = (opts.xEnd - opts.xStart) / (opts.pointCount - 1);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = opts.xStart + i * dx;\n const t = x[i] * opts.frequency + opts.phase / (2 * Math.PI);\n const baseValue = opts.amplitude * 2 * (t - Math.floor(t + 0.5));\n const noiseValue = opts.noise > 0 ? (Math.random() - 0.5) * 2 * opts.noise : 0;\n y[i] = baseValue + noiseValue + opts.offset;\n }\n\n return { x, y };\n}\n\n/**\n * Generate a triangle wave\n */\nexport function generateTriangleWave(options?: WaveformOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<WaveformOptions> = {\n pointCount: 1000,\n amplitude: 1,\n frequency: 1,\n phase: 0,\n noise: 0,\n xStart: 0,\n xEnd: 10,\n offset: 0,\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n const dx = (opts.xEnd - opts.xStart) / (opts.pointCount - 1);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = opts.xStart + i * dx;\n const t = x[i] * opts.frequency + opts.phase / (2 * Math.PI);\n const baseValue = opts.amplitude * 2 * Math.abs(2 * (t - Math.floor(t + 0.5))) - opts.amplitude;\n const noiseValue = opts.noise > 0 ? (Math.random() - 0.5) * 2 * opts.noise : 0;\n y[i] = baseValue + noiseValue + opts.offset;\n }\n\n return { x, y };\n}\n\n/**\n * Generate random data points\n */\nexport function generateRandomData(options?: RandomDataOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<RandomDataOptions> = {\n pointCount: 1000,\n xRange: [0, 100],\n yRange: [-1, 1],\n sorted: true,\n seed: Date.now(),\n ...options,\n };\n\n const rng = new SeededRandom(opts.seed);\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = rng.nextRange(opts.xRange[0], opts.xRange[1]);\n y[i] = rng.nextRange(opts.yRange[0], opts.yRange[1]);\n }\n\n // Sort by X if requested\n if (opts.sorted) {\n const indices = Array.from({ length: opts.pointCount }, (_, i) => i);\n indices.sort((a, b) => x[a] - x[b]);\n \n const sortedX = new Float32Array(opts.pointCount);\n const sortedY = new Float32Array(opts.pointCount);\n \n for (let i = 0; i < opts.pointCount; i++) {\n sortedX[i] = x[indices[i]];\n sortedY[i] = y[indices[i]];\n }\n \n return { x: sortedX, y: sortedY };\n }\n\n return { x, y };\n}\n\n/**\n * Generate a cyclic voltammogram (CV) mock data\n */\nexport function generateCVData(options?: {\n pointCount?: number;\n vMin?: number;\n vMax?: number;\n cycles?: number;\n peakCurrent?: number;\n noise?: number;\n}): { x: Float32Array; y: Float32Array } {\n const opts = {\n pointCount: 2000,\n vMin: -0.5,\n vMax: 0.5,\n cycles: 1,\n peakCurrent: 10e-6, // 10 µA\n noise: 0.02,\n ...options,\n };\n\n const totalPoints = opts.pointCount * opts.cycles;\n const x = new Float32Array(totalPoints);\n const y = new Float32Array(totalPoints);\n \n const pointsPerCycle = opts.pointCount;\n const halfCycle = pointsPerCycle / 2;\n\n for (let c = 0; c < opts.cycles; c++) {\n for (let i = 0; i < pointsPerCycle; i++) {\n const idx = c * pointsPerCycle + i;\n \n // Potential sweep\n if (i < halfCycle) {\n x[idx] = opts.vMin + (opts.vMax - opts.vMin) * (i / halfCycle);\n } else {\n x[idx] = opts.vMax - (opts.vMax - opts.vMin) * ((i - halfCycle) / halfCycle);\n }\n \n // Current response (simplified Randles-Sevcik)\n const E = x[idx];\n const E0 = 0; // Formal potential\n const scanDirection = i < halfCycle ? 1 : -1;\n \n // Gaussian-like peak\n const peakWidth = 0.1;\n const exponent = -Math.pow(E - E0, 2) / (2 * peakWidth * peakWidth);\n const peakCurrent = opts.peakCurrent * Math.exp(exponent);\n \n // Add capacitive current and noise\n const capacitive = scanDirection * opts.peakCurrent * 0.1;\n const noiseValue = (Math.random() - 0.5) * 2 * opts.noise * opts.peakCurrent;\n \n y[idx] = scanDirection * peakCurrent + capacitive + noiseValue;\n }\n }\n\n return { x, y };\n}\n\n/**\n * Generate electrochemical impedance spectroscopy (EIS) Nyquist data\n */\nexport function generateNyquistData(options?: {\n pointCount?: number;\n rSolution?: number;\n rCharge?: number;\n frequency?: [number, number];\n}): { x: Float32Array; y: Float32Array } {\n const opts = {\n pointCount: 50,\n rSolution: 100, // Ohms\n rCharge: 1000, // Ohms\n frequency: [1e5, 0.01] as [number, number],\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n \n // Logarithmic frequency spacing\n const logFMin = Math.log10(opts.frequency[1]);\n const logFMax = Math.log10(opts.frequency[0]);\n \n for (let i = 0; i < opts.pointCount; i++) {\n const logF = logFMax - (logFMax - logFMin) * (i / (opts.pointCount - 1));\n const omega = 2 * Math.PI * Math.pow(10, logF);\n \n // Simple Randles circuit: Rs + (Rct || CPE)\n const tau = opts.rCharge * 1e-5; // Time constant\n const realPart = opts.rSolution + opts.rCharge / (1 + Math.pow(omega * tau, 2));\n const imagPart = omega * tau * opts.rCharge / (1 + Math.pow(omega * tau, 2));\n \n x[i] = realPart;\n y[i] = -imagPart; // Negative for Nyquist convention\n }\n\n return { x, y };\n}\n\n// ============================================\n// Performance Benchmarking\n// ============================================\n\n/**\n * Benchmark chart rendering performance\n */\nexport async function benchmarkRender(\n chart: { render: () => void; getAllSeries: () => { getPointCount: () => number }[] },\n options?: BenchmarkOptions\n): Promise<BenchmarkResult> {\n const opts: Required<BenchmarkOptions> = {\n duration: 5000,\n warmup: 1000,\n targetFps: 55,\n verbose: false,\n ...options,\n };\n\n const fpsHistory: number[] = [];\n const frameTimes: number[] = [];\n let frameCount = 0;\n\n // Calculate total points\n const totalPoints = chart\n .getAllSeries()\n .reduce((sum, s) => sum + s.getPointCount(), 0);\n\n return new Promise((resolve) => {\n const endTime = performance.now() + opts.warmup + opts.duration;\n const warmupEndTime = performance.now() + opts.warmup;\n let recording = false;\n let recordingStartTime = 0;\n\n function frame() {\n const now = performance.now();\n\n if (now >= endTime) {\n const avgRenderMs =\n frameTimes.length > 0\n ? frameTimes.reduce((a, b) => a + b, 0) / frameTimes.length\n : 0;\n const recordElapsedMs =\n recordingStartTime > 0 ? now - recordingStartTime : opts.duration;\n // Wall-clock FPS (includes rAF pacing + work outside timed render)\n const wallFps =\n frameCount > 0 && recordElapsedMs > 0\n ? (frameCount / recordElapsedMs) * 1000\n : 0;\n // Instantaneous render throughput (can exceed monitor refresh; useful for micro-bench)\n const renderFps =\n fpsHistory.length > 0\n ? fpsHistory.reduce((a, b) => a + b, 0) / fpsHistory.length\n : avgRenderMs > 0\n ? 1000 / avgRenderMs\n : 0;\n\n const result: BenchmarkResult = {\n avgFps: Math.round(wallFps * 100) / 100,\n minFps: Math.round((fpsHistory.length > 0 ? Math.min(...fpsHistory) : wallFps) * 100) / 100,\n maxFps: Math.round((fpsHistory.length > 0 ? Math.max(...fpsHistory) : wallFps) * 100) / 100,\n avgFrameTime: Math.round(avgRenderMs * 1000) / 1000,\n frameCount,\n duration: opts.duration,\n pointsRendered: totalPoints,\n throughput: Math.round((totalPoints * wallFps) / 1000) * 1000,\n /** @internal render-only FPS (not wall clock) */\n ...(renderFps > 0 ? { renderFps: Math.round(renderFps * 100) / 100 } : {}),\n } as BenchmarkResult;\n\n resolve(result);\n return;\n }\n\n // Start recording after warmup\n if (now >= warmupEndTime && !recording) {\n recording = true;\n recordingStartTime = now;\n frameCount = 0;\n frameTimes.length = 0;\n fpsHistory.length = 0;\n }\n\n const renderStart = performance.now();\n chart.render();\n const renderEnd = performance.now();\n\n if (recording) {\n const frameTime = renderEnd - renderStart;\n frameTimes.push(frameTime);\n frameCount++;\n\n const recentTimes = frameTimes.slice(-30);\n if (recentTimes.length > 0) {\n const avgRecentTime = recentTimes.reduce((a, b) => a + b, 0) / recentTimes.length;\n if (avgRecentTime > 0) {\n fpsHistory.push(1000 / avgRecentTime);\n }\n }\n }\n\n requestAnimationFrame(frame);\n }\n\n requestAnimationFrame(frame);\n });\n}\n\n// ============================================\n// Snapshot Utilities\n// ============================================\n\n/**\n * Create a snapshot of chart state for testing\n */\nexport function createSnapshot(\n chart: {\n getViewBounds: () => { xMin: number; xMax: number; yMin: number; yMax: number };\n getAllSeries: () => { getId: () => string; getType: () => string; getPointCount: () => number; getStyle: () => Record<string, unknown> }[];\n exportImage?: () => string;\n },\n options?: SnapshotOptions\n): ChartSnapshot {\n const opts: Required<SnapshotOptions> = {\n format: 'json',\n includeData: false,\n includeStyles: true,\n ...options,\n };\n\n const series = chart.getAllSeries().map((s) => ({\n id: s.getId(),\n type: s.getType(),\n pointCount: s.getPointCount(),\n ...(opts.includeStyles ? { style: s.getStyle() } : {}),\n }));\n\n const snapshot: ChartSnapshot = {\n timestamp: Date.now(),\n config: {},\n series,\n bounds: chart.getViewBounds(),\n };\n\n if (opts.format === 'png' && chart.exportImage) {\n snapshot.image = chart.exportImage();\n }\n\n return snapshot;\n}\n\n/**\n * Compare two snapshots for equality\n */\nexport function compareSnapshots(\n a: ChartSnapshot,\n b: ChartSnapshot,\n tolerance: number = 1e-6\n): {\n equal: boolean;\n differences: string[];\n} {\n const differences: string[] = [];\n\n // Compare series count\n if (a.series.length !== b.series.length) {\n differences.push(`Series count: ${a.series.length} vs ${b.series.length}`);\n }\n\n // Compare series metadata\n for (let i = 0; i < Math.min(a.series.length, b.series.length); i++) {\n const sa = a.series[i];\n const sb = b.series[i];\n\n if (sa.id !== sb.id) {\n differences.push(`Series[${i}] id: \"${sa.id}\" vs \"${sb.id}\"`);\n }\n if (sa.type !== sb.type) {\n differences.push(`Series[${i}] type: \"${sa.type}\" vs \"${sb.type}\"`);\n }\n if (sa.pointCount !== sb.pointCount) {\n differences.push(`Series[${i}] pointCount: ${sa.pointCount} vs ${sb.pointCount}`);\n }\n }\n\n // Compare bounds with tolerance\n const boundsKeys: (keyof ChartSnapshot['bounds'])[] = ['xMin', 'xMax', 'yMin', 'yMax'];\n for (const key of boundsKeys) {\n if (Math.abs(a.bounds[key] - b.bounds[key]) > tolerance) {\n differences.push(`Bounds.${key}: ${a.bounds[key]} vs ${b.bounds[key]}`);\n }\n }\n\n return {\n equal: differences.length === 0,\n differences,\n };\n}\n\n// ============================================\n// Test Assertions\n// ============================================\n\n/**\n * Assert that a benchmark meets performance requirements\n */\nexport function assertPerformance(\n result: BenchmarkResult,\n requirements: {\n minFps?: number;\n maxFrameTime?: number;\n minThroughput?: number;\n }\n): { passed: boolean; failures: string[] } {\n const failures: string[] = [];\n\n if (requirements.minFps && result.avgFps < requirements.minFps) {\n failures.push(`FPS ${result.avgFps} < required ${requirements.minFps}`);\n }\n\n if (requirements.maxFrameTime && result.avgFrameTime > requirements.maxFrameTime) {\n failures.push(`Frame time ${result.avgFrameTime}ms > required ${requirements.maxFrameTime}ms`);\n }\n\n if (requirements.minThroughput && result.throughput < requirements.minThroughput) {\n failures.push(`Throughput ${result.throughput} < required ${requirements.minThroughput}`);\n }\n\n return {\n passed: failures.length === 0,\n failures,\n };\n}\n\n/**\n * Wait for a number of animation frames\n */\nexport function waitForFrames(count: number = 1): Promise<void> {\n return new Promise((resolve) => {\n let remaining = count;\n function tick() {\n remaining--;\n if (remaining <= 0) {\n resolve();\n } else {\n requestAnimationFrame(tick);\n }\n }\n requestAnimationFrame(tick);\n });\n}\n\n/**\n * Wait for a specified duration\n */\nexport function waitFor(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// Stage 1 grid spike + browser benchmarks\nexport {\n benchmarkCanvasGrid,\n benchmarkWebGLGrid,\n compareGridBackends,\n countGridVertices,\n type GridBenchmarkResult,\n type GridCompareResult,\n} from \"./gridSpikeBenchmark\";\n\nexport {\n getBaseline,\n compareScenarioToBaseline,\n buildStage1Report,\n effectiveBenchmarkFps,\n HEADLESS_LOW_FRAME_THRESHOLD,\n SMOKE_FLOORS,\n type Stage1ScenarioResult,\n type Stage1BrowserReport,\n} from \"./stage1BrowserBench\";\n\nexport {\n evaluateRendererCompare,\n type RendererCompareResult,\n} from \"./rendererBenchmark\";\n","import type {\n PluginContext,\n PluginManifest,\n InteractionEvent,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\nimport type {\n CrosshairValueMode,\n CornerPosition\n} from \"../../../core/layout\";\n\nexport interface CrosshairPluginConfig {\n /** Show vertical line (default: true) */\n showVertical?: boolean;\n /** Show horizontal line (default: true) */\n showHorizontal?: boolean;\n /** Line color (default: from theme) */\n color?: string;\n /** Line style (default: 'dashed') */\n lineStyle?: \"solid\" | \"dashed\" | \"dotted\";\n /** Line width (default: 1) */\n lineWidth?: number;\n /** \n * @deprecated Use valueDisplayMode instead. **Removed in v4.0.**\n * Show axis labels (will be converted to valueDisplayMode)\n */\n showAxisLabels?: boolean;\n /**\n * Display mode for X,Y coordinate values (default: 'disabled')\n * - 'disabled': Never show coordinate values\n * - 'corner': Show values in a fixed corner position\n * - 'floating': Show values next to the cursor (axis labels)\n */\n valueDisplayMode?: CrosshairValueMode;\n /**\n * Corner position when valueDisplayMode is 'corner' (default: 'top-left')\n */\n cornerPosition?: CornerPosition;\n /** Snap to nearest data point (default: false) */\n snapToData?: boolean;\n /** Value format options */\n valueFormat?: {\n /** X value precision (default: 4) */\n xPrecision?: number;\n /** Y value precision (default: 4) */\n yPrecision?: number;\n };\n}\n\nconst crosshairManifest: PluginManifest = {\n name: \"crosshair\",\n version: \"1.0.0\",\n description: \"Interactive crosshair that follows mouse cursor\",\n provides: [\"interaction\", \"visualization\"],\n tags: [\"cursor\", \"crosshair\", \"tooltip\"],\n};\n\nexport const CrosshairPlugin = definePlugin<CrosshairPluginConfig>(\n crosshairManifest,\n (config = {}) => {\n const {\n showVertical = true,\n showHorizontal = true,\n color,\n lineStyle = \"dashed\",\n lineWidth = 1,\n snapToData = false,\n valueFormat = { xPrecision: 4, yPrecision: 4 },\n } = config;\n\n // Handle deprecated showAxisLabels -> convert to valueDisplayMode\n let valueDisplayMode: CrosshairValueMode = config.valueDisplayMode ?? 'disabled';\n if (config.showAxisLabels !== undefined && config.valueDisplayMode === undefined) {\n valueDisplayMode = config.showAxisLabels ? 'floating' : 'disabled';\n }\n const cornerPosition: CornerPosition = config.cornerPosition ?? 'top-left';\n\n let cursorX = -1;\n let cursorY = -1;\n let overlayId: string;\n let canvas: HTMLCanvasElement | null = null;\n let ctx: CanvasRenderingContext2D | null = null;\n\n return {\n onInit(pluginCtx: PluginContext) {\n overlayId = \"crosshair-overlay\";\n const overlay = pluginCtx.ui.createOverlay(overlayId, {\n zIndex: 500,\n position: { top: \"0\", left: \"0\", right: \"0\", bottom: \"0\" },\n });\n\n canvas = document.createElement(\"canvas\");\n canvas.style.cssText = \"width: 100%; height: 100%;\";\n overlay.appendChild(canvas);\n\n ctx = canvas.getContext(\"2d\");\n resizeCanvas(pluginCtx);\n },\n\n onDestroy(pluginCtx: PluginContext) {\n pluginCtx.ui.removeOverlay(overlayId);\n canvas = null;\n ctx = null;\n },\n\n onResize(pluginCtx: PluginContext) {\n resizeCanvas(pluginCtx);\n },\n\n onInteraction(pluginCtx: PluginContext, event: InteractionEvent) {\n if (event.type === \"mousemove\") {\n cursorX = event.pixelX;\n cursorY = event.pixelY;\n\n if (snapToData && event.inPlotArea) {\n const nearest = pluginCtx.coords.pickPoint(cursorX, cursorY);\n if (nearest) {\n cursorX = nearest.pixelX;\n cursorY = nearest.pixelY;\n }\n }\n\n render(pluginCtx);\n }\n },\n\n onViewChange() {\n // Re-render on zoom/pan\n if (cursorX >= 0 && cursorY >= 0) {\n // Will be re-rendered on next frame\n }\n },\n };\n\n function resizeCanvas(pluginCtx: PluginContext) {\n if (!canvas || !ctx) return;\n const size = pluginCtx.render.canvasSize;\n const dpr = pluginCtx.render.pixelRatio;\n canvas.width = size.width * dpr;\n canvas.height = size.height * dpr;\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.scale(dpr, dpr);\n }\n\n function render(pluginCtx: PluginContext) {\n if (!ctx || !canvas) return;\n\n const { width, height } = pluginCtx.render.canvasSize;\n ctx.clearRect(0, 0, width, height);\n\n if (cursorX < 0 || cursorY < 0) return;\n\n const plotArea = pluginCtx.render.plotArea;\n if (\n cursorX < plotArea.x ||\n cursorX > plotArea.x + plotArea.width ||\n cursorY < plotArea.y ||\n cursorY > plotArea.y + plotArea.height\n ) {\n return;\n }\n\n const lineColor = color || (pluginCtx.ui.theme.cursor as unknown as Record<string, unknown>)?.color as string || \"#888888\";\n\n ctx.save();\n ctx.strokeStyle = lineColor;\n ctx.lineWidth = lineWidth;\n\n if (lineStyle === \"dashed\") {\n ctx.setLineDash([6, 4]);\n } else if (lineStyle === \"dotted\") {\n ctx.setLineDash([2, 2]);\n }\n\n // Vertical line\n if (showVertical) {\n ctx.beginPath();\n ctx.moveTo(cursorX, plotArea.y);\n ctx.lineTo(cursorX, plotArea.y + plotArea.height);\n ctx.stroke();\n }\n\n // Horizontal line\n if (showHorizontal) {\n ctx.beginPath();\n ctx.moveTo(plotArea.x, cursorY);\n ctx.lineTo(plotArea.x + plotArea.width, cursorY);\n ctx.stroke();\n }\n\n ctx.restore();\n\n // Value display based on mode\n if (valueDisplayMode === 'floating') {\n drawFloatingLabels(pluginCtx, ctx, cursorX, cursorY, lineColor);\n } else if (valueDisplayMode === 'corner') {\n drawCornerLabels(pluginCtx, ctx, cursorX, cursorY, lineColor);\n }\n // 'disabled' mode: don't draw any labels\n }\n\n function drawFloatingLabels(\n pluginCtx: PluginContext,\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n bgColor: string\n ) {\n const dataX = pluginCtx.coords.pixelToDataX(x);\n const dataY = pluginCtx.coords.pixelToDataY(y);\n const plotArea = pluginCtx.render.plotArea;\n\n ctx.save();\n ctx.font = \"11px system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n\n // X axis label\n const xText = dataX.toPrecision(valueFormat.xPrecision);\n const xMetrics = ctx.measureText(xText);\n const xLabelWidth = xMetrics.width + 8;\n const xLabelHeight = 18;\n const xLabelX = x - xLabelWidth / 2;\n const xLabelY = plotArea.y + plotArea.height + 2;\n\n ctx.fillStyle = bgColor;\n ctx.fillRect(xLabelX, xLabelY, xLabelWidth, xLabelHeight);\n ctx.fillStyle = \"#ffffff\";\n ctx.fillText(xText, x, xLabelY + 3);\n\n // Y axis label\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n const yText = dataY.toPrecision(valueFormat.yPrecision);\n const yMetrics = ctx.measureText(yText);\n const yLabelWidth = yMetrics.width + 8;\n const yLabelHeight = 18;\n const yLabelX = plotArea.x - yLabelWidth - 2;\n const yLabelY = y - yLabelHeight / 2;\n\n ctx.fillStyle = bgColor;\n ctx.fillRect(yLabelX, yLabelY, yLabelWidth, yLabelHeight);\n ctx.fillStyle = \"#ffffff\";\n ctx.fillText(yText, plotArea.x - 6, y);\n\n ctx.restore();\n }\n\n function drawCornerLabels(\n pluginCtx: PluginContext,\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n bgColor: string\n ) {\n const dataX = pluginCtx.coords.pixelToDataX(x);\n const dataY = pluginCtx.coords.pixelToDataY(y);\n const plotArea = pluginCtx.render.plotArea;\n\n ctx.save();\n ctx.font = \"11px system-ui, sans-serif\";\n\n const xText = `X: ${dataX.toPrecision(valueFormat.xPrecision)}`;\n const yText = `Y: ${dataY.toPrecision(valueFormat.yPrecision)}`;\n\n const xMetrics = ctx.measureText(xText);\n const yMetrics = ctx.measureText(yText);\n const maxWidth = Math.max(xMetrics.width, yMetrics.width);\n const padding = 6;\n const lineHeight = 16;\n const boxWidth = maxWidth + padding * 2;\n const boxHeight = lineHeight * 2 + padding * 2;\n\n // Determine corner position\n let boxX: number;\n let boxY: number;\n\n switch (cornerPosition) {\n case 'top-left':\n boxX = plotArea.x + 8;\n boxY = plotArea.y + 8;\n break;\n case 'top-right':\n boxX = plotArea.x + plotArea.width - boxWidth - 8;\n boxY = plotArea.y + 8;\n break;\n case 'bottom-left':\n boxX = plotArea.x + 8;\n boxY = plotArea.y + plotArea.height - boxHeight - 8;\n break;\n case 'bottom-right':\n boxX = plotArea.x + plotArea.width - boxWidth - 8;\n boxY = plotArea.y + plotArea.height - boxHeight - 8;\n break;\n default:\n boxX = plotArea.x + 8;\n boxY = plotArea.y + 8;\n }\n\n // Draw background\n ctx.fillStyle = bgColor;\n ctx.globalAlpha = 0.85;\n ctx.fillRect(boxX, boxY, boxWidth, boxHeight);\n ctx.globalAlpha = 1.0;\n\n // Draw border\n ctx.strokeStyle = \"rgba(255,255,255,0.3)\";\n ctx.lineWidth = 1;\n ctx.strokeRect(boxX, boxY, boxWidth, boxHeight);\n\n // Draw text\n ctx.fillStyle = \"#ffffff\";\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillText(xText, boxX + padding, boxY + padding);\n ctx.fillText(yText, boxX + padding, boxY + padding + lineHeight);\n\n ctx.restore();\n }\n }\n);\n\n","import type {\n PluginContext,\n PluginManifest,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\n\nexport interface StatsPluginConfig {\n /** Position of the stats overlay */\n position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n /** Which stats to show */\n show?: Array<\"count\" | \"mean\" | \"min\" | \"max\" | \"std\" | \"range\">;\n /** Series ID to compute stats for (default: all) */\n seriesId?: string;\n /** Update on every data change (default: true) */\n autoUpdate?: boolean;\n}\n\nconst statsManifest: PluginManifest = {\n name: \"statistics-overlay\",\n version: \"1.0.0\",\n description: \"Displays real-time statistics for chart data\",\n provides: [\"visualization\", \"analysis\"],\n tags: [\"statistics\", \"overlay\", \"analytics\"],\n};\n\nexport const StatsPlugin = definePlugin<StatsPluginConfig>(\n statsManifest,\n (config = {}) => {\n const {\n position = \"top-right\",\n show = [\"count\", \"mean\", \"min\", \"max\"],\n seriesId,\n autoUpdate = true,\n } = config;\n\n let overlayId: string;\n let container: HTMLDivElement | null = null;\n\n return {\n onInit(ctx: PluginContext) {\n overlayId = \"stats-overlay\";\n const posStyle: Record<string, string> = {};\n\n if (position.includes(\"top\")) posStyle.top = \"10px\";\n if (position.includes(\"bottom\")) posStyle.bottom = \"10px\";\n if (position.includes(\"left\")) posStyle.left = \"10px\";\n if (position.includes(\"right\")) posStyle.right = \"10px\";\n\n container = ctx.ui.createOverlay(overlayId, {\n zIndex: 800,\n position: posStyle,\n pointerEvents: false,\n });\n\n container.innerHTML = `\n <div style=\"\n background: rgba(0, 0, 0, 0.85);\n color: #fff;\n padding: 10px 14px;\n border-radius: 6px;\n font-family: ui-monospace, monospace;\n font-size: 12px;\n line-height: 1.6;\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n \">\n <div style=\"font-weight: bold; margin-bottom: 4px; color: #4ade80;\">📊 Statistics</div>\n <div class=\"stats-content\"></div>\n </div>\n `;\n\n updateStats(ctx);\n },\n\n onDestroy(ctx: PluginContext) {\n ctx.ui.removeOverlay(overlayId);\n container = null;\n },\n\n onDataUpdate(ctx: PluginContext) {\n if (autoUpdate) {\n updateStats(ctx);\n }\n },\n\n onSeriesAdd(ctx: PluginContext) {\n updateStats(ctx);\n },\n\n onSeriesRemove(ctx: PluginContext) {\n updateStats(ctx);\n },\n\n api: {\n refresh(ctx: PluginContext) {\n updateStats(ctx);\n },\n },\n };\n\n function updateStats(ctx: PluginContext) {\n if (!container) return;\n\n const content = container.querySelector(\".stats-content\");\n if (!content) return;\n\n const allSeries = ctx.data.getAllSeries();\n const targetSeries = seriesId\n ? allSeries.filter((s) => s.getId() === seriesId)\n : allSeries;\n\n if (targetSeries.length === 0) {\n content.innerHTML = \"<div style='color: #888'>No data</div>\";\n return;\n }\n\n // Aggregate all Y data\n let allY: number[] = [];\n targetSeries.forEach((series) => {\n const data = series.getData();\n if (data?.y) {\n allY = allY.concat(Array.from(data.y));\n }\n });\n\n if (allY.length === 0) {\n content.innerHTML = \"<div style='color: #888'>No data</div>\";\n return;\n }\n\n const stats = computeStats(allY);\n const lines: string[] = [];\n\n if (show.includes(\"count\")) {\n lines.push(`<div>N: <span style=\"color: #60a5fa\">${stats.count.toLocaleString()}</span></div>`);\n }\n if (show.includes(\"mean\")) {\n lines.push(`<div>μ: <span style=\"color: #60a5fa\">${stats.mean.toPrecision(4)}</span></div>`);\n }\n if (show.includes(\"min\")) {\n lines.push(`<div>Min: <span style=\"color: #60a5fa\">${stats.min.toPrecision(4)}</span></div>`);\n }\n if (show.includes(\"max\")) {\n lines.push(`<div>Max: <span style=\"color: #60a5fa\">${stats.max.toPrecision(4)}</span></div>`);\n }\n if (show.includes(\"std\")) {\n lines.push(`<div>σ: <span style=\"color: #60a5fa\">${stats.std.toPrecision(4)}</span></div>`);\n }\n if (show.includes(\"range\")) {\n lines.push(`<div>Range: <span style=\"color: #60a5fa\">${stats.range.toPrecision(4)}</span></div>`);\n }\n\n content.innerHTML = lines.join(\"\");\n }\n\n function computeStats(values: number[]) {\n const n = values.length;\n let sum = 0;\n let min = Infinity;\n let max = -Infinity;\n\n for (const v of values) {\n sum += v;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n\n const mean = sum / n;\n\n let sumSq = 0;\n for (const v of values) {\n sumSq += (v - mean) ** 2;\n }\n const std = Math.sqrt(sumSq / n);\n\n return {\n count: n,\n mean,\n min,\n max,\n std,\n range: max - min,\n };\n }\n }\n);\n","import type {\n PluginContext,\n PluginManifest,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\n\nexport interface WatermarkPluginConfig {\n /** Watermark text */\n text: string;\n /** Font size (default: 48) */\n fontSize?: number;\n /** Font family (default: system-ui) */\n fontFamily?: string;\n /** Text color with opacity (default: rgba(128,128,128,0.15)) */\n color?: string;\n /** Position (default: center) */\n position?: \"center\" | \"bottom-right\" | \"bottom-left\";\n /** Rotation in degrees (default: -30 for center, 0 for corners) */\n rotation?: number;\n}\n\nconst watermarkManifest: PluginManifest = {\n name: \"watermark\",\n version: \"1.0.0\",\n description: \"Adds a customizable watermark to the chart\",\n provides: [\"visualization\"],\n tags: [\"watermark\", \"branding\", \"overlay\"],\n};\n\nexport const WatermarkPlugin = definePlugin<WatermarkPluginConfig>(\n watermarkManifest,\n (config) => {\n if (!config?.text) {\n throw new Error(\"WatermarkPlugin requires 'text' configuration\");\n }\n\n const {\n text,\n fontSize = 48,\n fontFamily = \"system-ui, sans-serif\",\n color = \"rgba(128, 128, 128, 0.15)\",\n position = \"center\",\n rotation = position === \"center\" ? -30 : 0,\n } = config;\n\n return {\n onRenderOverlay(ctx: PluginContext) {\n const ctx2d = ctx.render.ctx2d;\n if (!ctx2d) return;\n\n // width/height available for future use\n void ctx.render.canvasSize;\n const plotArea = ctx.render.plotArea;\n\n ctx2d.save();\n ctx2d.font = `${fontSize}px ${fontFamily}`;\n ctx2d.fillStyle = color;\n ctx2d.textAlign = \"center\";\n ctx2d.textBaseline = \"middle\";\n\n let x: number, y: number;\n\n if (position === \"center\") {\n x = plotArea.x + plotArea.width / 2;\n y = plotArea.y + plotArea.height / 2;\n } else if (position === \"bottom-right\") {\n x = plotArea.x + plotArea.width - fontSize;\n y = plotArea.y + plotArea.height - fontSize / 2;\n } else {\n x = plotArea.x + fontSize;\n y = plotArea.y + plotArea.height - fontSize / 2;\n }\n\n ctx2d.translate(x, y);\n ctx2d.rotate((rotation * Math.PI) / 180);\n ctx2d.fillText(text, 0, 0);\n ctx2d.restore();\n },\n };\n }\n);\n","import type {\n PluginContext,\n PluginManifest,\n AfterRenderEvent,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\n\nexport interface GridHighlightConfig {\n /** Highlight intervals on X axis */\n xIntervals?: Array<{ start: number; end: number; color: string }>;\n /** Highlight intervals on Y axis */\n yIntervals?: Array<{ start: number; end: number; color: string }>;\n /** Opacity for highlight regions (default: 0.1) */\n opacity?: number;\n}\n\nconst gridHighlightManifest: PluginManifest = {\n name: \"grid-highlight\",\n version: \"1.0.0\",\n description: \"Highlights specific regions of the chart grid\",\n provides: [\"visualization\"],\n tags: [\"grid\", \"highlight\", \"regions\"],\n};\n\nexport const GridHighlightPlugin = definePlugin<GridHighlightConfig>(\n gridHighlightManifest,\n (config = {}) => {\n const { xIntervals = [], yIntervals = [], opacity = 0.1 } = config;\n\n return {\n onRenderOverlay(ctx: PluginContext, _event: AfterRenderEvent) {\n const ctx2d = ctx.render.ctx2d;\n if (!ctx2d) return;\n\n const plotArea = ctx.render.plotArea;\n // bounds available if needed for future features\n void ctx.data.getViewBounds();\n\n ctx2d.save();\n\n // Clip to plot area\n ctx2d.beginPath();\n ctx2d.rect(plotArea.x, plotArea.y, plotArea.width, plotArea.height);\n ctx2d.clip();\n\n ctx2d.globalAlpha = opacity;\n\n // Draw X intervals (vertical bands)\n for (const interval of xIntervals) {\n const x1 = ctx.coords.dataToPixelX(interval.start);\n const x2 = ctx.coords.dataToPixelX(interval.end);\n\n ctx2d.fillStyle = interval.color;\n ctx2d.fillRect(\n Math.min(x1, x2),\n plotArea.y,\n Math.abs(x2 - x1),\n plotArea.height\n );\n }\n\n // Draw Y intervals (horizontal bands)\n for (const interval of yIntervals) {\n const y1 = ctx.coords.dataToPixelY(interval.start);\n const y2 = ctx.coords.dataToPixelY(interval.end);\n\n ctx2d.fillStyle = interval.color;\n ctx2d.fillRect(\n plotArea.x,\n Math.min(y1, y2),\n plotArea.width,\n Math.abs(y2 - y1)\n );\n }\n\n ctx2d.restore();\n },\n };\n }\n);\n","import type {\n PluginContext,\n PluginManifest,\n DataUpdateEvent,\n ViewChangeEvent,\n InteractionEvent,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\n\nexport interface DataLoggerConfig {\n /** Log data updates (default: true) */\n logDataUpdates?: boolean;\n /** Log view changes (default: true) */\n logViewChanges?: boolean;\n /** Log interactions (default: false) */\n logInteractions?: boolean;\n /** Maximum log entries to keep (default: 100) */\n maxEntries?: number;\n}\n\nconst dataLoggerManifest: PluginManifest = {\n name: \"data-logger\",\n version: \"1.0.0\",\n description: \"Logs chart events for debugging and analysis\",\n provides: [\"analysis\"],\n tags: [\"debug\", \"logging\", \"events\"],\n};\n\nexport const DataLoggerPlugin = definePlugin<DataLoggerConfig>(\n dataLoggerManifest,\n (config = {}) => {\n const {\n logDataUpdates = true,\n logViewChanges = true,\n logInteractions = false,\n maxEntries = 100,\n } = config;\n\n interface LogEntry {\n timestamp: number;\n type: string;\n data: unknown;\n }\n\n const entries: LogEntry[] = [];\n\n function addEntry(type: string, data: unknown) {\n entries.push({\n timestamp: Date.now(),\n type,\n data,\n });\n\n if (entries.length > maxEntries) {\n entries.shift();\n }\n }\n\n return {\n onInit(ctx: PluginContext) {\n ctx.log.info(\"Data logger initialized\");\n },\n\n onDataUpdate(ctx: PluginContext, event: DataUpdateEvent) {\n if (logDataUpdates) {\n addEntry(\"dataUpdate\", {\n seriesId: event.seriesId,\n mode: event.mode,\n pointCount: event.pointCount,\n });\n ctx.log.debug(`Data update: ${event.seriesId} (${event.mode}, ${event.pointCount} points)`);\n }\n },\n\n onViewChange(ctx: PluginContext, event: ViewChangeEvent) {\n if (logViewChanges) {\n addEntry(\"viewChange\", {\n trigger: event.trigger,\n bounds: event.current,\n });\n ctx.log.debug(`View change: ${event.trigger}`);\n }\n },\n\n onInteraction(_ctx: PluginContext, event: InteractionEvent) {\n if (logInteractions) {\n addEntry(\"interaction\", {\n type: event.type,\n pixelX: event.pixelX,\n pixelY: event.pixelY,\n inPlotArea: event.inPlotArea,\n });\n }\n },\n\n onSerialize(_ctx: PluginContext) {\n return { entries };\n },\n\n onDeserialize(_ctx: PluginContext, data: unknown) {\n const saved = data as { entries?: LogEntry[] };\n if (saved?.entries) {\n entries.length = 0;\n entries.push(...saved.entries);\n }\n },\n\n api: {\n getEntries() {\n return [...entries];\n },\n clear() {\n entries.length = 0;\n },\n export() {\n return JSON.stringify(entries, null, 2);\n },\n },\n };\n }\n);\n","import type {\n PluginContext,\n PluginManifest,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\n\nexport interface DirectionIndicatorConfig {\n /** Series ID to track (if not specified, tracks the first series) */\n seriesId?: string;\n /** Number of recent points to analyze for direction (default: 20) */\n sampleSize?: number;\n /** Arrow color (default: from theme) */\n color?: string;\n /** Arrow size in pixels (default: 40) */\n size?: number;\n /** Minimum velocity to show arrow (default: 0.01) */\n minVelocity?: number;\n /** Number of points for smoothing the position/angle (default: 20) */\n historySize?: number;\n /** Hide arrow if no new points are received for this duration in ms (default: undefined/disabled) */\n idleTimeout?: number;\n}\n\ninterface DirectionData {\n angle: number; // Continuous angle in radians\n magnitude: number; // Normalized magnitude 0-1\n lastX: number; // Last data point X coordinate (data space)\n lastY: number; // Last data point Y coordinate (data space)\n smoothX: number; // Smoothed X position (pixel space)\n smoothY: number; // Smoothed Y position (pixel space)\n}\n\nconst directionIndicatorManifest: PluginManifest = {\n name: \"direction-indicator\",\n version: \"1.0.0\",\n description: \"Shows an arrow indicating the direction and trend of streaming data\",\n provides: [\"visualization\", \"analysis\"],\n tags: [\"streaming\", \"direction\", \"trend\", \"arrow\"],\n};\n\nexport const DirectionIndicatorPlugin = definePlugin<DirectionIndicatorConfig>(\n directionIndicatorManifest,\n (config = {}) => {\n const {\n seriesId,\n sampleSize = 20,\n color,\n size = 40,\n minVelocity = 0.01,\n historySize = 20,\n idleTimeout,\n } = config;\n\n let overlayId: string;\n let canvas: HTMLCanvasElement | null = null;\n let ctx: CanvasRenderingContext2D | null = null;\n let currentDirection: DirectionData | null = null;\n let targetSeriesId: string | null = null;\n \n // Smoothing buffers (moving average to reduce jitter)\n const positionHistoryX: number[] = [];\n const positionHistoryY: number[] = [];\n const angleHistory: number[] = [];\n\n let maxHistorySize = historySize;\n let timeoutTimer: any = null;\n let lastPointTimestamp = Date.now();\n let lastSeenX = -Infinity;\n let lastSeenY = -Infinity;\n let currentIdleTimeout = idleTimeout;\n\n return {\n onInit(pluginCtx: PluginContext) {\n overlayId = \"direction-indicator-overlay\";\n const overlay = pluginCtx.ui.createOverlay(overlayId, {\n zIndex: 600,\n position: { top: \"0\", left: \"0\", right: \"0\", bottom: \"0\" },\n pointerEvents: false,\n });\n\n canvas = document.createElement(\"canvas\");\n canvas.style.cssText = \"width: 100%; height: 100%; pointer-events: none;\";\n overlay.appendChild(canvas);\n\n ctx = canvas.getContext(\"2d\");\n resizeCanvas(pluginCtx);\n\n // Determine which series to track\n if (seriesId) {\n targetSeriesId = seriesId;\n } else {\n const allSeries = pluginCtx.data.getAllSeries();\n if (allSeries.length > 0) {\n targetSeriesId = allSeries[0].getId();\n }\n }\n },\n\n onDestroy(pluginCtx: PluginContext) {\n pluginCtx.ui.removeOverlay(overlayId);\n if (timeoutTimer) clearTimeout(timeoutTimer);\n canvas = null;\n ctx = null;\n currentDirection = null;\n },\n\n onResize(pluginCtx: PluginContext) {\n resizeCanvas(pluginCtx);\n },\n\n onAfterRender(pluginCtx: PluginContext) {\n // Update direction every frame for smooth rendering\n updateDirection(pluginCtx);\n render(pluginCtx);\n\n // Ensure we render again when the idle timeout expires to hide the arrow\n if (currentIdleTimeout) {\n if (timeoutTimer) clearTimeout(timeoutTimer);\n const age = Date.now() - lastPointTimestamp;\n if (age < currentIdleTimeout) {\n timeoutTimer = setTimeout(() => {\n pluginCtx.requestRender();\n }, currentIdleTimeout - age + 10);\n }\n }\n },\n\n onConfigChange(_pluginCtx: PluginContext, newConfig: DirectionIndicatorConfig) {\n if (newConfig.historySize !== undefined) {\n maxHistorySize = newConfig.historySize;\n // Reset history buffers if size changes significantly or just trim/expand? \n // Simpler to just let them adjust over time or trim if needed.\n // If we want immediate effect, we might want to trim if smaller.\n while (positionHistoryX.length > maxHistorySize) positionHistoryX.shift();\n while (positionHistoryY.length > maxHistorySize) positionHistoryY.shift();\n while (angleHistory.length > maxHistorySize) angleHistory.shift();\n }\n\n if (newConfig.idleTimeout !== undefined) {\n currentIdleTimeout = newConfig.idleTimeout;\n }\n }\n };\n\n function resizeCanvas(pluginCtx: PluginContext) {\n if (!canvas || !ctx) return;\n const canvasSize = pluginCtx.render.canvasSize;\n const dpr = pluginCtx.render.pixelRatio;\n canvas.width = canvasSize.width * dpr;\n canvas.height = canvasSize.height * dpr;\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.scale(dpr, dpr);\n }\n\n function updateDirection(pluginCtx: PluginContext) {\n if (!targetSeriesId) return;\n\n const series = pluginCtx.data.getSeries(targetSeriesId);\n if (!series) return;\n\n const data = pluginCtx.data.getSeriesData(targetSeriesId);\n if (!data || !data.x || !data.y) return;\n\n const totalPoints = data.x.length;\n if (totalPoints < 2) return;\n\n // Get last point coordinates in data space\n const lastX = data.x[totalPoints - 1];\n const lastY = data.y[totalPoints - 1];\n\n // Detect if this is a new point\n if (lastX !== lastSeenX || lastY !== lastSeenY) {\n lastSeenX = lastX;\n lastSeenY = lastY;\n lastPointTimestamp = Date.now();\n }\n\n // Get last N points for direction calculation\n const n = Math.min(sampleSize, totalPoints);\n const startIdx = totalPoints - n;\n\n // Calculate direction using linear regression on recent points IN PIXEL SPACE\n let sumT = 0, sumPX = 0, sumPY = 0, sumTPX = 0, sumTPY = 0, sumTT = 0;\n\n for (let i = startIdx; i < totalPoints; i++) {\n const t = i - startIdx; // Time index\n const dataX = data.x[i];\n const dataY = data.y[i];\n \n // Convert to pixel coordinates\n const pixelX = pluginCtx.coords.dataToPixelX(dataX);\n const pixelY = pluginCtx.coords.dataToPixelY(dataY);\n\n sumT += t;\n sumPX += pixelX;\n sumPY += pixelY;\n sumTPX += t * pixelX;\n sumTPY += t * pixelY;\n sumTT += t * t;\n }\n\n const meanT = sumT / n;\n const meanPX = sumPX / n;\n const meanPY = sumPY / n;\n\n // Calculate slopes in pixel space (dpx/dt and dpy/dt)\n const denominator = sumTT - n * meanT * meanT;\n if (Math.abs(denominator) < 1e-10) return; // Avoid division by zero\n \n const slopePX = (sumTPX - n * meanT * meanPX) / denominator;\n const slopePY = (sumTPY - n * meanT * meanPY) / denominator;\n\n // Calculate continuous angle in pixel space (canvas coordinates)\n const rawAngle = Math.atan2(slopePY, slopePX);\n \n // Convert last point to pixel coordinates\n const lastPixelX = pluginCtx.coords.dataToPixelX(lastX);\n const lastPixelY = pluginCtx.coords.dataToPixelY(lastY);\n \n // Add to position history for smoothing\n positionHistoryX.push(lastPixelX);\n positionHistoryY.push(lastPixelY);\n if (positionHistoryX.length > maxHistorySize) {\n positionHistoryX.shift();\n positionHistoryY.shift();\n }\n \n // Add to angle history for smoothing\n angleHistory.push(rawAngle);\n if (angleHistory.length > maxHistorySize) {\n angleHistory.shift();\n }\n \n // Apply moving average to smooth position and angle\n const smoothX = average(positionHistoryX);\n const smoothY = average(positionHistoryY);\n const smoothedAngle = smoothAngle(angleHistory);\n \n // Calculate magnitude in pixel space\n const magnitude = Math.sqrt(slopePX * slopePX + slopePY * slopePY);\n\n currentDirection = { angle: smoothedAngle, magnitude, lastX, lastY, smoothX, smoothY };\n }\n \n function average(values: number[]): number {\n if (values.length === 0) return 0;\n return values.reduce((sum, val) => sum + val, 0) / values.length;\n }\n \n function smoothAngle(angles: number[]): number {\n if (angles.length === 0) return 0;\n \n // Convert angles to unit vectors to handle wraparound correctly\n let sumX = 0;\n let sumY = 0;\n \n for (const angle of angles) {\n sumX += Math.cos(angle);\n sumY += Math.sin(angle);\n }\n \n // Average the vectors and convert back to angle\n return Math.atan2(sumY / angles.length, sumX / angles.length);\n }\n\n function render(pluginCtx: PluginContext) {\n if (!ctx || !canvas || !currentDirection) return;\n\n const { width, height } = pluginCtx.render.canvasSize;\n ctx.clearRect(0, 0, width, height);\n\n // Check for idle timeout\n if (currentIdleTimeout !== undefined) {\n const age = Date.now() - lastPointTimestamp;\n if (age > currentIdleTimeout) return;\n }\n\n if (currentDirection.magnitude < minVelocity) return;\n\n // Use smoothed position for fluid movement\n const smoothX = currentDirection.smoothX;\n const smoothY = currentDirection.smoothY;\n\n const arrowColor = color || \"#FF9800\";\n \n ctx.save();\n\n // Draw arrow at smoothed position with smoothed angle\n drawArrow(ctx, smoothX, smoothY, currentDirection.angle, size, arrowColor);\n\n ctx.restore();\n }\n\n function drawArrow(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n angle: number,\n length: number,\n color: string\n ) {\n // Triangle dimensions (only the arrow head)\n const triangleHeight = length * 0.6;\n const triangleWidth = length * 0.4;\n\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(angle);\n\n // Draw filled triangle pointing in the direction of movement\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.moveTo(triangleHeight / 2, 0); // Tip of the triangle\n ctx.lineTo(-triangleHeight / 2, -triangleWidth / 2); // Bottom left\n ctx.lineTo(-triangleHeight / 2, triangleWidth / 2); // Bottom right\n ctx.closePath();\n ctx.fill();\n\n ctx.restore();\n }\n }\n);\n","/**\n * Velo Plot - Built-in Plugins\n * \n * Collection of official plugins that demonstrate the plugin system\n * capabilities and provide common functionality.\n * \n * @module plugins/builtins\n */\n\nexport * from \"./crosshair\";\nexport * from \"./stats\";\nexport * from \"./watermark\";\nexport * from \"./grid-highlight\";\nexport * from \"./data-logger\";\nexport * from \"./direction-indicator\";\n\nimport { CrosshairPlugin } from \"./crosshair\";\nimport { StatsPlugin } from \"./stats\";\nimport { WatermarkPlugin } from \"./watermark\";\nimport { GridHighlightPlugin } from \"./grid-highlight\";\nimport { DataLoggerPlugin } from \"./data-logger\";\nimport { DirectionIndicatorPlugin } from \"./direction-indicator\";\n\n/**\n * Plugin collection for easy registration\n */\nexport const BuiltinPlugins = {\n Crosshair: CrosshairPlugin,\n Statistics: StatsPlugin,\n Watermark: WatermarkPlugin,\n GridHighlight: GridHighlightPlugin,\n DataLogger: DataLoggerPlugin,\n DirectionIndicator: DirectionIndicatorPlugin,\n};\n","/**\n * @fileoverview Drag & Drop editing plugin for interactive point manipulation\n * @module plugins/drag-edit\n */\n\nimport type {\n PluginDragEditConfig,\n DragEditAPI,\n DraggedPoint,\n DragEditEvent,\n DragConstraint,\n} from './types';\nimport type {\n ChartPlugin,\n PluginContext,\n PluginManifest,\n} from '../types';\n\nconst manifest: PluginManifest = {\n name: 'velo-plot-drag-edit',\n version: '1.0.0',\n description: 'Interactive drag & drop editing of data points',\n provides: ['drag-edit', 'point-editing'],\n tags: ['interaction', 'editing', 'ux'],\n};\n\nconst DEFAULT_CONFIG: Required<PluginDragEditConfig> = {\n enabled: true,\n constraint: 'both',\n snapToGrid: false,\n snapIntervalX: 1,\n snapIntervalY: 1,\n dragThreshold: 5,\n hitRadius: 10,\n editableSeries: [],\n validator: () => ({ valid: true }),\n onDragStart: () => {},\n onDrag: () => {},\n onDragEnd: () => {},\n highlightColor: '#ffff00',\n showPreview: true,\n previewStyle: {\n color: '#ffffff',\n width: 2,\n dash: [5, 5],\n opacity: 0.5,\n },\n};\n\nexport function PluginDragEdit(\n userConfig: Partial<PluginDragEditConfig> = {}\n): ChartPlugin<PluginDragEditConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n \n // Drag state\n let isDragging = false;\n let draggedPoint: DraggedPoint | null = null;\n let dragStartX = 0;\n let dragStartY = 0;\n let hasMoved = false;\n\n /**\n * Find nearest point to mouse position\n */\n function findNearestPoint(mouseX: number, mouseY: number): DraggedPoint | null {\n if (!ctx) return null;\n\n // Use built-in pick functionality\n const picked = ctx.coords.pickPoint(mouseX, mouseY, config.hitRadius);\n \n if (!picked) return null;\n\n // Check if series is editable\n if (config.editableSeries.length > 0 && !config.editableSeries.includes(picked.seriesId)) {\n return null;\n }\n\n return {\n seriesId: picked.seriesId,\n index: picked.index,\n originalX: picked.x,\n originalY: picked.y,\n currentX: picked.x,\n currentY: picked.y,\n };\n }\n\n /**\n * Convert pixel coordinates to data coordinates\n */\n function pixelToData(pixelX: number, pixelY: number): { x: number; y: number } {\n if (!ctx) return { x: 0, y: 0 };\n\n return {\n x: ctx.coords.pixelToDataX(pixelX),\n y: ctx.coords.pixelToDataY(pixelY),\n };\n }\n\n /**\n * Snap value to grid\n */\n function snapToGrid(value: number, interval: number): number {\n return Math.round(value / interval) * interval;\n }\n\n /**\n * Apply drag constraints\n */\n function applyConstraints(\n newX: number,\n newY: number,\n constraint: DragConstraint\n ): { x: number; y: number } {\n if (!draggedPoint) return { x: newX, y: newY };\n\n switch (constraint) {\n case 'x':\n return { x: newX, y: draggedPoint.originalY };\n case 'y':\n return { x: draggedPoint.originalX, y: newY };\n case 'none':\n return { x: draggedPoint.originalX, y: draggedPoint.originalY };\n default:\n return { x: newX, y: newY };\n }\n }\n\n /**\n * Validate and apply snapping\n */\n function validateAndSnap(x: number, y: number): { x: number; y: number; valid: boolean } {\n let finalX = x;\n let finalY = y;\n\n // Apply snapping\n if (config.snapToGrid) {\n finalX = snapToGrid(x, config.snapIntervalX);\n finalY = snapToGrid(y, config.snapIntervalY);\n }\n\n // Run custom validation\n if (draggedPoint && config.validator) {\n const tempPoint: DraggedPoint = { ...draggedPoint, currentX: finalX, currentY: finalY };\n const validation = config.validator(tempPoint);\n\n if (typeof validation === 'boolean') {\n return { x: finalX, y: finalY, valid: validation };\n }\n\n if (!validation.valid) {\n return { x: finalX, y: finalY, valid: false };\n }\n\n // Apply snap suggestions from validator\n if (validation.snapX !== undefined) finalX = validation.snapX;\n if (validation.snapY !== undefined) finalY = validation.snapY;\n }\n\n return { x: finalX, y: finalY, valid: true };\n }\n\n /**\n * Update point data\n */\n function updatePointData(seriesId: string, index: number, newX: number, newY: number): void {\n if (!ctx) return;\n\n const series = (ctx.chart as any).getSeries?.(seriesId);\n if (!series) return;\n\n const data = series.getData();\n if (!data || !data.x || !data.y) return;\n\n // Update the data arrays\n data.x[index] = newX;\n data.y[index] = newY;\n\n // Invalidate buffers to trigger GPU upload\n series.invalidateBuffers?.();\n\n // Trigger chart re-render\n ctx.requestRender();\n }\n\n /**\n * Create drag event\n */\n function createDragEvent(): DragEditEvent | null {\n if (!draggedPoint) return null;\n\n return {\n seriesId: draggedPoint.seriesId,\n index: draggedPoint.index,\n oldX: draggedPoint.originalX,\n oldY: draggedPoint.originalY,\n newX: draggedPoint.currentX,\n newY: draggedPoint.currentY,\n deltaX: draggedPoint.currentX - draggedPoint.originalX,\n deltaY: draggedPoint.currentY - draggedPoint.originalY,\n };\n }\n\n /**\n * Draw preview overlay\n */\n function drawPreview(pCtx: PluginContext): void {\n if (!isDragging || !draggedPoint || !config.showPreview) return;\n\n const { render, coords } = pCtx;\n const { ctx2d } = render;\n if (!ctx2d) return;\n\n ctx2d.save();\n\n // Convert data coordinates to pixel coordinates\n const origPixelX = coords.dataToPixelX(draggedPoint.originalX);\n const origPixelY = coords.dataToPixelY(draggedPoint.originalY);\n \n const currPixelX = coords.dataToPixelX(draggedPoint.currentX);\n const currPixelY = coords.dataToPixelY(draggedPoint.currentY);\n\n // Draw preview line from original to current position\n ctx2d.strokeStyle = config.previewStyle.color || '#ffffff';\n ctx2d.lineWidth = config.previewStyle.width || 2;\n ctx2d.globalAlpha = config.previewStyle.opacity || 0.5;\n ctx2d.setLineDash(config.previewStyle.dash || [5, 5]);\n\n ctx2d.beginPath();\n ctx2d.moveTo(origPixelX, origPixelY);\n ctx2d.lineTo(currPixelX, currPixelY);\n ctx2d.stroke();\n\n // Draw highlight circle at current position\n ctx2d.globalAlpha = 1;\n ctx2d.fillStyle = config.highlightColor;\n ctx2d.setLineDash([]);\n ctx2d.beginPath();\n ctx2d.arc(currPixelX, currPixelY, 6, 0, Math.PI * 2);\n ctx2d.fill();\n\n // Draw outline\n ctx2d.strokeStyle = '#000000';\n ctx2d.lineWidth = 1;\n ctx2d.stroke();\n\n ctx2d.restore();\n }\n\n // API implementation\n const api: DragEditAPI & Record<string, unknown> = {\n enable() {\n config.enabled = true;\n },\n disable() {\n config.enabled = false;\n if (isDragging) {\n draggedPoint = null;\n isDragging = false;\n hasMoved = false;\n ctx?.requestRender();\n }\n },\n isEnabled() {\n return config.enabled;\n },\n setEditableSeries(seriesIds: string[]) {\n config.editableSeries = seriesIds;\n },\n getDraggedPoint() {\n return draggedPoint;\n },\n cancelDrag() {\n if (isDragging && draggedPoint) {\n draggedPoint = null;\n isDragging = false;\n hasMoved = false;\n ctx?.requestRender();\n }\n },\n updateConfig(newConfig: Partial<PluginDragEditConfig>) {\n Object.assign(config, newConfig);\n },\n };\n\n return {\n manifest,\n\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n\n // Attach to chart API\n (ctx.chart as any).dragEdit = api;\n },\n\n onDestroy(_pluginCtx: PluginContext) {\n // Remove from chart API\n delete (_pluginCtx.chart as any).dragEdit;\n\n ctx = null;\n },\n\n onInteraction(_pluginCtx: PluginContext, event: import('../types').InteractionEvent) {\n if (!config.enabled) return;\n\n if (event.type === 'mousedown') {\n const point = findNearestPoint(event.pixelX, event.pixelY);\n if (point) {\n draggedPoint = point;\n dragStartX = event.pixelX;\n dragStartY = event.pixelY;\n hasMoved = false;\n isDragging = false;\n // Prevent default to stop panning when clicking on a point\n event.preventDefault();\n }\n } else if (event.type === 'mousemove') {\n if (!draggedPoint) return;\n\n // Check if we've moved beyond threshold\n if (!isDragging) {\n const dx = event.pixelX - dragStartX;\n const dy = event.pixelY - dragStartY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (distance > config.dragThreshold) {\n isDragging = true;\n hasMoved = true;\n\n // Fire drag start event\n const dragEvent = createDragEvent();\n if (dragEvent) config.onDragStart(dragEvent);\n } else {\n return;\n }\n }\n\n // Prevent default during dragging\n if (isDragging) {\n event.preventDefault();\n }\n\n // Convert to data coordinates\n let { x, y } = pixelToData(event.pixelX, event.pixelY);\n\n // Apply constraints\n ({ x, y } = applyConstraints(x, y, config.constraint));\n\n // Validate and snap\n const { x: finalX, y: finalY, valid } = validateAndSnap(x, y);\n\n if (valid) {\n draggedPoint.currentX = finalX;\n draggedPoint.currentY = finalY;\n\n // Fire drag event (for callbacks)\n const dragEvent = createDragEvent();\n if (dragEvent) config.onDrag(dragEvent);\n\n // Request render to show preview line\n ctx?.requestRender();\n }\n } else if (event.type === 'mouseup') {\n if (!draggedPoint) return;\n\n if (isDragging && hasMoved) {\n // Apply the changes\n updatePointData(\n draggedPoint.seriesId,\n draggedPoint.index,\n draggedPoint.currentX,\n draggedPoint.currentY\n );\n\n // Fire drag end event\n const dragEvent = createDragEvent();\n if (dragEvent) config.onDragEnd(dragEvent);\n\n // Prevent default on mouseup to avoid triggering click events\n event.preventDefault();\n }\n\n // Reset state\n draggedPoint = null;\n isDragging = false;\n hasMoved = false;\n ctx?.requestRender();\n }\n },\n\n onRenderOverlay(pluginCtx: PluginContext) {\n drawPreview(pluginCtx);\n },\n\n api,\n };\n}\n\nexport default PluginDragEdit;\n\n// Type exports\nexport type {\n PluginDragEditConfig,\n DragEditAPI,\n DraggedPoint,\n DragEditEvent,\n DragConstraint,\n} from './types';\n","/**\n * Velo Plot - Plugin System\n * \n * Comprehensive plugin architecture for extending chart functionality.\n * \n * Features:\n * - Complete lifecycle hooks (init, render, data, view, interaction, destroy)\n * - Rich plugin context with access to all chart internals\n * - Plugin storage for persistent state\n * - Dependency management between plugins\n * - Global registry for third-party plugins\n * - Built-in plugins for common use cases\n * \n * @packageDocumentation\n * @module plugins\n */\n\n// ============================================\n// Core Types\n// ============================================\nexport type {\n // Manifest & Metadata\n PluginVersion,\n PluginCapability,\n PluginManifest,\n\n // Context Types\n PluginContext,\n RenderContext,\n CoordinateContext,\n DataContext,\n UIContext,\n EventContext,\n PluginStorage,\n PluginLogger,\n OverlayOptions,\n NotificationOptions,\n PickResult,\n\n // Hook Event Types\n BeforeRenderEvent,\n AfterRenderEvent,\n InteractionEvent,\n ViewChangeEvent,\n SeriesChangeEvent,\n DataUpdateEvent,\n\n // Plugin Types\n ChartPlugin,\n PluginFactory,\n TypedPlugin,\n\n // Manager Types\n PluginManager,\n PluginRegistry,\n PluginRegistryEntry,\n} from \"./types\";\n\n// ============================================\n// Core Implementation\n// ============================================\nexport { createPluginContext } from \"./PluginContext\";\nexport type { ContextDependencies } from \"./PluginContext\";\n\nexport { PluginManagerImpl } from \"./PluginManager\";\n\n// ============================================\n// Registry\n// ============================================\nexport {\n getPluginRegistry,\n registerPlugin,\n definePlugin,\n defineAndRegister,\n loadPlugin,\n listPluginsByCategory,\n validateManifest,\n checkPluginCompatibility,\n} from \"./PluginRegistry\";\n\n// ============================================\n// Built-in Plugins\n// ============================================\nexport {\n // Individual plugins\n CrosshairPlugin,\n StatsPlugin,\n WatermarkPlugin,\n GridHighlightPlugin,\n DataLoggerPlugin,\n DirectionIndicatorPlugin,\n\n // Plugin collection\n BuiltinPlugins,\n\n // Plugin configs\n type CrosshairPluginConfig,\n type StatsPluginConfig,\n type WatermarkPluginConfig,\n type GridHighlightConfig,\n type DataLoggerConfig,\n type DirectionIndicatorConfig,\n} from \"./builtins\";\n\n// ============================================\n// Modular Plugins\n// ============================================\nexport { Plugin3D, type Plugin3DConfig } from \"./3d\";\nexport { PluginGpu, type PluginGpuConfig } from \"./gpu\";\nexport { PluginAnalysis, type PluginAnalysisConfig } from \"./analysis\";\nexport { PluginTools, type PluginToolsConfig } from \"./tools\";\nexport { PluginAnnotations, type PluginAnnotationsConfig } from \"./annotations\";\nexport { PluginStreaming, type PluginStreamingConfig } from \"./streaming\";\nexport { PluginThemeEditor, type PluginThemeEditorConfig } from \"./theme-editor\";\nexport { PluginI18n, type PluginI18nConfig } from \"./i18n\";\nexport { PluginKeyboard, type PluginKeyboardConfig } from \"./keyboard\";\nexport { PluginClipboard, type PluginClipboardConfig } from \"./clipboard\";\nexport { PluginSync, type PluginSyncConfig } from \"./sync\";\nexport { PluginDebug, type PluginDebugConfig } from \"./debug\";\nexport { PluginLoading, type PluginLoadingConfig } from \"./loading\";\nexport { PluginDataExport, type PluginDataExportConfig } from \"./data-export\";\nexport { PluginContextMenu, type PluginContextMenuConfig } from \"./context-menu\";\nexport { PluginAnomalyDetection, type PluginAnomalyDetectionConfig, type AnomalyDetectionResult, type AnomalyPoint, type AnomalyMethod } from \"./anomaly-detection\";\nexport { PluginMLIntegration, type PluginMLIntegrationConfig, type MLIntegrationAPI, type MLModelAPI, type PredictionResult, type VisualizationConfig } from \"./ml-integration\";\nexport { PluginPatternRecognition, type PluginPatternRecognitionConfig, type PatternRecognitionAPI, type PatternMatch, type PatternDetectionResult } from \"./pattern-recognition\";\nexport { PluginRegression, type PluginRegressionConfig, type RegressionAPI, type RegressionResult, type RegressionData } from \"./regression\";\nexport { PluginRadar, type PluginRadarConfig, type RadarAPI, type RadarSeriesData, type RadarPoint } from \"./radar\";\nexport { PluginSnapshot, type PluginSnapshotConfig, type SnapshotExportAPI, type SnapshotExportOptions, type SnapshotResolution, type SnapshotFormat } from \"./snapshot\";\nexport { PluginDataTransform, type PluginDataTransformConfig, type DataTransformAPI, type TransformOp, type TransformType } from \"./data-transform\";\nexport { PluginLaTeX, type PluginLaTeXConfig, type LaTeXPluginAPI, type LaTeXDimensions } from \"./latex\";\nexport * from \"./forecasting\";\n\n// Drag & Drop Editing\nexport { PluginDragEdit, type PluginDragEditConfig, type DragEditAPI, type DragEditEvent } from \"./drag-edit\";\n\n// Caching\nexport { PluginCaching, type PluginCachingConfig, type CachingAPI, type CacheStats } from \"./caching\";\n\n// Lazy Loading\nexport { PluginLazyLoad, type PluginLazyLoadConfig, type LazyLoadAPI, type DataProvider } from \"./lazy-load\";\n\n// Broken Axis\nexport { PluginBrokenAxis, type PluginBrokenAxisConfig, type BrokenAxisAPI, type AxisBreak } from \"./broken-axis\";\n\n// Video Recorder\nexport { PluginVideoRecorder, type PluginVideoRecorderConfig, type VideoRecorderAPI, type VideoRecorderOptions } from \"./video-recorder\";\n\n// Offscreen Rendering\nexport { PluginOffscreen, type PluginOffscreenConfig, type OffscreenAPI, type OffscreenStats, type OffscreenMode, type OffscreenTransferMode, type OffscreenFallbackMode } from \"./offscreen\";\n\n// Virtualization\nexport { PluginVirtualization, type PluginVirtualizationConfig, type VirtualizationAPI, type VirtualizationStats, type VirtualizationMode, type VirtualizationStrategy } from \"./virtualization\";\n\n// Stage 2 — Trading\nexport { PluginDrawingTools, type PluginDrawingToolsConfig, type DrawingToolsAPI, type DrawingMode } from \"./drawing-tools\";\nexport { PluginReplay, type PluginReplayConfig, type ReplayAPI } from \"./replay\";\n\n// ROI\nexport { PluginROI, type PluginROIConfig, type RoiAPI, type RoiRegion, type RoiPoint, type RoiMaskResult, type RoiTool, type RoiEvent, type RoiSelectedEvent } from \"./roi\";\n\n// ============================================\n// Helper for creating typed plugins\n// ============================================\n\n/**\n * Helper function to create a plugin with proper typing\n * \n * @example\n * ```typescript\n * const MyPlugin = createPlugin({\n * manifest: {\n * name: 'my-plugin',\n * version: '1.0.0',\n * provides: ['analysis'],\n * },\n * onInit(ctx) {\n * ctx.log.info('Plugin initialized!');\n * },\n * onAfterRender(ctx, event) {\n * // Custom rendering\n * },\n * api: {\n * doSomething() { return 'done'; }\n * }\n * });\n * \n * chart.use(MyPlugin);\n * ```\n */\nexport function createPlugin<TConfig = void, TApi extends Record<string, unknown> = {}>(\n definition: import(\"./types\").ChartPlugin<TConfig> & { api?: TApi }\n): import(\"./types\").ChartPlugin<TConfig> & { api: TApi } {\n return definition as import(\"./types\").ChartPlugin<TConfig> & { api: TApi };\n}\n\n/**\n * Helper function to create a configurable plugin factory\n * \n * @example\n * ```typescript\n * interface MyConfig {\n * color: string;\n * enabled: boolean;\n * }\n * \n * const MyPlugin = createConfigurablePlugin<MyConfig>(\n * {\n * name: 'my-plugin',\n * version: '1.0.0',\n * },\n * (config) => ({\n * onInit(ctx) {\n * ctx.log.info(`Color: ${config?.color}`);\n * }\n * })\n * );\n * \n * chart.use(MyPlugin({ color: 'red', enabled: true }));\n * ```\n */\nexport function createConfigurablePlugin<TConfig = void>(\n manifest: import(\"./types\").PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): import(\"./types\").PluginFactory<TConfig> {\n return (config?: TConfig) => ({\n ...factory(config),\n manifest,\n });\n}\n","/**\n * Velo Plot - High-Performance Scientific Charting\n */\nimport \"./scientific/registerScientific\";\nimport { registerTradingBundle } from \"./trading/registerTrading\";\n\nregisterTradingBundle();\n\n// ============================================\n// Core exports\n// ============================================\nexport { createChart } from \"./core/Chart\";\nexport { Series } from \"./core/Series\";\nexport { EventEmitter } from \"./core/EventEmitter\";\nexport type { Chart, ChartOptions, ExportOptions } from \"./core/Chart\";\n\n// ============================================\n// Animation\n// ============================================\nexport {\n AnimationEngine,\n easings,\n DEFAULT_ANIMATION_CONFIG,\n mergeAnimationConfig,\n getSharedAnimationEngine,\n} from \"./core/animation\";\nexport type {\n AnimationOptions,\n AnimationHandle,\n BoundsAnimation,\n ChartAnimationConfig,\n EasingFunction,\n EasingName,\n} from \"./core/animation\";\n\n// ============================================\n// Chart Initialization Queue (for multiple charts)\n// ============================================\nexport {\n ChartInitQueue,\n getChartInitQueue,\n queueChartInit,\n waitForAnimations,\n resetChartQueue,\n} from \"./core/ChartInitQueue\";\n\n// ============================================\n// Annotations\n// ============================================\nexport { AnnotationManager } from \"./core/annotations\";\nexport type {\n Annotation,\n AnnotationType,\n HorizontalLineAnnotation,\n VerticalLineAnnotation,\n RectangleAnnotation,\n BandAnnotation,\n TextAnnotation,\n ArrowAnnotation,\n} from \"./core/annotations\";\n\n// ============================================\n// Types\n// ============================================\nexport type {\n AxisOptions,\n SeriesOptions,\n SeriesData,\n SeriesStyle,\n SeriesUpdateData,\n ZoomOptions,\n CursorOptions,\n ChartEventMap,\n Point,\n Bounds,\n Range,\n ScaleType,\n SeriesType,\n StepMode,\n ErrorBarStyle,\n ErrorBarDirection,\n ScatterSymbol,\n DeltaMeasurement,\n PeakMeasurement,\n // Polar Charts\n PolarMode,\n PolarData,\n PolarStyle,\n PolarOptions,\n // Ternary Charts\n TernaryData,\n TernaryStyle,\n TernaryOptions,\n} from \"./types\";\n\n// ============================================\n// Scales\n// ============================================\nexport { LinearScale, LogScale, createScale, type Scale } from \"./scales\";\n\n// ============================================\n// Renderer\n// ============================================\nexport {\n NativeWebGLRenderer,\n interleaveData,\n parseColor,\n createRenderer,\n createNativeRenderer,\n WebGPURenderer,\n type WebGPURendererOptions,\n type IWebGLRenderer,\n type SeriesRenderData,\n type RenderOptions,\n} from \"./renderer\";\n\n// ============================================\n// Theme\n// ============================================\nexport {\n DARK_THEME,\n LIGHT_THEME,\n MIDNIGHT_THEME,\n ELECTROCHEM_THEME,\n DEFAULT_THEME,\n createTheme,\n getThemeByName,\n type ChartTheme,\n type GridTheme,\n type AxisTheme,\n type LegendTheme,\n type CursorTheme,\n} from \"./theme\";\n\n// ============================================\n// Layout & Positioning\n// ============================================\nexport {\n DEFAULT_LAYOUT,\n mergeLayoutOptions,\n type LayoutOptions,\n type LegendOptions,\n type CrosshairOptions,\n type CrosshairValueMode,\n type CornerPosition,\n type ChartTitleOptions,\n type AxisLayoutOptions,\n type ChartMargins,\n type PlotAreaPadding,\n type LegendPositionPreset,\n type ToolbarPositionPreset,\n type ToolbarPosition,\n} from \"./core/layout\";\n\n// ============================================\n// Overlay\n// ============================================\nexport {\n OverlayRenderer,\n} from \"./core/OverlayRenderer\";\n\n// ============================================\n// Persistence & Serialization\n// ============================================\nexport {\n SERIALIZATION_VERSION,\n encodeFloat32Array,\n decodeFloat32Array,\n compressString,\n decompressString,\n stateToUrlHash,\n urlHashToState,\n validateChartState,\n StateHistory,\n type SerializedAxis,\n type SerializedSeries,\n type ChartState,\n type SerializeOptions,\n type DeserializeOptions,\n type StateSnapshot,\n} from \"./serialization\";\n\nexport type {\n PlotArea,\n CursorState,\n} from \"./types\";\n\n// ============================================\n// Tooltip System\n// ============================================\nexport {\n TooltipManager,\n TOOLTIP_THEMES,\n getTooltipThemeForChartTheme,\n} from \"./plugins/tools/tooltip\";\n\nexport type {\n TooltipData,\n TooltipType,\n TooltipTheme,\n TooltipOptions,\n TooltipTemplate,\n DataPointTooltip,\n CrosshairTooltip,\n HeatmapTooltip,\n} from \"./plugins/tools/tooltip\";\n\n// ============================================\n// Downsampling\n// ============================================\nexport {\n lttbDownsample,\n minMaxDownsample,\n ohlcMinMaxDownsample,\n calculateTargetPoints,\n sliceSeriesToViewport,\n lowerBoundX,\n upperBoundX,\n} from \"./workers/downsample\";\n\nexport {\n downsampleAsync,\n ohlcDownsampleAsync,\n destroyDownsamplePool,\n getDownsamplePoolSize,\n} from \"./workers/downsampleAsync\";\n\nexport {\n rsiAsync,\n smaAsync,\n emaAsync,\n macdAsync,\n bollingerBandsAsync,\n destroyIndicatorPool,\n} from \"./workers/indicatorsAsync\";\n\nexport { WorkerPool, nextTaskId } from \"./workers/pool\";\nexport type { WorkerPoolOptions } from \"./workers/pool\";\n\n// ============================================\n// Data Analysis utilities\n// ============================================\nexport {\n formatWithPrefix,\n formatValue,\n formatScientific,\n getBestPrefix,\n detectCycles,\n generateCycleColors,\n detectPeaks,\n validateData,\n calculateStats,\n movingAverage,\n downsampleLTTB,\n subtractBaseline,\n // Math\n integrate,\n derivative,\n cumulativeIntegral,\n calculateR2,\n solveLinearSystem,\n // Spectral / FFT\n fft,\n ifft,\n analyzeSpectrum,\n powerSpectrum,\n dominantFrequency,\n analyzeComplexSpectrum,\n fftFromComplexInput,\n hanningWindow,\n hammingWindow,\n blackmanWindow,\n nextPowerOf2,\n complexToArrays,\n arraysToComplex,\n ifftFromArrays,\n ifftComplex,\n getPositiveFrequencies,\n // Filters\n lowPassFilter,\n highPassFilter,\n bandPassFilter,\n bandStopFilter,\n butterworth,\n exponentialMovingAverage,\n gaussianSmooth,\n savitzkyGolay,\n medianFilter,\n singleFrequencyFilter,\n // Statistics\n crossCorrelation,\n autoCorrelation,\n detectAnomalies,\n trapezoidalIntegration,\n simpsonsIntegration,\n tTest,\n generateContours,\n joinSegments,\n type ContourLine,\n type ContourPoint,\n type ContourLabel,\n type ContourOptions,\n type CycleInfo,\n type Peak,\n type PrefixInfo,\n type ValidationResult,\n type DataStats,\n type FFTResult,\n type ComplexFFTResult,\n type PowerSpectrumResult,\n type FilterOptions,\n type ButterworthOptions,\n type SingleFrequencyFilterOptions,\n} from \"./plugins/analysis\";\n\n// ============================================\n// Streaming utilities\n// ============================================\nexport {\n createWebSocketStream,\n connectStreamToChart,\n createMessageParser,\n createMockStream,\n type WebSocketStream,\n type WebSocketStreamConfig,\n type DataPoint,\n type StreamStats,\n type WebSocketState,\n} from \"./streaming\";\n\n// ============================================\n// React bindings\n// ============================================\nexport {\n VeloPlot,\n StackedPlot,\n useVeloPlot,\n useStackedPlot,\n useIndicator,\n useChartSync,\n useChartGroup,\n SciPlot,\n SciChart,\n useSciPlot,\n useSciChart,\n type VeloPlotProps,\n type VeloPlotRef,\n type VeloPlotSeries,\n type StackedPlotProps,\n type StackedPlotRef,\n type UseVeloPlotOptions,\n type UseVeloPlotReturn,\n type UseStackedPlotOptions,\n type UseStackedPlotReturn,\n type UseIndicatorReturn,\n type UseChartSyncReturn,\n type SciPlotProps,\n type SciPlotRef,\n type SciPlotSeries,\n type SciChartProps,\n type SciChartRef,\n type SciChartSeries,\n type UseSciPlotOptions,\n type UseSciPlotReturn,\n type UseSciChartOptions,\n type UseSciChartReturn,\n} from \"./react\";\n\n// ============================================\n// GPU Abstraction Layer (Experimental)\n// ============================================\nexport {\n // Backends\n WebGPUBackend,\n WebGLBackend,\n\n // Renderer facade\n GpuRenderer,\n createGpuRenderer,\n\n // Adapter utilities\n SeriesAdapter,\n parseColorToRGBA,\n\n // Resource management\n PipelineCache,\n BaseBufferStore,\n BaseTextureStore,\n\n // Benchmark\n GpuBenchmark,\n\n // GPU Compute\n GpuCompute,\n} from \"./gpu\";\n\nexport type {\n // Core types\n GpuBackendType,\n RGBA,\n GpuViewport,\n GpuBackend,\n BufferId,\n TextureId,\n\n // Frame types\n FrameUniforms,\n\n // Draw types\n DrawKind,\n DrawCall,\n DrawList,\n PointSymbol,\n\n // Adapter types\n SeriesData as GpuSeriesData,\n Bounds as GpuBounds,\n GpuRenderOptions,\n GpuRendererOptions,\n BackendPreference,\n WebGPUBackendOptions,\n\n // Benchmark types\n BenchmarkResult,\n BenchmarkOptions,\n\n // Compute types\n DataStats as GpuDataStats,\n DataBounds as GpuDataBounds,\n Peak as GpuPeak,\n GpuComputeOptions,\n} from \"./gpu\";\n\n// ============================================\n// Internationalization (i18n)\n// ============================================\nexport {\n setGlobalLocale,\n getGlobalLocale,\n getLocale,\n registerLocale,\n createLocaleFormatter,\n LOCALE_EN_US,\n LOCALE_ES_ES,\n LOCALE_DE_DE,\n LOCALE_FR_FR,\n LOCALE_PT_BR,\n LOCALE_ZH_CN,\n LOCALE_JA_JP,\n type LocaleConfig,\n type LocaleFormatter,\n} from \"./core/locale\";\n\n// ============================================\n// Keyboard Shortcuts\n// ============================================\nexport {\n KeyBindingManager,\n DEFAULT_KEY_BINDINGS,\n createKeyBinding,\n parseShortcut,\n type KeyAction,\n type KeyBinding,\n type KeyBindingCallbacks,\n type KeyBindingManagerOptions,\n} from \"./core/keybindings\";\n\n// ============================================\n// Clipboard\n// ============================================\nexport {\n ClipboardManager,\n getClipboardManager,\n copyToClipboard,\n formatData,\n type ClipboardFormat,\n type ClipboardOptions,\n type ClipboardDataPoint,\n type ClipboardResult,\n} from \"./core/clipboard\";\n\n// ============================================\n// Debug Overlay\n// ============================================\nexport {\n DebugOverlay,\n createDebugOverlay,\n enableDebugMode,\n type DebugStats,\n type DebugOverlayOptions,\n} from \"./core/debug\";\n\n// ============================================\n// Loading Indicators\n// ============================================\nexport {\n LoadingIndicator,\n createLoadingIndicator,\n showLoading,\n showProgress,\n type LoadingIndicatorType,\n type LoadingIndicatorOptions,\n type LoadingState,\n} from \"./core/loading\";\n\n// ============================================\n// Testing Utilities (for test environments)\n// ============================================\nexport {\n // Data generators\n generateSineWave,\n generateSquareWave,\n generateSawtoothWave,\n generateTriangleWave,\n generateRandomData,\n generateCVData,\n generateNyquistData,\n\n // Benchmarking\n benchmarkRender,\n assertPerformance,\n compareGridBackends,\n evaluateRendererCompare,\n benchmarkCanvasGrid,\n benchmarkWebGLGrid,\n getBaseline,\n compareScenarioToBaseline,\n\n // Snapshots\n createSnapshot,\n compareSnapshots,\n\n // Utilities\n waitForFrames,\n waitFor,\n\n // Types\n type MockChartOptions,\n type WaveformOptions,\n type RandomDataOptions,\n type BenchmarkResult as TestBenchmarkResult,\n type BenchmarkOptions as TestBenchmarkOptions,\n type SnapshotOptions,\n type ChartSnapshot,\n} from \"./testing\";\n\n// ============================================\n// Chart Synchronization\n// ============================================\nexport {\n ChartGroup,\n createChartGroup,\n linkCharts,\n createMasterSlave,\n type SyncAxis,\n type SyncOptions,\n type ChartLike,\n type SyncEvent,\n} from \"./core/sync\";\n\n// ============================================\n// Stacked multi-pane charts\n// ============================================\nexport {\n createStackedChart,\n STACKED_MAX_PANES,\n STACKED_DEFAULT_MIN_PANE_RATIO,\n type StackedChart,\n type StackedChartOptions,\n type StackedPaneConfig,\n type StackedSyncOptions,\n} from \"./core/stacked\";\n\n// ============================================\n// Trading indicator panes (histogram + lines + fills)\n// ============================================\nexport {\n buildIndicatorSeries,\n createIndicatorSeries,\n buildIndicatorPane,\n buildIndicatorPaneFromPreset,\n addIndicatorToChart,\n computeIndicatorFromSeries,\n computeIndicatorPreset,\n detectIndicatorMarkers,\n type IndicatorData,\n type IndicatorSeriesOptions,\n type IndicatorStyle,\n type IndicatorLineLayer,\n type IndicatorLineColorZones,\n type BuildIndicatorPaneOptions,\n type AddIndicatorOptions,\n type AddIndicatorResult,\n type IndicatorPresetName,\n} from \"./core/indicator\";\n\n// ============================================\n// Stage 2 — Trading (time scale, markers, heikin-ashi)\n// ============================================\nexport {\n mapToBusinessDayScale,\n isBusinessDay,\n businessDaySpanMs,\n type TimeScaleOptions,\n type BusinessDayMapping,\n} from \"./core/time/TimeScale\";\nexport {\n isBusinessDayScaleActive,\n applyBusinessDayX,\n formatBusinessDayTick,\n} from \"./core/time/applyTimeScale\";\nexport { computeHeikinAshi } from \"./core/chart/heikinAshi\";\nexport { buildPositionLineAnnotation, type PositionLineOptions } from \"./core/chart/positionLines\";\nexport type { DatafeedAdapter, Bar, SymbolInfo } from \"./trading/datafeed\";\nexport { barsToOhlc } from \"./trading/datafeed\";\nexport { createMockDatafeed } from \"./trading/mockDatafeed\";\nexport type {\n CandlestickMarker,\n CandlestickMarkerPosition,\n CandlestickMarkerShape,\n} from \"./core/chart/candlestickMarkers\";\nexport type { PriceAlertOptions } from \"./core/chart/ChartAlerts\";\n\n// ============================================\n// Theme Editor\n// ============================================\nexport {\n ThemeEditor,\n createThemeEditor,\n getPresetTheme,\n getPresetNames,\n THEME_PRESETS,\n type EditorTheme,\n type ThemeEditorOptions,\n type ThemePreset,\n type ColorGroup,\n type ColorProperty,\n} from \"./core/theme-editor\";\n\n// ============================================\n// Streaming Backpressure\n// ============================================\nexport {\n BackpressureManager,\n CircularBuffer,\n createBackpressureManager,\n createRealtimeBackpressure,\n createLosslessBackpressure,\n type OverflowStrategy,\n type BackpressureConfig,\n type PressureStats,\n type BufferHealth,\n} from \"./streaming/backpressure\";\n\n// ============================================\n// Financial/Technical Indicators\n// ============================================\nexport {\n sma,\n ema,\n wma,\n dema,\n tema,\n rsi,\n macd,\n stochastic,\n roc,\n momentum,\n bollingerBands,\n atr,\n standardDeviation,\n vwap,\n obv,\n adx,\n aroon,\n percentChange,\n cumsum,\n normalize,\n type IndicatorResult,\n type OHLCData,\n} from \"./plugins/analysis\";\n\n// ============================================\n// Plugin System\n// ============================================\nexport {\n // Core functionality\n createPluginContext,\n PluginManagerImpl,\n\n // Registry\n getPluginRegistry,\n registerPlugin,\n definePlugin,\n defineAndRegister,\n loadPlugin,\n listPluginsByCategory,\n validateManifest,\n checkPluginCompatibility,\n\n // Helpers\n createPlugin,\n createConfigurablePlugin,\n\n // Built-in plugins\n CrosshairPlugin,\n StatsPlugin,\n WatermarkPlugin,\n GridHighlightPlugin,\n DataLoggerPlugin,\n DirectionIndicatorPlugin,\n Plugin3D,\n PluginGpu,\n PluginTools,\n PluginAnalysis,\n PluginAnnotations,\n PluginStreaming,\n PluginThemeEditor,\n PluginI18n,\n PluginKeyboard,\n PluginClipboard,\n PluginSync,\n PluginDebug,\n PluginLoading,\n PluginDataExport,\n PluginContextMenu,\n PluginAnomalyDetection,\n PluginMLIntegration,\n PluginPatternRecognition,\n PluginRegression,\n PluginRadar,\n PluginSnapshot,\n PluginDataTransform,\n PluginLaTeX,\n PluginDragEdit,\n PluginCaching,\n PluginLazyLoad,\n PluginBrokenAxis,\n PluginVideoRecorder,\n PluginOffscreen,\n PluginVirtualization,\n PluginDrawingTools,\n PluginReplay,\n PluginROI,\n PluginForecasting,\n BuiltinPlugins,\n} from \"./plugins\";\n\nexport type {\n // Manifest & Metadata\n PluginVersion,\n PluginCapability,\n PluginManifest,\n\n // Context Types\n PluginContext,\n RenderContext,\n CoordinateContext,\n DataContext,\n UIContext as PluginUIContext,\n EventContext as PluginEventContext,\n PluginStorage,\n PluginLogger,\n OverlayOptions,\n NotificationOptions,\n PickResult,\n\n // Hook Event Types\n BeforeRenderEvent,\n AfterRenderEvent,\n InteractionEvent,\n ViewChangeEvent,\n SeriesChangeEvent,\n DataUpdateEvent,\n\n // Plugin Types\n ChartPlugin,\n PluginFactory,\n TypedPlugin,\n PluginManager,\n PluginRegistry,\n PluginRegistryEntry,\n ContextDependencies,\n\n // Built-in plugin configs\n CrosshairPluginConfig,\n StatsPluginConfig,\n WatermarkPluginConfig,\n GridHighlightConfig,\n DataLoggerConfig,\n DirectionIndicatorConfig,\n Plugin3DConfig,\n PluginGpuConfig,\n PluginToolsConfig,\n PluginAnalysisConfig,\n PluginAnnotationsConfig,\n PluginStreamingConfig,\n PluginThemeEditorConfig,\n PluginI18nConfig,\n PluginKeyboardConfig,\n PluginClipboardConfig,\n PluginSyncConfig,\n PluginDebugConfig,\n PluginLoadingConfig,\n PluginDataExportConfig,\n PluginContextMenuConfig,\n PluginAnomalyDetectionConfig,\n PluginMLIntegrationConfig,\n PluginPatternRecognitionConfig,\n PluginRegressionConfig,\n PluginRadarConfig,\n PluginSnapshotConfig,\n PluginDataTransformConfig,\n PluginLaTeXConfig,\n PluginDragEditConfig,\n PluginCachingConfig,\n PluginLazyLoadConfig,\n PluginBrokenAxisConfig,\n PluginVideoRecorderConfig,\n PluginOffscreenConfig,\n PluginVirtualizationConfig,\n PluginROIConfig,\n PluginForecastingConfig,\n\n // API & Result Types\n RegressionAPI,\n RegressionResult,\n RegressionData,\n MLIntegrationAPI,\n MLModelAPI,\n PredictionResult,\n VisualizationConfig,\n DataTransformAPI,\n TransformOp,\n TransformType,\n RadarAPI,\n RadarSeriesData,\n RadarPoint,\n LaTeXPluginAPI,\n LaTeXDimensions,\n DragEditAPI,\n DragEditEvent,\n CachingAPI,\n CacheStats,\n LazyLoadAPI,\n DataProvider,\n OffscreenAPI,\n OffscreenStats,\n OffscreenMode,\n OffscreenTransferMode,\n OffscreenFallbackMode,\n VirtualizationAPI,\n VirtualizationStats,\n VirtualizationMode,\n VirtualizationStrategy,\n RoiAPI,\n RoiRegion,\n RoiPoint,\n RoiMaskResult,\n RoiTool,\n RoiEvent,\n RoiSelectedEvent,\n BrokenAxisAPI,\n AxisBreak,\n VideoRecorderAPI,\n VideoRecorderOptions,\n SnapshotExportAPI as SnapshotAPI,\n SnapshotExportOptions,\n SnapshotResolution,\n SnapshotFormat,\n AnomalyDetectionResult,\n AnomalyPoint,\n AnomalyMethod,\n PatternRecognitionAPI,\n PatternMatch,\n PatternDetectionResult,\n ForecastingAPI,\n ForecastingOptions,\n ForecastingResult,\n ForecastingParams\n} from \"./plugins\";\n\n"],"names":["interleaveBoxPlotData","x","min","q1","median","q3","max","width","n","w","lineData","boxData","lIdx","bIdx","i","xi","mi","q1i","medi","q3i","maxti","interleaveWaterfallData","y","isSubtotal","positiveData","negativeData","subtotalData","connectorData","pIdx","nIdx","sIdx","cIdx","runningTotal","yi","isSub","barBottom","barTop","nextX","interleaveBarData","barWidth","result","halfWidth","base","x0","x1","y0","y1","calculateBarWidth","minSpacing","spacing","interleaveHeatmapData","z","height","numCells","idx","j","v00","v10","v01","v11","getColormap","name","data","t","r","g","b","interleaveCandlestickData","open","high","low","close","hollow","bullishBody","bearishBody","halfWick","isBullish","target","bodyTop","bodyBottom","appendRect","arr","x2","y2","updateErrorAndStepBuffers","ctx","s","d","seriesId","seriesType","errData","interleaveErrorData","stepMode","interleaveStepData","updateBarBuffer","updateHeatmapBuffer","_b","_a","hData","hStyle","colormapName","_c","updateCandlestickBuffer","bullish","bearish","updateBoxplotBuffer","lines","boxes","updateWaterfallBuffer","wfData","updatePolarBuffer","polarData","style","angleMode","closePath","fillData","interleavePolarFillData","interleavePolarLineData","updateBandOrAreaBuffer","interleaveBandData","updateDefaultBuffer","interleaveData","registered","registerExtendedSeriesBuffers","registerSeriesBufferHandler","type","renderHeatmap","gl","prog","buffer","count","uniforms","zBounds","texture","renderBar","color","renderBoxPlot","programs","computeSeriesColor","fillColor","renderHeatmapSeries","seriesUniforms","renderBarSeries","renderBoxplotSeries","renderWaterfallSeries","dpr","positiveColor","parseColor","negativeColor","subtotalColor","connectorColor","registerExtendedFrameRenderers","registerFrameRenderer","drawGauge","plotArea","value","needleColor","needleWidth","ranges","radiusScale","startAngle","endAngle","showValue","valueColor","valueSize","label","centerX","centerY","maxRadius","totalAngle","valueRatio","currentAngle","range","rStart","rEnd","numTicks","angle","innerR","outerR","drawSankey","nodes","links","nodeWidth","nodePadding","palette","linkOpacity","showLabels","zoomFactor","effectiveWidth","effectiveHeight","offsetX","offsetY","workingArea","allNodeIds","l","nodeIds","nodeLevels","targets","id","changed","srcLevel","currentDstLevel","newDstLevel","maxLevel","layers","nodeInValue","nodeOutValue","getNodeValue","maxLayerTotal","layerNodes","layerTotal","nodeRegistry","numLayers","horizontalSpacing","nodeHeights","layerHeightSum","val","h","totalPadding","totalContentHeight","currentY","found","sourceOffsets","targetOffsets","link","src","dst","sOffset","tOffset","sValue","tValue","srcFlowHeight","dstFlowHeight","y3","cpOffset","gradient","node","grad","nodeName","isFirstLayer","isLastLayer","registerExtendedOverlayDrawers","registerOverlaySeriesDrawer","gData","gStyle","sData","sStyle","registerHeatmapProgram","bundle","createProgram","HEATMAP_VERT","HEATMAP_FRAG","registerWebGPURenderer","ChartImpl","chart","options","initWebGPURenderer","c","createGpuChartRenderer","gpu","NativeWebGLRenderer","registerExtendedSeries","escapeXml","text","primaryYScale","yAxes","primaryYAxisId","exportToSVG","series","_viewBounds","xAxis","theme","axisOptions","yScale","svg","drawSVGGrid","drawSeriesSVG","drawSVGAxes","drawSVGTickLabels","points","px","py","prevPx","prevPy","midX","p0","yTop","yHeight","bw","bullishColor","bearishColor","isBull","pyOpen","pyClose","pyHigh","pyLow","_xAxis","_yScale","axisY","snapLineCoord","axisX","xScale","xOpts","yOpts","xTickCount","yTickCount","domainSpan","xFont","yFont","tick","snapLabelCoord","formatXTickValue","formatYTickValue","patched","patchExportSVG","rect","ChartAlertManager","events","getSeries","__publicField","alert","prices","latest","prev","triggered","payload","STYLE_COLORS","STYLE_LABELS","buildPositionLineAnnotation","registerTradingSeriesPreprocessors","registerSeriesOptionsPreprocessor","opts","ha","computeHeikinAshi","isBusinessDayScaleActive","displayX","mapping","applyBusinessDayX","registerSeriesOptionsExpander","buildIndicatorSeries","registerSeriesDataPreprocessor","patchChartTradingMethods","proto","preset","addIndicatorToChart","getAlertManager","self","mode","plugin","originalDestroy","registerTradingBundle","WebGPURenderer","canvas","format","VERT_SRC","FRAG_SRC","compileShader","source","shader","vs","fs","program","buildGridLineVertices","spec","xLines","yLines","vertCount","out","o","WebGLGridSpike","buf","vertices","lineSegments","createMinimalMock2D","noop","getCanvas2DContext","makePlotArea","margin","tickPixelLines","_plotArea","measureFrames","runFrame","frames","samples","t0","avg","v","p95","benchmarkCanvasGrid","DARK_THEME","LinearScale","renderer","OverlayRenderer","benchmarkWebGLGrid","spike","compareGridBackends","canvas2d","webgl","gainPercent","getBaseline","baseline","compareScenarioToBaseline","scenarioId","failures","threshold","minAllowed","maxAllowed","evaluateRendererCompare","webgpu","webgpuActive","minRatio","ratio","meetsTarget","SeededRandom","seed","generateSineWave","dx","baseValue","noiseValue","generateSquareWave","generateSawtoothWave","generateTriangleWave","generateRandomData","rng","indices","_","a","sortedX","sortedY","generateCVData","totalPoints","pointsPerCycle","halfCycle","E","E0","scanDirection","peakWidth","exponent","peakCurrent","capacitive","generateNyquistData","logFMin","logFMax","logF","omega","tau","realPart","imagPart","benchmarkRender","fpsHistory","frameTimes","frameCount","sum","resolve","endTime","warmupEndTime","recording","recordingStartTime","frame","now","avgRenderMs","recordElapsedMs","wallFps","renderFps","renderStart","renderEnd","frameTime","recentTimes","avgRecentTime","createSnapshot","snapshot","compareSnapshots","tolerance","differences","sa","sb","boundsKeys","key","assertPerformance","requirements","waitForFrames","remaining","waitFor","ms","crosshairManifest","CrosshairPlugin","definePlugin","config","showVertical","showHorizontal","lineStyle","lineWidth","snapToData","valueFormat","valueDisplayMode","cornerPosition","cursorX","cursorY","overlayId","pluginCtx","overlay","resizeCanvas","event","nearest","render","size","lineColor","drawFloatingLabels","drawCornerLabels","bgColor","dataX","dataY","xText","xLabelWidth","xLabelHeight","xLabelX","xLabelY","yText","yLabelWidth","yLabelHeight","yLabelX","yLabelY","xMetrics","yMetrics","maxWidth","padding","lineHeight","boxWidth","boxHeight","boxX","boxY","statsManifest","StatsPlugin","position","show","autoUpdate","container","posStyle","updateStats","content","allSeries","targetSeries","allY","stats","computeStats","values","mean","sumSq","std","watermarkManifest","WatermarkPlugin","fontSize","fontFamily","rotation","ctx2d","gridHighlightManifest","GridHighlightPlugin","xIntervals","yIntervals","opacity","_event","interval","dataLoggerManifest","DataLoggerPlugin","logDataUpdates","logViewChanges","logInteractions","maxEntries","entries","addEntry","_ctx","saved","directionIndicatorManifest","DirectionIndicatorPlugin","sampleSize","minVelocity","historySize","idleTimeout","currentDirection","targetSeriesId","positionHistoryX","positionHistoryY","angleHistory","maxHistorySize","timeoutTimer","lastPointTimestamp","lastSeenX","lastSeenY","currentIdleTimeout","updateDirection","age","_pluginCtx","newConfig","canvasSize","lastX","lastY","startIdx","sumT","sumPX","sumPY","sumTPX","sumTPY","sumTT","pixelX","pixelY","meanT","meanPX","meanPY","denominator","slopePX","slopePY","rawAngle","lastPixelX","lastPixelY","smoothX","average","smoothY","smoothedAngle","smoothAngle","magnitude","angles","sumX","sumY","arrowColor","drawArrow","length","triangleHeight","triangleWidth","BuiltinPlugins","manifest","DEFAULT_CONFIG","PluginDragEdit","userConfig","isDragging","draggedPoint","dragStartX","dragStartY","hasMoved","findNearestPoint","mouseX","mouseY","picked","pixelToData","snapToGrid","applyConstraints","newX","newY","constraint","validateAndSnap","finalX","finalY","tempPoint","validation","updatePointData","index","createDragEvent","drawPreview","pCtx","coords","origPixelX","origPixelY","currPixelX","currPixelY","api","seriesIds","point","dy","dragEvent","valid","createPlugin","definition","createConfigurablePlugin","factory"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"velo-plot.full.js","sources":["../src/renderer/native/utilsExtended.ts","../src/renderer/HeatmapRenderer.ts","../src/renderer/CandlestickRenderer.ts","../src/renderer/seriesBufferExtended.ts","../src/renderer/native/drawExtended.ts","../src/renderer/native/frameRenderExtended.ts","../src/renderer/GaugeRenderer.ts","../src/renderer/SankeyRenderer.ts","../src/renderer/overlaySeriesExtended.ts","../src/renderer/native/programFactoryExtended.ts","../src/renderer/registerWebGPU.ts","../src/renderer/registerExtendedSeries.ts","../src/core/chart/exporter/SVGExporter.ts","../src/renderer/registerSVG.ts","../src/core/chart/chartExportPatch.ts","../src/core/chart/ChartAlerts.ts","../src/core/chart/positionLines.ts","../src/trading/registerTrading.ts","../src/renderer/WebGPURenderer.ts","../src/renderer/spike/WebGLGridSpike.ts","../src/testing/gridSpikeBenchmark.ts","../src/testing/stage1BrowserBench.ts","../src/testing/rendererBenchmark.ts","../src/testing/index.ts","../src/plugins/builtins/crosshair/CrosshairPlugin.ts","../src/plugins/builtins/stats/StatsPlugin.ts","../src/plugins/builtins/watermark/WatermarkPlugin.ts","../src/plugins/builtins/grid-highlight/GridHighlightPlugin.ts","../src/plugins/builtins/data-logger/DataLoggerPlugin.ts","../src/plugins/builtins/direction-indicator/DirectionIndicatorPlugin.ts","../src/plugins/builtins/index.ts","../src/plugins/drag-edit/index.ts","../src/plugins/index.ts","../src/index.ts"],"sourcesContent":["export function interleaveBoxPlotData(\n x: Float32Array | Float64Array | number[],\n min: Float32Array | Float64Array | number[],\n q1: Float32Array | Float64Array | number[],\n median: Float32Array | Float64Array | number[],\n q3: Float32Array | Float64Array | number[],\n max: Float32Array | Float64Array | number[],\n width: number\n): { lines: Float32Array; boxes: Float32Array } {\n const n = x.length;\n const w = width / 2;\n \n // Lines: 5 segments per box: 14 points per box if we use separate lines\n // Actually, let's use 10 points (5 lines x 2 points)\n const lineData = new Float32Array(n * 20);\n \n // Boxes: 1 rectangle (2 triangles) per box = 6 vertices * 2 floats = 12 floats per box\n const boxData = new Float32Array(n * 12);\n \n let lIdx = 0;\n let bIdx = 0;\n \n for (let i = 0; i < n; i++) {\n const xi = x[i];\n const mi = min[i];\n const q1i = q1[i];\n const medi = median[i];\n const q3i = q3[i];\n const maxti = max[i];\n \n // Lines\n // 1. Lower whisker\n lineData[lIdx++] = xi; lineData[lIdx++] = mi;\n lineData[lIdx++] = xi; lineData[lIdx++] = q1i;\n // 2. Upper whisker\n lineData[lIdx++] = xi; lineData[lIdx++] = q3i;\n lineData[lIdx++] = xi; lineData[lIdx++] = maxti;\n // 3. Median\n lineData[lIdx++] = xi - w; lineData[lIdx++] = medi;\n lineData[lIdx++] = xi + w; lineData[lIdx++] = medi;\n // 4. Q1 bottom cap\n lineData[lIdx++] = xi - w; lineData[lIdx++] = q1i;\n lineData[lIdx++] = xi + w; lineData[lIdx++] = q1i;\n // 5. Q3 top cap\n lineData[lIdx++] = xi - w; lineData[lIdx++] = q3i;\n lineData[lIdx++] = xi + w; lineData[lIdx++] = q3i;\n \n // Rectangle (Box)\n boxData[bIdx++] = xi - w; boxData[bIdx++] = q1i;\n boxData[bIdx++] = xi + w; boxData[bIdx++] = q1i;\n boxData[bIdx++] = xi + w; boxData[bIdx++] = q3i;\n boxData[bIdx++] = xi - w; boxData[bIdx++] = q1i;\n boxData[bIdx++] = xi + w; boxData[bIdx++] = q3i;\n boxData[bIdx++] = xi - w; boxData[bIdx++] = q3i;\n }\n \n return { lines: lineData, boxes: boxData };\n}\n\n/**\n * Interleave data for Waterfall charts\n * Creates rectangles that show cumulative changes from a running total\n */\nexport function interleaveWaterfallData(\n x: Float32Array | Float64Array | number[],\n y: Float32Array | Float64Array | number[],\n width: number,\n isSubtotal?: boolean[]\n): { \n positiveData: Float32Array; \n negativeData: Float32Array; \n subtotalData: Float32Array;\n connectorData: Float32Array;\n positiveCount: number;\n negativeCount: number;\n subtotalCount: number;\n} {\n const n = x.length;\n const w = width / 2;\n \n // Each bar is 2 triangles = 6 vertices\n const positiveData = new Float32Array(n * 12);\n const negativeData = new Float32Array(n * 12);\n const subtotalData = new Float32Array(n * 12);\n const connectorData = new Float32Array((n - 1) * 4); // Horizontal lines connecting bars\n \n let pIdx = 0, nIdx = 0, sIdx = 0, cIdx = 0;\n let runningTotal = 0;\n \n for (let i = 0; i < n; i++) {\n const xi = x[i];\n const yi = y[i];\n const isSub = isSubtotal?.[i] ?? false;\n \n let barBottom: number, barTop: number;\n \n if (isSub) {\n // Subtotal bar: from 0 to current running total\n barBottom = 0;\n barTop = runningTotal;\n \n // Draw subtotal bar\n subtotalData[sIdx++] = xi - w; subtotalData[sIdx++] = barBottom;\n subtotalData[sIdx++] = xi + w; subtotalData[sIdx++] = barBottom;\n subtotalData[sIdx++] = xi + w; subtotalData[sIdx++] = barTop;\n subtotalData[sIdx++] = xi - w; subtotalData[sIdx++] = barBottom;\n subtotalData[sIdx++] = xi + w; subtotalData[sIdx++] = barTop;\n subtotalData[sIdx++] = xi - w; subtotalData[sIdx++] = barTop;\n } else {\n // Regular bar: from running total to running total + value\n barBottom = runningTotal;\n barTop = runningTotal + yi;\n runningTotal = barTop;\n \n if (yi >= 0) {\n // Positive bar\n positiveData[pIdx++] = xi - w; positiveData[pIdx++] = barBottom;\n positiveData[pIdx++] = xi + w; positiveData[pIdx++] = barBottom;\n positiveData[pIdx++] = xi + w; positiveData[pIdx++] = barTop;\n positiveData[pIdx++] = xi - w; positiveData[pIdx++] = barBottom;\n positiveData[pIdx++] = xi + w; positiveData[pIdx++] = barTop;\n positiveData[pIdx++] = xi - w; positiveData[pIdx++] = barTop;\n } else {\n // Negative bar (barTop < barBottom)\n negativeData[nIdx++] = xi - w; negativeData[nIdx++] = barTop;\n negativeData[nIdx++] = xi + w; negativeData[nIdx++] = barTop;\n negativeData[nIdx++] = xi + w; negativeData[nIdx++] = barBottom;\n negativeData[nIdx++] = xi - w; negativeData[nIdx++] = barTop;\n negativeData[nIdx++] = xi + w; negativeData[nIdx++] = barBottom;\n negativeData[nIdx++] = xi - w; negativeData[nIdx++] = barBottom;\n }\n }\n \n // Connector line to next bar (if not last)\n if (i < n - 1) {\n const nextX = x[i + 1];\n connectorData[cIdx++] = xi + w;\n connectorData[cIdx++] = barTop;\n connectorData[cIdx++] = nextX - w;\n connectorData[cIdx++] = barTop;\n }\n }\n \n return {\n positiveData: positiveData.subarray(0, pIdx),\n negativeData: negativeData.subarray(0, nIdx),\n subtotalData: subtotalData.subarray(0, sIdx),\n connectorData: connectorData.subarray(0, cIdx),\n positiveCount: pIdx / 2,\n negativeCount: nIdx / 2,\n subtotalCount: sIdx / 2\n };\n}\n","/**\n * Prepare Heatmap data for WebGL rendering\n * Creates a mesh of triangles for the grid.\n * \n * @param x - X coordinates of grid columns\n * @param y - Y coordinates of grid rows\n * @param z - Z values (matrix flattened in row-major order: width=x.length, height=y.length)\n * @returns Interleaved data [x, y, value, ...] ready for gl.TRIANGLES\n */\nexport function interleaveHeatmapData(\n x: Float32Array | Float64Array | number[],\n y: Float32Array | Float64Array | number[],\n z: Float32Array | Float64Array | number[]\n): Float32Array {\n const width = x.length;\n const height = y.length;\n \n if (width * height > z.length) {\n console.warn(\"[Heatmap] Z array is too small for the specified grid dimensions\");\n }\n\n // Each cell is 2 triangles = 6 vertices\n // Each vertex has 3 floats: [x, y, value]\n const numCells = (width - 1) * (height - 1);\n const result = new Float32Array(numCells * 6 * 3);\n \n let idx = 0;\n for (let j = 0; j < height - 1; j++) {\n for (let i = 0; i < width - 1; i++) {\n // Corners\n const x0 = x[i];\n const x1 = x[i+1];\n const y0 = y[j];\n const y1 = y[j+1];\n \n const v00 = z[j * width + i];\n const v10 = z[j * width + (i + 1)];\n const v01 = z[(j + 1) * width + i];\n const v11 = z[(j + 1) * width + (i + 1)];\n \n // Triangle 1 (BL, BR, TL)\n result[idx++] = x0; result[idx++] = y0; result[idx++] = v00;\n result[idx++] = x1; result[idx++] = y0; result[idx++] = v10;\n result[idx++] = x0; result[idx++] = y1; result[idx++] = v01;\n \n // Triangle 2 (TL, BR, TR)\n result[idx++] = x0; result[idx++] = y1; result[idx++] = v01;\n result[idx++] = x1; result[idx++] = y0; result[idx++] = v10;\n result[idx++] = x1; result[idx++] = y1; result[idx++] = v11;\n }\n }\n \n return result;\n}\n\n/**\n * Generates a colormap texture data\n * Viridis approximation\n */\nexport function getColormap(name: string = 'viridis'): Uint8Array {\n const size = 256;\n const data = new Uint8Array(size * 4);\n \n for (let i = 0; i < size; i++) {\n const t = i / (size - 1);\n let r, g, b;\n \n if (name === 'jet') {\n r = Math.min(Math.max(1.5 - Math.abs(t * 4 - 3), 0), 1);\n g = Math.min(Math.max(1.5 - Math.abs(t * 4 - 2), 0), 1);\n b = Math.min(Math.max(1.5 - Math.abs(t * 4 - 1), 0), 1);\n } else if (name === 'grayscale') {\n r = g = b = t;\n } else if (name === 'plasma') {\n r = 0.5 + 0.5 * Math.sin(Math.PI * (t - 0.5));\n g = 0.5 + 0.5 * Math.sin(Math.PI * t);\n b = 0.8;\n } else { // default viridis approx\n r = 0.267 * (1 - t) + 0.993 * t;\n g = 0.005 * (1 - t) + 0.906 * t;\n b = 0.337 * (1 - t) + 0.144 * t;\n // More accurate viridis constants could be used\n }\n \n data[i * 4 + 0] = r * 255;\n data[i * 4 + 1] = g * 255;\n data[i * 4 + 2] = b * 255;\n data[i * 4 + 3] = 255;\n }\n \n return data;\n}\n","/**\n * Candlestick Renderer Utilities\n */\n\n/**\n * Interleave data for candlestick rendering\n * Each candle is represented by a body (box) and a wick (line/thin box)\n * Returns a Float32Array of interleaved [x, y] coordinates for TRIANGLES\n */\nexport function interleaveCandlestickData(\n x: Float32Array | Float64Array,\n open: Float32Array | Float64Array,\n high: Float32Array | Float64Array,\n low: Float32Array | Float64Array,\n close: Float32Array | Float64Array,\n width: number,\n hollow = false,\n): { bullish: Float32Array; bearish: Float32Array } {\n const n = x.length;\n const bullishBody: number[] = [];\n const bearishBody: number[] = [];\n \n const halfWidth = width / 2;\n const wickWidth = width / 10;\n const halfWick = wickWidth / 2;\n\n for (let i = 0; i < n; i++) {\n if (!Number.isFinite(x[i])) continue;\n const isBullish = close[i] >= open[i];\n const target = isBullish ? bullishBody : bearishBody;\n \n const bodyTop = Math.max(open[i], close[i]);\n const bodyBottom = Math.min(open[i], close[i]);\n \n // Body (skip filled body for hollow bullish candles)\n if (!(hollow && isBullish)) {\n appendRect(target, x[i] - halfWidth, bodyBottom, x[i] + halfWidth, bodyTop);\n }\n \n // Wick (Rectangle as 2 triangles, thin)\n appendRect(target, x[i] - halfWick, low[i], x[i] + halfWick, high[i]);\n }\n\n return {\n bullish: new Float32Array(bullishBody),\n bearish: new Float32Array(bearishBody)\n };\n}\n\nfunction appendRect(arr: number[], x1: number, y1: number, x2: number, y2: number) {\n // Triangle 1\n arr.push(x1, y1, x2, y1, x1, y2);\n // Triangle 2\n arr.push(x2, y1, x2, y2, x1, y2);\n}\n","/**\n * Extended series buffer handlers (bar, heatmap, candlestick, polar, boxplot, waterfall).\n */\nimport { Series } from \"../core/Series\";\nimport { interleaveBarData, calculateBarWidth } from \"./BarRenderer\";\nimport { interleaveHeatmapData, getColormap } from \"./HeatmapRenderer\";\nimport { interleaveCandlestickData } from \"./CandlestickRenderer\";\nimport {\n interleavePolarFillData,\n interleavePolarLineData,\n} from \"./PolarRenderer\";\nimport {\n interleaveBoxPlotData,\n interleaveWaterfallData,\n} from \"./native/utilsExtended\";\nimport {\n interleaveBandData,\n interleaveData,\n interleaveErrorData,\n interleaveStepData,\n} from \"./native/utilsCore\";\nimport { registerSeriesBufferHandler } from \"../core/chart/series/seriesTypeRegistry\";\n\nconst CORE_LITE_TYPES = new Set([\n \"line\",\n \"scatter\",\n \"line+scatter\",\n \"step\",\n \"step+scatter\",\n \"band\",\n \"area\",\n]);\n\nfunction updateErrorAndStepBuffers(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesId = s.getId();\n const seriesType = s.getType();\n\n if (s.hasErrorData()) {\n const errData = interleaveErrorData(\n d.x,\n d.y,\n {\n yError: d.yError,\n yErrorMinus: d.yErrorMinus,\n yErrorPlus: d.yErrorPlus,\n },\n {\n xError: d.xError,\n xErrorMinus: d.xErrorMinus,\n xErrorPlus: d.xErrorPlus,\n },\n );\n ctx.renderer.createBuffer(`${seriesId}_errors`, errData);\n }\n\n if (seriesType === \"step\" || seriesType === \"step+scatter\") {\n const stepMode = s.getStyle().stepMode ?? \"after\";\n ctx.renderer.createBuffer(\n `${seriesId}_step`,\n interleaveStepData(d.x, d.y, stepMode),\n );\n }\n}\n\nfunction updateBarBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const barWidth = (s.getStyle() as any).barWidth ?? calculateBarWidth(d.x);\n ctx.renderer.createBuffer(\n s.getId(),\n interleaveBarData(d.x, d.y, barWidth),\n );\n updateErrorAndStepBuffers(ctx, s);\n s.resetLastAppendCount();\n}\n\nfunction updateHeatmapBuffer(ctx: any, s: Series): void {\n const hData = s.getHeatmapData();\n const hStyle = s.getHeatmapStyle();\n if (!hData || hData.xValues.length < 2) return;\n // GPU-only setup: the SVG renderer draws heatmaps directly from\n // getHeatmapData(), so guard WebGL-specific calls so non-WebGL renderers\n // don't throw (e.g. renderer: 'svg').\n if (typeof ctx.renderer?.createColormapTexture !== \"function\") {\n s.resetLastAppendCount();\n return;\n }\n ctx.renderer.installHeatmapProgram?.();\n ctx.renderer.createBuffer(\n s.getId(),\n interleaveHeatmapData(hData.xValues, hData.yValues, hData.zValues),\n );\n const colormapName = hStyle?.colorScale?.name || \"viridis\";\n ctx.renderer.createColormapTexture(\n `${s.getId()}_colormap`,\n getColormap(colormapName),\n );\n s.resetLastAppendCount();\n}\n\nfunction updateCandlestickBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesId = s.getId();\n if (d.open && d.high && d.low && d.close) {\n const barWidth = (s.getStyle() as any).barWidth ?? calculateBarWidth(d.x);\n const hollow = Boolean((s.getStyle() as any).hollow);\n const { bullish, bearish } = interleaveCandlestickData(\n d.x,\n d.open,\n d.high,\n d.low,\n d.close,\n barWidth,\n hollow,\n );\n ctx.renderer.createBuffer(`${seriesId}_bullish`, bullish);\n ctx.renderer.createBuffer(`${seriesId}_bearish`, bearish);\n s.bullishCount = bullish.length / 2;\n s.bearishCount = bearish.length / 2;\n }\n s.resetLastAppendCount();\n}\n\nfunction updateBoxplotBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesId = s.getId();\n if (d.low && d.open && d.median && d.close && d.high) {\n const barWidth = (s.getStyle() as any).barWidth ?? calculateBarWidth(d.x);\n const { lines, boxes } = interleaveBoxPlotData(\n d.x,\n d.low,\n d.open,\n d.median,\n d.close,\n d.high,\n barWidth,\n );\n ctx.renderer.createBuffer(`${seriesId}_box_lines`, lines);\n ctx.renderer.createBuffer(`${seriesId}_box_faces`, boxes);\n }\n s.resetLastAppendCount();\n}\n\nfunction updateWaterfallBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesId = s.getId();\n const barWidth = (s.getStyle() as any).barWidth ?? calculateBarWidth(d.x);\n const isSubtotal = (s.getStyle() as any).isSubtotal;\n const wfData = interleaveWaterfallData(d.x, d.y, barWidth, isSubtotal);\n ctx.renderer.createBuffer(`${seriesId}_wf_positive`, wfData.positiveData);\n ctx.renderer.createBuffer(`${seriesId}_wf_negative`, wfData.negativeData);\n ctx.renderer.createBuffer(`${seriesId}_wf_subtotal`, wfData.subtotalData);\n ctx.renderer.createBuffer(`${seriesId}_wf_connectors`, wfData.connectorData);\n s.waterfallCounts = {\n positive: wfData.positiveCount,\n negative: wfData.negativeCount,\n subtotal: wfData.subtotalCount,\n connectors: wfData.connectorData.length / 2,\n };\n s.resetLastAppendCount();\n}\n\nfunction updatePolarBuffer(ctx: any, s: Series): void {\n const polarData = s.getPolarData();\n if (!polarData || polarData.r.length === 0) return;\n\n const style = s.getStyle() as any;\n const angleMode = style.angleMode || \"degrees\";\n const closePath = style.closePath !== false;\n const fill = style.fill || false;\n\n if (fill) {\n const fillData = interleavePolarFillData(polarData, angleMode, closePath);\n ctx.renderer.createBuffer(s.getId(), fillData);\n } else {\n const lineData = interleavePolarLineData(polarData, angleMode, closePath);\n ctx.renderer.createBuffer(s.getId(), lineData);\n }\n s.resetLastAppendCount();\n}\n\nfunction updateBandOrAreaBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n const seriesType = s.getType();\n const y2 =\n seriesType === \"area\"\n ? new Float32Array(d.x.length).fill(0)\n : d.y2 || new Float32Array(d.x.length).fill(0);\n ctx.renderer.createBuffer(s.getId(), interleaveBandData(d.x, d.y, y2));\n updateErrorAndStepBuffers(ctx, s);\n s.resetLastAppendCount();\n}\n\nfunction updateDefaultBuffer(ctx: any, s: Series): void {\n const d = s.getData();\n ctx.renderer.createBuffer(s.getId(), interleaveData(d.x, d.y));\n updateErrorAndStepBuffers(ctx, s);\n s.resetLastAppendCount();\n}\n\nlet registered = false;\n\n/** Register extended series buffer handlers (call from trading/scientific/full entries). */\nexport function registerExtendedSeriesBuffers(): void {\n if (registered) return;\n registered = true;\n\n registerSeriesBufferHandler(\"bar\", updateBarBuffer);\n registerSeriesBufferHandler(\"heatmap\", updateHeatmapBuffer);\n registerSeriesBufferHandler(\"candlestick\", updateCandlestickBuffer);\n registerSeriesBufferHandler(\"boxplot\", updateBoxplotBuffer);\n registerSeriesBufferHandler(\"waterfall\", updateWaterfallBuffer);\n registerSeriesBufferHandler(\"polar\", updatePolarBuffer);\n registerSeriesBufferHandler(\"band\", updateBandOrAreaBuffer);\n registerSeriesBufferHandler(\"area\", updateBandOrAreaBuffer);\n registerSeriesBufferHandler(\"heikin-ashi\", (ctx: any, s) => {\n const d = s.getData();\n if (!d?.x?.length) return;\n ctx.renderer.createBuffer(s.getId(), interleaveData(d.x, d.y));\n s.resetLastAppendCount();\n });\n\n for (const type of [\n \"line\",\n \"scatter\",\n \"line+scatter\",\n \"step\",\n \"step+scatter\",\n ]) {\n registerSeriesBufferHandler(type, updateDefaultBuffer);\n }\n}\n\nexport { CORE_LITE_TYPES };\n","import type { ShaderProgram } from \"./types\";\nimport { computeSeriesColor } from \"./drawCore\";\n\nexport function renderHeatmap(\n gl: WebGLRenderingContext,\n prog: ShaderProgram,\n buffer: WebGLBuffer,\n count: number,\n uniforms: { scale: [number, number]; translate: [number, number] },\n zBounds: { min: number; max: number } = { min: 0, max: 1 },\n texture?: WebGLTexture\n): void {\n gl.useProgram(prog.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n\n gl.enableVertexAttribArray(prog.attributes.position);\n gl.vertexAttribPointer(prog.attributes.position, 2, gl.FLOAT, false, 12, 0);\n\n if (prog.attributes.value !== undefined && prog.attributes.value !== -1) {\n gl.enableVertexAttribArray(prog.attributes.value);\n gl.vertexAttribPointer(prog.attributes.value, 1, gl.FLOAT, false, 12, 8);\n }\n\n gl.uniform2f(prog.uniforms.uScale, uniforms.scale[0], uniforms.scale[1]);\n gl.uniform2f(\n prog.uniforms.uTranslate,\n uniforms.translate[0],\n uniforms.translate[1]\n );\n\n if (prog.uniforms.uMinValue)\n gl.uniform1f(prog.uniforms.uMinValue, zBounds.min);\n if (prog.uniforms.uMaxValue)\n gl.uniform1f(prog.uniforms.uMaxValue, zBounds.max);\n\n if (texture && prog.uniforms.uColormap) {\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.uniform1i(prog.uniforms.uColormap, 0);\n } else if (prog.uniforms.uColormap) {\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n\n gl.drawArrays(gl.TRIANGLES, 0, count);\n\n gl.disableVertexAttribArray(prog.attributes.position);\n if (prog.attributes.value !== undefined && prog.attributes.value !== -1) {\n gl.disableVertexAttribArray(prog.attributes.value);\n }\n}\n\nexport function renderBar(\n gl: WebGLRenderingContext,\n prog: ShaderProgram,\n buffer: WebGLBuffer,\n count: number,\n uniforms: { scale: [number, number]; translate: [number, number] },\n color: [number, number, number, number]\n): void {\n gl.useProgram(prog.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(prog.attributes.position);\n gl.vertexAttribPointer(prog.attributes.position, 2, gl.FLOAT, false, 0, 0);\n\n gl.uniform2f(prog.uniforms.uScale, uniforms.scale[0], uniforms.scale[1]);\n gl.uniform2f(\n prog.uniforms.uTranslate,\n uniforms.translate[0],\n uniforms.translate[1]\n );\n gl.uniform4f(prog.uniforms.uColor!, color[0], color[1], color[2], color[3]);\n\n gl.drawArrays(gl.TRIANGLES, 0, count);\n gl.disableVertexAttribArray(prog.attributes.position);\n}\n\nexport function renderBoxPlot(\n gl: WebGLRenderingContext,\n programs: { line: ShaderProgram; point: ShaderProgram },\n data: {\n boxBuffer: WebGLBuffer;\n boxCount: number;\n linesBuffer: WebGLBuffer;\n linesCount: number;\n },\n uniforms: { scale: [number, number]; translate: [number, number] },\n style: { color?: string; opacity?: number; width?: number }\n): void {\n const color = computeSeriesColor(style);\n\n gl.useProgram(programs.line.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, data.boxBuffer);\n gl.enableVertexAttribArray(programs.line.attributes.position);\n gl.vertexAttribPointer(programs.line.attributes.position, 2, gl.FLOAT, false, 0, 0);\n\n gl.uniform2f(programs.line.uniforms.uScale, uniforms.scale[0], uniforms.scale[1]);\n gl.uniform2f(\n programs.line.uniforms.uTranslate,\n uniforms.translate[0],\n uniforms.translate[1]\n );\n\n const fillColor = [...color] as [number, number, number, number];\n fillColor[3] *= 0.5;\n gl.uniform4f(programs.line.uniforms.uColor!, fillColor[0], fillColor[1], fillColor[2], fillColor[3]);\n\n gl.drawArrays(gl.TRIANGLES, 0, data.boxCount);\n\n gl.uniform4f(programs.line.uniforms.uColor!, color[0], color[1], color[2], color[3]);\n gl.lineWidth(style.width || 1);\n gl.bindBuffer(gl.ARRAY_BUFFER, data.linesBuffer);\n gl.vertexAttribPointer(programs.line.attributes.position, 2, gl.FLOAT, false, 0, 0);\n\n gl.drawArrays(gl.LINES, 0, data.linesCount);\n\n gl.disableVertexAttribArray(programs.line.attributes.position);\n}\n","import { parseColor } from \"./utilsCore\";\nimport { renderBar, renderBoxPlot, renderHeatmap } from \"./drawExtended\";\nimport { registerFrameRenderer } from \"./frameRenderRegistry\";\nimport type { FrameRenderContext } from \"./frameRenderRegistry\";\nimport type { NativeSeriesRenderData } from \"./types\";\n\nfunction renderHeatmapSeries(\n ctx: FrameRenderContext,\n s: NativeSeriesRenderData,\n seriesUniforms: { scale: [number, number]; translate: [number, number] },\n): void {\n renderHeatmap(\n ctx.gl,\n ctx.programs.heatmapProgram,\n s.buffer,\n s.count,\n seriesUniforms,\n s.zBounds,\n s.colormapTexture,\n );\n}\n\nfunction renderBarSeries(\n ctx: FrameRenderContext,\n s: NativeSeriesRenderData,\n seriesUniforms: { scale: [number, number]; translate: [number, number] },\n color: [number, number, number, number],\n): void {\n renderBar(\n ctx.gl,\n ctx.programs.lineProgram,\n s.buffer,\n s.count,\n seriesUniforms,\n color,\n );\n}\n\nfunction renderBoxplotSeries(\n ctx: FrameRenderContext,\n s: NativeSeriesRenderData,\n seriesUniforms: { scale: [number, number]; translate: [number, number] },\n): void {\n if (s.boxBuffer && s.boxLinesBuffer) {\n renderBoxPlot(\n ctx.gl,\n { line: ctx.programs.lineProgram, point: ctx.programs.pointProgram },\n {\n boxBuffer: s.boxBuffer,\n boxCount: s.boxCount || 0,\n linesBuffer: s.boxLinesBuffer,\n linesCount: s.boxLinesCount || 0,\n },\n seriesUniforms,\n s.style,\n );\n }\n}\n\nfunction renderWaterfallSeries(\n ctx: FrameRenderContext,\n s: NativeSeriesRenderData,\n seriesUniforms: { scale: [number, number]; translate: [number, number] },\n): void {\n const { gl, programs, dpr } = ctx;\n const positiveColor = parseColor(s.style.positiveColor || \"#22c55e\");\n const negativeColor = parseColor(s.style.negativeColor || \"#ef4444\");\n const subtotalColor = parseColor(s.style.subtotalColor || \"#3b82f6\");\n const connectorColor = parseColor(s.style.connectorColor || \"#64748b\");\n\n if (s.wfPositiveBuffer && s.wfPositiveCount && s.wfPositiveCount > 0) {\n gl.useProgram(programs.lineProgram.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, s.wfPositiveBuffer);\n gl.enableVertexAttribArray(programs.lineProgram.attributes.position);\n gl.vertexAttribPointer(\n programs.lineProgram.attributes.position,\n 2,\n gl.FLOAT,\n false,\n 0,\n 0,\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uScale,\n seriesUniforms.scale[0],\n seriesUniforms.scale[1],\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uTranslate,\n seriesUniforms.translate[0],\n seriesUniforms.translate[1],\n );\n gl.uniform4f(\n programs.lineProgram.uniforms.uColor!,\n positiveColor[0],\n positiveColor[1],\n positiveColor[2],\n 0.9,\n );\n gl.drawArrays(gl.TRIANGLES, 0, s.wfPositiveCount);\n }\n\n if (s.wfNegativeBuffer && s.wfNegativeCount && s.wfNegativeCount > 0) {\n gl.useProgram(programs.lineProgram.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, s.wfNegativeBuffer);\n gl.enableVertexAttribArray(programs.lineProgram.attributes.position);\n gl.vertexAttribPointer(\n programs.lineProgram.attributes.position,\n 2,\n gl.FLOAT,\n false,\n 0,\n 0,\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uScale,\n seriesUniforms.scale[0],\n seriesUniforms.scale[1],\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uTranslate,\n seriesUniforms.translate[0],\n seriesUniforms.translate[1],\n );\n gl.uniform4f(\n programs.lineProgram.uniforms.uColor!,\n negativeColor[0],\n negativeColor[1],\n negativeColor[2],\n 0.9,\n );\n gl.drawArrays(gl.TRIANGLES, 0, s.wfNegativeCount);\n }\n\n if (s.wfSubtotalBuffer && s.wfSubtotalCount && s.wfSubtotalCount > 0) {\n gl.useProgram(programs.lineProgram.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, s.wfSubtotalBuffer);\n gl.enableVertexAttribArray(programs.lineProgram.attributes.position);\n gl.vertexAttribPointer(\n programs.lineProgram.attributes.position,\n 2,\n gl.FLOAT,\n false,\n 0,\n 0,\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uScale,\n seriesUniforms.scale[0],\n seriesUniforms.scale[1],\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uTranslate,\n seriesUniforms.translate[0],\n seriesUniforms.translate[1],\n );\n gl.uniform4f(\n programs.lineProgram.uniforms.uColor!,\n subtotalColor[0],\n subtotalColor[1],\n subtotalColor[2],\n 0.9,\n );\n gl.drawArrays(gl.TRIANGLES, 0, s.wfSubtotalCount);\n }\n\n if (\n s.style.showConnectors !== false &&\n s.wfConnectorBuffer &&\n s.wfConnectorCount &&\n s.wfConnectorCount > 0\n ) {\n gl.useProgram(programs.lineProgram.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, s.wfConnectorBuffer);\n gl.enableVertexAttribArray(programs.lineProgram.attributes.position);\n gl.vertexAttribPointer(\n programs.lineProgram.attributes.position,\n 2,\n gl.FLOAT,\n false,\n 0,\n 0,\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uScale,\n seriesUniforms.scale[0],\n seriesUniforms.scale[1],\n );\n gl.uniform2f(\n programs.lineProgram.uniforms.uTranslate,\n seriesUniforms.translate[0],\n seriesUniforms.translate[1],\n );\n gl.uniform4f(\n programs.lineProgram.uniforms.uColor!,\n connectorColor[0],\n connectorColor[1],\n connectorColor[2],\n 0.6,\n );\n gl.lineWidth(1);\n gl.drawArrays(gl.LINES, 0, s.wfConnectorCount);\n }\n\n gl.disableVertexAttribArray(programs.lineProgram.attributes.position);\n void dpr;\n}\n\nlet registered = false;\n\nexport function registerExtendedFrameRenderers(): void {\n if (registered) return;\n registered = true;\n\n registerFrameRenderer(\"heatmap\", (ctx, s, uniforms) =>\n renderHeatmapSeries(ctx, s, uniforms),\n );\n registerFrameRenderer(\"bar\", (ctx, s, uniforms, color) =>\n renderBarSeries(ctx, s, uniforms, color),\n );\n registerFrameRenderer(\"boxplot\", (ctx, s, uniforms) =>\n renderBoxplotSeries(ctx, s, uniforms),\n );\n registerFrameRenderer(\"waterfall\", (ctx, s, uniforms) =>\n renderWaterfallSeries(ctx, s, uniforms),\n );\n}\n","/**\n * Gauge Chart Renderer\n * \n * Renders a dial/gauge with ranges and a needle.\n * Uses Canvas 2D for high-quality decorative elements.\n */\n\nimport type { GaugeData, GaugeStyle, PlotArea } from \"../types\";\n\nexport function drawGauge(\n ctx: CanvasRenderingContext2D,\n data: GaugeData,\n style: GaugeStyle,\n plotArea: PlotArea\n): void {\n const { value, min, max } = data;\n const {\n needleColor = \"#333\",\n needleWidth = 3,\n ranges = [],\n radius: radiusScale = 0.8,\n startAngle = 135,\n endAngle = 405,\n showValue = true,\n valueColor = \"#fff\",\n valueSize = 24,\n label\n } = style;\n\n const centerX = plotArea.x + plotArea.width / 2;\n const centerY = plotArea.y + plotArea.height / 2;\n const maxRadius = (Math.min(plotArea.width, plotArea.height) / 2) * radiusScale;\n\n const totalAngle = endAngle - startAngle;\n const valueRatio = Math.max(0, Math.min(1, (value - min) / (max - min)));\n const currentAngle = (startAngle + valueRatio * totalAngle) * (Math.PI / 180);\n\n ctx.save();\n \n // Draw background arc\n ctx.beginPath();\n ctx.arc(centerX, centerY, maxRadius, startAngle * (Math.PI / 180), endAngle * (Math.PI / 180));\n ctx.strokeStyle = \"rgba(255, 255, 255, 0.1)\";\n ctx.lineWidth = maxRadius * 0.2;\n ctx.lineCap = \"round\";\n ctx.stroke();\n\n // Draw defined ranges\n for (const range of ranges) {\n const rStart = Math.max(0, Math.min(1, (range.from - min) / (max - min)));\n const rEnd = Math.max(0, Math.min(1, (range.to - min) / (max - min)));\n \n ctx.beginPath();\n ctx.arc(\n centerX, \n centerY, \n maxRadius, \n (startAngle + rStart * totalAngle) * (Math.PI / 180), \n (startAngle + rEnd * totalAngle) * (Math.PI / 180)\n );\n ctx.strokeStyle = range.color;\n ctx.lineWidth = maxRadius * 0.2;\n ctx.stroke();\n }\n\n // Draw Ticks\n const numTicks = 11;\n for (let i = 0; i < numTicks; i++) {\n const angle = (startAngle + (i / (numTicks - 1)) * totalAngle) * (Math.PI / 180);\n const innerR = maxRadius * 0.85;\n const outerR = maxRadius * 0.95;\n \n ctx.beginPath();\n ctx.moveTo(centerX + innerR * Math.cos(angle), centerY + innerR * Math.sin(angle));\n ctx.lineTo(centerX + outerR * Math.cos(angle), centerY + outerR * Math.sin(angle));\n ctx.strokeStyle = \"rgba(255, 255, 255, 0.5)\";\n ctx.lineWidth = 2;\n ctx.stroke();\n }\n\n // Draw Needle\n ctx.beginPath();\n ctx.moveTo(centerX, centerY);\n ctx.lineTo(centerX + maxRadius * 0.9 * Math.cos(currentAngle), centerY + maxRadius * 0.9 * Math.sin(currentAngle));\n ctx.strokeStyle = needleColor;\n ctx.lineWidth = needleWidth;\n ctx.lineCap = \"round\";\n \n // Needle shadow/glow\n ctx.shadowColor = needleColor;\n ctx.shadowBlur = 10;\n ctx.stroke();\n ctx.shadowBlur = 0;\n\n // Center hub\n ctx.beginPath();\n ctx.arc(centerX, centerY, 8, 0, Math.PI * 2);\n ctx.fillStyle = needleColor;\n ctx.fill();\n ctx.strokeStyle = \"#fff\";\n ctx.lineWidth = 2;\n ctx.stroke();\n\n // Value text\n if (showValue) {\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.font = `bold ${valueSize}px Inter, sans-serif`;\n ctx.fillStyle = valueColor;\n ctx.fillText(value.toFixed(1), centerX, centerY + maxRadius * 0.4);\n \n if (label) {\n ctx.font = `${valueSize * 0.5}px Inter, sans-serif`;\n ctx.fillStyle = \"rgba(255, 255, 255, 0.6)\";\n ctx.fillText(label, centerX, centerY + maxRadius * 0.6);\n }\n }\n\n ctx.restore();\n}\n","import type { SankeyData, SankeyStyle, PlotArea, SankeyNode } from \"../types\";\nimport { computeSankeyLayout } from \"./sankeyLayout\";\n\nexport function drawSankey(\n ctx: CanvasRenderingContext2D,\n data: SankeyData,\n style: SankeyStyle,\n plotArea: PlotArea,\n): void {\n const layout = computeSankeyLayout(data, style, plotArea);\n if (!layout) return;\n\n const { nodeRegistry, links, nodeOutValue, nodeInValue, workingArea } = layout;\n const { linkOpacity, showLabels, nodeWidth } = layout.style;\n\n ctx.save();\n\n links.forEach((entry) => {\n const src = entry.source;\n const dst = entry.target;\n const sOffset = entry.sourceOffset;\n const tOffset = entry.targetOffset;\n\n const sValue = nodeOutValue.get(entry.link.source) || 1;\n const tValue = nodeInValue.get(entry.link.target) || 1;\n\n const srcFlowHeight = (entry.link.value / sValue) * src.height;\n const dstFlowHeight = (entry.link.value / tValue) * dst.height;\n\n const x0 = src.x + src.width;\n const y0 = src.y + sOffset;\n const y1 = y0 + srcFlowHeight;\n\n const x2 = dst.x;\n const y2 = dst.y + tOffset;\n const y3 = y2 + dstFlowHeight;\n\n const cpOffset = (x2 - x0) * 0.5;\n\n const gradient = ctx.createLinearGradient(x0, (y0 + y1) / 2, x2, (y2 + y3) / 2);\n gradient.addColorStop(0, src.color);\n gradient.addColorStop(1, dst.color);\n\n ctx.beginPath();\n ctx.moveTo(x0, y0);\n ctx.bezierCurveTo(x0 + cpOffset, y0, x2 - cpOffset, y2, x2, y2);\n ctx.lineTo(x2, y3);\n ctx.bezierCurveTo(x2 - cpOffset, y3, x0 + cpOffset, y1, x0, y1);\n ctx.closePath();\n\n ctx.fillStyle = gradient;\n ctx.globalAlpha = linkOpacity;\n ctx.fill();\n\n ctx.strokeStyle = src.color;\n ctx.globalAlpha = linkOpacity * 0.3;\n ctx.lineWidth = 0.5;\n ctx.stroke();\n });\n\n ctx.restore();\n\n ctx.save();\n ctx.globalAlpha = 1.0;\n\n nodeRegistry.forEach((node) => {\n ctx.fillStyle = node.color;\n ctx.fillRect(node.x, node.y, node.width, node.height);\n\n const grad = ctx.createLinearGradient(node.x, node.y, node.x + node.width, node.y);\n grad.addColorStop(0, \"rgba(255, 255, 255, 0.15)\");\n grad.addColorStop(1, \"rgba(0, 0, 0, 0.15)\");\n ctx.fillStyle = grad;\n ctx.fillRect(node.x, node.y, node.width, node.height);\n });\n\n ctx.restore();\n\n if (showLabels) {\n ctx.save();\n ctx.font = \"bold 11px Inter, -apple-system, sans-serif\";\n ctx.textBaseline = \"middle\";\n\n nodeRegistry.forEach((node, id) => {\n let nodeName = String(id);\n const found = (data.nodes as SankeyNode[]).find((n) => n.id === id);\n if (found?.name) nodeName = found.name;\n\n const isFirstLayer = node.x <= workingArea.x + 5;\n const isLastLayer = node.x >= workingArea.x + workingArea.width - nodeWidth - 5;\n\n ctx.shadowBlur = 3;\n ctx.shadowColor = \"rgba(0, 0, 0, 0.7)\";\n ctx.fillStyle = \"#ffffff\";\n\n if (isFirstLayer) {\n ctx.textAlign = \"right\";\n ctx.fillText(nodeName, node.x - 10, node.y + node.height / 2);\n } else if (isLastLayer) {\n ctx.textAlign = \"left\";\n ctx.fillText(nodeName, node.x + node.width + 10, node.y + node.height / 2);\n } else {\n ctx.textAlign = \"center\";\n ctx.fillText(nodeName, node.x + node.width / 2, node.y - 10);\n }\n });\n\n ctx.restore();\n }\n}\n\nexport { computeSankeyLayout } from \"./sankeyLayout\";\n","import { drawGauge } from \"./GaugeRenderer\";\nimport { drawSankey } from \"./SankeyRenderer\";\nimport { registerOverlaySeriesDrawer } from \"../core/chart/overlaySeriesRegistry\";\n\nlet registered = false;\n\nexport function registerExtendedOverlayDrawers(): void {\n if (registered) return;\n registered = true;\n\n registerOverlaySeriesDrawer(\"gauge\", (ctx, s, plotArea) => {\n const gData = s.getGaugeData();\n const gStyle = s.getGaugeStyle();\n if (gData && gStyle) drawGauge(ctx, gData, gStyle, plotArea);\n });\n\n registerOverlaySeriesDrawer(\"sankey\", (ctx, s, plotArea) => {\n const sData = s.getSankeyData();\n const sStyle = s.getSankeyStyle();\n if (sData && sStyle) drawSankey(ctx, sData, sStyle, plotArea);\n });\n}\n","import type { ProgramBundle } from \"./types\";\nimport { HEATMAP_FRAG, HEATMAP_VERT } from \"./shaderSources\";\nimport { createProgram } from \"./programFactoryCore\";\n\n/** Compile the heatmap shader program (scientific/trading/full bundles). */\nexport function registerHeatmapProgram(\n gl: WebGLRenderingContext,\n bundle: ProgramBundle,\n): void {\n bundle.heatmapProgram = createProgram(gl, HEATMAP_VERT, HEATMAP_FRAG, \"heatmap\");\n}\n","import { ChartImpl } from \"../core/chart/ChartCore\";\nimport { NativeWebGLRenderer } from \"./NativeWebGLRenderer\";\n\nlet registered = false;\n\n/** Enable `renderer: 'webgpu'` for charts (extended bundles only). */\nexport function registerWebGPURenderer(): void {\n if (registered) return;\n registered = true;\n\n ChartImpl.afterConstruct = (chart, options) => {\n if (options.renderer !== \"webgpu\") return;\n (chart as { _webgpuInitPromise?: Promise<void> })._webgpuInitPromise =\n initWebGPURenderer(chart);\n };\n}\n\nasync function initWebGPURenderer(chart: ChartImpl): Promise<void> {\n const c = chart as any;\n const { createGpuChartRenderer } = await import(\"./GpuChartRenderer\");\n const gpu = await createGpuChartRenderer(c.webglCanvas, {\n backend: \"webgpu\",\n powerPreference: \"high-performance\",\n });\n\n if (gpu) {\n c.renderer = gpu;\n c.activeRendererType = gpu.backend;\n c.renderer.setDPR(c.dpr);\n c.renderLoop?.setRenderer(c.renderer);\n return;\n }\n\n console.warn(\n \"[VeloPlot] WebGPU unavailable — falling back to WebGL2. \" +\n \"See docs/adr/001-webgpu-renderer-strategy.md.\",\n );\n c.renderer = new NativeWebGLRenderer(c.webglCanvas);\n c.activeRendererType = \"webgl\";\n c.renderer.setDPR(c.dpr);\n c.renderLoop?.setRenderer(c.renderer);\n}\n","/**\n * Registers extended series buffers and frame renderers for trading/scientific/full bundles.\n */\nimport { registerExtendedSeriesBuffers } from \"./seriesBufferExtended\";\nimport { registerExtendedFrameRenderers } from \"./native/frameRenderExtended\";\nimport { registerExtendedOverlayDrawers } from \"./overlaySeriesExtended\";\nimport { registerHeatmapProgram } from \"./native/programFactoryExtended\";\nimport { NativeWebGLRenderer } from \"./NativeWebGLRenderer\";\nimport { registerWebGPURenderer } from \"./registerWebGPU\";\n\nlet registered = false;\n\nexport function registerExtendedSeries(): void {\n if (registered) return;\n registered = true;\n NativeWebGLRenderer.heatmapProgramInstaller = registerHeatmapProgram;\n registerWebGPURenderer();\n registerExtendedSeriesBuffers();\n registerExtendedFrameRenderers();\n registerExtendedOverlayDrawers();\n}\n","/**\n * SVG Export — public facade delegating to modular v2 pipeline.\n */\nimport type { Series } from \"../../Series\";\nimport type { Bounds, PlotArea } from \"../../../types\";\nimport type { Scale } from \"../../../scales\";\nimport type { ChartTheme } from \"../../../theme\";\nimport {\n buildSVGExportContext,\n type SVGExportOptions,\n type SVGExportInput,\n captureLayoutSnapshot,\n} from \"./svg/SVGExportContext\";\nimport { renderSVG } from \"./svg/SVGOrchestrator\";\n\nexport type { SVGExportOptions } from \"./svg/SVGExportContext\";\nexport { captureLayoutSnapshot, buildSVGExportContext } from \"./svg/SVGExportContext\";\nexport { renderSVG } from \"./svg/SVGOrchestrator\";\n\n/** @deprecated Use buildSVGExportContext + renderSVG */\nexport function exportToSVG(\n series: Series[],\n viewBounds: Bounds,\n plotArea: PlotArea,\n xAxis: Scale,\n yAxes: Map<string, Scale>,\n theme: ChartTheme,\n width: number,\n height: number,\n axisOptions: SVGExportOptions = {},\n): string {\n const ctx = buildSVGExportContext({\n series,\n viewBounds,\n plotArea,\n xScale: xAxis,\n yAxes,\n theme,\n width,\n height,\n options: axisOptions,\n xAxisOptions: axisOptions.xAxis,\n yAxisOptionsMap: new Map(\n axisOptions.primaryYAxisId\n ? [[axisOptions.primaryYAxisId, axisOptions.yAxis ?? {}]]\n : [[\"default\", axisOptions.yAxis ?? {}]],\n ),\n primaryYAxisId: axisOptions.primaryYAxisId,\n });\n return renderSVG(ctx);\n}\n\nexport function exportChartToSVG(input: SVGExportInput): string {\n return renderSVG(buildSVGExportContext(input));\n}\n\nexport function exportChartSnapshot(\n chart: Parameters<typeof captureLayoutSnapshot>[0],\n options?: SVGExportOptions,\n): string {\n return renderSVG(captureLayoutSnapshot(chart, options));\n}\n","import { ChartImpl } from \"../core/chart/ChartCore\";\n\nlet registered = false;\n\n/**\n * Enable `renderer: 'svg'` — live vector chart (same API as canvas/WebGL, no 3D).\n * Requires extended bundle (trading / scientific / full) with SVG export patched.\n */\nexport function registerSVGRenderer(): void {\n if (registered) return;\n registered = true;\n\n const prev = ChartImpl.afterConstruct;\n ChartImpl.afterConstruct = (chart, options) => {\n prev?.(chart, options);\n if (options.renderer !== \"svg\") return;\n initSVGRenderer(chart);\n };\n}\n\nfunction initSVGRenderer(chart: ChartImpl): void {\n const host = chart as unknown as {\n svgRoot?: SVGSVGElement | null;\n webglCanvas?: HTMLCanvasElement;\n overlayCanvas?: HTMLCanvasElement;\n };\n\n if (!host.svgRoot) return;\n\n host.webglCanvas!.style.display = \"none\";\n if (host.overlayCanvas) {\n host.overlayCanvas.style.display = \"block\";\n host.overlayCanvas.style.pointerEvents = \"none\";\n host.overlayCanvas.style.zIndex = \"2\";\n }\n host.svgRoot.style.display = \"block\";\n host.svgRoot.style.zIndex = \"1\";\n}\n","import { ChartImpl } from \"./ChartCore\";\nimport { exportChartSnapshot, type SVGExportOptions } from \"./exporter/SVGExporter\";\nimport { registerSVGRenderer } from \"../../renderer/registerSVG\";\n\nlet patched = false;\n\n/** Restore sync SVG export on Chart (trading/scientific/full bundles). */\nexport function patchExportSVG(): void {\n if (patched) return;\n patched = true;\n\n registerSVGRenderer();\n\n ChartImpl.prototype.exportSVG = function (options?: SVGExportOptions): string {\n return exportChartSnapshot(this as unknown as Parameters<typeof exportChartSnapshot>[0], options);\n };\n}\n","/**\n * Price alert registry (Stage 2.18).\n */\n\nimport type { EventEmitter } from \"../EventEmitter\";\nimport type { ChartEventMap } from \"../../types\";\n\nexport type AlertDirection = \"above\" | \"below\" | \"cross\";\n\nexport interface PriceAlertOptions {\n id?: string;\n price: number;\n direction: AlertDirection;\n seriesId?: string;\n /** Fire once then remove (default true) */\n once?: boolean;\n}\n\nexport interface AlertEvent {\n id: string;\n price: number;\n direction: AlertDirection;\n seriesId?: string;\n triggeredAt: number;\n triggerPrice: number;\n}\n\nexport interface AlertableSeries {\n getId(): string;\n getData(): { x: Float32Array | Float64Array; y?: Float32Array | Float64Array; close?: Float32Array | Float64Array };\n}\n\nexport class ChartAlertManager {\n private alerts = new Map<string, PriceAlertOptions & { id: string }>();\n private idCounter = 0;\n\n constructor(\n private events: EventEmitter<ChartEventMap>,\n private getSeries: (id?: string) => AlertableSeries | undefined,\n ) {}\n\n addAlert(options: PriceAlertOptions): string {\n const id = options.id ?? `alert_${++this.idCounter}`;\n this.alerts.set(id, { ...options, id });\n return id;\n }\n\n removeAlert(id: string): boolean {\n return this.alerts.delete(id);\n }\n\n clearAlerts(): void {\n this.alerts.clear();\n }\n\n getAlerts(): PriceAlertOptions[] {\n return Array.from(this.alerts.values());\n }\n\n /** Call after data updates / render tick. */\n evaluate(): void {\n for (const [id, alert] of [...this.alerts.entries()]) {\n const series = this.getSeries(alert.seriesId);\n if (!series) continue;\n\n const data = series.getData();\n const prices = data.close ?? data.y;\n if (!prices?.length) continue;\n\n const latest = prices[prices.length - 1];\n if (!Number.isFinite(latest)) continue;\n\n const prev = prices.length > 1 ? prices[prices.length - 2] : latest;\n let triggered = false;\n\n switch (alert.direction) {\n case \"above\":\n triggered = latest >= alert.price;\n break;\n case \"below\":\n triggered = latest <= alert.price;\n break;\n case \"cross\":\n triggered =\n (prev < alert.price && latest >= alert.price) ||\n (prev > alert.price && latest <= alert.price);\n break;\n }\n\n if (!triggered) continue;\n\n const payload: AlertEvent = {\n id,\n price: alert.price,\n direction: alert.direction,\n seriesId: alert.seriesId ?? series.getId(),\n triggeredAt: Date.now(),\n triggerPrice: latest,\n };\n\n this.events.emit(\"alert\", payload);\n\n if (alert.once !== false) {\n this.alerts.delete(id);\n }\n }\n }\n\n destroy(): void {\n this.alerts.clear();\n }\n}\n","/**\n * Position lines — entry, stop-loss, take-profit (Stage 2.15).\n */\n\nimport type { Annotation } from \"../annotations/types\";\n\nexport type PositionLineStyle = \"entry\" | \"sl\" | \"tp\";\n\nexport interface PositionLineOptions {\n id?: string;\n price: number;\n label?: string;\n color?: string;\n style?: PositionLineStyle;\n interactive?: boolean;\n}\n\nconst STYLE_COLORS: Record<PositionLineStyle, string> = {\n entry: \"#38bdf8\",\n sl: \"#ef4444\",\n tp: \"#22c55e\",\n};\n\nconst STYLE_LABELS: Record<PositionLineStyle, string> = {\n entry: \"Entry\",\n sl: \"SL\",\n tp: \"TP\",\n};\n\nexport function buildPositionLineAnnotation(\n options: PositionLineOptions,\n id: string,\n): Annotation {\n const style = options.style ?? \"entry\";\n return {\n id,\n type: \"horizontal-line\",\n y: options.price,\n color: options.color ?? STYLE_COLORS[style],\n label: options.label ?? STYLE_LABELS[style],\n labelPosition: \"right\",\n lineDash: style === \"sl\" ? [6, 4] : style === \"tp\" ? [4, 4] : undefined,\n interactive: options.interactive ?? false,\n };\n}\n","/**\n * Trading-specific series preprocessors and chart method extensions.\n */\nimport type { SeriesOptions } from \"../types\";\nimport { computeHeikinAshi } from \"../core/chart/heikinAshi\";\nimport {\n applyBusinessDayX,\n isBusinessDayScaleActive,\n} from \"../core/time/applyTimeScale\";\nimport { buildIndicatorSeries } from \"../core/indicator/buildIndicatorSeries\";\nimport type { IndicatorSeriesOptions } from \"../core/indicator/types\";\nimport {\n registerSeriesOptionsExpander,\n registerSeriesOptionsPreprocessor,\n} from \"../core/chart/series/seriesOptionsRegistry\";\nimport { registerSeriesDataPreprocessor } from \"../core/chart/series/SeriesActions\";\nimport { registerExtendedSeries } from \"../renderer/registerExtendedSeries\";\nimport { patchExportSVG } from \"../core/chart/chartExportPatch\";\nimport { ChartImpl } from \"../core/chart/ChartCore\";\nimport {\n addIndicatorToChart,\n type AddIndicatorOptions,\n type AddIndicatorResult,\n type IndicatorPresetName,\n} from \"../core/indicator/addIndicator\";\nimport {\n ChartAlertManager,\n type PriceAlertOptions,\n} from \"../core/chart/ChartAlerts\";\nimport {\n buildPositionLineAnnotation,\n type PositionLineOptions,\n} from \"../core/chart/positionLines\";\nimport type { DrawingMode } from \"../plugins/drawing-tools\";\n\nlet registered = false;\n\nfunction registerTradingSeriesPreprocessors(): void {\n registerSeriesOptionsPreprocessor((ctx: any, options) => {\n if (options.type === \"heatmap\" || options.type === \"indicator\") {\n return options;\n }\n\n let opts = { ...options } as SeriesOptions;\n\n if ((opts.type as string) === \"heikin-ashi\") {\n const d = opts.data;\n if (d?.open && d.high && d.low && d.close) {\n const ha = computeHeikinAshi({\n open: d.open,\n high: d.high,\n low: d.low,\n close: d.close,\n });\n opts = {\n ...opts,\n type: \"candlestick\",\n data: { ...d, ...ha },\n };\n }\n }\n\n if (isBusinessDayScaleActive(ctx.xAxisOptions) && opts.data?.x?.length) {\n const { displayX, mapping } = applyBusinessDayX(\n opts.data.x,\n ctx.xAxisOptions,\n );\n ctx.setTimeScaleMapping(mapping);\n opts = {\n ...opts,\n data: { ...opts.data, x: displayX },\n };\n }\n\n return opts;\n });\n\n registerSeriesOptionsExpander((options) => {\n if ((options as SeriesOptions).type === \"indicator\") {\n return buildIndicatorSeries(options as IndicatorSeriesOptions);\n }\n return [options];\n });\n\n registerSeriesDataPreprocessor((ctx: any, data: import(\"../types\").SeriesUpdateData) => {\n if (data.x && isBusinessDayScaleActive(ctx.xAxisOptions)) {\n const { displayX, mapping } = applyBusinessDayX(data.x, ctx.xAxisOptions);\n ctx.setTimeScaleMapping(mapping);\n return { ...data, x: displayX };\n }\n return data;\n });\n}\n\nexport function patchChartTradingMethods(): void {\n const proto = ChartImpl.prototype as any;\n\n if (proto._tradingPatched) return;\n proto._tradingPatched = true;\n\n proto.addIndicator = async function (\n this: ChartImpl,\n preset: IndicatorPresetName,\n options?: AddIndicatorOptions,\n ): Promise<AddIndicatorResult> {\n return addIndicatorToChart(this, preset, options);\n };\n\n proto.addAlert = function (\n this: ChartImpl,\n options: PriceAlertOptions,\n ): string {\n return getAlertManager(this).addAlert(options);\n };\n\n proto.removeAlert = function (this: ChartImpl, id: string): boolean {\n return getAlertManager(this).removeAlert(id);\n };\n\n proto.clearAlerts = function (this: ChartImpl): void {\n getAlertManager(this).clearAlerts();\n };\n\n proto.getAlerts = function (this: ChartImpl): PriceAlertOptions[] {\n return getAlertManager(this).getAlerts();\n };\n\n proto.addPositionLine = function (\n this: ChartImpl,\n options: PositionLineOptions,\n ): string {\n const self = this as ChartImpl & { _positionLineCounter?: number };\n if (self._positionLineCounter === undefined) self._positionLineCounter = 0;\n const id = options.id ?? `position-${++self._positionLineCounter}`;\n self.addAnnotation(buildPositionLineAnnotation(options, id));\n return id;\n };\n\n proto.setDrawingMode = function (this: ChartImpl, mode: DrawingMode): void {\n const plugin = this.getPlugin<{ setMode?: (m: DrawingMode) => void }>(\n \"velo-plot-drawing-tools\",\n );\n plugin?.setMode?.(mode);\n };\n\n const originalDestroy = proto.destroy;\n proto.destroy = function (this: ChartImpl) {\n const self = this as any;\n self._alertManager?.destroy();\n self._alertManager = undefined;\n self.setFeatureHooks(null);\n return originalDestroy.call(this);\n };\n}\n\nfunction getAlertManager(chart: ChartImpl): ChartAlertManager {\n const self = chart as any;\n if (!self._alertManager) {\n self._alertManager = new ChartAlertManager(chart.events, (seriesId) => {\n const s = seriesId ? chart.series.get(seriesId) : undefined;\n if (s) return s as import(\"../core/chart/ChartAlerts\").AlertableSeries;\n const first = chart.series.values().next().value;\n return first as import(\"../core/chart/ChartAlerts\").AlertableSeries | undefined;\n });\n chart.setFeatureHooks({\n onDataUpdate: () => self._alertManager?.evaluate(),\n getAlerts: () => self._alertManager?.getAlerts() ?? [],\n destroy: () => self._alertManager?.destroy(),\n });\n }\n return self._alertManager;\n}\n\n/** Register trading extensions (call on `velo-plot/trading` import). */\nexport function registerTradingBundle(): void {\n if (registered) return;\n registered = true;\n registerExtendedSeries();\n registerTradingSeriesPreprocessors();\n patchChartTradingMethods();\n patchExportSVG();\n}\n\n// Auto-register when trading entry is imported\nregisterTradingBundle();\n","export interface WebGPURendererOptions {\n powerPreference?: \"low-power\" | \"high-performance\";\n preferredFormat?: string;\n antialias?: boolean;\n}\n\nexport class WebGPURenderer {\n public readonly available: boolean;\n\n private canvas: HTMLCanvasElement;\n private adapter: any;\n private device: any;\n private context: any;\n\n constructor(canvas: HTMLCanvasElement, opts: WebGPURendererOptions = {}) {\n this.canvas = canvas;\n this.available = WebGPURenderer.isSupported();\n void opts;\n }\n\n static isSupported(): boolean {\n return (\n typeof (globalThis as any).navigator !== \"undefined\" &&\n typeof (globalThis as any).navigator.gpu !== \"undefined\"\n );\n }\n\n async init(opts: WebGPURendererOptions = {}): Promise<void> {\n if (!this.available) {\n throw new Error(\"[VeloPlot] WebGPU is not supported in this environment\");\n }\n\n const gpu = (globalThis as any).navigator.gpu;\n this.adapter = await gpu.requestAdapter({\n powerPreference: opts.powerPreference ?? \"high-performance\",\n });\n\n if (!this.adapter) {\n throw new Error(\"[VeloPlot] Failed to request WebGPU adapter\");\n }\n\n this.device = await this.adapter.requestDevice();\n\n const ctx = (this.canvas as any).getContext(\"webgpu\");\n if (!ctx) {\n throw new Error(\"[VeloPlot] Failed to get WebGPU context\");\n }\n\n this.context = ctx;\n\n const format =\n opts.preferredFormat ??\n (gpu.getPreferredCanvasFormat\n ? gpu.getPreferredCanvasFormat()\n : \"bgra8unorm\");\n\n this.context.configure({\n device: this.device,\n format,\n alphaMode: \"premultiplied\",\n });\n }\n\n destroy(): void {\n this.device = undefined;\n this.adapter = undefined;\n this.context = undefined;\n }\n}\n","/**\n * WebGL grid spike — batched GL_LINES renderer for axis grid lines.\n * Labels remain on Canvas 2D; this spike covers grid lines only.\n * @module renderer/spike/WebGLGridSpike\n */\n\nexport interface GridLineSpec {\n /** Plot area in CSS pixels */\n plotArea: { x: number; y: number; width: number; height: number };\n /** Pixel X positions for vertical grid lines */\n xLines: number[];\n /** Pixel Y positions for horizontal grid lines */\n yLines: number[];\n /** Canvas width (physical pixels) */\n width: number;\n /** Canvas height (physical pixels) */\n height: number;\n /** Line color RGBA 0–1 */\n color?: [number, number, number, number];\n /** Line width in pixels */\n lineWidth?: number;\n}\n\nconst VERT_SRC = `\n attribute vec2 aPosition;\n uniform vec2 uResolution;\n void main() {\n vec2 clip = (aPosition / uResolution) * 2.0 - 1.0;\n gl_Position = vec4(clip.x, -clip.y, 0.0, 1.0);\n }\n`;\n\nconst FRAG_SRC = `\n precision mediump float;\n uniform vec4 uColor;\n void main() {\n gl_FragColor = uColor;\n }\n`;\n\nfunction compileShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type);\n if (!shader) throw new Error(\"createShader failed\");\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n throw new Error(gl.getShaderInfoLog(shader) ?? \"shader compile failed\");\n }\n return shader;\n}\n\nfunction createProgram(gl: WebGLRenderingContext): WebGLProgram {\n const vs = compileShader(gl, gl.VERTEX_SHADER, VERT_SRC);\n const fs = compileShader(gl, gl.FRAGMENT_SHADER, FRAG_SRC);\n const program = gl.createProgram();\n if (!program) throw new Error(\"createProgram failed\");\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error(gl.getProgramInfoLog(program) ?? \"program link failed\");\n }\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n return program;\n}\n\n/** Build interleaved [x,y] vertex pairs for GL_LINES from tick pixel positions */\nexport function buildGridLineVertices(spec: GridLineSpec): Float32Array {\n const { plotArea, xLines, yLines } = spec;\n const y0 = plotArea.y;\n const y1 = plotArea.y + plotArea.height;\n const x0 = plotArea.x;\n const x1 = plotArea.x + plotArea.width;\n\n const vertCount = (xLines.length + yLines.length) * 2;\n const out = new Float32Array(vertCount * 2);\n let o = 0;\n\n for (const x of xLines) {\n out[o++] = x;\n out[o++] = y0;\n out[o++] = x;\n out[o++] = y1;\n }\n\n for (const y of yLines) {\n out[o++] = x0;\n out[o++] = y;\n out[o++] = x1;\n out[o++] = y;\n }\n\n return out;\n}\n\nexport class WebGLGridSpike {\n private gl: WebGLRenderingContext;\n private program: WebGLProgram;\n private buffer: WebGLBuffer;\n private aPosition: number;\n private uResolution: WebGLUniformLocation;\n private uColor: WebGLUniformLocation;\n\n constructor(canvas: HTMLCanvasElement) {\n const gl = canvas.getContext(\"webgl\", {\n alpha: true,\n antialias: false,\n preserveDrawingBuffer: true,\n });\n if (!gl) throw new Error(\"WebGL not available for grid spike\");\n\n this.gl = gl;\n this.program = createProgram(gl);\n this.aPosition = gl.getAttribLocation(this.program, \"aPosition\");\n this.uResolution = gl.getUniformLocation(this.program, \"uResolution\")!;\n this.uColor = gl.getUniformLocation(this.program, \"uColor\")!;\n\n const buf = gl.createBuffer();\n if (!buf) throw new Error(\"createBuffer failed\");\n this.buffer = buf;\n }\n\n /** Upload vertices and draw grid lines */\n draw(spec: GridLineSpec): number {\n const gl = this.gl;\n const vertices = buildGridLineVertices(spec);\n const lineSegments = vertices.length / 4;\n\n gl.viewport(0, 0, spec.width, spec.height);\n gl.clearColor(0.04, 0.05, 0.08, 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n\n gl.useProgram(this.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.DYNAMIC_DRAW);\n gl.enableVertexAttribArray(this.aPosition);\n gl.vertexAttribPointer(this.aPosition, 2, gl.FLOAT, false, 0, 0);\n\n gl.uniform2f(this.uResolution, spec.width, spec.height);\n const c = spec.color ?? [0.2, 0.22, 0.3, 0.6];\n gl.uniform4f(this.uColor, c[0], c[1], c[2], c[3]);\n gl.lineWidth(spec.lineWidth ?? 1);\n\n gl.drawArrays(gl.LINES, 0, vertices.length / 2);\n return lineSegments;\n }\n\n destroy(): void {\n const gl = this.gl;\n gl.deleteBuffer(this.buffer);\n gl.deleteProgram(this.program);\n }\n}\n","/**\n * Grid rendering benchmark — Canvas 2D vs WebGL spike comparison.\n * @module testing/gridSpikeBenchmark\n */\n\nimport { OverlayRenderer } from \"../core/OverlayRenderer\";\nimport { LinearScale } from \"../scales\";\nimport { DARK_THEME } from \"../theme\";\nimport { WebGLGridSpike, buildGridLineVertices, type GridLineSpec } from \"../renderer/spike/WebGLGridSpike\";\nimport { snapLineCoord } from \"../core/render/pixelSnap\";\nimport type { PlotArea } from \"../types\";\n\nexport interface GridBenchmarkResult {\n backend: \"canvas2d\" | \"webgl\";\n dpr: number;\n width: number;\n height: number;\n xTicks: number;\n yTicks: number;\n lineSegments: number;\n avgFrameUs: number;\n p95FrameUs: number;\n frames: number;\n}\n\nexport interface GridCompareResult {\n canvas2d: GridBenchmarkResult;\n webgl: GridBenchmarkResult | null;\n /** Positive = WebGL faster */\n gainPercent: number;\n recommendation: \"implement\" | \"defer\";\n}\n\nfunction createMinimalMock2D(canvas: HTMLCanvasElement): CanvasRenderingContext2D {\n const noop = () => {};\n return {\n canvas,\n strokeStyle: \"\",\n fillStyle: \"\",\n lineWidth: 1,\n font: \"\",\n textAlign: \"left\",\n textBaseline: \"alphabetic\",\n beginPath: noop,\n moveTo: noop,\n lineTo: noop,\n stroke: noop,\n fill: noop,\n clearRect: noop,\n setTransform: noop,\n setLineDash: noop,\n save: noop,\n restore: noop,\n translate: noop,\n rotate: noop,\n fillText: noop,\n measureText: (text: string) => ({ width: text.length * 7 } as TextMetrics),\n } as unknown as CanvasRenderingContext2D;\n}\n\nfunction getCanvas2DContext(width: number, height: number): CanvasRenderingContext2D {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n return canvas.getContext(\"2d\") ?? createMinimalMock2D(canvas);\n}\n\nfunction makePlotArea(width: number, height: number): PlotArea {\n const margin = { top: 40, right: 40, bottom: 50, left: 60 };\n return {\n x: margin.left,\n y: margin.top,\n width: width - margin.left - margin.right,\n height: height - margin.top - margin.bottom,\n };\n}\n\nfunction tickPixelLines(\n _plotArea: PlotArea,\n xScale: LinearScale,\n yScale: LinearScale,\n xTickCount: number,\n yTickCount: number,\n): { xLines: number[]; yLines: number[] } {\n const xLines = xScale.ticks(xTickCount).map((t) => snapLineCoord(xScale.transform(t)));\n const yLines = yScale.ticks(yTickCount).map((t) => snapLineCoord(yScale.transform(t)));\n return { xLines, yLines };\n}\n\nfunction measureFrames(runFrame: () => void, frames: number): { avg: number; p95: number } {\n const samples: number[] = [];\n for (let i = 0; i < frames; i++) {\n const t0 = performance.now();\n runFrame();\n samples.push((performance.now() - t0) * 1000);\n }\n samples.sort((a, b) => a - b);\n const avg = samples.reduce((s, v) => s + v, 0) / samples.length;\n const p95 = samples[Math.floor(samples.length * 0.95)] ?? avg;\n return { avg, p95 };\n}\n\n/** Benchmark Canvas 2D grid via OverlayRenderer.drawGrid */\nexport function benchmarkCanvasGrid(options: {\n width?: number;\n height?: number;\n dpr?: number;\n xTickCount?: number;\n yTickCount?: number;\n frames?: number;\n showMinor?: boolean;\n} = {}): GridBenchmarkResult {\n const width = Math.round((options.width ?? 1920) * (options.dpr ?? 1));\n const height = Math.round((options.height ?? 1080) * (options.dpr ?? 1));\n const xTickCount = options.xTickCount ?? 24;\n const yTickCount = options.yTickCount ?? 16;\n const frames = options.frames ?? 120;\n\n const ctx = getCanvas2DContext(width, height);\n\n const theme = {\n ...DARK_THEME,\n grid: {\n ...DARK_THEME.grid,\n visible: true,\n showMinor: options.showMinor ?? true,\n },\n };\n\n const plotArea = makePlotArea(width, height);\n const xScale = new LinearScale();\n const yScale = new LinearScale();\n xScale.setDomain(0, 1_000_000);\n yScale.setDomain(-1, 1);\n xScale.setRange(plotArea.x, plotArea.x + plotArea.width);\n yScale.setRange(plotArea.y + plotArea.height, plotArea.y);\n\n const renderer = new OverlayRenderer(ctx, theme);\n\n const { avg, p95 } = measureFrames(() => {\n ctx.clearRect(0, 0, width, height);\n renderer.drawGrid(plotArea, xScale, yScale, { tickCount: xTickCount }, { tickCount: yTickCount });\n }, frames);\n\n const { xLines, yLines } = tickPixelLines(plotArea, xScale, yScale, xTickCount, yTickCount);\n\n return {\n backend: \"canvas2d\",\n dpr: options.dpr ?? 1,\n width,\n height,\n xTicks: xTickCount,\n yTicks: yTickCount,\n lineSegments: xLines.length + yLines.length,\n avgFrameUs: Math.round(avg),\n p95FrameUs: Math.round(p95),\n frames,\n };\n}\n\n/** Benchmark WebGL grid spike (returns null if WebGL unavailable) */\nexport function benchmarkWebGLGrid(options: {\n width?: number;\n height?: number;\n dpr?: number;\n xTickCount?: number;\n yTickCount?: number;\n frames?: number;\n} = {}): GridBenchmarkResult | null {\n const width = Math.round((options.width ?? 1920) * (options.dpr ?? 1));\n const height = Math.round((options.height ?? 1080) * (options.dpr ?? 1));\n const xTickCount = options.xTickCount ?? 24;\n const yTickCount = options.yTickCount ?? 16;\n const frames = options.frames ?? 120;\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n let spike: WebGLGridSpike;\n try {\n spike = new WebGLGridSpike(canvas);\n } catch {\n return null;\n }\n\n const plotArea = makePlotArea(width, height);\n const xScale = new LinearScale();\n const yScale = new LinearScale();\n xScale.setDomain(0, 1_000_000);\n yScale.setDomain(-1, 1);\n xScale.setRange(plotArea.x, plotArea.x + plotArea.width);\n yScale.setRange(plotArea.y + plotArea.height, plotArea.y);\n\n const { xLines, yLines } = tickPixelLines(plotArea, xScale, yScale, xTickCount, yTickCount);\n const spec: GridLineSpec = { plotArea, xLines, yLines, width, height };\n\n let lineSegments = 0;\n const { avg, p95 } = measureFrames(() => {\n lineSegments = spike.draw(spec);\n }, frames);\n\n spike.destroy();\n\n return {\n backend: \"webgl\",\n dpr: options.dpr ?? 1,\n width,\n height,\n xTicks: xTickCount,\n yTicks: yTickCount,\n lineSegments,\n avgFrameUs: Math.round(avg),\n p95FrameUs: Math.round(p95),\n frames,\n };\n}\n\n/** Compare backends; recommends implement if WebGL ≥20% faster */\nexport function compareGridBackends(options?: {\n dpr?: number;\n frames?: number;\n}): GridCompareResult {\n const dpr = options?.dpr ?? 2;\n const frames = options?.frames ?? 120;\n\n const canvas2d = benchmarkCanvasGrid({ dpr, frames, showMinor: true });\n const webgl = benchmarkWebGLGrid({ dpr, frames });\n\n if (!webgl) {\n return {\n canvas2d,\n webgl: null,\n gainPercent: 0,\n recommendation: \"defer\",\n };\n }\n\n const gainPercent = ((canvas2d.avgFrameUs - webgl.avgFrameUs) / canvas2d.avgFrameUs) * 100;\n\n return {\n canvas2d,\n webgl,\n gainPercent: Math.round(gainPercent * 10) / 10,\n recommendation: gainPercent >= 20 ? \"implement\" : \"defer\",\n };\n}\n\n/** Vertex builder smoke test (no GL required) */\nexport function countGridVertices(xTickCount: number, yTickCount: number): number {\n const spec: GridLineSpec = {\n plotArea: { x: 60, y: 40, width: 800, height: 400 },\n xLines: Array.from({ length: xTickCount }, (_, i) => 60 + i * 30),\n yLines: Array.from({ length: yTickCount }, (_, i) => 40 + i * 25),\n width: 960,\n height: 540,\n };\n return buildGridLineVertices(spec).length / 2;\n}\n","/**\n * Stage 1 browser benchmark harness — scenarios + baseline comparison.\n * @module testing/stage1BrowserBench\n */\n\nimport type { BenchmarkResult } from \"./index\";\nimport baseline from \"./baselines/v1.15.0.json\";\n\nexport interface Stage1ScenarioResult {\n id: string;\n benchmark: BenchmarkResult;\n passed: boolean;\n failures: string[];\n baselineMinFps?: number;\n}\n\nexport interface Stage1BrowserReport {\n timestamp: number;\n version: string;\n scenarios: Stage1ScenarioResult[];\n allPassed: boolean;\n regressionThreshold: number;\n}\n\nexport interface BaselineScenario {\n minAvgFps?: number;\n maxAvgFrameTimeMs?: number;\n maxAvgFrameUs?: number;\n dpr?: number;\n points?: number;\n description?: string;\n}\n\n/** When wall-clock frame count is below this, headless rAF is unreliable — use renderFps. */\nexport const HEADLESS_LOW_FRAME_THRESHOLD = 30;\n\n/** Headless smoke floors (renderFps or effective FPS). Desktop uses baseline minAvgFps. */\nexport const SMOKE_FLOORS: Record<string, number> = {\n \"line-1m-pan\": 5,\n \"candlestick-500k\": 25,\n \"stack-5pane-resize\": 20,\n \"line-200k-webgl\": 3,\n \"line-200k-webgpu\": 2,\n \"boxplot-5k-webgpu\": 2,\n};\n\n/** Pick wall or render FPS depending on headless throttling artifacts. */\nexport function effectiveBenchmarkFps(\n result: Pick<BenchmarkResult, \"avgFps\" | \"renderFps\" | \"frameCount\">,\n isHeadless: boolean,\n): number {\n const wall = result.avgFps ?? 0;\n const render = result.renderFps ?? 0;\n const frames = result.frameCount ?? 0;\n\n if (!isHeadless) return wall;\n\n if (render > 0 && (frames < HEADLESS_LOW_FRAME_THRESHOLD || wall < 10)) {\n return render;\n }\n return wall;\n}\n\nexport function getBaseline(): typeof baseline {\n return baseline;\n}\n\n/** Compare a benchmark result against v1.15 baseline for a scenario */\nexport function compareScenarioToBaseline(\n scenarioId: string,\n result: BenchmarkResult | { avgFrameUs: number; backend?: string },\n): { passed: boolean; failures: string[] } {\n const spec = (baseline.scenarios as Record<string, BaselineScenario>)[scenarioId];\n if (!spec) {\n return { passed: true, failures: [] };\n }\n\n const failures: string[] = [];\n const threshold = baseline.regressionThreshold ?? 0.1;\n\n if (\"avgFps\" in result && spec.minAvgFps !== undefined) {\n const minAllowed = spec.minAvgFps * (1 - threshold);\n if (result.avgFps < minAllowed) {\n failures.push(\n `FPS ${result.avgFps} < baseline min ${spec.minAvgFps} (allowed ${minAllowed.toFixed(1)} with ${threshold * 100}% slack)`,\n );\n }\n }\n\n if (\"avgFrameTime\" in result && spec.maxAvgFrameTimeMs !== undefined) {\n const maxAllowed = spec.maxAvgFrameTimeMs * (1 + threshold);\n if (result.avgFrameTime > maxAllowed) {\n failures.push(\n `Frame time ${result.avgFrameTime}ms > baseline max ${spec.maxAvgFrameTimeMs}ms`,\n );\n }\n }\n\n if (\"avgFrameUs\" in result && spec.maxAvgFrameUs !== undefined) {\n const maxAllowed = spec.maxAvgFrameUs * (1 + threshold);\n if (result.avgFrameUs > maxAllowed) {\n failures.push(\n `Grid frame ${result.avgFrameUs}µs > baseline max ${spec.maxAvgFrameUs}µs`,\n );\n }\n }\n\n return { passed: failures.length === 0, failures };\n}\n\n/** Build a full Stage 1 report from scenario results */\nexport function buildStage1Report(\n scenarios: Stage1ScenarioResult[],\n): Stage1BrowserReport {\n return {\n timestamp: Date.now(),\n version: baseline.version,\n scenarios,\n allPassed: scenarios.every((s) => s.passed),\n regressionThreshold: baseline.regressionThreshold,\n };\n}\n","/**\n * WebGL vs WebGPU chart renderer comparison helpers.\n * @module testing/rendererBenchmark\n */\n\nimport type { BenchmarkResult } from \"./index\";\n\nexport interface RendererCompareResult {\n webgl: BenchmarkResult;\n webgpu: BenchmarkResult | null;\n webgpuActive: boolean;\n /** webgpuFps / webglFps — ≥1 means WebGPU is faster or equal */\n fpsRatio: number;\n /** Meets ADR target: WebGPU ≥ 95% of WebGL FPS */\n meetsTarget: boolean;\n recommendation: \"webgpu-ready\" | \"webgl-faster\" | \"webgpu-unavailable\";\n}\n\nexport function evaluateRendererCompare(\n webgl: BenchmarkResult,\n webgpu: BenchmarkResult | null,\n webgpuActive: boolean,\n minRatio = 0.95,\n): RendererCompareResult {\n if (!webgpuActive || !webgpu) {\n return {\n webgl,\n webgpu,\n webgpuActive: false,\n fpsRatio: 0,\n meetsTarget: false,\n recommendation: \"webgpu-unavailable\",\n };\n }\n\n const ratio = webgl.avgFps > 0 ? webgpu.avgFps / webgl.avgFps : 0;\n const meetsTarget = ratio >= minRatio;\n\n return {\n webgl,\n webgpu,\n webgpuActive: true,\n fpsRatio: ratio,\n meetsTarget,\n recommendation: meetsTarget ? \"webgpu-ready\" : \"webgl-faster\",\n };\n}\n","/**\n * Velo Plot - Testing Utilities\n * \n * Provides utilities for testing chart applications:\n * - Mock data generators\n * - Chart test harness\n * - Snapshot helpers\n * - Performance benchmarks\n * \n * @module testing\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport interface MockChartOptions {\n /** Canvas width (default: 800) */\n width?: number;\n /** Canvas height (default: 600) */\n height?: number;\n /** Device pixel ratio (default: 1) */\n devicePixelRatio?: number;\n /** Theme (default: 'dark') */\n theme?: string;\n /** Enable WebGL mock (default: true) */\n mockWebGL?: boolean;\n}\n\nexport interface WaveformOptions {\n /** Number of points (default: 1000) */\n pointCount?: number;\n /** Amplitude (default: 1) */\n amplitude?: number;\n /** Frequency in Hz (default: 1) */\n frequency?: number;\n /** Phase offset in radians (default: 0) */\n phase?: number;\n /** Noise level (0-1, default: 0) */\n noise?: number;\n /** X start value (default: 0) */\n xStart?: number;\n /** X end value (default: 10) */\n xEnd?: number;\n /** DC offset (default: 0) */\n offset?: number;\n}\n\nexport interface RandomDataOptions {\n /** Number of points (default: 1000) */\n pointCount?: number;\n /** X range [min, max] (default: [0, 100]) */\n xRange?: [number, number];\n /** Y range [min, max] (default: [-1, 1]) */\n yRange?: [number, number];\n /** Sort by X value (default: true) */\n sorted?: boolean;\n /** Seed for reproducible random (optional) */\n seed?: number;\n}\n\nexport interface BenchmarkResult {\n /** Average frames per second */\n avgFps: number;\n /** Minimum FPS recorded */\n minFps: number;\n /** Maximum FPS recorded */\n maxFps: number;\n /** Average frame time in ms */\n avgFrameTime: number;\n /** Total frames rendered */\n frameCount: number;\n /** Test duration in ms */\n duration: number;\n /** Points per frame */\n pointsRendered: number;\n /** Points per second throughput */\n throughput: number;\n /** Render-only throughput (1000 / avgFrameTime); can exceed wall FPS */\n renderFps?: number;\n}\n\nexport interface BenchmarkOptions {\n /** Duration of benchmark in ms (default: 5000) */\n duration?: number;\n /** Warmup duration in ms (default: 1000) */\n warmup?: number;\n /** Target FPS for assertions (default: 55) */\n targetFps?: number;\n /** Enable console output (default: false) */\n verbose?: boolean;\n}\n\nexport interface SnapshotOptions {\n /** Output format: 'json' | 'png' | 'canvas' (default: 'json') */\n format?: 'json' | 'png' | 'canvas';\n /** Include data in snapshot (default: false for performance) */\n includeData?: boolean;\n /** Include styles in snapshot (default: true) */\n includeStyles?: boolean;\n}\n\nexport interface ChartSnapshot {\n /** Snapshot timestamp */\n timestamp: number;\n /** Chart configuration */\n config: Record<string, unknown>;\n /** Series metadata (without data by default) */\n series: {\n id: string;\n type: string;\n pointCount: number;\n style?: Record<string, unknown>;\n }[];\n /** View bounds */\n bounds: {\n xMin: number;\n xMax: number;\n yMin: number;\n yMax: number;\n };\n /** Canvas data URL (if format is 'png') */\n image?: string;\n}\n\n// ============================================\n// Seeded Random Number Generator\n// ============================================\n\nclass SeededRandom {\n private seed: number;\n\n constructor(seed: number) {\n this.seed = seed;\n }\n\n next(): number {\n // Mulberry32 PRNG\n let t = (this.seed += 0x6d2b79f5);\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n }\n\n nextRange(min: number, max: number): number {\n return min + this.next() * (max - min);\n }\n}\n\n// ============================================\n// Data Generators\n// ============================================\n\n/**\n * Generate a sine wave\n */\nexport function generateSineWave(options?: WaveformOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<WaveformOptions> = {\n pointCount: 1000,\n amplitude: 1,\n frequency: 1,\n phase: 0,\n noise: 0,\n xStart: 0,\n xEnd: 10,\n offset: 0,\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n const dx = (opts.xEnd - opts.xStart) / (opts.pointCount - 1);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = opts.xStart + i * dx;\n const baseValue =\n opts.amplitude * Math.sin(2 * Math.PI * opts.frequency * x[i] + opts.phase);\n const noiseValue = opts.noise > 0 ? (Math.random() - 0.5) * 2 * opts.noise : 0;\n y[i] = baseValue + noiseValue + opts.offset;\n }\n\n return { x, y };\n}\n\n/**\n * Generate a square wave\n */\nexport function generateSquareWave(options?: WaveformOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<WaveformOptions> = {\n pointCount: 1000,\n amplitude: 1,\n frequency: 1,\n phase: 0,\n noise: 0,\n xStart: 0,\n xEnd: 10,\n offset: 0,\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n const dx = (opts.xEnd - opts.xStart) / (opts.pointCount - 1);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = opts.xStart + i * dx;\n const t = x[i] * opts.frequency + opts.phase / (2 * Math.PI);\n const baseValue = Math.sign(Math.sin(2 * Math.PI * t)) * opts.amplitude;\n const noiseValue = opts.noise > 0 ? (Math.random() - 0.5) * 2 * opts.noise : 0;\n y[i] = baseValue + noiseValue + opts.offset;\n }\n\n return { x, y };\n}\n\n/**\n * Generate a sawtooth wave\n */\nexport function generateSawtoothWave(options?: WaveformOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<WaveformOptions> = {\n pointCount: 1000,\n amplitude: 1,\n frequency: 1,\n phase: 0,\n noise: 0,\n xStart: 0,\n xEnd: 10,\n offset: 0,\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n const dx = (opts.xEnd - opts.xStart) / (opts.pointCount - 1);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = opts.xStart + i * dx;\n const t = x[i] * opts.frequency + opts.phase / (2 * Math.PI);\n const baseValue = opts.amplitude * 2 * (t - Math.floor(t + 0.5));\n const noiseValue = opts.noise > 0 ? (Math.random() - 0.5) * 2 * opts.noise : 0;\n y[i] = baseValue + noiseValue + opts.offset;\n }\n\n return { x, y };\n}\n\n/**\n * Generate a triangle wave\n */\nexport function generateTriangleWave(options?: WaveformOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<WaveformOptions> = {\n pointCount: 1000,\n amplitude: 1,\n frequency: 1,\n phase: 0,\n noise: 0,\n xStart: 0,\n xEnd: 10,\n offset: 0,\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n const dx = (opts.xEnd - opts.xStart) / (opts.pointCount - 1);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = opts.xStart + i * dx;\n const t = x[i] * opts.frequency + opts.phase / (2 * Math.PI);\n const baseValue = opts.amplitude * 2 * Math.abs(2 * (t - Math.floor(t + 0.5))) - opts.amplitude;\n const noiseValue = opts.noise > 0 ? (Math.random() - 0.5) * 2 * opts.noise : 0;\n y[i] = baseValue + noiseValue + opts.offset;\n }\n\n return { x, y };\n}\n\n/**\n * Generate random data points\n */\nexport function generateRandomData(options?: RandomDataOptions): {\n x: Float32Array;\n y: Float32Array;\n} {\n const opts: Required<RandomDataOptions> = {\n pointCount: 1000,\n xRange: [0, 100],\n yRange: [-1, 1],\n sorted: true,\n seed: Date.now(),\n ...options,\n };\n\n const rng = new SeededRandom(opts.seed);\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n\n for (let i = 0; i < opts.pointCount; i++) {\n x[i] = rng.nextRange(opts.xRange[0], opts.xRange[1]);\n y[i] = rng.nextRange(opts.yRange[0], opts.yRange[1]);\n }\n\n // Sort by X if requested\n if (opts.sorted) {\n const indices = Array.from({ length: opts.pointCount }, (_, i) => i);\n indices.sort((a, b) => x[a] - x[b]);\n \n const sortedX = new Float32Array(opts.pointCount);\n const sortedY = new Float32Array(opts.pointCount);\n \n for (let i = 0; i < opts.pointCount; i++) {\n sortedX[i] = x[indices[i]];\n sortedY[i] = y[indices[i]];\n }\n \n return { x: sortedX, y: sortedY };\n }\n\n return { x, y };\n}\n\n/**\n * Generate a cyclic voltammogram (CV) mock data\n */\nexport function generateCVData(options?: {\n pointCount?: number;\n vMin?: number;\n vMax?: number;\n cycles?: number;\n peakCurrent?: number;\n noise?: number;\n}): { x: Float32Array; y: Float32Array } {\n const opts = {\n pointCount: 2000,\n vMin: -0.5,\n vMax: 0.5,\n cycles: 1,\n peakCurrent: 10e-6, // 10 µA\n noise: 0.02,\n ...options,\n };\n\n const totalPoints = opts.pointCount * opts.cycles;\n const x = new Float32Array(totalPoints);\n const y = new Float32Array(totalPoints);\n \n const pointsPerCycle = opts.pointCount;\n const halfCycle = pointsPerCycle / 2;\n\n for (let c = 0; c < opts.cycles; c++) {\n for (let i = 0; i < pointsPerCycle; i++) {\n const idx = c * pointsPerCycle + i;\n \n // Potential sweep\n if (i < halfCycle) {\n x[idx] = opts.vMin + (opts.vMax - opts.vMin) * (i / halfCycle);\n } else {\n x[idx] = opts.vMax - (opts.vMax - opts.vMin) * ((i - halfCycle) / halfCycle);\n }\n \n // Current response (simplified Randles-Sevcik)\n const E = x[idx];\n const E0 = 0; // Formal potential\n const scanDirection = i < halfCycle ? 1 : -1;\n \n // Gaussian-like peak\n const peakWidth = 0.1;\n const exponent = -Math.pow(E - E0, 2) / (2 * peakWidth * peakWidth);\n const peakCurrent = opts.peakCurrent * Math.exp(exponent);\n \n // Add capacitive current and noise\n const capacitive = scanDirection * opts.peakCurrent * 0.1;\n const noiseValue = (Math.random() - 0.5) * 2 * opts.noise * opts.peakCurrent;\n \n y[idx] = scanDirection * peakCurrent + capacitive + noiseValue;\n }\n }\n\n return { x, y };\n}\n\n/**\n * Generate electrochemical impedance spectroscopy (EIS) Nyquist data\n */\nexport function generateNyquistData(options?: {\n pointCount?: number;\n rSolution?: number;\n rCharge?: number;\n frequency?: [number, number];\n}): { x: Float32Array; y: Float32Array } {\n const opts = {\n pointCount: 50,\n rSolution: 100, // Ohms\n rCharge: 1000, // Ohms\n frequency: [1e5, 0.01] as [number, number],\n ...options,\n };\n\n const x = new Float32Array(opts.pointCount);\n const y = new Float32Array(opts.pointCount);\n \n // Logarithmic frequency spacing\n const logFMin = Math.log10(opts.frequency[1]);\n const logFMax = Math.log10(opts.frequency[0]);\n \n for (let i = 0; i < opts.pointCount; i++) {\n const logF = logFMax - (logFMax - logFMin) * (i / (opts.pointCount - 1));\n const omega = 2 * Math.PI * Math.pow(10, logF);\n \n // Simple Randles circuit: Rs + (Rct || CPE)\n const tau = opts.rCharge * 1e-5; // Time constant\n const realPart = opts.rSolution + opts.rCharge / (1 + Math.pow(omega * tau, 2));\n const imagPart = omega * tau * opts.rCharge / (1 + Math.pow(omega * tau, 2));\n \n x[i] = realPart;\n y[i] = -imagPart; // Negative for Nyquist convention\n }\n\n return { x, y };\n}\n\n// ============================================\n// Performance Benchmarking\n// ============================================\n\n/**\n * Benchmark chart rendering performance\n */\nexport async function benchmarkRender(\n chart: { render: () => void; getAllSeries: () => { getPointCount: () => number }[] },\n options?: BenchmarkOptions\n): Promise<BenchmarkResult> {\n const opts: Required<BenchmarkOptions> = {\n duration: 5000,\n warmup: 1000,\n targetFps: 55,\n verbose: false,\n ...options,\n };\n\n const fpsHistory: number[] = [];\n const frameTimes: number[] = [];\n let frameCount = 0;\n\n // Calculate total points\n const totalPoints = chart\n .getAllSeries()\n .reduce((sum, s) => sum + s.getPointCount(), 0);\n\n return new Promise((resolve) => {\n const endTime = performance.now() + opts.warmup + opts.duration;\n const warmupEndTime = performance.now() + opts.warmup;\n let recording = false;\n let recordingStartTime = 0;\n\n function frame() {\n const now = performance.now();\n\n if (now >= endTime) {\n const avgRenderMs =\n frameTimes.length > 0\n ? frameTimes.reduce((a, b) => a + b, 0) / frameTimes.length\n : 0;\n const recordElapsedMs =\n recordingStartTime > 0 ? now - recordingStartTime : opts.duration;\n // Wall-clock FPS (includes rAF pacing + work outside timed render)\n const wallFps =\n frameCount > 0 && recordElapsedMs > 0\n ? (frameCount / recordElapsedMs) * 1000\n : 0;\n // Instantaneous render throughput (can exceed monitor refresh; useful for micro-bench)\n const renderFps =\n fpsHistory.length > 0\n ? fpsHistory.reduce((a, b) => a + b, 0) / fpsHistory.length\n : avgRenderMs > 0\n ? 1000 / avgRenderMs\n : 0;\n\n const result: BenchmarkResult = {\n avgFps: Math.round(wallFps * 100) / 100,\n minFps: Math.round((fpsHistory.length > 0 ? Math.min(...fpsHistory) : wallFps) * 100) / 100,\n maxFps: Math.round((fpsHistory.length > 0 ? Math.max(...fpsHistory) : wallFps) * 100) / 100,\n avgFrameTime: Math.round(avgRenderMs * 1000) / 1000,\n frameCount,\n duration: opts.duration,\n pointsRendered: totalPoints,\n throughput: Math.round((totalPoints * wallFps) / 1000) * 1000,\n /** @internal render-only FPS (not wall clock) */\n ...(renderFps > 0 ? { renderFps: Math.round(renderFps * 100) / 100 } : {}),\n } as BenchmarkResult;\n\n resolve(result);\n return;\n }\n\n // Start recording after warmup\n if (now >= warmupEndTime && !recording) {\n recording = true;\n recordingStartTime = now;\n frameCount = 0;\n frameTimes.length = 0;\n fpsHistory.length = 0;\n }\n\n const renderStart = performance.now();\n chart.render();\n const renderEnd = performance.now();\n\n if (recording) {\n const frameTime = renderEnd - renderStart;\n frameTimes.push(frameTime);\n frameCount++;\n\n const recentTimes = frameTimes.slice(-30);\n if (recentTimes.length > 0) {\n const avgRecentTime = recentTimes.reduce((a, b) => a + b, 0) / recentTimes.length;\n if (avgRecentTime > 0) {\n fpsHistory.push(1000 / avgRecentTime);\n }\n }\n }\n\n requestAnimationFrame(frame);\n }\n\n requestAnimationFrame(frame);\n });\n}\n\n// ============================================\n// Snapshot Utilities\n// ============================================\n\n/**\n * Create a snapshot of chart state for testing\n */\nexport function createSnapshot(\n chart: {\n getViewBounds: () => { xMin: number; xMax: number; yMin: number; yMax: number };\n getAllSeries: () => { getId: () => string; getType: () => string; getPointCount: () => number; getStyle: () => Record<string, unknown> }[];\n exportImage?: () => string;\n },\n options?: SnapshotOptions\n): ChartSnapshot {\n const opts: Required<SnapshotOptions> = {\n format: 'json',\n includeData: false,\n includeStyles: true,\n ...options,\n };\n\n const series = chart.getAllSeries().map((s) => ({\n id: s.getId(),\n type: s.getType(),\n pointCount: s.getPointCount(),\n ...(opts.includeStyles ? { style: s.getStyle() } : {}),\n }));\n\n const snapshot: ChartSnapshot = {\n timestamp: Date.now(),\n config: {},\n series,\n bounds: chart.getViewBounds(),\n };\n\n if (opts.format === 'png' && chart.exportImage) {\n snapshot.image = chart.exportImage();\n }\n\n return snapshot;\n}\n\n/**\n * Compare two snapshots for equality\n */\nexport function compareSnapshots(\n a: ChartSnapshot,\n b: ChartSnapshot,\n tolerance: number = 1e-6\n): {\n equal: boolean;\n differences: string[];\n} {\n const differences: string[] = [];\n\n // Compare series count\n if (a.series.length !== b.series.length) {\n differences.push(`Series count: ${a.series.length} vs ${b.series.length}`);\n }\n\n // Compare series metadata\n for (let i = 0; i < Math.min(a.series.length, b.series.length); i++) {\n const sa = a.series[i];\n const sb = b.series[i];\n\n if (sa.id !== sb.id) {\n differences.push(`Series[${i}] id: \"${sa.id}\" vs \"${sb.id}\"`);\n }\n if (sa.type !== sb.type) {\n differences.push(`Series[${i}] type: \"${sa.type}\" vs \"${sb.type}\"`);\n }\n if (sa.pointCount !== sb.pointCount) {\n differences.push(`Series[${i}] pointCount: ${sa.pointCount} vs ${sb.pointCount}`);\n }\n }\n\n // Compare bounds with tolerance\n const boundsKeys: (keyof ChartSnapshot['bounds'])[] = ['xMin', 'xMax', 'yMin', 'yMax'];\n for (const key of boundsKeys) {\n if (Math.abs(a.bounds[key] - b.bounds[key]) > tolerance) {\n differences.push(`Bounds.${key}: ${a.bounds[key]} vs ${b.bounds[key]}`);\n }\n }\n\n return {\n equal: differences.length === 0,\n differences,\n };\n}\n\n// ============================================\n// Test Assertions\n// ============================================\n\n/**\n * Assert that a benchmark meets performance requirements\n */\nexport function assertPerformance(\n result: BenchmarkResult,\n requirements: {\n minFps?: number;\n maxFrameTime?: number;\n minThroughput?: number;\n }\n): { passed: boolean; failures: string[] } {\n const failures: string[] = [];\n\n if (requirements.minFps && result.avgFps < requirements.minFps) {\n failures.push(`FPS ${result.avgFps} < required ${requirements.minFps}`);\n }\n\n if (requirements.maxFrameTime && result.avgFrameTime > requirements.maxFrameTime) {\n failures.push(`Frame time ${result.avgFrameTime}ms > required ${requirements.maxFrameTime}ms`);\n }\n\n if (requirements.minThroughput && result.throughput < requirements.minThroughput) {\n failures.push(`Throughput ${result.throughput} < required ${requirements.minThroughput}`);\n }\n\n return {\n passed: failures.length === 0,\n failures,\n };\n}\n\n/**\n * Wait for a number of animation frames\n */\nexport function waitForFrames(count: number = 1): Promise<void> {\n return new Promise((resolve) => {\n let remaining = count;\n function tick() {\n remaining--;\n if (remaining <= 0) {\n resolve();\n } else {\n requestAnimationFrame(tick);\n }\n }\n requestAnimationFrame(tick);\n });\n}\n\n/**\n * Wait for a specified duration\n */\nexport function waitFor(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// Stage 1 grid spike + browser benchmarks\nexport {\n benchmarkCanvasGrid,\n benchmarkWebGLGrid,\n compareGridBackends,\n countGridVertices,\n type GridBenchmarkResult,\n type GridCompareResult,\n} from \"./gridSpikeBenchmark\";\n\nexport {\n getBaseline,\n compareScenarioToBaseline,\n buildStage1Report,\n effectiveBenchmarkFps,\n HEADLESS_LOW_FRAME_THRESHOLD,\n SMOKE_FLOORS,\n type Stage1ScenarioResult,\n type Stage1BrowserReport,\n} from \"./stage1BrowserBench\";\n\nexport {\n evaluateRendererCompare,\n type RendererCompareResult,\n} from \"./rendererBenchmark\";\n","import type {\n PluginContext,\n PluginManifest,\n InteractionEvent,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\nimport type {\n CrosshairValueMode,\n CornerPosition\n} from \"../../../core/layout\";\n\nexport interface CrosshairPluginConfig {\n /** Show vertical line (default: true) */\n showVertical?: boolean;\n /** Show horizontal line (default: true) */\n showHorizontal?: boolean;\n /** Line color (default: from theme) */\n color?: string;\n /** Line style (default: 'dashed') */\n lineStyle?: \"solid\" | \"dashed\" | \"dotted\";\n /** Line width (default: 1) */\n lineWidth?: number;\n /** \n * @deprecated Use valueDisplayMode instead. **Removed in v4.0.**\n * Show axis labels (will be converted to valueDisplayMode)\n */\n showAxisLabels?: boolean;\n /**\n * Display mode for X,Y coordinate values (default: 'disabled')\n * - 'disabled': Never show coordinate values\n * - 'corner': Show values in a fixed corner position\n * - 'floating': Show values next to the cursor (axis labels)\n */\n valueDisplayMode?: CrosshairValueMode;\n /**\n * Corner position when valueDisplayMode is 'corner' (default: 'top-left')\n */\n cornerPosition?: CornerPosition;\n /** Snap to nearest data point (default: false) */\n snapToData?: boolean;\n /** Value format options */\n valueFormat?: {\n /** X value precision (default: 4) */\n xPrecision?: number;\n /** Y value precision (default: 4) */\n yPrecision?: number;\n };\n}\n\nconst crosshairManifest: PluginManifest = {\n name: \"crosshair\",\n version: \"1.0.0\",\n description: \"Interactive crosshair that follows mouse cursor\",\n provides: [\"interaction\", \"visualization\"],\n tags: [\"cursor\", \"crosshair\", \"tooltip\"],\n};\n\nexport const CrosshairPlugin = definePlugin<CrosshairPluginConfig>(\n crosshairManifest,\n (config = {}) => {\n const {\n showVertical = true,\n showHorizontal = true,\n color,\n lineStyle = \"dashed\",\n lineWidth = 1,\n snapToData = false,\n valueFormat = { xPrecision: 4, yPrecision: 4 },\n } = config;\n\n // Handle deprecated showAxisLabels -> convert to valueDisplayMode\n let valueDisplayMode: CrosshairValueMode = config.valueDisplayMode ?? 'disabled';\n if (config.showAxisLabels !== undefined && config.valueDisplayMode === undefined) {\n valueDisplayMode = config.showAxisLabels ? 'floating' : 'disabled';\n }\n const cornerPosition: CornerPosition = config.cornerPosition ?? 'top-left';\n\n let cursorX = -1;\n let cursorY = -1;\n let overlayId: string;\n let canvas: HTMLCanvasElement | null = null;\n let ctx: CanvasRenderingContext2D | null = null;\n\n return {\n onInit(pluginCtx: PluginContext) {\n overlayId = \"crosshair-overlay\";\n const overlay = pluginCtx.ui.createOverlay(overlayId, {\n zIndex: 500,\n position: { top: \"0\", left: \"0\", right: \"0\", bottom: \"0\" },\n });\n\n canvas = document.createElement(\"canvas\");\n canvas.style.cssText = \"width: 100%; height: 100%;\";\n overlay.appendChild(canvas);\n\n ctx = canvas.getContext(\"2d\");\n resizeCanvas(pluginCtx);\n },\n\n onDestroy(pluginCtx: PluginContext) {\n pluginCtx.ui.removeOverlay(overlayId);\n canvas = null;\n ctx = null;\n },\n\n onResize(pluginCtx: PluginContext) {\n resizeCanvas(pluginCtx);\n },\n\n onInteraction(pluginCtx: PluginContext, event: InteractionEvent) {\n if (event.type === \"mousemove\") {\n cursorX = event.pixelX;\n cursorY = event.pixelY;\n\n if (snapToData && event.inPlotArea) {\n const nearest = pluginCtx.coords.pickPoint(cursorX, cursorY);\n if (nearest) {\n cursorX = nearest.pixelX;\n cursorY = nearest.pixelY;\n }\n }\n\n render(pluginCtx);\n }\n },\n\n onViewChange() {\n // Re-render on zoom/pan\n if (cursorX >= 0 && cursorY >= 0) {\n // Will be re-rendered on next frame\n }\n },\n };\n\n function resizeCanvas(pluginCtx: PluginContext) {\n if (!canvas || !ctx) return;\n const size = pluginCtx.render.canvasSize;\n const dpr = pluginCtx.render.pixelRatio;\n canvas.width = size.width * dpr;\n canvas.height = size.height * dpr;\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.scale(dpr, dpr);\n }\n\n function render(pluginCtx: PluginContext) {\n if (!ctx || !canvas) return;\n\n const { width, height } = pluginCtx.render.canvasSize;\n ctx.clearRect(0, 0, width, height);\n\n if (cursorX < 0 || cursorY < 0) return;\n\n const plotArea = pluginCtx.render.plotArea;\n if (\n cursorX < plotArea.x ||\n cursorX > plotArea.x + plotArea.width ||\n cursorY < plotArea.y ||\n cursorY > plotArea.y + plotArea.height\n ) {\n return;\n }\n\n const lineColor = color || (pluginCtx.ui.theme.cursor as unknown as Record<string, unknown>)?.color as string || \"#888888\";\n\n ctx.save();\n ctx.strokeStyle = lineColor;\n ctx.lineWidth = lineWidth;\n\n if (lineStyle === \"dashed\") {\n ctx.setLineDash([6, 4]);\n } else if (lineStyle === \"dotted\") {\n ctx.setLineDash([2, 2]);\n }\n\n // Vertical line\n if (showVertical) {\n ctx.beginPath();\n ctx.moveTo(cursorX, plotArea.y);\n ctx.lineTo(cursorX, plotArea.y + plotArea.height);\n ctx.stroke();\n }\n\n // Horizontal line\n if (showHorizontal) {\n ctx.beginPath();\n ctx.moveTo(plotArea.x, cursorY);\n ctx.lineTo(plotArea.x + plotArea.width, cursorY);\n ctx.stroke();\n }\n\n ctx.restore();\n\n // Value display based on mode\n if (valueDisplayMode === 'floating') {\n drawFloatingLabels(pluginCtx, ctx, cursorX, cursorY, lineColor);\n } else if (valueDisplayMode === 'corner') {\n drawCornerLabels(pluginCtx, ctx, cursorX, cursorY, lineColor);\n }\n // 'disabled' mode: don't draw any labels\n }\n\n function drawFloatingLabels(\n pluginCtx: PluginContext,\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n bgColor: string\n ) {\n const dataX = pluginCtx.coords.pixelToDataX(x);\n const dataY = pluginCtx.coords.pixelToDataY(y);\n const plotArea = pluginCtx.render.plotArea;\n\n ctx.save();\n ctx.font = \"11px system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n\n // X axis label\n const xText = dataX.toPrecision(valueFormat.xPrecision);\n const xMetrics = ctx.measureText(xText);\n const xLabelWidth = xMetrics.width + 8;\n const xLabelHeight = 18;\n const xLabelX = x - xLabelWidth / 2;\n const xLabelY = plotArea.y + plotArea.height + 2;\n\n ctx.fillStyle = bgColor;\n ctx.fillRect(xLabelX, xLabelY, xLabelWidth, xLabelHeight);\n ctx.fillStyle = \"#ffffff\";\n ctx.fillText(xText, x, xLabelY + 3);\n\n // Y axis label\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n const yText = dataY.toPrecision(valueFormat.yPrecision);\n const yMetrics = ctx.measureText(yText);\n const yLabelWidth = yMetrics.width + 8;\n const yLabelHeight = 18;\n const yLabelX = plotArea.x - yLabelWidth - 2;\n const yLabelY = y - yLabelHeight / 2;\n\n ctx.fillStyle = bgColor;\n ctx.fillRect(yLabelX, yLabelY, yLabelWidth, yLabelHeight);\n ctx.fillStyle = \"#ffffff\";\n ctx.fillText(yText, plotArea.x - 6, y);\n\n ctx.restore();\n }\n\n function drawCornerLabels(\n pluginCtx: PluginContext,\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n bgColor: string\n ) {\n const dataX = pluginCtx.coords.pixelToDataX(x);\n const dataY = pluginCtx.coords.pixelToDataY(y);\n const plotArea = pluginCtx.render.plotArea;\n\n ctx.save();\n ctx.font = \"11px system-ui, sans-serif\";\n\n const xText = `X: ${dataX.toPrecision(valueFormat.xPrecision)}`;\n const yText = `Y: ${dataY.toPrecision(valueFormat.yPrecision)}`;\n\n const xMetrics = ctx.measureText(xText);\n const yMetrics = ctx.measureText(yText);\n const maxWidth = Math.max(xMetrics.width, yMetrics.width);\n const padding = 6;\n const lineHeight = 16;\n const boxWidth = maxWidth + padding * 2;\n const boxHeight = lineHeight * 2 + padding * 2;\n\n // Determine corner position\n let boxX: number;\n let boxY: number;\n\n switch (cornerPosition) {\n case 'top-left':\n boxX = plotArea.x + 8;\n boxY = plotArea.y + 8;\n break;\n case 'top-right':\n boxX = plotArea.x + plotArea.width - boxWidth - 8;\n boxY = plotArea.y + 8;\n break;\n case 'bottom-left':\n boxX = plotArea.x + 8;\n boxY = plotArea.y + plotArea.height - boxHeight - 8;\n break;\n case 'bottom-right':\n boxX = plotArea.x + plotArea.width - boxWidth - 8;\n boxY = plotArea.y + plotArea.height - boxHeight - 8;\n break;\n default:\n boxX = plotArea.x + 8;\n boxY = plotArea.y + 8;\n }\n\n // Draw background\n ctx.fillStyle = bgColor;\n ctx.globalAlpha = 0.85;\n ctx.fillRect(boxX, boxY, boxWidth, boxHeight);\n ctx.globalAlpha = 1.0;\n\n // Draw border\n ctx.strokeStyle = \"rgba(255,255,255,0.3)\";\n ctx.lineWidth = 1;\n ctx.strokeRect(boxX, boxY, boxWidth, boxHeight);\n\n // Draw text\n ctx.fillStyle = \"#ffffff\";\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillText(xText, boxX + padding, boxY + padding);\n ctx.fillText(yText, boxX + padding, boxY + padding + lineHeight);\n\n ctx.restore();\n }\n }\n);\n\n","import type {\n PluginContext,\n PluginManifest,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\n\nexport interface StatsPluginConfig {\n /** Position of the stats overlay */\n position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n /** Which stats to show */\n show?: Array<\"count\" | \"mean\" | \"min\" | \"max\" | \"std\" | \"range\">;\n /** Series ID to compute stats for (default: all) */\n seriesId?: string;\n /** Update on every data change (default: true) */\n autoUpdate?: boolean;\n}\n\nconst statsManifest: PluginManifest = {\n name: \"statistics-overlay\",\n version: \"1.0.0\",\n description: \"Displays real-time statistics for chart data\",\n provides: [\"visualization\", \"analysis\"],\n tags: [\"statistics\", \"overlay\", \"analytics\"],\n};\n\nexport const StatsPlugin = definePlugin<StatsPluginConfig>(\n statsManifest,\n (config = {}) => {\n const {\n position = \"top-right\",\n show = [\"count\", \"mean\", \"min\", \"max\"],\n seriesId,\n autoUpdate = true,\n } = config;\n\n let overlayId: string;\n let container: HTMLDivElement | null = null;\n\n return {\n onInit(ctx: PluginContext) {\n overlayId = \"stats-overlay\";\n const posStyle: Record<string, string> = {};\n\n if (position.includes(\"top\")) posStyle.top = \"10px\";\n if (position.includes(\"bottom\")) posStyle.bottom = \"10px\";\n if (position.includes(\"left\")) posStyle.left = \"10px\";\n if (position.includes(\"right\")) posStyle.right = \"10px\";\n\n container = ctx.ui.createOverlay(overlayId, {\n zIndex: 800,\n position: posStyle,\n pointerEvents: false,\n });\n\n container.innerHTML = `\n <div style=\"\n background: rgba(0, 0, 0, 0.85);\n color: #fff;\n padding: 10px 14px;\n border-radius: 6px;\n font-family: ui-monospace, monospace;\n font-size: 12px;\n line-height: 1.6;\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n \">\n <div style=\"font-weight: bold; margin-bottom: 4px; color: #4ade80;\">📊 Statistics</div>\n <div class=\"stats-content\"></div>\n </div>\n `;\n\n updateStats(ctx);\n },\n\n onDestroy(ctx: PluginContext) {\n ctx.ui.removeOverlay(overlayId);\n container = null;\n },\n\n onDataUpdate(ctx: PluginContext) {\n if (autoUpdate) {\n updateStats(ctx);\n }\n },\n\n onSeriesAdd(ctx: PluginContext) {\n updateStats(ctx);\n },\n\n onSeriesRemove(ctx: PluginContext) {\n updateStats(ctx);\n },\n\n api: {\n refresh(ctx: PluginContext) {\n updateStats(ctx);\n },\n },\n };\n\n function updateStats(ctx: PluginContext) {\n if (!container) return;\n\n const content = container.querySelector(\".stats-content\");\n if (!content) return;\n\n const allSeries = ctx.data.getAllSeries();\n const targetSeries = seriesId\n ? allSeries.filter((s) => s.getId() === seriesId)\n : allSeries;\n\n if (targetSeries.length === 0) {\n content.innerHTML = \"<div style='color: #888'>No data</div>\";\n return;\n }\n\n // Aggregate all Y data\n let allY: number[] = [];\n targetSeries.forEach((series) => {\n const data = series.getData();\n if (data?.y) {\n allY = allY.concat(Array.from(data.y));\n }\n });\n\n if (allY.length === 0) {\n content.innerHTML = \"<div style='color: #888'>No data</div>\";\n return;\n }\n\n const stats = computeStats(allY);\n const lines: string[] = [];\n\n if (show.includes(\"count\")) {\n lines.push(`<div>N: <span style=\"color: #60a5fa\">${stats.count.toLocaleString()}</span></div>`);\n }\n if (show.includes(\"mean\")) {\n lines.push(`<div>μ: <span style=\"color: #60a5fa\">${stats.mean.toPrecision(4)}</span></div>`);\n }\n if (show.includes(\"min\")) {\n lines.push(`<div>Min: <span style=\"color: #60a5fa\">${stats.min.toPrecision(4)}</span></div>`);\n }\n if (show.includes(\"max\")) {\n lines.push(`<div>Max: <span style=\"color: #60a5fa\">${stats.max.toPrecision(4)}</span></div>`);\n }\n if (show.includes(\"std\")) {\n lines.push(`<div>σ: <span style=\"color: #60a5fa\">${stats.std.toPrecision(4)}</span></div>`);\n }\n if (show.includes(\"range\")) {\n lines.push(`<div>Range: <span style=\"color: #60a5fa\">${stats.range.toPrecision(4)}</span></div>`);\n }\n\n content.innerHTML = lines.join(\"\");\n }\n\n function computeStats(values: number[]) {\n const n = values.length;\n let sum = 0;\n let min = Infinity;\n let max = -Infinity;\n\n for (const v of values) {\n sum += v;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n\n const mean = sum / n;\n\n let sumSq = 0;\n for (const v of values) {\n sumSq += (v - mean) ** 2;\n }\n const std = Math.sqrt(sumSq / n);\n\n return {\n count: n,\n mean,\n min,\n max,\n std,\n range: max - min,\n };\n }\n }\n);\n","import type {\n PluginContext,\n PluginManifest,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\nimport { exportWatermark } from \"../../../core/chart/exporter/svg/plugins/watermark\";\n\nexport interface WatermarkPluginConfig {\n /** Watermark text */\n text: string;\n /** Font size (default: 48) */\n fontSize?: number;\n /** Font family (default: system-ui) */\n fontFamily?: string;\n /** Text color with opacity (default: rgba(128,128,128,0.15)) */\n color?: string;\n /** Position (default: center) */\n position?: \"center\" | \"bottom-right\" | \"bottom-left\";\n /** Rotation in degrees (default: -30 for center, 0 for corners) */\n rotation?: number;\n}\n\nconst watermarkManifest: PluginManifest = {\n name: \"watermark\",\n version: \"1.0.0\",\n description: \"Adds a customizable watermark to the chart\",\n provides: [\"visualization\"],\n tags: [\"watermark\", \"branding\", \"overlay\"],\n};\n\nexport const WatermarkPlugin = definePlugin<WatermarkPluginConfig>(\n watermarkManifest,\n (config) => {\n if (!config?.text) {\n throw new Error(\"WatermarkPlugin requires 'text' configuration\");\n }\n\n const {\n text,\n fontSize = 48,\n fontFamily = \"system-ui, sans-serif\",\n color = \"rgba(128, 128, 128, 0.15)\",\n position = \"center\",\n rotation = position === \"center\" ? -30 : 0,\n } = config;\n\n return {\n onRenderOverlay(ctx: PluginContext) {\n const ctx2d = ctx.render.ctx2d;\n if (!ctx2d) return;\n\n // width/height available for future use\n void ctx.render.canvasSize;\n const plotArea = ctx.render.plotArea;\n\n ctx2d.save();\n ctx2d.font = `${fontSize}px ${fontFamily}`;\n ctx2d.fillStyle = color;\n ctx2d.textAlign = \"center\";\n ctx2d.textBaseline = \"middle\";\n\n let x: number, y: number;\n\n if (position === \"center\") {\n x = plotArea.x + plotArea.width / 2;\n y = plotArea.y + plotArea.height / 2;\n } else if (position === \"bottom-right\") {\n x = plotArea.x + plotArea.width - fontSize;\n y = plotArea.y + plotArea.height - fontSize / 2;\n } else {\n x = plotArea.x + fontSize;\n y = plotArea.y + plotArea.height - fontSize / 2;\n }\n\n ctx2d.translate(x, y);\n ctx2d.rotate((rotation * Math.PI) / 180);\n ctx2d.fillText(text, 0, 0);\n ctx2d.restore();\n },\n onExportSVG(svgCtx) {\n if (!svgCtx.builder || svgCtx.exportContext?.options.includeOverlays === false) return;\n exportWatermark(svgCtx, text, {\n opacity: 0.15,\n rotation,\n color,\n });\n },\n };\n }\n);\n","import type {\n PluginContext,\n PluginManifest,\n AfterRenderEvent,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\nimport { exportGridHighlight } from \"../../../core/chart/exporter/svg/plugins/watermark\";\n\nexport interface GridHighlightConfig {\n /** Highlight intervals on X axis */\n xIntervals?: Array<{ start: number; end: number; color: string }>;\n /** Highlight intervals on Y axis */\n yIntervals?: Array<{ start: number; end: number; color: string }>;\n /** Opacity for highlight regions (default: 0.1) */\n opacity?: number;\n}\n\nconst gridHighlightManifest: PluginManifest = {\n name: \"grid-highlight\",\n version: \"1.0.0\",\n description: \"Highlights specific regions of the chart grid\",\n provides: [\"visualization\"],\n tags: [\"grid\", \"highlight\", \"regions\"],\n};\n\nexport const GridHighlightPlugin = definePlugin<GridHighlightConfig>(\n gridHighlightManifest,\n (config = {}) => {\n const { xIntervals = [], yIntervals = [], opacity = 0.1 } = config;\n\n return {\n onRenderOverlay(ctx: PluginContext, _event: AfterRenderEvent) {\n const ctx2d = ctx.render.ctx2d;\n if (!ctx2d) return;\n\n const plotArea = ctx.render.plotArea;\n // bounds available if needed for future features\n void ctx.data.getViewBounds();\n\n ctx2d.save();\n\n // Clip to plot area\n ctx2d.beginPath();\n ctx2d.rect(plotArea.x, plotArea.y, plotArea.width, plotArea.height);\n ctx2d.clip();\n\n ctx2d.globalAlpha = opacity;\n\n // Draw X intervals (vertical bands)\n for (const interval of xIntervals) {\n const x1 = ctx.coords.dataToPixelX(interval.start);\n const x2 = ctx.coords.dataToPixelX(interval.end);\n\n ctx2d.fillStyle = interval.color;\n ctx2d.fillRect(\n Math.min(x1, x2),\n plotArea.y,\n Math.abs(x2 - x1),\n plotArea.height\n );\n }\n\n // Draw Y intervals (horizontal bands)\n for (const interval of yIntervals) {\n const y1 = ctx.coords.dataToPixelY(interval.start);\n const y2 = ctx.coords.dataToPixelY(interval.end);\n\n ctx2d.fillStyle = interval.color;\n ctx2d.fillRect(\n plotArea.x,\n Math.min(y1, y2),\n plotArea.width,\n Math.abs(y2 - y1)\n );\n }\n\n ctx2d.restore();\n },\n onExportSVG(svgCtx) {\n if (!svgCtx.builder || svgCtx.exportContext?.options.includeOverlays === false) return;\n const bands: Array<{ axis: \"x\" | \"y\"; min: number; max: number; color?: string }> = [];\n for (const interval of xIntervals) {\n bands.push({ axis: \"x\", min: interval.start, max: interval.end, color: interval.color });\n }\n for (const interval of yIntervals) {\n bands.push({ axis: \"y\", min: interval.start, max: interval.end, color: interval.color });\n }\n exportGridHighlight(svgCtx, bands);\n },\n };\n }\n);\n","import type {\n PluginContext,\n PluginManifest,\n DataUpdateEvent,\n ViewChangeEvent,\n InteractionEvent,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\n\nexport interface DataLoggerConfig {\n /** Log data updates (default: true) */\n logDataUpdates?: boolean;\n /** Log view changes (default: true) */\n logViewChanges?: boolean;\n /** Log interactions (default: false) */\n logInteractions?: boolean;\n /** Maximum log entries to keep (default: 100) */\n maxEntries?: number;\n}\n\nconst dataLoggerManifest: PluginManifest = {\n name: \"data-logger\",\n version: \"1.0.0\",\n description: \"Logs chart events for debugging and analysis\",\n provides: [\"analysis\"],\n tags: [\"debug\", \"logging\", \"events\"],\n};\n\nexport const DataLoggerPlugin = definePlugin<DataLoggerConfig>(\n dataLoggerManifest,\n (config = {}) => {\n const {\n logDataUpdates = true,\n logViewChanges = true,\n logInteractions = false,\n maxEntries = 100,\n } = config;\n\n interface LogEntry {\n timestamp: number;\n type: string;\n data: unknown;\n }\n\n const entries: LogEntry[] = [];\n\n function addEntry(type: string, data: unknown) {\n entries.push({\n timestamp: Date.now(),\n type,\n data,\n });\n\n if (entries.length > maxEntries) {\n entries.shift();\n }\n }\n\n return {\n onInit(ctx: PluginContext) {\n ctx.log.info(\"Data logger initialized\");\n },\n\n onDataUpdate(ctx: PluginContext, event: DataUpdateEvent) {\n if (logDataUpdates) {\n addEntry(\"dataUpdate\", {\n seriesId: event.seriesId,\n mode: event.mode,\n pointCount: event.pointCount,\n });\n ctx.log.debug(`Data update: ${event.seriesId} (${event.mode}, ${event.pointCount} points)`);\n }\n },\n\n onViewChange(ctx: PluginContext, event: ViewChangeEvent) {\n if (logViewChanges) {\n addEntry(\"viewChange\", {\n trigger: event.trigger,\n bounds: event.current,\n });\n ctx.log.debug(`View change: ${event.trigger}`);\n }\n },\n\n onInteraction(_ctx: PluginContext, event: InteractionEvent) {\n if (logInteractions) {\n addEntry(\"interaction\", {\n type: event.type,\n pixelX: event.pixelX,\n pixelY: event.pixelY,\n inPlotArea: event.inPlotArea,\n });\n }\n },\n\n onSerialize(_ctx: PluginContext) {\n return { entries };\n },\n\n onDeserialize(_ctx: PluginContext, data: unknown) {\n const saved = data as { entries?: LogEntry[] };\n if (saved?.entries) {\n entries.length = 0;\n entries.push(...saved.entries);\n }\n },\n\n api: {\n getEntries() {\n return [...entries];\n },\n clear() {\n entries.length = 0;\n },\n export() {\n return JSON.stringify(entries, null, 2);\n },\n },\n };\n }\n);\n","import type {\n PluginContext,\n PluginManifest,\n} from \"../../types\";\nimport { definePlugin } from \"../../PluginRegistry\";\n\nexport interface DirectionIndicatorConfig {\n /** Series ID to track (if not specified, tracks the first series) */\n seriesId?: string;\n /** Number of recent points to analyze for direction (default: 20) */\n sampleSize?: number;\n /** Arrow color (default: from theme) */\n color?: string;\n /** Arrow size in pixels (default: 40) */\n size?: number;\n /** Minimum velocity to show arrow (default: 0.01) */\n minVelocity?: number;\n /** Number of points for smoothing the position/angle (default: 20) */\n historySize?: number;\n /** Hide arrow if no new points are received for this duration in ms (default: undefined/disabled) */\n idleTimeout?: number;\n}\n\ninterface DirectionData {\n angle: number; // Continuous angle in radians\n magnitude: number; // Normalized magnitude 0-1\n lastX: number; // Last data point X coordinate (data space)\n lastY: number; // Last data point Y coordinate (data space)\n smoothX: number; // Smoothed X position (pixel space)\n smoothY: number; // Smoothed Y position (pixel space)\n}\n\nconst directionIndicatorManifest: PluginManifest = {\n name: \"direction-indicator\",\n version: \"1.0.0\",\n description: \"Shows an arrow indicating the direction and trend of streaming data\",\n provides: [\"visualization\", \"analysis\"],\n tags: [\"streaming\", \"direction\", \"trend\", \"arrow\"],\n};\n\nexport const DirectionIndicatorPlugin = definePlugin<DirectionIndicatorConfig>(\n directionIndicatorManifest,\n (config = {}) => {\n const {\n seriesId,\n sampleSize = 20,\n color,\n size = 40,\n minVelocity = 0.01,\n historySize = 20,\n idleTimeout,\n } = config;\n\n let overlayId: string;\n let canvas: HTMLCanvasElement | null = null;\n let ctx: CanvasRenderingContext2D | null = null;\n let currentDirection: DirectionData | null = null;\n let targetSeriesId: string | null = null;\n \n // Smoothing buffers (moving average to reduce jitter)\n const positionHistoryX: number[] = [];\n const positionHistoryY: number[] = [];\n const angleHistory: number[] = [];\n\n let maxHistorySize = historySize;\n let timeoutTimer: any = null;\n let lastPointTimestamp = Date.now();\n let lastSeenX = -Infinity;\n let lastSeenY = -Infinity;\n let currentIdleTimeout = idleTimeout;\n\n return {\n onInit(pluginCtx: PluginContext) {\n overlayId = \"direction-indicator-overlay\";\n const overlay = pluginCtx.ui.createOverlay(overlayId, {\n zIndex: 600,\n position: { top: \"0\", left: \"0\", right: \"0\", bottom: \"0\" },\n pointerEvents: false,\n });\n\n canvas = document.createElement(\"canvas\");\n canvas.style.cssText = \"width: 100%; height: 100%; pointer-events: none;\";\n overlay.appendChild(canvas);\n\n ctx = canvas.getContext(\"2d\");\n resizeCanvas(pluginCtx);\n\n // Determine which series to track\n if (seriesId) {\n targetSeriesId = seriesId;\n } else {\n const allSeries = pluginCtx.data.getAllSeries();\n if (allSeries.length > 0) {\n targetSeriesId = allSeries[0].getId();\n }\n }\n },\n\n onDestroy(pluginCtx: PluginContext) {\n pluginCtx.ui.removeOverlay(overlayId);\n if (timeoutTimer) clearTimeout(timeoutTimer);\n canvas = null;\n ctx = null;\n currentDirection = null;\n },\n\n onResize(pluginCtx: PluginContext) {\n resizeCanvas(pluginCtx);\n },\n\n onAfterRender(pluginCtx: PluginContext) {\n // Update direction every frame for smooth rendering\n updateDirection(pluginCtx);\n render(pluginCtx);\n\n // Ensure we render again when the idle timeout expires to hide the arrow\n if (currentIdleTimeout) {\n if (timeoutTimer) clearTimeout(timeoutTimer);\n const age = Date.now() - lastPointTimestamp;\n if (age < currentIdleTimeout) {\n timeoutTimer = setTimeout(() => {\n pluginCtx.requestRender();\n }, currentIdleTimeout - age + 10);\n }\n }\n },\n\n onConfigChange(_pluginCtx: PluginContext, newConfig: DirectionIndicatorConfig) {\n if (newConfig.historySize !== undefined) {\n maxHistorySize = newConfig.historySize;\n // Reset history buffers if size changes significantly or just trim/expand? \n // Simpler to just let them adjust over time or trim if needed.\n // If we want immediate effect, we might want to trim if smaller.\n while (positionHistoryX.length > maxHistorySize) positionHistoryX.shift();\n while (positionHistoryY.length > maxHistorySize) positionHistoryY.shift();\n while (angleHistory.length > maxHistorySize) angleHistory.shift();\n }\n\n if (newConfig.idleTimeout !== undefined) {\n currentIdleTimeout = newConfig.idleTimeout;\n }\n }\n };\n\n function resizeCanvas(pluginCtx: PluginContext) {\n if (!canvas || !ctx) return;\n const canvasSize = pluginCtx.render.canvasSize;\n const dpr = pluginCtx.render.pixelRatio;\n canvas.width = canvasSize.width * dpr;\n canvas.height = canvasSize.height * dpr;\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.scale(dpr, dpr);\n }\n\n function updateDirection(pluginCtx: PluginContext) {\n if (!targetSeriesId) return;\n\n const series = pluginCtx.data.getSeries(targetSeriesId);\n if (!series) return;\n\n const data = pluginCtx.data.getSeriesData(targetSeriesId);\n if (!data || !data.x || !data.y) return;\n\n const totalPoints = data.x.length;\n if (totalPoints < 2) return;\n\n // Get last point coordinates in data space\n const lastX = data.x[totalPoints - 1];\n const lastY = data.y[totalPoints - 1];\n\n // Detect if this is a new point\n if (lastX !== lastSeenX || lastY !== lastSeenY) {\n lastSeenX = lastX;\n lastSeenY = lastY;\n lastPointTimestamp = Date.now();\n }\n\n // Get last N points for direction calculation\n const n = Math.min(sampleSize, totalPoints);\n const startIdx = totalPoints - n;\n\n // Calculate direction using linear regression on recent points IN PIXEL SPACE\n let sumT = 0, sumPX = 0, sumPY = 0, sumTPX = 0, sumTPY = 0, sumTT = 0;\n\n for (let i = startIdx; i < totalPoints; i++) {\n const t = i - startIdx; // Time index\n const dataX = data.x[i];\n const dataY = data.y[i];\n \n // Convert to pixel coordinates\n const pixelX = pluginCtx.coords.dataToPixelX(dataX);\n const pixelY = pluginCtx.coords.dataToPixelY(dataY);\n\n sumT += t;\n sumPX += pixelX;\n sumPY += pixelY;\n sumTPX += t * pixelX;\n sumTPY += t * pixelY;\n sumTT += t * t;\n }\n\n const meanT = sumT / n;\n const meanPX = sumPX / n;\n const meanPY = sumPY / n;\n\n // Calculate slopes in pixel space (dpx/dt and dpy/dt)\n const denominator = sumTT - n * meanT * meanT;\n if (Math.abs(denominator) < 1e-10) return; // Avoid division by zero\n \n const slopePX = (sumTPX - n * meanT * meanPX) / denominator;\n const slopePY = (sumTPY - n * meanT * meanPY) / denominator;\n\n // Calculate continuous angle in pixel space (canvas coordinates)\n const rawAngle = Math.atan2(slopePY, slopePX);\n \n // Convert last point to pixel coordinates\n const lastPixelX = pluginCtx.coords.dataToPixelX(lastX);\n const lastPixelY = pluginCtx.coords.dataToPixelY(lastY);\n \n // Add to position history for smoothing\n positionHistoryX.push(lastPixelX);\n positionHistoryY.push(lastPixelY);\n if (positionHistoryX.length > maxHistorySize) {\n positionHistoryX.shift();\n positionHistoryY.shift();\n }\n \n // Add to angle history for smoothing\n angleHistory.push(rawAngle);\n if (angleHistory.length > maxHistorySize) {\n angleHistory.shift();\n }\n \n // Apply moving average to smooth position and angle\n const smoothX = average(positionHistoryX);\n const smoothY = average(positionHistoryY);\n const smoothedAngle = smoothAngle(angleHistory);\n \n // Calculate magnitude in pixel space\n const magnitude = Math.sqrt(slopePX * slopePX + slopePY * slopePY);\n\n currentDirection = { angle: smoothedAngle, magnitude, lastX, lastY, smoothX, smoothY };\n }\n \n function average(values: number[]): number {\n if (values.length === 0) return 0;\n return values.reduce((sum, val) => sum + val, 0) / values.length;\n }\n \n function smoothAngle(angles: number[]): number {\n if (angles.length === 0) return 0;\n \n // Convert angles to unit vectors to handle wraparound correctly\n let sumX = 0;\n let sumY = 0;\n \n for (const angle of angles) {\n sumX += Math.cos(angle);\n sumY += Math.sin(angle);\n }\n \n // Average the vectors and convert back to angle\n return Math.atan2(sumY / angles.length, sumX / angles.length);\n }\n\n function render(pluginCtx: PluginContext) {\n if (!ctx || !canvas || !currentDirection) return;\n\n const { width, height } = pluginCtx.render.canvasSize;\n ctx.clearRect(0, 0, width, height);\n\n // Check for idle timeout\n if (currentIdleTimeout !== undefined) {\n const age = Date.now() - lastPointTimestamp;\n if (age > currentIdleTimeout) return;\n }\n\n if (currentDirection.magnitude < minVelocity) return;\n\n // Use smoothed position for fluid movement\n const smoothX = currentDirection.smoothX;\n const smoothY = currentDirection.smoothY;\n\n const arrowColor = color || \"#FF9800\";\n \n ctx.save();\n\n // Draw arrow at smoothed position with smoothed angle\n drawArrow(ctx, smoothX, smoothY, currentDirection.angle, size, arrowColor);\n\n ctx.restore();\n }\n\n function drawArrow(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n angle: number,\n length: number,\n color: string\n ) {\n // Triangle dimensions (only the arrow head)\n const triangleHeight = length * 0.6;\n const triangleWidth = length * 0.4;\n\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(angle);\n\n // Draw filled triangle pointing in the direction of movement\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.moveTo(triangleHeight / 2, 0); // Tip of the triangle\n ctx.lineTo(-triangleHeight / 2, -triangleWidth / 2); // Bottom left\n ctx.lineTo(-triangleHeight / 2, triangleWidth / 2); // Bottom right\n ctx.closePath();\n ctx.fill();\n\n ctx.restore();\n }\n }\n);\n","/**\n * Velo Plot - Built-in Plugins\n * \n * Collection of official plugins that demonstrate the plugin system\n * capabilities and provide common functionality.\n * \n * @module plugins/builtins\n */\n\nexport * from \"./crosshair\";\nexport * from \"./stats\";\nexport * from \"./watermark\";\nexport * from \"./grid-highlight\";\nexport * from \"./data-logger\";\nexport * from \"./direction-indicator\";\n\nimport { CrosshairPlugin } from \"./crosshair\";\nimport { StatsPlugin } from \"./stats\";\nimport { WatermarkPlugin } from \"./watermark\";\nimport { GridHighlightPlugin } from \"./grid-highlight\";\nimport { DataLoggerPlugin } from \"./data-logger\";\nimport { DirectionIndicatorPlugin } from \"./direction-indicator\";\n\n/**\n * Plugin collection for easy registration\n */\nexport const BuiltinPlugins = {\n Crosshair: CrosshairPlugin,\n Statistics: StatsPlugin,\n Watermark: WatermarkPlugin,\n GridHighlight: GridHighlightPlugin,\n DataLogger: DataLoggerPlugin,\n DirectionIndicator: DirectionIndicatorPlugin,\n};\n","/**\n * @fileoverview Drag & Drop editing plugin for interactive point manipulation\n * @module plugins/drag-edit\n */\n\nimport type {\n PluginDragEditConfig,\n DragEditAPI,\n DraggedPoint,\n DragEditEvent,\n DragConstraint,\n} from './types';\nimport type {\n ChartPlugin,\n PluginContext,\n PluginManifest,\n} from '../types';\n\nconst manifest: PluginManifest = {\n name: 'velo-plot-drag-edit',\n version: '1.0.0',\n description: 'Interactive drag & drop editing of data points',\n provides: ['drag-edit', 'point-editing'],\n tags: ['interaction', 'editing', 'ux'],\n};\n\nconst DEFAULT_CONFIG: Required<PluginDragEditConfig> = {\n enabled: true,\n constraint: 'both',\n snapToGrid: false,\n snapIntervalX: 1,\n snapIntervalY: 1,\n dragThreshold: 5,\n hitRadius: 10,\n editableSeries: [],\n validator: () => ({ valid: true }),\n onDragStart: () => {},\n onDrag: () => {},\n onDragEnd: () => {},\n highlightColor: '#ffff00',\n showPreview: true,\n previewStyle: {\n color: '#ffffff',\n width: 2,\n dash: [5, 5],\n opacity: 0.5,\n },\n};\n\nexport function PluginDragEdit(\n userConfig: Partial<PluginDragEditConfig> = {}\n): ChartPlugin<PluginDragEditConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n \n // Drag state\n let isDragging = false;\n let draggedPoint: DraggedPoint | null = null;\n let dragStartX = 0;\n let dragStartY = 0;\n let hasMoved = false;\n\n /**\n * Find nearest point to mouse position\n */\n function findNearestPoint(mouseX: number, mouseY: number): DraggedPoint | null {\n if (!ctx) return null;\n\n // Use built-in pick functionality\n const picked = ctx.coords.pickPoint(mouseX, mouseY, config.hitRadius);\n \n if (!picked) return null;\n\n // Check if series is editable\n if (config.editableSeries.length > 0 && !config.editableSeries.includes(picked.seriesId)) {\n return null;\n }\n\n return {\n seriesId: picked.seriesId,\n index: picked.index,\n originalX: picked.x,\n originalY: picked.y,\n currentX: picked.x,\n currentY: picked.y,\n };\n }\n\n /**\n * Convert pixel coordinates to data coordinates\n */\n function pixelToData(pixelX: number, pixelY: number): { x: number; y: number } {\n if (!ctx) return { x: 0, y: 0 };\n\n return {\n x: ctx.coords.pixelToDataX(pixelX),\n y: ctx.coords.pixelToDataY(pixelY),\n };\n }\n\n /**\n * Snap value to grid\n */\n function snapToGrid(value: number, interval: number): number {\n return Math.round(value / interval) * interval;\n }\n\n /**\n * Apply drag constraints\n */\n function applyConstraints(\n newX: number,\n newY: number,\n constraint: DragConstraint\n ): { x: number; y: number } {\n if (!draggedPoint) return { x: newX, y: newY };\n\n switch (constraint) {\n case 'x':\n return { x: newX, y: draggedPoint.originalY };\n case 'y':\n return { x: draggedPoint.originalX, y: newY };\n case 'none':\n return { x: draggedPoint.originalX, y: draggedPoint.originalY };\n default:\n return { x: newX, y: newY };\n }\n }\n\n /**\n * Validate and apply snapping\n */\n function validateAndSnap(x: number, y: number): { x: number; y: number; valid: boolean } {\n let finalX = x;\n let finalY = y;\n\n // Apply snapping\n if (config.snapToGrid) {\n finalX = snapToGrid(x, config.snapIntervalX);\n finalY = snapToGrid(y, config.snapIntervalY);\n }\n\n // Run custom validation\n if (draggedPoint && config.validator) {\n const tempPoint: DraggedPoint = { ...draggedPoint, currentX: finalX, currentY: finalY };\n const validation = config.validator(tempPoint);\n\n if (typeof validation === 'boolean') {\n return { x: finalX, y: finalY, valid: validation };\n }\n\n if (!validation.valid) {\n return { x: finalX, y: finalY, valid: false };\n }\n\n // Apply snap suggestions from validator\n if (validation.snapX !== undefined) finalX = validation.snapX;\n if (validation.snapY !== undefined) finalY = validation.snapY;\n }\n\n return { x: finalX, y: finalY, valid: true };\n }\n\n /**\n * Update point data\n */\n function updatePointData(seriesId: string, index: number, newX: number, newY: number): void {\n if (!ctx) return;\n\n const series = (ctx.chart as any).getSeries?.(seriesId);\n if (!series) return;\n\n const data = series.getData();\n if (!data || !data.x || !data.y) return;\n\n // Update the data arrays\n data.x[index] = newX;\n data.y[index] = newY;\n\n // Invalidate buffers to trigger GPU upload\n series.invalidateBuffers?.();\n\n // Trigger chart re-render\n ctx.requestRender();\n }\n\n /**\n * Create drag event\n */\n function createDragEvent(): DragEditEvent | null {\n if (!draggedPoint) return null;\n\n return {\n seriesId: draggedPoint.seriesId,\n index: draggedPoint.index,\n oldX: draggedPoint.originalX,\n oldY: draggedPoint.originalY,\n newX: draggedPoint.currentX,\n newY: draggedPoint.currentY,\n deltaX: draggedPoint.currentX - draggedPoint.originalX,\n deltaY: draggedPoint.currentY - draggedPoint.originalY,\n };\n }\n\n /**\n * Draw preview overlay\n */\n function drawPreview(pCtx: PluginContext): void {\n if (!isDragging || !draggedPoint || !config.showPreview) return;\n\n const { render, coords } = pCtx;\n const { ctx2d } = render;\n if (!ctx2d) return;\n\n ctx2d.save();\n\n // Convert data coordinates to pixel coordinates\n const origPixelX = coords.dataToPixelX(draggedPoint.originalX);\n const origPixelY = coords.dataToPixelY(draggedPoint.originalY);\n \n const currPixelX = coords.dataToPixelX(draggedPoint.currentX);\n const currPixelY = coords.dataToPixelY(draggedPoint.currentY);\n\n // Draw preview line from original to current position\n ctx2d.strokeStyle = config.previewStyle.color || '#ffffff';\n ctx2d.lineWidth = config.previewStyle.width || 2;\n ctx2d.globalAlpha = config.previewStyle.opacity || 0.5;\n ctx2d.setLineDash(config.previewStyle.dash || [5, 5]);\n\n ctx2d.beginPath();\n ctx2d.moveTo(origPixelX, origPixelY);\n ctx2d.lineTo(currPixelX, currPixelY);\n ctx2d.stroke();\n\n // Draw highlight circle at current position\n ctx2d.globalAlpha = 1;\n ctx2d.fillStyle = config.highlightColor;\n ctx2d.setLineDash([]);\n ctx2d.beginPath();\n ctx2d.arc(currPixelX, currPixelY, 6, 0, Math.PI * 2);\n ctx2d.fill();\n\n // Draw outline\n ctx2d.strokeStyle = '#000000';\n ctx2d.lineWidth = 1;\n ctx2d.stroke();\n\n ctx2d.restore();\n }\n\n // API implementation\n const api: DragEditAPI & Record<string, unknown> = {\n enable() {\n config.enabled = true;\n },\n disable() {\n config.enabled = false;\n if (isDragging) {\n draggedPoint = null;\n isDragging = false;\n hasMoved = false;\n ctx?.requestRender();\n }\n },\n isEnabled() {\n return config.enabled;\n },\n setEditableSeries(seriesIds: string[]) {\n config.editableSeries = seriesIds;\n },\n getDraggedPoint() {\n return draggedPoint;\n },\n cancelDrag() {\n if (isDragging && draggedPoint) {\n draggedPoint = null;\n isDragging = false;\n hasMoved = false;\n ctx?.requestRender();\n }\n },\n updateConfig(newConfig: Partial<PluginDragEditConfig>) {\n Object.assign(config, newConfig);\n },\n };\n\n return {\n manifest,\n\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n\n // Attach to chart API\n (ctx.chart as any).dragEdit = api;\n },\n\n onDestroy(_pluginCtx: PluginContext) {\n // Remove from chart API\n delete (_pluginCtx.chart as any).dragEdit;\n\n ctx = null;\n },\n\n onInteraction(_pluginCtx: PluginContext, event: import('../types').InteractionEvent) {\n if (!config.enabled) return;\n\n if (event.type === 'mousedown') {\n const point = findNearestPoint(event.pixelX, event.pixelY);\n if (point) {\n draggedPoint = point;\n dragStartX = event.pixelX;\n dragStartY = event.pixelY;\n hasMoved = false;\n isDragging = false;\n // Prevent default to stop panning when clicking on a point\n event.preventDefault();\n }\n } else if (event.type === 'mousemove') {\n if (!draggedPoint) return;\n\n // Check if we've moved beyond threshold\n if (!isDragging) {\n const dx = event.pixelX - dragStartX;\n const dy = event.pixelY - dragStartY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (distance > config.dragThreshold) {\n isDragging = true;\n hasMoved = true;\n\n // Fire drag start event\n const dragEvent = createDragEvent();\n if (dragEvent) config.onDragStart(dragEvent);\n } else {\n return;\n }\n }\n\n // Prevent default during dragging\n if (isDragging) {\n event.preventDefault();\n }\n\n // Convert to data coordinates\n let { x, y } = pixelToData(event.pixelX, event.pixelY);\n\n // Apply constraints\n ({ x, y } = applyConstraints(x, y, config.constraint));\n\n // Validate and snap\n const { x: finalX, y: finalY, valid } = validateAndSnap(x, y);\n\n if (valid) {\n draggedPoint.currentX = finalX;\n draggedPoint.currentY = finalY;\n\n // Fire drag event (for callbacks)\n const dragEvent = createDragEvent();\n if (dragEvent) config.onDrag(dragEvent);\n\n // Request render to show preview line\n ctx?.requestRender();\n }\n } else if (event.type === 'mouseup') {\n if (!draggedPoint) return;\n\n if (isDragging && hasMoved) {\n // Apply the changes\n updatePointData(\n draggedPoint.seriesId,\n draggedPoint.index,\n draggedPoint.currentX,\n draggedPoint.currentY\n );\n\n // Fire drag end event\n const dragEvent = createDragEvent();\n if (dragEvent) config.onDragEnd(dragEvent);\n\n // Prevent default on mouseup to avoid triggering click events\n event.preventDefault();\n }\n\n // Reset state\n draggedPoint = null;\n isDragging = false;\n hasMoved = false;\n ctx?.requestRender();\n }\n },\n\n onRenderOverlay(pluginCtx: PluginContext) {\n drawPreview(pluginCtx);\n },\n\n api,\n };\n}\n\nexport default PluginDragEdit;\n\n// Type exports\nexport type {\n PluginDragEditConfig,\n DragEditAPI,\n DraggedPoint,\n DragEditEvent,\n DragConstraint,\n} from './types';\n","/**\n * Velo Plot - Plugin System\n * \n * Comprehensive plugin architecture for extending chart functionality.\n * \n * Features:\n * - Complete lifecycle hooks (init, render, data, view, interaction, destroy)\n * - Rich plugin context with access to all chart internals\n * - Plugin storage for persistent state\n * - Dependency management between plugins\n * - Global registry for third-party plugins\n * - Built-in plugins for common use cases\n * \n * @packageDocumentation\n * @module plugins\n */\n\n// ============================================\n// Core Types\n// ============================================\nexport type {\n // Manifest & Metadata\n PluginVersion,\n PluginCapability,\n PluginManifest,\n\n // Context Types\n PluginContext,\n RenderContext,\n CoordinateContext,\n DataContext,\n UIContext,\n EventContext,\n PluginStorage,\n PluginLogger,\n OverlayOptions,\n NotificationOptions,\n PickResult,\n\n // Hook Event Types\n BeforeRenderEvent,\n AfterRenderEvent,\n InteractionEvent,\n ViewChangeEvent,\n SeriesChangeEvent,\n DataUpdateEvent,\n\n // Plugin Types\n ChartPlugin,\n PluginFactory,\n TypedPlugin,\n\n // Manager Types\n PluginManager,\n PluginRegistry,\n PluginRegistryEntry,\n} from \"./types\";\n\n// ============================================\n// Core Implementation\n// ============================================\nexport { createPluginContext } from \"./PluginContext\";\nexport type { ContextDependencies } from \"./PluginContext\";\n\nexport { PluginManagerImpl } from \"./PluginManager\";\n\n// ============================================\n// Registry\n// ============================================\nexport {\n getPluginRegistry,\n registerPlugin,\n definePlugin,\n defineAndRegister,\n loadPlugin,\n listPluginsByCategory,\n validateManifest,\n checkPluginCompatibility,\n} from \"./PluginRegistry\";\n\n// ============================================\n// Built-in Plugins\n// ============================================\nexport {\n // Individual plugins\n CrosshairPlugin,\n StatsPlugin,\n WatermarkPlugin,\n GridHighlightPlugin,\n DataLoggerPlugin,\n DirectionIndicatorPlugin,\n\n // Plugin collection\n BuiltinPlugins,\n\n // Plugin configs\n type CrosshairPluginConfig,\n type StatsPluginConfig,\n type WatermarkPluginConfig,\n type GridHighlightConfig,\n type DataLoggerConfig,\n type DirectionIndicatorConfig,\n} from \"./builtins\";\n\n// ============================================\n// Modular Plugins\n// ============================================\nexport { Plugin3D, type Plugin3DConfig } from \"./3d\";\nexport { PluginGpu, type PluginGpuConfig } from \"./gpu\";\nexport { PluginAnalysis, type PluginAnalysisConfig } from \"./analysis\";\nexport { PluginTools, type PluginToolsConfig } from \"./tools\";\nexport { PluginAnnotations, type PluginAnnotationsConfig } from \"./annotations\";\nexport { PluginStreaming, type PluginStreamingConfig } from \"./streaming\";\nexport { PluginThemeEditor, type PluginThemeEditorConfig } from \"./theme-editor\";\nexport { PluginI18n, type PluginI18nConfig } from \"./i18n\";\nexport { PluginKeyboard, type PluginKeyboardConfig } from \"./keyboard\";\nexport { PluginClipboard, type PluginClipboardConfig } from \"./clipboard\";\nexport { PluginSync, type PluginSyncConfig } from \"./sync\";\nexport { PluginDebug, type PluginDebugConfig } from \"./debug\";\nexport { PluginLoading, type PluginLoadingConfig } from \"./loading\";\nexport { PluginDataExport, type PluginDataExportConfig } from \"./data-export\";\nexport { PluginContextMenu, type PluginContextMenuConfig } from \"./context-menu\";\nexport { PluginAnomalyDetection, type PluginAnomalyDetectionConfig, type AnomalyDetectionResult, type AnomalyPoint, type AnomalyMethod } from \"./anomaly-detection\";\nexport { PluginMLIntegration, type PluginMLIntegrationConfig, type MLIntegrationAPI, type MLModelAPI, type PredictionResult, type VisualizationConfig } from \"./ml-integration\";\nexport { PluginPatternRecognition, type PluginPatternRecognitionConfig, type PatternRecognitionAPI, type PatternMatch, type PatternDetectionResult } from \"./pattern-recognition\";\nexport { PluginRegression, type PluginRegressionConfig, type RegressionAPI, type RegressionResult, type RegressionData } from \"./regression\";\nexport { PluginRadar, type PluginRadarConfig, type RadarAPI, type RadarSeriesData, type RadarPoint } from \"./radar\";\nexport { PluginSnapshot, type PluginSnapshotConfig, type SnapshotExportAPI, type SnapshotExportOptions, type SnapshotResolution, type SnapshotFormat } from \"./snapshot\";\nexport { PluginDataTransform, type PluginDataTransformConfig, type DataTransformAPI, type TransformOp, type TransformType } from \"./data-transform\";\nexport { PluginLaTeX, type PluginLaTeXConfig, type LaTeXPluginAPI, type LaTeXDimensions } from \"./latex\";\nexport * from \"./forecasting\";\n\n// Drag & Drop Editing\nexport { PluginDragEdit, type PluginDragEditConfig, type DragEditAPI, type DragEditEvent } from \"./drag-edit\";\n\n// Caching\nexport { PluginCaching, type PluginCachingConfig, type CachingAPI, type CacheStats } from \"./caching\";\n\n// Lazy Loading\nexport { PluginLazyLoad, type PluginLazyLoadConfig, type LazyLoadAPI, type DataProvider } from \"./lazy-load\";\n\n// Broken Axis\nexport { PluginBrokenAxis, type PluginBrokenAxisConfig, type BrokenAxisAPI, type AxisBreak } from \"./broken-axis\";\n\n// Video Recorder\nexport { PluginVideoRecorder, type PluginVideoRecorderConfig, type VideoRecorderAPI, type VideoRecorderOptions } from \"./video-recorder\";\n\n// Offscreen Rendering\nexport { PluginOffscreen, type PluginOffscreenConfig, type OffscreenAPI, type OffscreenStats, type OffscreenMode, type OffscreenTransferMode, type OffscreenFallbackMode } from \"./offscreen\";\n\n// Virtualization\nexport { PluginVirtualization, type PluginVirtualizationConfig, type VirtualizationAPI, type VirtualizationStats, type VirtualizationMode, type VirtualizationStrategy } from \"./virtualization\";\n\n// Stage 2 — Trading\nexport { PluginDrawingTools, type PluginDrawingToolsConfig, type DrawingToolsAPI, type DrawingMode } from \"./drawing-tools\";\nexport { PluginReplay, type PluginReplayConfig, type ReplayAPI } from \"./replay\";\n\n// ROI\nexport { PluginROI, type PluginROIConfig, type RoiAPI, type RoiRegion, type RoiPoint, type RoiMaskResult, type RoiTool, type RoiEvent, type RoiSelectedEvent } from \"./roi\";\n\n// ============================================\n// Helper for creating typed plugins\n// ============================================\n\n/**\n * Helper function to create a plugin with proper typing\n * \n * @example\n * ```typescript\n * const MyPlugin = createPlugin({\n * manifest: {\n * name: 'my-plugin',\n * version: '1.0.0',\n * provides: ['analysis'],\n * },\n * onInit(ctx) {\n * ctx.log.info('Plugin initialized!');\n * },\n * onAfterRender(ctx, event) {\n * // Custom rendering\n * },\n * api: {\n * doSomething() { return 'done'; }\n * }\n * });\n * \n * chart.use(MyPlugin);\n * ```\n */\nexport function createPlugin<TConfig = void, TApi extends Record<string, unknown> = {}>(\n definition: import(\"./types\").ChartPlugin<TConfig> & { api?: TApi }\n): import(\"./types\").ChartPlugin<TConfig> & { api: TApi } {\n return definition as import(\"./types\").ChartPlugin<TConfig> & { api: TApi };\n}\n\n/**\n * Helper function to create a configurable plugin factory\n * \n * @example\n * ```typescript\n * interface MyConfig {\n * color: string;\n * enabled: boolean;\n * }\n * \n * const MyPlugin = createConfigurablePlugin<MyConfig>(\n * {\n * name: 'my-plugin',\n * version: '1.0.0',\n * },\n * (config) => ({\n * onInit(ctx) {\n * ctx.log.info(`Color: ${config?.color}`);\n * }\n * })\n * );\n * \n * chart.use(MyPlugin({ color: 'red', enabled: true }));\n * ```\n */\nexport function createConfigurablePlugin<TConfig = void>(\n manifest: import(\"./types\").PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): import(\"./types\").PluginFactory<TConfig> {\n return (config?: TConfig) => ({\n ...factory(config),\n manifest,\n });\n}\n","/**\n * Velo Plot - High-Performance Scientific Charting\n */\nimport \"./scientific/registerScientific\";\nimport { registerTradingBundle } from \"./trading/registerTrading\";\n\nregisterTradingBundle();\n\n// ============================================\n// Core exports\n// ============================================\nexport { createChart } from \"./core/Chart\";\nexport { Series } from \"./core/Series\";\nexport { EventEmitter } from \"./core/EventEmitter\";\nexport type { Chart, ChartOptions, ExportOptions } from \"./core/Chart\";\n\n// ============================================\n// Animation\n// ============================================\nexport {\n AnimationEngine,\n easings,\n DEFAULT_ANIMATION_CONFIG,\n mergeAnimationConfig,\n getSharedAnimationEngine,\n} from \"./core/animation\";\nexport type {\n AnimationOptions,\n AnimationHandle,\n BoundsAnimation,\n ChartAnimationConfig,\n EasingFunction,\n EasingName,\n} from \"./core/animation\";\n\n// ============================================\n// Chart Initialization Queue (for multiple charts)\n// ============================================\nexport {\n ChartInitQueue,\n getChartInitQueue,\n queueChartInit,\n waitForAnimations,\n resetChartQueue,\n} from \"./core/ChartInitQueue\";\n\n// ============================================\n// Annotations\n// ============================================\nexport { AnnotationManager } from \"./core/annotations\";\nexport type {\n Annotation,\n AnnotationType,\n HorizontalLineAnnotation,\n VerticalLineAnnotation,\n RectangleAnnotation,\n BandAnnotation,\n TextAnnotation,\n ArrowAnnotation,\n} from \"./core/annotations\";\n\n// ============================================\n// Types\n// ============================================\nexport type {\n AxisOptions,\n SeriesOptions,\n SeriesData,\n SeriesStyle,\n SeriesUpdateData,\n ZoomOptions,\n CursorOptions,\n ChartEventMap,\n Point,\n Bounds,\n Range,\n ScaleType,\n SeriesType,\n StepMode,\n ErrorBarStyle,\n ErrorBarDirection,\n ScatterSymbol,\n DeltaMeasurement,\n PeakMeasurement,\n // Polar Charts\n PolarMode,\n PolarData,\n PolarStyle,\n PolarOptions,\n // Ternary Charts\n TernaryData,\n TernaryStyle,\n TernaryOptions,\n} from \"./types\";\n\n// ============================================\n// Scales\n// ============================================\nexport { LinearScale, LogScale, createScale, type Scale } from \"./scales\";\n\n// ============================================\n// Renderer\n// ============================================\nexport {\n NativeWebGLRenderer,\n interleaveData,\n parseColor,\n createRenderer,\n createNativeRenderer,\n WebGPURenderer,\n type WebGPURendererOptions,\n type IWebGLRenderer,\n type SeriesRenderData,\n type RenderOptions,\n} from \"./renderer\";\n\n// ============================================\n// Theme\n// ============================================\nexport {\n DARK_THEME,\n LIGHT_THEME,\n MIDNIGHT_THEME,\n ELECTROCHEM_THEME,\n DEFAULT_THEME,\n createTheme,\n getThemeByName,\n type ChartTheme,\n type GridTheme,\n type AxisTheme,\n type LegendTheme,\n type CursorTheme,\n} from \"./theme\";\n\n// ============================================\n// Layout & Positioning\n// ============================================\nexport {\n DEFAULT_LAYOUT,\n mergeLayoutOptions,\n type LayoutOptions,\n type LegendOptions,\n type CrosshairOptions,\n type CrosshairValueMode,\n type CornerPosition,\n type ChartTitleOptions,\n type AxisLayoutOptions,\n type ChartMargins,\n type PlotAreaPadding,\n type LegendPositionPreset,\n type ToolbarPositionPreset,\n type ToolbarPosition,\n} from \"./core/layout\";\n\n// ============================================\n// Overlay\n// ============================================\nexport {\n OverlayRenderer,\n} from \"./core/OverlayRenderer\";\n\n// ============================================\n// Persistence & Serialization\n// ============================================\nexport {\n SERIALIZATION_VERSION,\n encodeFloat32Array,\n decodeFloat32Array,\n compressString,\n decompressString,\n stateToUrlHash,\n urlHashToState,\n validateChartState,\n StateHistory,\n type SerializedAxis,\n type SerializedSeries,\n type ChartState,\n type SerializeOptions,\n type DeserializeOptions,\n type StateSnapshot,\n} from \"./serialization\";\n\nexport type {\n PlotArea,\n CursorState,\n} from \"./types\";\n\n// ============================================\n// Tooltip System\n// ============================================\nexport {\n TooltipManager,\n TOOLTIP_THEMES,\n getTooltipThemeForChartTheme,\n} from \"./plugins/tools/tooltip\";\n\nexport type {\n TooltipData,\n TooltipType,\n TooltipTheme,\n TooltipOptions,\n TooltipTemplate,\n DataPointTooltip,\n CrosshairTooltip,\n HeatmapTooltip,\n} from \"./plugins/tools/tooltip\";\n\n// ============================================\n// Downsampling\n// ============================================\nexport {\n lttbDownsample,\n minMaxDownsample,\n ohlcMinMaxDownsample,\n calculateTargetPoints,\n sliceSeriesToViewport,\n lowerBoundX,\n upperBoundX,\n} from \"./workers/downsample\";\n\nexport {\n downsampleAsync,\n ohlcDownsampleAsync,\n destroyDownsamplePool,\n getDownsamplePoolSize,\n} from \"./workers/downsampleAsync\";\n\nexport {\n rsiAsync,\n smaAsync,\n emaAsync,\n macdAsync,\n bollingerBandsAsync,\n destroyIndicatorPool,\n} from \"./workers/indicatorsAsync\";\n\nexport { WorkerPool, nextTaskId } from \"./workers/pool\";\nexport type { WorkerPoolOptions } from \"./workers/pool\";\n\n// ============================================\n// Data Analysis utilities\n// ============================================\nexport {\n formatWithPrefix,\n formatValue,\n formatScientific,\n getBestPrefix,\n detectCycles,\n generateCycleColors,\n detectPeaks,\n validateData,\n calculateStats,\n movingAverage,\n downsampleLTTB,\n subtractBaseline,\n // Math\n integrate,\n derivative,\n cumulativeIntegral,\n calculateR2,\n solveLinearSystem,\n // Spectral / FFT\n fft,\n ifft,\n analyzeSpectrum,\n powerSpectrum,\n dominantFrequency,\n analyzeComplexSpectrum,\n fftFromComplexInput,\n hanningWindow,\n hammingWindow,\n blackmanWindow,\n nextPowerOf2,\n complexToArrays,\n arraysToComplex,\n ifftFromArrays,\n ifftComplex,\n getPositiveFrequencies,\n // Filters\n lowPassFilter,\n highPassFilter,\n bandPassFilter,\n bandStopFilter,\n butterworth,\n exponentialMovingAverage,\n gaussianSmooth,\n savitzkyGolay,\n medianFilter,\n singleFrequencyFilter,\n // Statistics\n crossCorrelation,\n autoCorrelation,\n detectAnomalies,\n trapezoidalIntegration,\n simpsonsIntegration,\n tTest,\n generateContours,\n joinSegments,\n type ContourLine,\n type ContourPoint,\n type ContourLabel,\n type ContourOptions,\n type CycleInfo,\n type Peak,\n type PrefixInfo,\n type ValidationResult,\n type DataStats,\n type FFTResult,\n type ComplexFFTResult,\n type PowerSpectrumResult,\n type FilterOptions,\n type ButterworthOptions,\n type SingleFrequencyFilterOptions,\n} from \"./plugins/analysis\";\n\n// ============================================\n// Streaming utilities\n// ============================================\nexport {\n createWebSocketStream,\n connectStreamToChart,\n createMessageParser,\n createMockStream,\n type WebSocketStream,\n type WebSocketStreamConfig,\n type DataPoint,\n type StreamStats,\n type WebSocketState,\n} from \"./streaming\";\n\n// ============================================\n// React bindings\n// ============================================\nexport {\n VeloPlot,\n StackedPlot,\n useVeloPlot,\n useStackedPlot,\n useIndicator,\n useChartSync,\n useChartGroup,\n SciPlot,\n SciChart,\n useSciPlot,\n useSciChart,\n type VeloPlotProps,\n type VeloPlotRef,\n type VeloPlotSeries,\n type StackedPlotProps,\n type StackedPlotRef,\n type UseVeloPlotOptions,\n type UseVeloPlotReturn,\n type UseStackedPlotOptions,\n type UseStackedPlotReturn,\n type UseIndicatorReturn,\n type UseChartSyncReturn,\n type SciPlotProps,\n type SciPlotRef,\n type SciPlotSeries,\n type SciChartProps,\n type SciChartRef,\n type SciChartSeries,\n type UseSciPlotOptions,\n type UseSciPlotReturn,\n type UseSciChartOptions,\n type UseSciChartReturn,\n} from \"./react\";\n\n// ============================================\n// GPU Abstraction Layer (Experimental)\n// ============================================\nexport {\n // Backends\n WebGPUBackend,\n WebGLBackend,\n\n // Renderer facade\n GpuRenderer,\n createGpuRenderer,\n\n // Adapter utilities\n SeriesAdapter,\n parseColorToRGBA,\n\n // Resource management\n PipelineCache,\n BaseBufferStore,\n BaseTextureStore,\n\n // Benchmark\n GpuBenchmark,\n\n // GPU Compute\n GpuCompute,\n} from \"./gpu\";\n\nexport type {\n // Core types\n GpuBackendType,\n RGBA,\n GpuViewport,\n GpuBackend,\n BufferId,\n TextureId,\n\n // Frame types\n FrameUniforms,\n\n // Draw types\n DrawKind,\n DrawCall,\n DrawList,\n PointSymbol,\n\n // Adapter types\n SeriesData as GpuSeriesData,\n Bounds as GpuBounds,\n GpuRenderOptions,\n GpuRendererOptions,\n BackendPreference,\n WebGPUBackendOptions,\n\n // Benchmark types\n BenchmarkResult,\n BenchmarkOptions,\n\n // Compute types\n DataStats as GpuDataStats,\n DataBounds as GpuDataBounds,\n Peak as GpuPeak,\n GpuComputeOptions,\n} from \"./gpu\";\n\n// ============================================\n// Internationalization (i18n)\n// ============================================\nexport {\n setGlobalLocale,\n getGlobalLocale,\n getLocale,\n registerLocale,\n createLocaleFormatter,\n LOCALE_EN_US,\n LOCALE_ES_ES,\n LOCALE_DE_DE,\n LOCALE_FR_FR,\n LOCALE_PT_BR,\n LOCALE_ZH_CN,\n LOCALE_JA_JP,\n type LocaleConfig,\n type LocaleFormatter,\n} from \"./core/locale\";\n\n// ============================================\n// Keyboard Shortcuts\n// ============================================\nexport {\n KeyBindingManager,\n DEFAULT_KEY_BINDINGS,\n createKeyBinding,\n parseShortcut,\n type KeyAction,\n type KeyBinding,\n type KeyBindingCallbacks,\n type KeyBindingManagerOptions,\n} from \"./core/keybindings\";\n\n// ============================================\n// Clipboard\n// ============================================\nexport {\n ClipboardManager,\n getClipboardManager,\n copyToClipboard,\n formatData,\n type ClipboardFormat,\n type ClipboardOptions,\n type ClipboardDataPoint,\n type ClipboardResult,\n} from \"./core/clipboard\";\n\n// ============================================\n// Debug Overlay\n// ============================================\nexport {\n DebugOverlay,\n createDebugOverlay,\n enableDebugMode,\n type DebugStats,\n type DebugOverlayOptions,\n} from \"./core/debug\";\n\n// ============================================\n// Loading Indicators\n// ============================================\nexport {\n LoadingIndicator,\n createLoadingIndicator,\n showLoading,\n showProgress,\n type LoadingIndicatorType,\n type LoadingIndicatorOptions,\n type LoadingState,\n} from \"./core/loading\";\n\n// ============================================\n// Testing Utilities (for test environments)\n// ============================================\nexport {\n // Data generators\n generateSineWave,\n generateSquareWave,\n generateSawtoothWave,\n generateTriangleWave,\n generateRandomData,\n generateCVData,\n generateNyquistData,\n\n // Benchmarking\n benchmarkRender,\n assertPerformance,\n compareGridBackends,\n evaluateRendererCompare,\n benchmarkCanvasGrid,\n benchmarkWebGLGrid,\n getBaseline,\n compareScenarioToBaseline,\n\n // Snapshots\n createSnapshot,\n compareSnapshots,\n\n // Utilities\n waitForFrames,\n waitFor,\n\n // Types\n type MockChartOptions,\n type WaveformOptions,\n type RandomDataOptions,\n type BenchmarkResult as TestBenchmarkResult,\n type BenchmarkOptions as TestBenchmarkOptions,\n type SnapshotOptions,\n type ChartSnapshot,\n} from \"./testing\";\n\n// ============================================\n// Chart Synchronization\n// ============================================\nexport {\n ChartGroup,\n createChartGroup,\n linkCharts,\n createMasterSlave,\n type SyncAxis,\n type SyncOptions,\n type ChartLike,\n type SyncEvent,\n} from \"./core/sync\";\n\n// ============================================\n// Stacked multi-pane charts\n// ============================================\nexport {\n createStackedChart,\n STACKED_MAX_PANES,\n STACKED_DEFAULT_MIN_PANE_RATIO,\n type StackedChart,\n type StackedChartOptions,\n type StackedPaneConfig,\n type StackedSyncOptions,\n} from \"./core/stacked\";\n\n// ============================================\n// Trading indicator panes (histogram + lines + fills)\n// ============================================\nexport {\n buildIndicatorSeries,\n createIndicatorSeries,\n buildIndicatorPane,\n buildIndicatorPaneFromPreset,\n addIndicatorToChart,\n computeIndicatorFromSeries,\n computeIndicatorPreset,\n detectIndicatorMarkers,\n type IndicatorData,\n type IndicatorSeriesOptions,\n type IndicatorStyle,\n type IndicatorLineLayer,\n type IndicatorLineColorZones,\n type BuildIndicatorPaneOptions,\n type AddIndicatorOptions,\n type AddIndicatorResult,\n type IndicatorPresetName,\n} from \"./core/indicator\";\n\n// ============================================\n// Stage 2 — Trading (time scale, markers, heikin-ashi)\n// ============================================\nexport {\n mapToBusinessDayScale,\n isBusinessDay,\n businessDaySpanMs,\n type TimeScaleOptions,\n type BusinessDayMapping,\n} from \"./core/time/TimeScale\";\nexport {\n isBusinessDayScaleActive,\n applyBusinessDayX,\n formatBusinessDayTick,\n} from \"./core/time/applyTimeScale\";\nexport { computeHeikinAshi } from \"./core/chart/heikinAshi\";\nexport { buildPositionLineAnnotation, type PositionLineOptions } from \"./core/chart/positionLines\";\nexport type { DatafeedAdapter, Bar, SymbolInfo } from \"./trading/datafeed\";\nexport { barsToOhlc } from \"./trading/datafeed\";\nexport { createMockDatafeed } from \"./trading/mockDatafeed\";\nexport type {\n CandlestickMarker,\n CandlestickMarkerPosition,\n CandlestickMarkerShape,\n} from \"./core/chart/candlestickMarkers\";\nexport type { PriceAlertOptions } from \"./core/chart/ChartAlerts\";\n\n// ============================================\n// Theme Editor\n// ============================================\nexport {\n ThemeEditor,\n createThemeEditor,\n getPresetTheme,\n getPresetNames,\n THEME_PRESETS,\n type EditorTheme,\n type ThemeEditorOptions,\n type ThemePreset,\n type ColorGroup,\n type ColorProperty,\n} from \"./core/theme-editor\";\n\n// ============================================\n// Streaming Backpressure\n// ============================================\nexport {\n BackpressureManager,\n CircularBuffer,\n createBackpressureManager,\n createRealtimeBackpressure,\n createLosslessBackpressure,\n type OverflowStrategy,\n type BackpressureConfig,\n type PressureStats,\n type BufferHealth,\n} from \"./streaming/backpressure\";\n\n// ============================================\n// Financial/Technical Indicators\n// ============================================\nexport {\n sma,\n ema,\n wma,\n dema,\n tema,\n rsi,\n macd,\n stochastic,\n roc,\n momentum,\n bollingerBands,\n atr,\n standardDeviation,\n vwap,\n obv,\n adx,\n aroon,\n percentChange,\n cumsum,\n normalize,\n type IndicatorResult,\n type OHLCData,\n} from \"./plugins/analysis\";\n\n// ============================================\n// Plugin System\n// ============================================\nexport {\n // Core functionality\n createPluginContext,\n PluginManagerImpl,\n\n // Registry\n getPluginRegistry,\n registerPlugin,\n definePlugin,\n defineAndRegister,\n loadPlugin,\n listPluginsByCategory,\n validateManifest,\n checkPluginCompatibility,\n\n // Helpers\n createPlugin,\n createConfigurablePlugin,\n\n // Built-in plugins\n CrosshairPlugin,\n StatsPlugin,\n WatermarkPlugin,\n GridHighlightPlugin,\n DataLoggerPlugin,\n DirectionIndicatorPlugin,\n Plugin3D,\n PluginGpu,\n PluginTools,\n PluginAnalysis,\n PluginAnnotations,\n PluginStreaming,\n PluginThemeEditor,\n PluginI18n,\n PluginKeyboard,\n PluginClipboard,\n PluginSync,\n PluginDebug,\n PluginLoading,\n PluginDataExport,\n PluginContextMenu,\n PluginAnomalyDetection,\n PluginMLIntegration,\n PluginPatternRecognition,\n PluginRegression,\n PluginRadar,\n PluginSnapshot,\n PluginDataTransform,\n PluginLaTeX,\n PluginDragEdit,\n PluginCaching,\n PluginLazyLoad,\n PluginBrokenAxis,\n PluginVideoRecorder,\n PluginOffscreen,\n PluginVirtualization,\n PluginDrawingTools,\n PluginReplay,\n PluginROI,\n PluginForecasting,\n BuiltinPlugins,\n} from \"./plugins\";\n\nexport type {\n // Manifest & Metadata\n PluginVersion,\n PluginCapability,\n PluginManifest,\n\n // Context Types\n PluginContext,\n RenderContext,\n CoordinateContext,\n DataContext,\n UIContext as PluginUIContext,\n EventContext as PluginEventContext,\n PluginStorage,\n PluginLogger,\n OverlayOptions,\n NotificationOptions,\n PickResult,\n\n // Hook Event Types\n BeforeRenderEvent,\n AfterRenderEvent,\n InteractionEvent,\n ViewChangeEvent,\n SeriesChangeEvent,\n DataUpdateEvent,\n\n // Plugin Types\n ChartPlugin,\n PluginFactory,\n TypedPlugin,\n PluginManager,\n PluginRegistry,\n PluginRegistryEntry,\n ContextDependencies,\n\n // Built-in plugin configs\n CrosshairPluginConfig,\n StatsPluginConfig,\n WatermarkPluginConfig,\n GridHighlightConfig,\n DataLoggerConfig,\n DirectionIndicatorConfig,\n Plugin3DConfig,\n PluginGpuConfig,\n PluginToolsConfig,\n PluginAnalysisConfig,\n PluginAnnotationsConfig,\n PluginStreamingConfig,\n PluginThemeEditorConfig,\n PluginI18nConfig,\n PluginKeyboardConfig,\n PluginClipboardConfig,\n PluginSyncConfig,\n PluginDebugConfig,\n PluginLoadingConfig,\n PluginDataExportConfig,\n PluginContextMenuConfig,\n PluginAnomalyDetectionConfig,\n PluginMLIntegrationConfig,\n PluginPatternRecognitionConfig,\n PluginRegressionConfig,\n PluginRadarConfig,\n PluginSnapshotConfig,\n PluginDataTransformConfig,\n PluginLaTeXConfig,\n PluginDragEditConfig,\n PluginCachingConfig,\n PluginLazyLoadConfig,\n PluginBrokenAxisConfig,\n PluginVideoRecorderConfig,\n PluginOffscreenConfig,\n PluginVirtualizationConfig,\n PluginROIConfig,\n PluginForecastingConfig,\n\n // API & Result Types\n RegressionAPI,\n RegressionResult,\n RegressionData,\n MLIntegrationAPI,\n MLModelAPI,\n PredictionResult,\n VisualizationConfig,\n DataTransformAPI,\n TransformOp,\n TransformType,\n RadarAPI,\n RadarSeriesData,\n RadarPoint,\n LaTeXPluginAPI,\n LaTeXDimensions,\n DragEditAPI,\n DragEditEvent,\n CachingAPI,\n CacheStats,\n LazyLoadAPI,\n DataProvider,\n OffscreenAPI,\n OffscreenStats,\n OffscreenMode,\n OffscreenTransferMode,\n OffscreenFallbackMode,\n VirtualizationAPI,\n VirtualizationStats,\n VirtualizationMode,\n VirtualizationStrategy,\n RoiAPI,\n RoiRegion,\n RoiPoint,\n RoiMaskResult,\n RoiTool,\n RoiEvent,\n RoiSelectedEvent,\n BrokenAxisAPI,\n AxisBreak,\n VideoRecorderAPI,\n VideoRecorderOptions,\n SnapshotExportAPI as SnapshotAPI,\n SnapshotExportOptions,\n SnapshotResolution,\n SnapshotFormat,\n AnomalyDetectionResult,\n AnomalyPoint,\n AnomalyMethod,\n PatternRecognitionAPI,\n PatternMatch,\n PatternDetectionResult,\n ForecastingAPI,\n ForecastingOptions,\n ForecastingResult,\n ForecastingParams\n} from \"./plugins\";\n\n"],"names":["interleaveBoxPlotData","x","min","q1","median","q3","max","width","n","w","lineData","boxData","lIdx","bIdx","i","xi","mi","q1i","medi","q3i","maxti","interleaveWaterfallData","y","isSubtotal","positiveData","negativeData","subtotalData","connectorData","pIdx","nIdx","sIdx","cIdx","runningTotal","yi","isSub","barBottom","barTop","nextX","interleaveHeatmapData","z","height","numCells","result","idx","j","x0","x1","y0","y1","v00","v10","v01","v11","getColormap","name","data","t","r","g","b","interleaveCandlestickData","open","high","low","close","hollow","bullishBody","bearishBody","halfWidth","halfWick","isBullish","target","bodyTop","bodyBottom","appendRect","arr","x2","y2","updateErrorAndStepBuffers","ctx","s","d","seriesId","seriesType","errData","interleaveErrorData","stepMode","interleaveStepData","updateBarBuffer","barWidth","calculateBarWidth","interleaveBarData","updateHeatmapBuffer","hData","hStyle","_a","_c","_b","colormapName","_d","updateCandlestickBuffer","bullish","bearish","updateBoxplotBuffer","lines","boxes","updateWaterfallBuffer","wfData","updatePolarBuffer","polarData","style","angleMode","closePath","fillData","interleavePolarFillData","interleavePolarLineData","updateBandOrAreaBuffer","interleaveBandData","updateDefaultBuffer","interleaveData","registered","registerExtendedSeriesBuffers","registerSeriesBufferHandler","type","renderHeatmap","gl","prog","buffer","count","uniforms","zBounds","texture","renderBar","color","renderBoxPlot","programs","computeSeriesColor","fillColor","renderHeatmapSeries","seriesUniforms","renderBarSeries","renderBoxplotSeries","renderWaterfallSeries","dpr","positiveColor","parseColor","negativeColor","subtotalColor","connectorColor","registerExtendedFrameRenderers","registerFrameRenderer","drawGauge","plotArea","value","needleColor","needleWidth","ranges","radiusScale","startAngle","endAngle","showValue","valueColor","valueSize","label","centerX","centerY","maxRadius","totalAngle","valueRatio","currentAngle","range","rStart","rEnd","numTicks","angle","innerR","outerR","drawSankey","layout","computeSankeyLayout","nodeRegistry","links","nodeOutValue","nodeInValue","workingArea","linkOpacity","showLabels","nodeWidth","entry","src","dst","sOffset","tOffset","sValue","tValue","srcFlowHeight","dstFlowHeight","y3","cpOffset","gradient","node","grad","id","nodeName","found","isFirstLayer","isLastLayer","registerExtendedOverlayDrawers","registerOverlaySeriesDrawer","gData","gStyle","sData","sStyle","registerHeatmapProgram","bundle","createProgram","HEATMAP_VERT","HEATMAP_FRAG","registerWebGPURenderer","ChartImpl","chart","options","initWebGPURenderer","c","createGpuChartRenderer","gpu","NativeWebGLRenderer","registerExtendedSeries","exportChartSnapshot","renderSVG","captureLayoutSnapshot","registerSVGRenderer","prev","initSVGRenderer","host","patched","patchExportSVG","ChartAlertManager","events","getSeries","__publicField","alert","series","prices","latest","triggered","payload","STYLE_COLORS","STYLE_LABELS","buildPositionLineAnnotation","registerTradingSeriesPreprocessors","registerSeriesOptionsPreprocessor","opts","ha","computeHeikinAshi","isBusinessDayScaleActive","displayX","mapping","applyBusinessDayX","registerSeriesOptionsExpander","buildIndicatorSeries","registerSeriesDataPreprocessor","patchChartTradingMethods","proto","preset","addIndicatorToChart","getAlertManager","self","mode","plugin","originalDestroy","registerTradingBundle","WebGPURenderer","canvas","format","VERT_SRC","FRAG_SRC","compileShader","source","shader","vs","fs","program","buildGridLineVertices","spec","xLines","yLines","vertCount","out","o","WebGLGridSpike","buf","vertices","lineSegments","createMinimalMock2D","noop","text","getCanvas2DContext","makePlotArea","margin","tickPixelLines","_plotArea","xScale","yScale","xTickCount","yTickCount","snapLineCoord","measureFrames","runFrame","frames","samples","t0","a","avg","v","p95","benchmarkCanvasGrid","theme","DARK_THEME","LinearScale","renderer","OverlayRenderer","benchmarkWebGLGrid","spike","compareGridBackends","canvas2d","webgl","gainPercent","getBaseline","baseline","compareScenarioToBaseline","scenarioId","failures","threshold","minAllowed","maxAllowed","evaluateRendererCompare","webgpu","webgpuActive","minRatio","ratio","meetsTarget","SeededRandom","seed","generateSineWave","dx","baseValue","noiseValue","generateSquareWave","generateSawtoothWave","generateTriangleWave","generateRandomData","rng","indices","_","sortedX","sortedY","generateCVData","totalPoints","pointsPerCycle","halfCycle","E","E0","scanDirection","peakWidth","exponent","peakCurrent","capacitive","generateNyquistData","logFMin","logFMax","logF","omega","tau","realPart","imagPart","benchmarkRender","fpsHistory","frameTimes","frameCount","sum","resolve","endTime","warmupEndTime","recording","recordingStartTime","frame","now","avgRenderMs","recordElapsedMs","wallFps","renderFps","renderStart","renderEnd","frameTime","recentTimes","avgRecentTime","createSnapshot","snapshot","compareSnapshots","tolerance","differences","sa","sb","boundsKeys","key","assertPerformance","requirements","waitForFrames","remaining","tick","waitFor","ms","crosshairManifest","CrosshairPlugin","definePlugin","config","showVertical","showHorizontal","lineStyle","lineWidth","snapToData","valueFormat","valueDisplayMode","cornerPosition","cursorX","cursorY","overlayId","pluginCtx","overlay","resizeCanvas","event","nearest","render","size","lineColor","drawFloatingLabels","drawCornerLabels","bgColor","dataX","dataY","xText","xLabelWidth","xLabelHeight","xLabelX","xLabelY","yText","yLabelWidth","yLabelHeight","yLabelX","yLabelY","xMetrics","yMetrics","maxWidth","padding","lineHeight","boxWidth","boxHeight","boxX","boxY","statsManifest","StatsPlugin","position","show","autoUpdate","container","posStyle","updateStats","content","allSeries","targetSeries","allY","stats","computeStats","values","mean","sumSq","std","watermarkManifest","WatermarkPlugin","fontSize","fontFamily","rotation","ctx2d","svgCtx","exportWatermark","gridHighlightManifest","GridHighlightPlugin","xIntervals","yIntervals","opacity","_event","interval","bands","exportGridHighlight","dataLoggerManifest","DataLoggerPlugin","logDataUpdates","logViewChanges","logInteractions","maxEntries","entries","addEntry","_ctx","saved","directionIndicatorManifest","DirectionIndicatorPlugin","sampleSize","minVelocity","historySize","idleTimeout","currentDirection","targetSeriesId","positionHistoryX","positionHistoryY","angleHistory","maxHistorySize","timeoutTimer","lastPointTimestamp","lastSeenX","lastSeenY","currentIdleTimeout","updateDirection","age","_pluginCtx","newConfig","canvasSize","lastX","lastY","startIdx","sumT","sumPX","sumPY","sumTPX","sumTPY","sumTT","pixelX","pixelY","meanT","meanPX","meanPY","denominator","slopePX","slopePY","rawAngle","lastPixelX","lastPixelY","smoothX","average","smoothY","smoothedAngle","smoothAngle","magnitude","val","angles","sumX","sumY","arrowColor","drawArrow","length","triangleHeight","triangleWidth","BuiltinPlugins","manifest","DEFAULT_CONFIG","PluginDragEdit","userConfig","isDragging","draggedPoint","dragStartX","dragStartY","hasMoved","findNearestPoint","mouseX","mouseY","picked","pixelToData","snapToGrid","applyConstraints","newX","newY","constraint","validateAndSnap","finalX","finalY","tempPoint","validation","updatePointData","index","createDragEvent","drawPreview","pCtx","coords","origPixelX","origPixelY","currPixelX","currPixelY","api","seriesIds","point","dy","dragEvent","valid","createPlugin","definition","createConfigurablePlugin","factory"],"mappings":"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"}
|