velo-plot 2.20.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/README.md +26 -12
  2. package/dist/ChartCore-AnR_3Xkb.js +7338 -0
  3. package/dist/ChartCore-AnR_3Xkb.js.map +1 -0
  4. package/dist/GpuChartRenderer-Dxc0hrQA.js +75 -0
  5. package/dist/GpuChartRenderer-Dxc0hrQA.js.map +1 -0
  6. package/dist/{index.core-COREBDNq.js → PluginRegistry-CzMHebYP.js} +24 -38
  7. package/dist/PluginRegistry-CzMHebYP.js.map +1 -0
  8. package/dist/a11y-Bw6urYpr.js +105 -0
  9. package/dist/a11y-Bw6urYpr.js.map +1 -0
  10. package/dist/angular/hooks-entry.d.ts +1 -0
  11. package/dist/angular/hooks.d.ts +26 -0
  12. package/dist/angular/index.d.ts +8 -0
  13. package/dist/angular/velo-plot.component.d.ts +46 -0
  14. package/dist/angular-hooks.d.ts +1 -0
  15. package/dist/angular-hooks.js +9 -0
  16. package/dist/angular-hooks.js.map +1 -0
  17. package/dist/angular.d.ts +1 -0
  18. package/dist/angular.js +166 -0
  19. package/dist/angular.js.map +1 -0
  20. package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -1
  21. package/dist/astro/StackedPlot.astro +19 -0
  22. package/dist/astro/VeloPlot.astro +23 -0
  23. package/dist/{axisFormat-CzumxpCL.js → axisFormat-Sz4WIJfQ.js} +2 -2
  24. package/dist/{axisFormat-CzumxpCL.js.map → axisFormat-Sz4WIJfQ.js.map} +1 -1
  25. package/dist/bindings/shared/a11y.d.ts +26 -0
  26. package/dist/bindings/shared/chartLifecycle.d.ts +16 -0
  27. package/dist/bindings/shared/chartSyncBridge.d.ts +8 -0
  28. package/dist/bindings/shared/dimensions.d.ts +1 -0
  29. package/dist/bindings/shared/index.d.ts +9 -0
  30. package/dist/bindings/shared/indicatorBridge.d.ts +11 -0
  31. package/dist/bindings/shared/optionsSync.d.ts +7 -0
  32. package/dist/bindings/shared/seriesDiff.d.ts +8 -0
  33. package/dist/bindings/shared/stackedSync.d.ts +9 -0
  34. package/dist/bindings/shared/types.d.ts +46 -0
  35. package/dist/bindings/test-utils/index.d.ts +35 -0
  36. package/dist/bindings/test-utils/mockLifecycle.d.ts +120 -0
  37. package/dist/bindings/test-utils/vitestSveltePlugin.d.ts +3 -0
  38. package/dist/chartSyncBridge-D_rCtbFq.js +58 -0
  39. package/dist/chartSyncBridge-D_rCtbFq.js.map +1 -0
  40. package/dist/core/Chart.d.ts +1 -1
  41. package/dist/core/ChartStatistics.d.ts +1 -1
  42. package/dist/core/InteractionManager.d.ts +7 -1
  43. package/dist/core/OverlayRenderer.d.ts +5 -0
  44. package/dist/core/annotations/types.d.ts +1 -1
  45. package/dist/core/chart/ChartCore.d.ts +14 -19
  46. package/dist/core/chart/ChartFeatureHooks.d.ts +7 -0
  47. package/dist/core/chart/chartExportPatch.d.ts +2 -0
  48. package/dist/core/chart/overlaySeriesRegistry.d.ts +7 -0
  49. package/dist/core/chart/series/SeriesActions.d.ts +1 -0
  50. package/dist/core/chart/series/SeriesBufferLite.d.ts +13 -0
  51. package/dist/core/chart/series/seriesOptionsRegistry.d.ts +8 -0
  52. package/dist/core/chart/series/seriesTypeRegistry.d.ts +5 -0
  53. package/dist/core/chart/types.d.ts +1 -1
  54. package/dist/core/clipboard/index.d.ts +1 -1
  55. package/dist/core/debug/index.d.ts +1 -1
  56. package/dist/core/keybindings/index.d.ts +1 -1
  57. package/dist/core/loading/index.d.ts +1 -1
  58. package/dist/core/locale/index.d.ts +1 -1
  59. package/dist/core/stacked/paneResize.d.ts +3 -0
  60. package/dist/core/stacked/types.d.ts +10 -0
  61. package/dist/core/theme-editor/index.d.ts +1 -1
  62. package/dist/createStackedChart-DqcLCFGS.js +1338 -0
  63. package/dist/createStackedChart-DqcLCFGS.js.map +1 -0
  64. package/dist/examples/PluginDemonstration.d.ts +1 -1
  65. package/dist/hooks-DH-3bewj.js +69 -0
  66. package/dist/hooks-DH-3bewj.js.map +1 -0
  67. package/dist/{index-BBpJwOct.js → index-0InEyj0q.js} +119 -121
  68. package/dist/index-0InEyj0q.js.map +1 -0
  69. package/dist/{index-qunX30Xu.js → index-B7PTX94B.js} +2133 -2133
  70. package/dist/index-B7PTX94B.js.map +1 -0
  71. package/dist/{index-BMiZoKmm.js → index-BgrvqltV.js} +67 -67
  72. package/dist/index-BgrvqltV.js.map +1 -0
  73. package/dist/{index-DoYxf1cV.js → index-CWxIHdwX.js} +38 -98
  74. package/dist/index-CWxIHdwX.js.map +1 -0
  75. package/dist/index-CaXWSOTk.js.map +1 -1
  76. package/dist/{mockDatafeed-927foCM4.js → index-Cv6ZDLWf.js} +227 -217
  77. package/dist/index-Cv6ZDLWf.js.map +1 -0
  78. package/dist/index-Dag88bW4.js.map +1 -1
  79. package/dist/index-qhscKTDy.js.map +1 -1
  80. package/dist/index.core.d.ts +9 -7
  81. package/dist/index.d.ts +2 -15
  82. package/dist/indicators--eJGmVox.js.map +1 -1
  83. package/dist/optionsSync-QUiN4Inw.js +119 -0
  84. package/dist/optionsSync-QUiN4Inw.js.map +1 -0
  85. package/dist/plugins/3d/index.d.ts +2 -2
  86. package/dist/plugins/3d.d.ts +2 -2
  87. package/dist/plugins/3d.js +3 -1
  88. package/dist/plugins/3d.js.map +1 -1
  89. package/dist/plugins/analysis/index.d.ts +1 -1
  90. package/dist/plugins/analysis/indicators.d.ts +1 -1
  91. package/dist/plugins/analysis.d.ts +2 -2
  92. package/dist/plugins/analysis.js +2 -2
  93. package/dist/plugins/analysis.js.map +1 -1
  94. package/dist/plugins/annotations/index.d.ts +1 -1
  95. package/dist/plugins/annotations.d.ts +2 -2
  96. package/dist/plugins/annotations.js.map +1 -1
  97. package/dist/plugins/anomaly-detection.js +1 -1
  98. package/dist/plugins/anomaly-detection.js.map +1 -1
  99. package/dist/plugins/broken-axis.d.ts +2 -2
  100. package/dist/plugins/builtins/crosshair/CrosshairPlugin.d.ts +1 -1
  101. package/dist/plugins/builtins/index.d.ts +1 -1
  102. package/dist/plugins/caching.d.ts +2 -2
  103. package/dist/plugins/clipboard/index.d.ts +2 -2
  104. package/dist/plugins/clipboard.d.ts +2 -2
  105. package/dist/plugins/clipboard.js.map +1 -1
  106. package/dist/plugins/context-menu/index.d.ts +1 -1
  107. package/dist/plugins/context-menu.d.ts +2 -2
  108. package/dist/plugins/context-menu.js +1 -1
  109. package/dist/plugins/context-menu.js.map +1 -1
  110. package/dist/plugins/createPlugin.d.ts +8 -0
  111. package/dist/plugins/data-export/index.d.ts +1 -1
  112. package/dist/plugins/data-export.d.ts +2 -2
  113. package/dist/plugins/data-export.js +2 -2
  114. package/dist/plugins/data-export.js.map +1 -1
  115. package/dist/plugins/data-transform.d.ts +2 -2
  116. package/dist/plugins/data-transform.js +19 -19
  117. package/dist/plugins/data-transform.js.map +1 -1
  118. package/dist/plugins/debug/index.d.ts +2 -2
  119. package/dist/plugins/debug.d.ts +2 -2
  120. package/dist/plugins/debug.js +33 -33
  121. package/dist/plugins/debug.js.map +1 -1
  122. package/dist/plugins/forecasting/index.d.ts +1 -1
  123. package/dist/plugins/forecasting.js.map +1 -1
  124. package/dist/plugins/gpu/index.d.ts +2 -2
  125. package/dist/plugins/gpu.d.ts +2 -2
  126. package/dist/plugins/gpu.js +2033 -209
  127. package/dist/plugins/gpu.js.map +1 -1
  128. package/dist/plugins/i18n/index.d.ts +2 -2
  129. package/dist/plugins/i18n.d.ts +2 -2
  130. package/dist/plugins/i18n.js +286 -23
  131. package/dist/plugins/i18n.js.map +1 -1
  132. package/dist/plugins/index.d.ts +1 -1
  133. package/dist/plugins/keyboard.d.ts +2 -2
  134. package/dist/plugins/keyboard.js +65 -5
  135. package/dist/plugins/keyboard.js.map +1 -1
  136. package/dist/plugins/latex.js +766 -207
  137. package/dist/plugins/latex.js.map +1 -1
  138. package/dist/plugins/lazy-load.d.ts +2 -2
  139. package/dist/plugins/loading/index.d.ts +2 -3
  140. package/dist/plugins/loading.d.ts +2 -2
  141. package/dist/plugins/loading.js +3 -4
  142. package/dist/plugins/ml-integration.d.ts +2 -2
  143. package/dist/plugins/ml-integration.js +5 -5
  144. package/dist/plugins/ml-integration.js.map +1 -1
  145. package/dist/plugins/offscreen.d.ts +2 -2
  146. package/dist/plugins/offscreen.js +11 -10
  147. package/dist/plugins/offscreen.js.map +1 -1
  148. package/dist/plugins/pattern-recognition.d.ts +2 -2
  149. package/dist/plugins/pattern-recognition.js +1 -1
  150. package/dist/plugins/pattern-recognition.js.map +1 -1
  151. package/dist/plugins/radar.d.ts +2 -2
  152. package/dist/plugins/regression.d.ts +2 -2
  153. package/dist/plugins/regression.js +255 -257
  154. package/dist/plugins/regression.js.map +1 -1
  155. package/dist/plugins/roi.js +9 -9
  156. package/dist/plugins/roi.js.map +1 -1
  157. package/dist/plugins/snapshot/index.d.ts +1 -1
  158. package/dist/plugins/snapshot/types.d.ts +1 -1
  159. package/dist/plugins/snapshot.d.ts +2 -2
  160. package/dist/plugins/snapshot.js.map +1 -1
  161. package/dist/plugins/streaming/index.d.ts +2 -2
  162. package/dist/plugins/streaming.d.ts +2 -2
  163. package/dist/plugins/streaming.js +1 -1
  164. package/dist/plugins/sync/index.d.ts +3 -2
  165. package/dist/plugins/sync.d.ts +2 -2
  166. package/dist/plugins/sync.js.map +1 -1
  167. package/dist/plugins/theme-editor/index.d.ts +1 -1
  168. package/dist/plugins/theme-editor.d.ts +2 -2
  169. package/dist/plugins/tools/index.d.ts +1 -1
  170. package/dist/plugins/tools/tooltip/index.d.ts +1 -1
  171. package/dist/plugins/tools.d.ts +2 -2
  172. package/dist/plugins/tools.js +1 -1
  173. package/dist/plugins/types.d.ts +1 -1
  174. package/dist/plugins/video-recorder.d.ts +2 -2
  175. package/dist/plugins/virtualization.d.ts +2 -2
  176. package/dist/plugins/virtualization.js +1 -1
  177. package/dist/pool-DZ8shSqv.js +109 -0
  178. package/dist/pool-DZ8shSqv.js.map +1 -0
  179. package/dist/react/StackedPlot.d.ts +31 -0
  180. package/dist/react/VeloPlot.d.ts +29 -0
  181. package/dist/react/index.d.ts +25 -3
  182. package/dist/react/useChartSync.d.ts +8 -0
  183. package/dist/react/useIndicator.d.ts +12 -0
  184. package/dist/react/useVeloPlot.d.ts +19 -0
  185. package/dist/react.js +325 -24
  186. package/dist/react.js.map +1 -1
  187. package/dist/renderer/NativeWebGLRenderer.d.ts +2 -1
  188. package/dist/renderer/native/NativeWebGLRenderer.d.ts +5 -1
  189. package/dist/renderer/native/draw.d.ts +2 -47
  190. package/dist/renderer/native/drawCore.d.ts +27 -0
  191. package/dist/renderer/native/drawExtended.d.ts +29 -0
  192. package/dist/renderer/native/frameRenderExtended.d.ts +1 -0
  193. package/dist/renderer/native/frameRenderRegistry.d.ts +27 -0
  194. package/dist/renderer/native/programFactoryCore.d.ts +6 -0
  195. package/dist/renderer/native/programFactoryExtended.d.ts +4 -0
  196. package/dist/renderer/native/utils.d.ts +3 -29
  197. package/dist/renderer/native/utilsCore.d.ts +14 -0
  198. package/dist/renderer/native/utilsExtended.d.ts +17 -0
  199. package/dist/renderer/overlaySeriesExtended.d.ts +1 -0
  200. package/dist/renderer/registerExtendedSeries.d.ts +1 -0
  201. package/dist/renderer/registerWebGPU.d.ts +2 -0
  202. package/dist/renderer/seriesBufferExtended.d.ts +4 -0
  203. package/dist/scientific/index.d.ts +44 -0
  204. package/dist/scientific/registerScientific.d.ts +1 -0
  205. package/dist/scientific.d.ts +1 -0
  206. package/dist/scientific.js +91 -0
  207. package/dist/scientific.js.map +1 -0
  208. package/dist/solid/VeloPlot.d.ts +16 -0
  209. package/dist/solid/index.d.ts +13 -0
  210. package/dist/solid/useChartSync.d.ts +6 -0
  211. package/dist/solid/useIndicator.d.ts +11 -0
  212. package/dist/solid/useStackedPlot.d.ts +14 -0
  213. package/dist/solid/useVeloPlot.d.ts +18 -0
  214. package/dist/solid.d.ts +1 -0
  215. package/dist/solid.js +169 -0
  216. package/dist/solid.js.map +1 -0
  217. package/dist/stackedSync-tnrunZMt.js +100 -0
  218. package/dist/stackedSync-tnrunZMt.js.map +1 -0
  219. package/dist/svelte/StackedPlot.svelte +29 -0
  220. package/dist/svelte/StackedPlot.test.ts +114 -0
  221. package/dist/svelte/VeloPlot.svelte +44 -0
  222. package/dist/svelte/VeloPlot.test.ts +105 -0
  223. package/dist/svelte/index.d.ts +11 -0
  224. package/dist/svelte/index.test.ts +20 -0
  225. package/dist/svelte/index.ts +15 -0
  226. package/dist/svelte/useChartSync.d.ts +8 -0
  227. package/dist/svelte/useChartSync.test.ts +49 -0
  228. package/dist/svelte/useChartSync.ts +29 -0
  229. package/dist/svelte/useIndicator.d.ts +13 -0
  230. package/dist/svelte/useIndicator.test.ts +67 -0
  231. package/dist/svelte/useIndicator.ts +43 -0
  232. package/dist/svelte/useStackedPlot.d.ts +16 -0
  233. package/dist/svelte/useStackedPlot.test.ts +76 -0
  234. package/dist/svelte/useStackedPlot.ts +54 -0
  235. package/dist/svelte/useVeloPlot.d.ts +21 -0
  236. package/dist/svelte/useVeloPlot.test.ts +100 -0
  237. package/dist/svelte/useVeloPlot.ts +81 -0
  238. package/dist/svelte.d.ts +1 -0
  239. package/dist/svelte.js +140 -0
  240. package/dist/svelte.js.map +1 -0
  241. package/dist/testing/index.d.ts +1 -1
  242. package/dist/theme/index.d.ts +2 -1
  243. package/dist/trading/index.d.ts +1 -4
  244. package/dist/trading/registerTrading.d.ts +3 -0
  245. package/dist/trading.js +42 -42
  246. package/dist/types.d.ts +4 -4
  247. package/dist/{utils-BK5UUXxj.js → utils-Dx0h0bgQ.js} +9 -9
  248. package/dist/{utils-BK5UUXxj.js.map → utils-Dx0h0bgQ.js.map} +1 -1
  249. package/dist/velo-plot.full.js +2216 -1346
  250. package/dist/velo-plot.full.js.map +1 -1
  251. package/dist/velo-plot.js +33 -28
  252. package/dist/velo-plot.js.map +1 -1
  253. package/dist/vue/StackedPlot.vue.d.ts +48 -0
  254. package/dist/vue/VeloPlot.vue.d.ts +64 -0
  255. package/dist/vue/index.d.ts +250 -0
  256. package/dist/vue/useChartSync.d.ts +52 -0
  257. package/dist/vue/useIndicator.d.ts +23 -0
  258. package/dist/vue/useStackedPlot.d.ts +15 -0
  259. package/dist/vue/useVeloPlot.d.ts +20 -0
  260. package/dist/vue.d.ts +1 -0
  261. package/dist/vue.js +309 -0
  262. package/dist/vue.js.map +1 -0
  263. package/dist/workers/indicatorsAsync.d.ts +2 -0
  264. package/dist/workers/pool.d.ts +9 -0
  265. package/package.json +96 -10
  266. package/dist/ChartCore-ivzLqxVb.js +0 -8350
  267. package/dist/ChartCore-ivzLqxVb.js.map +0 -1
  268. package/dist/SciPlot-CEU4ApgD.js +0 -463
  269. package/dist/SciPlot-CEU4ApgD.js.map +0 -1
  270. package/dist/createStackedChart-DxNW0VkF.js +0 -705
  271. package/dist/createStackedChart-DxNW0VkF.js.map +0 -1
  272. package/dist/gpuRenderer-BpaMYz-k.js +0 -1848
  273. package/dist/gpuRenderer-BpaMYz-k.js.map +0 -1
  274. package/dist/index-BBpJwOct.js.map +0 -1
  275. package/dist/index-BMiZoKmm.js.map +0 -1
  276. package/dist/index-DoYxf1cV.js.map +0 -1
  277. package/dist/index-qunX30Xu.js.map +0 -1
  278. package/dist/index-x4stH3jD.js +0 -282
  279. package/dist/index-x4stH3jD.js.map +0 -1
  280. package/dist/index.core-COREBDNq.js.map +0 -1
  281. package/dist/mockDatafeed-927foCM4.js.map +0 -1
  282. package/dist/pool-15HMCNv8.js +0 -88
  283. package/dist/pool-15HMCNv8.js.map +0 -1
  284. package/dist/react/SciPlot.d.ts +0 -60
  285. package/dist/react/useSciPlot.d.ts +0 -56
  286. package/dist/symbols-DT0eLlpW.js +0 -568
  287. package/dist/symbols-DT0eLlpW.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular.js","sources":["../src/bindings/shared/dimensions.ts","../src/angular/velo-plot.component.ts","../src/angular/index.ts"],"sourcesContent":["export function formatBindingDimension(value: number | string): string {\n return typeof value === \"number\" ? `${value}px` : value;\n}\n","import {\n Component,\n input,\n output,\n viewChild,\n ElementRef,\n OnDestroy,\n AfterViewInit,\n effect,\n} from \"@angular/core\";\nimport { createStackedChart } from \"../core/stacked\";\nimport type { StackedChart, StackedPaneConfig, StackedChartOptions } from \"../core/stacked\";\nimport type { Chart } from \"../core/Chart\";\nimport type { Bounds, CursorOptions } from \"../types\";\nimport {\n createChartLifecycle,\n diffSeries,\n type VeloPlotSeries,\n type ChartBindingOptions,\n pickSyncableOptions,\n optionsChanged,\n syncChartOptions,\n} from \"../bindings/shared\";\nimport { formatBindingDimension } from \"../bindings/shared/dimensions\";\n\n@Component({\n selector: \"velo-plot\",\n standalone: true,\n template: `<div #container class=\"velo-plot-container\" role=\"img\" [style.width]=\"widthStyle\" [style.height]=\"heightStyle\"></div>`,\n styles: [`:host { display: block; } .velo-plot-container { position: relative; }`],\n})\nexport class VeloPlotComponent implements OnDestroy, AfterViewInit {\n readonly series = input<VeloPlotSeries[]>([]);\n readonly width = input<number | string>(\"100%\");\n readonly height = input<number | string>(400);\n readonly cursor = input<CursorOptions | undefined>();\n readonly chartOptions = input<ChartBindingOptions>({});\n readonly zoomChange = output<Bounds>();\n\n readonly containerRef = viewChild<ElementRef<HTMLDivElement>>(\"container\");\n\n chart: Chart | null = null;\n private destroy: (() => void) | null = null;\n private previousSeries = new Map<string, VeloPlotSeries>();\n private prevSync = pickSyncableOptions({});\n\n constructor() {\n effect(() => {\n this.containerRef();\n this.syncOptionsAndSeries();\n });\n }\n\n ngAfterViewInit(): void {\n const el = this.containerRef()?.nativeElement;\n if (el) this.mountChart(el);\n }\n\n mountChart(container: HTMLDivElement): void {\n if (this.chart) return;\n const handle = createChartLifecycle(container, this.chartOptions());\n this.chart = handle.chart;\n this.destroy = handle.destroy;\n this.prevSync = pickSyncableOptions(this.chartOptions());\n this.syncOptionsAndSeries();\n }\n\n get widthStyle(): string {\n return formatBindingDimension(this.width());\n }\n\n get heightStyle(): string {\n return formatBindingDimension(this.height());\n }\n\n ngOnDestroy(): void {\n this.destroy?.();\n this.chart = null;\n }\n\n private syncOptionsAndSeries(): void {\n if (!this.chart) return;\n const next = pickSyncableOptions(this.chartOptions());\n if (optionsChanged(this.prevSync, next)) {\n syncChartOptions(this.chart, this.prevSync, next);\n this.prevSync = next;\n }\n this.applySeries();\n }\n\n private applySeries(): void {\n if (!this.chart) return;\n this.previousSeries = diffSeries(\n {\n addSeries: (o) => this.chart!.addSeries(o),\n updateSeries: (id, d) => this.chart!.updateSeries(id, d),\n removeSeries: (id) => this.chart!.removeSeries(id),\n autoScale: () => this.chart!.autoScale(),\n },\n this.series(),\n this.previousSeries,\n );\n }\n\n resetZoom(): void {\n this.chart?.resetZoom();\n }\n\n getChart(): Chart | null {\n return this.chart;\n }\n}\n\n@Component({\n selector: \"velo-stacked-plot\",\n standalone: true,\n template: `<div #container class=\"velo-plot-stacked\" role=\"img\" [style.width]=\"widthStyle\" [style.height]=\"heightStyle\"></div>`,\n styles: [`:host { display: block; } .velo-plot-stacked { position: relative; }`],\n})\nexport class StackedPlotComponent implements OnDestroy, AfterViewInit {\n readonly panes = input<StackedPaneConfig[]>([]);\n readonly width = input<number | string>(\"100%\");\n readonly height = input<number | string>(480);\n readonly stackOptions = input<Omit<StackedChartOptions, \"container\" | \"panes\">>({});\n\n readonly containerRef = viewChild<ElementRef<HTMLDivElement>>(\"container\");\n\n stack: StackedChart | null = null;\n private destroy: (() => void) | null = null;\n\n get widthStyle(): string {\n return formatBindingDimension(this.width());\n }\n\n get heightStyle(): string {\n return formatBindingDimension(this.height());\n }\n\n ngAfterViewInit(): void {\n const el = this.containerRef()?.nativeElement;\n if (el) this.mountStack(el);\n }\n\n mountStack(container: HTMLDivElement): void {\n if (this.stack) return;\n const created = createStackedChart({\n ...this.stackOptions(),\n panes: this.panes(),\n container,\n });\n this.stack = created;\n this.destroy = () => created.destroy();\n }\n\n ngOnDestroy(): void {\n this.destroy?.();\n this.stack = null;\n }\n\n fitAll(): void {\n this.stack?.fitAll();\n }\n\n resetAll(): void {\n this.stack?.resetAll();\n }\n}\n\nexport { useVeloPlotAngular, useStackedPlotAngular, useIndicatorAngular, useChartSyncAngular } from \"./hooks\";\n","export {\n VeloPlotComponent,\n StackedPlotComponent,\n} from \"./velo-plot.component\";\nexport {\n VeloPlotHost,\n useVeloPlotAngular,\n useStackedPlotAngular,\n useIndicatorAngular,\n useChartSyncAngular,\n} from \"./hooks\";\n\nimport { VeloPlotComponent as VeloPlotComponentImpl } from \"./velo-plot.component\";\nimport { useVeloPlotAngular as useVeloPlotAngularImpl } from \"./hooks\";\n\n/** @deprecated Use `VeloPlotComponent` instead. **Removed in v4.0.** */\nexport const SciPlotComponent = VeloPlotComponentImpl;\n/** @deprecated Use `useVeloPlotAngular` instead. **Removed in v4.0.** */\nexport const useSciPlotAngular = useVeloPlotAngularImpl;\n"],"names":["formatBindingDimension","value","_VeloPlotComponent_decorators","Component","VeloPlotComponent","__publicField","input","output","viewChild","pickSyncableOptions","effect","el","_a","container","handle","createChartLifecycle","next","optionsChanged","syncChartOptions","diffSeries","o","id","d","_init","__decoratorStart","__decorateElement","__runInitializers","_StackedPlotComponent_decorators","StackedPlotComponent","created","createStackedChart","SciPlotComponent","VeloPlotComponentImpl","useSciPlotAngular","useVeloPlotAngularImpl"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"indicator.worker-bv0zC4EX.js","sources":["../src/plugins/analysis/indicators.ts","../src/workers/indicator.worker.ts"],"sourcesContent":["/**\n * Sci Plot - Financial/Technical Indicators Module\n * \n * Provides common financial and technical analysis indicators:\n * - Moving Averages (SMA, EMA, WMA)\n * - Momentum Indicators (RSI, MACD, Stochastic)\n * - Volatility (Bollinger Bands, ATR)\n * - Volume (VWAP, OBV)\n * - Trend (ADX, Aroon)\n * \n * @module indicators\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport interface IndicatorResult {\n /** Indicator values (NaN for insufficient data) */\n values: Float32Array;\n /** Additional line (e.g., signal line for MACD) */\n signal?: Float32Array;\n /** Upper band (e.g., Bollinger upper) */\n upper?: Float32Array;\n /** Lower band (e.g., Bollinger lower) */\n lower?: Float32Array;\n /** Histogram (e.g., MACD histogram) */\n histogram?: Float32Array;\n}\n\nexport interface OHLCData {\n open: Float32Array | Float64Array;\n high: Float32Array | Float64Array;\n low: Float32Array | Float64Array;\n close: Float32Array | Float64Array;\n volume?: Float32Array | Float64Array;\n}\n\n// ============================================\n// Moving Averages\n// ============================================\n\n/**\n * Simple Moving Average (SMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function sma(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n if (period < 1 || period > input.length) {\n result.fill(NaN);\n return result;\n }\n\n // Fill initial values with NaN\n for (let i = 0; i < period - 1; i++) {\n result[i] = NaN;\n }\n\n // Calculate first SMA\n let sum = 0;\n for (let i = 0; i < period; i++) {\n sum += input[i];\n }\n result[period - 1] = sum / period;\n\n // Calculate remaining SMAs using sliding window\n for (let i = period; i < input.length; i++) {\n sum = sum - input[i - period] + input[i];\n result[i] = sum / period;\n }\n\n return result;\n}\n\n/**\n * Exponential Moving Average (EMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function ema(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n if (period < 1 || period > input.length) {\n result.fill(NaN);\n return result;\n }\n\n const multiplier = 2 / (period + 1);\n\n // Fill initial values with NaN\n for (let i = 0; i < period - 1; i++) {\n result[i] = NaN;\n }\n\n // First EMA is SMA\n let sum = 0;\n for (let i = 0; i < period; i++) {\n sum += input[i];\n }\n result[period - 1] = sum / period;\n\n // Calculate remaining EMAs\n for (let i = period; i < input.length; i++) {\n result[i] = (input[i] - result[i - 1]) * multiplier + result[i - 1];\n }\n\n return result;\n}\n\n/**\n * Weighted Moving Average (WMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function wma(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n if (period < 1 || period > input.length) {\n result.fill(NaN);\n return result;\n }\n\n const weightSum = (period * (period + 1)) / 2;\n\n // Fill initial values with NaN\n for (let i = 0; i < period - 1; i++) {\n result[i] = NaN;\n }\n\n // Calculate WMAs\n for (let i = period - 1; i < input.length; i++) {\n let weightedSum = 0;\n for (let j = 0; j < period; j++) {\n weightedSum += input[i - period + 1 + j] * (j + 1);\n }\n result[i] = weightedSum / weightSum;\n }\n\n return result;\n}\n\n/**\n * Double Exponential Moving Average (DEMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function dema(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const ema1 = ema(data, period);\n const ema2 = ema(ema1, period);\n const result = new Float32Array(data.length);\n\n for (let i = 0; i < data.length; i++) {\n result[i] = 2 * ema1[i] - ema2[i];\n }\n\n return result;\n}\n\n/**\n * Triple Exponential Moving Average (TEMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function tema(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const ema1 = ema(data, period);\n const ema2 = ema(ema1, period);\n const ema3 = ema(ema2, period);\n const result = new Float32Array(data.length);\n\n for (let i = 0; i < data.length; i++) {\n result[i] = 3 * ema1[i] - 3 * ema2[i] + ema3[i];\n }\n\n return result;\n}\n\n// ============================================\n// Momentum Indicators\n// ============================================\n\n/**\n * Relative Strength Index (RSI)\n * @param data Close prices\n * @param period RSI period (default: 14)\n */\nexport function rsi(data: Float32Array | Float64Array | number[], period: number = 14): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n if (period < 1 || input.length < period + 1) {\n result.fill(NaN);\n return result;\n }\n\n // Fill initial values with NaN\n for (let i = 0; i < period; i++) {\n result[i] = NaN;\n }\n\n // Calculate initial average gain/loss\n let avgGain = 0;\n let avgLoss = 0;\n\n for (let i = 1; i <= period; i++) {\n const change = input[i] - input[i - 1];\n if (change > 0) {\n avgGain += change;\n } else {\n avgLoss += Math.abs(change);\n }\n }\n\n avgGain /= period;\n avgLoss /= period;\n\n // First RSI value\n if (avgLoss === 0) {\n result[period] = 100;\n } else {\n const rs = avgGain / avgLoss;\n result[period] = 100 - (100 / (1 + rs));\n }\n\n // Calculate remaining RSI values using smoothed averages\n for (let i = period + 1; i < input.length; i++) {\n const change = input[i] - input[i - 1];\n let gain = 0;\n let loss = 0;\n\n if (change > 0) {\n gain = change;\n } else {\n loss = Math.abs(change);\n }\n\n avgGain = (avgGain * (period - 1) + gain) / period;\n avgLoss = (avgLoss * (period - 1) + loss) / period;\n\n if (avgLoss === 0) {\n result[i] = 100;\n } else {\n const rs = avgGain / avgLoss;\n result[i] = 100 - (100 / (1 + rs));\n }\n }\n\n return result;\n}\n\n/**\n * Moving Average Convergence Divergence (MACD)\n * @param data Close prices\n * @param fastPeriod Fast EMA period (default: 12)\n * @param slowPeriod Slow EMA period (default: 26)\n * @param signalPeriod Signal line period (default: 9)\n */\nexport function macd(\n data: Float32Array | Float64Array | number[],\n fastPeriod: number = 12,\n slowPeriod: number = 26,\n signalPeriod: number = 9\n): IndicatorResult {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n \n const fastEma = ema(input, fastPeriod);\n const slowEma = ema(input, slowPeriod);\n \n // MACD Line = Fast EMA - Slow EMA\n const macdLine = new Float32Array(input.length);\n for (let i = 0; i < input.length; i++) {\n macdLine[i] = fastEma[i] - slowEma[i];\n }\n \n // Signal Line = EMA of MACD Line\n const signal = ema(macdLine, signalPeriod);\n \n // Histogram = MACD Line - Signal Line\n const histogram = new Float32Array(input.length);\n for (let i = 0; i < input.length; i++) {\n histogram[i] = macdLine[i] - signal[i];\n }\n\n return {\n values: macdLine,\n signal,\n histogram,\n };\n}\n\n/**\n * Stochastic Oscillator\n * @param ohlc OHLC data\n * @param kPeriod %K period (default: 14)\n * @param dPeriod %D smoothing period (default: 3)\n */\nexport function stochastic(\n ohlc: OHLCData,\n kPeriod: number = 14,\n dPeriod: number = 3\n): IndicatorResult {\n const { high, low, close } = ohlc;\n const length = close.length;\n const kValues = new Float32Array(length);\n \n // Calculate %K\n for (let i = 0; i < length; i++) {\n if (i < kPeriod - 1) {\n kValues[i] = NaN;\n continue;\n }\n \n let highest = -Infinity;\n let lowest = Infinity;\n \n for (let j = i - kPeriod + 1; j <= i; j++) {\n if (high[j] > highest) highest = high[j];\n if (low[j] < lowest) lowest = low[j];\n }\n \n const range = highest - lowest;\n if (range === 0) {\n kValues[i] = 50; // Neutral when no range\n } else {\n kValues[i] = ((close[i] - lowest) / range) * 100;\n }\n }\n \n // %D is SMA of %K\n const dValues = sma(kValues, dPeriod);\n\n return {\n values: kValues, // %K\n signal: dValues, // %D\n };\n}\n\n/**\n * Rate of Change (ROC)\n * @param data Close prices\n * @param period ROC period (default: 10)\n */\nexport function roc(data: Float32Array | Float64Array | number[], period: number = 10): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n for (let i = 0; i < period; i++) {\n result[i] = NaN;\n }\n \n for (let i = period; i < input.length; i++) {\n const pastValue = input[i - period];\n if (pastValue === 0) {\n result[i] = NaN;\n } else {\n result[i] = ((input[i] - pastValue) / pastValue) * 100;\n }\n }\n\n return result;\n}\n\n/**\n * Momentum\n * @param data Close prices\n * @param period Momentum period (default: 10)\n */\nexport function momentum(data: Float32Array | Float64Array | number[], period: number = 10): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n for (let i = 0; i < period; i++) {\n result[i] = NaN;\n }\n \n for (let i = period; i < input.length; i++) {\n result[i] = input[i] - input[i - period];\n }\n\n return result;\n}\n\n// ============================================\n// Volatility Indicators\n// ============================================\n\n/**\n * Bollinger Bands\n * @param data Close prices\n * @param period SMA period (default: 20)\n * @param stdDev Standard deviation multiplier (default: 2)\n */\nexport function bollingerBands(\n data: Float32Array | Float64Array | number[],\n period: number = 20,\n stdDev: number = 2\n): IndicatorResult {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const middle = sma(input, period);\n const upper = new Float32Array(input.length);\n const lower = new Float32Array(input.length);\n\n for (let i = 0; i < input.length; i++) {\n if (i < period - 1) {\n upper[i] = NaN;\n lower[i] = NaN;\n continue;\n }\n\n // Calculate standard deviation\n let sumSquares = 0;\n for (let j = i - period + 1; j <= i; j++) {\n const diff = input[j] - middle[i];\n sumSquares += diff * diff;\n }\n const std = Math.sqrt(sumSquares / period);\n\n upper[i] = middle[i] + stdDev * std;\n lower[i] = middle[i] - stdDev * std;\n }\n\n return {\n values: middle,\n upper,\n lower,\n };\n}\n\n/**\n * Average True Range (ATR)\n * @param ohlc OHLC data\n * @param period ATR period (default: 14)\n */\nexport function atr(ohlc: OHLCData, period: number = 14): Float32Array {\n const { high, low, close } = ohlc;\n const length = close.length;\n const tr = new Float32Array(length);\n \n // True Range calculation\n tr[0] = high[0] - low[0];\n \n for (let i = 1; i < length; i++) {\n const hl = high[i] - low[i];\n const hc = Math.abs(high[i] - close[i - 1]);\n const lc = Math.abs(low[i] - close[i - 1]);\n tr[i] = Math.max(hl, hc, lc);\n }\n\n // ATR is smoothed average of True Range\n return ema(tr, period);\n}\n\n/**\n * Standard Deviation\n * @param data Input data\n * @param period Period for calculation (default: 20)\n */\nexport function standardDeviation(data: Float32Array | Float64Array | number[], period: number = 20): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n const avg = sma(input, period);\n\n for (let i = 0; i < input.length; i++) {\n if (i < period - 1) {\n result[i] = NaN;\n continue;\n }\n\n let sumSquares = 0;\n for (let j = i - period + 1; j <= i; j++) {\n const diff = input[j] - avg[i];\n sumSquares += diff * diff;\n }\n result[i] = Math.sqrt(sumSquares / period);\n }\n\n return result;\n}\n\n// ============================================\n// Volume Indicators\n// ============================================\n\n/**\n * Volume Weighted Average Price (VWAP)\n * @param ohlc OHLC data with volume\n */\nexport function vwap(ohlc: OHLCData): Float32Array {\n const { high, low, close, volume } = ohlc;\n \n if (!volume) {\n throw new Error('VWAP requires volume data');\n }\n\n const length = close.length;\n const result = new Float32Array(length);\n \n let cumulativeTPV = 0; // Cumulative Typical Price * Volume\n let cumulativeVolume = 0;\n\n for (let i = 0; i < length; i++) {\n const typicalPrice = (high[i] + low[i] + close[i]) / 3;\n cumulativeTPV += typicalPrice * volume[i];\n cumulativeVolume += volume[i];\n \n if (cumulativeVolume === 0) {\n result[i] = typicalPrice;\n } else {\n result[i] = cumulativeTPV / cumulativeVolume;\n }\n }\n\n return result;\n}\n\n/**\n * On-Balance Volume (OBV)\n * @param close Close prices\n * @param volume Volume data\n */\nexport function obv(\n close: Float32Array | Float64Array | number[],\n volume: Float32Array | Float64Array | number[]\n): Float32Array {\n const closeInput = close instanceof Float32Array || close instanceof Float64Array ? close : Float32Array.from(close);\n const volumeInput = volume instanceof Float32Array || volume instanceof Float64Array ? volume : Float32Array.from(volume);\n \n const result = new Float32Array(closeInput.length);\n result[0] = volumeInput[0];\n\n for (let i = 1; i < closeInput.length; i++) {\n if (closeInput[i] > closeInput[i - 1]) {\n result[i] = result[i - 1] + volumeInput[i];\n } else if (closeInput[i] < closeInput[i - 1]) {\n result[i] = result[i - 1] - volumeInput[i];\n } else {\n result[i] = result[i - 1];\n }\n }\n\n return result;\n}\n\n// ============================================\n// Trend Indicators\n// ============================================\n\n/**\n * Average Directional Index (ADX)\n * @param ohlc OHLC data\n * @param period ADX period (default: 14)\n */\nexport function adx(ohlc: OHLCData, period: number = 14): IndicatorResult {\n const { high, low, close } = ohlc;\n const length = close.length;\n \n const plusDM = new Float32Array(length);\n const minusDM = new Float32Array(length);\n const tr = new Float32Array(length);\n \n // Calculate +DM, -DM, TR\n tr[0] = high[0] - low[0];\n plusDM[0] = 0;\n minusDM[0] = 0;\n\n for (let i = 1; i < length; i++) {\n const upMove = high[i] - high[i - 1];\n const downMove = low[i - 1] - low[i];\n \n plusDM[i] = upMove > downMove && upMove > 0 ? upMove : 0;\n minusDM[i] = downMove > upMove && downMove > 0 ? downMove : 0;\n \n const hl = high[i] - low[i];\n const hc = Math.abs(high[i] - close[i - 1]);\n const lc = Math.abs(low[i] - close[i - 1]);\n tr[i] = Math.max(hl, hc, lc);\n }\n\n // Smooth with EMA\n const smoothedTR = ema(tr, period);\n const smoothedPlusDM = ema(plusDM, period);\n const smoothedMinusDM = ema(minusDM, period);\n\n // Calculate +DI and -DI\n const plusDI = new Float32Array(length);\n const minusDI = new Float32Array(length);\n const dx = new Float32Array(length);\n\n for (let i = 0; i < length; i++) {\n if (smoothedTR[i] === 0 || isNaN(smoothedTR[i])) {\n plusDI[i] = NaN;\n minusDI[i] = NaN;\n dx[i] = NaN;\n } else {\n plusDI[i] = (smoothedPlusDM[i] / smoothedTR[i]) * 100;\n minusDI[i] = (smoothedMinusDM[i] / smoothedTR[i]) * 100;\n \n const diSum = plusDI[i] + minusDI[i];\n dx[i] = diSum === 0 ? 0 : (Math.abs(plusDI[i] - minusDI[i]) / diSum) * 100;\n }\n }\n\n // ADX is smoothed DX\n const adxValues = ema(dx, period);\n\n return {\n values: adxValues,\n upper: plusDI, // +DI\n lower: minusDI, // -DI\n };\n}\n\n/**\n * Aroon Indicator\n * @param ohlc OHLC data\n * @param period Aroon period (default: 25)\n */\nexport function aroon(ohlc: OHLCData, period: number = 25): IndicatorResult {\n const { high, low } = ohlc;\n const length = high.length;\n \n const aroonUp = new Float32Array(length);\n const aroonDown = new Float32Array(length);\n\n for (let i = 0; i < length; i++) {\n if (i < period) {\n aroonUp[i] = NaN;\n aroonDown[i] = NaN;\n continue;\n }\n\n let highestIdx = i;\n let lowestIdx = i;\n let highest = -Infinity;\n let lowest = Infinity;\n\n for (let j = i - period; j <= i; j++) {\n if (high[j] > highest) {\n highest = high[j];\n highestIdx = j;\n }\n if (low[j] < lowest) {\n lowest = low[j];\n lowestIdx = j;\n }\n }\n\n aroonUp[i] = ((period - (i - highestIdx)) / period) * 100;\n aroonDown[i] = ((period - (i - lowestIdx)) / period) * 100;\n }\n\n // Aroon Oscillator = Aroon Up - Aroon Down\n const oscillator = new Float32Array(length);\n for (let i = 0; i < length; i++) {\n oscillator[i] = aroonUp[i] - aroonDown[i];\n }\n\n return {\n values: oscillator,\n upper: aroonUp,\n lower: aroonDown,\n };\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\n/**\n * Calculate percentage change\n */\nexport function percentChange(data: Float32Array | Float64Array | number[], period: number = 1): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n for (let i = 0; i < period; i++) {\n result[i] = NaN;\n }\n \n for (let i = period; i < input.length; i++) {\n const prev = input[i - period];\n if (prev === 0) {\n result[i] = NaN;\n } else {\n result[i] = ((input[i] - prev) / prev) * 100;\n }\n }\n\n return result;\n}\n\n/**\n * Calculate cumulative sum\n */\nexport function cumsum(data: Float32Array | Float64Array | number[]): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n result[0] = input[0];\n for (let i = 1; i < input.length; i++) {\n result[i] = result[i - 1] + input[i];\n }\n\n return result;\n}\n\n/**\n * Normalize data to 0-100 range\n */\nexport function normalize(data: Float32Array | Float64Array | number[]): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n let min = Infinity;\n let max = -Infinity;\n \n for (let i = 0; i < input.length; i++) {\n if (!isNaN(input[i])) {\n if (input[i] < min) min = input[i];\n if (input[i] > max) max = input[i];\n }\n }\n\n const range = max - min;\n if (range === 0) {\n result.fill(50);\n } else {\n for (let i = 0; i < input.length; i++) {\n result[i] = ((input[i] - min) / range) * 100;\n }\n }\n\n return result;\n}\n","/**\n * Indicator calculations in a Web Worker.\n * @module workers/indicator.worker\n */\n\nimport { rsi, macd, bollingerBands, sma, ema } from \"../plugins/analysis/indicators\";\n\ninterface IndicatorTask {\n id: string;\n type: \"indicator\";\n indicator: \"rsi\" | \"macd\" | \"bollingerBands\" | \"sma\" | \"ema\";\n data: Float32Array | Float64Array;\n period?: number;\n fastPeriod?: number;\n slowPeriod?: number;\n signalPeriod?: number;\n stdDev?: number;\n}\n\ninterface IndicatorResultMessage {\n id: string;\n type: \"indicator-result\";\n indicator: string;\n values: Float32Array;\n signal?: Float32Array;\n upper?: Float32Array;\n lower?: Float32Array;\n histogram?: Float32Array;\n duration: number;\n}\n\ninterface ErrorMessage {\n id: string;\n type: \"error\";\n error: string;\n}\n\nself.onmessage = function (event: MessageEvent<IndicatorTask>) {\n const message = event.data;\n\n try {\n const start = performance.now();\n let response: IndicatorResultMessage;\n\n switch (message.indicator) {\n case \"rsi\": {\n const values = rsi(message.data, message.period ?? 14);\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"rsi\",\n values,\n duration: performance.now() - start,\n };\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, [values.buffer]);\n return;\n }\n case \"sma\": {\n const values = sma(message.data, message.period ?? 14);\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"sma\",\n values,\n duration: performance.now() - start,\n };\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, [values.buffer]);\n return;\n }\n case \"ema\": {\n const values = ema(message.data, message.period ?? 14);\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"ema\",\n values,\n duration: performance.now() - start,\n };\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, [values.buffer]);\n return;\n }\n case \"macd\": {\n const result = macd(\n message.data,\n message.fastPeriod ?? 12,\n message.slowPeriod ?? 26,\n message.signalPeriod ?? 9,\n );\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"macd\",\n values: result.values,\n signal: result.signal,\n histogram: result.histogram,\n duration: performance.now() - start,\n };\n const transfer: Transferable[] = [result.values.buffer];\n if (result.signal) transfer.push(result.signal.buffer);\n if (result.histogram) transfer.push(result.histogram.buffer);\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, transfer);\n return;\n }\n case \"bollingerBands\": {\n const result = bollingerBands(message.data, message.period ?? 20, message.stdDev ?? 2);\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"bollingerBands\",\n values: result.values,\n upper: result.upper,\n lower: result.lower,\n duration: performance.now() - start,\n };\n const transfer: Transferable[] = [result.values.buffer];\n if (result.upper) transfer.push(result.upper.buffer);\n if (result.lower) transfer.push(result.lower.buffer);\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, transfer);\n return;\n }\n default: {\n const err: ErrorMessage = {\n id: message.id,\n type: \"error\",\n error: `Unknown indicator: ${(message as IndicatorTask).indicator}`,\n };\n self.postMessage(err);\n }\n }\n } catch (error) {\n const err: ErrorMessage = {\n id: message.id,\n type: \"error\",\n error: error instanceof Error ? error.message : String(error),\n };\n self.postMessage(err);\n }\n};\n\nexport type { IndicatorTask, IndicatorResultMessage, ErrorMessage };\n"],"names":["sma","data","period","input","result","i","sum","ema","multiplier","rsi","avgGain","avgLoss","change","rs","gain","loss","macd","fastPeriod","slowPeriod","signalPeriod","fastEma","slowEma","macdLine","signal","histogram","bollingerBands","stdDev","middle","upper","lower","sumSquares","j","diff","std","event","message","start","response","values","transfer","err","error"],"mappings":"yBA+CO,SAASA,EAAIC,EAA8CC,EAA8B,CAC9F,MAAMC,EAAQF,aAAgB,cAAgBA,aAAgB,aAAeA,EAAO,aAAa,KAAKA,CAAI,EACpGG,EAAS,IAAI,aAAaD,EAAM,MAAM,EAE5C,GAAID,EAAS,GAAKA,EAASC,EAAM,OAC/B,OAAAC,EAAO,KAAK,GAAG,EACRA,EAIT,QAASC,EAAI,EAAGA,EAAIH,EAAS,EAAGG,IAC9BD,EAAOC,CAAC,EAAI,IAId,IAAIC,EAAM,EACV,QAASD,EAAI,EAAGA,EAAIH,EAAQG,IAC1BC,GAAOH,EAAME,CAAC,EAEhBD,EAAOF,EAAS,CAAC,EAAII,EAAMJ,EAG3B,QAASG,EAAIH,EAAQG,EAAIF,EAAM,OAAQE,IACrCC,EAAMA,EAAMH,EAAME,EAAIH,CAAM,EAAIC,EAAME,CAAC,EACvCD,EAAOC,CAAC,EAAIC,EAAMJ,EAGpB,OAAOE,CACT,CAOO,SAASG,EAAIN,EAA8CC,EAA8B,CAC9F,MAAMC,EAAQF,aAAgB,cAAgBA,aAAgB,aAAeA,EAAO,aAAa,KAAKA,CAAI,EACpGG,EAAS,IAAI,aAAaD,EAAM,MAAM,EAE5C,GAAID,EAAS,GAAKA,EAASC,EAAM,OAC/B,OAAAC,EAAO,KAAK,GAAG,EACRA,EAGT,MAAMI,EAAa,GAAKN,EAAS,GAGjC,QAASG,EAAI,EAAGA,EAAIH,EAAS,EAAGG,IAC9BD,EAAOC,CAAC,EAAI,IAId,IAAIC,EAAM,EACV,QAASD,EAAI,EAAGA,EAAIH,EAAQG,IAC1BC,GAAOH,EAAME,CAAC,EAEhBD,EAAOF,EAAS,CAAC,EAAII,EAAMJ,EAG3B,QAASG,EAAIH,EAAQG,EAAIF,EAAM,OAAQE,IACrCD,EAAOC,CAAC,GAAKF,EAAME,CAAC,EAAID,EAAOC,EAAI,CAAC,GAAKG,EAAaJ,EAAOC,EAAI,CAAC,EAGpE,OAAOD,CACT,CA+EO,SAASK,EAAIR,EAA8CC,EAAiB,GAAkB,CACnG,MAAMC,EAAQF,aAAgB,cAAgBA,aAAgB,aAAeA,EAAO,aAAa,KAAKA,CAAI,EACpGG,EAAS,IAAI,aAAaD,EAAM,MAAM,EAE5C,GAAID,EAAS,GAAKC,EAAM,OAASD,EAAS,EACxC,OAAAE,EAAO,KAAK,GAAG,EACRA,EAIT,QAASC,EAAI,EAAGA,EAAIH,EAAQG,IAC1BD,EAAOC,CAAC,EAAI,IAId,IAAIK,EAAU,EACVC,EAAU,EAEd,QAASN,EAAI,EAAGA,GAAKH,EAAQG,IAAK,CAChC,MAAMO,EAAST,EAAME,CAAC,EAAIF,EAAME,EAAI,CAAC,EACjCO,EAAS,EACXF,GAAWE,EAEXD,GAAW,KAAK,IAAIC,CAAM,CAE9B,CAMA,GAJAF,GAAWR,EACXS,GAAWT,EAGPS,IAAY,EACdP,EAAOF,CAAM,EAAI,QACZ,CACL,MAAMW,EAAKH,EAAUC,EACrBP,EAAOF,CAAM,EAAI,IAAO,KAAO,EAAIW,EACrC,CAGA,QAASR,EAAIH,EAAS,EAAGG,EAAIF,EAAM,OAAQE,IAAK,CAC9C,MAAMO,EAAST,EAAME,CAAC,EAAIF,EAAME,EAAI,CAAC,EACrC,IAAIS,EAAO,EACPC,EAAO,EAWX,GATIH,EAAS,EACXE,EAAOF,EAEPG,EAAO,KAAK,IAAIH,CAAM,EAGxBF,GAAWA,GAAWR,EAAS,GAAKY,GAAQZ,EAC5CS,GAAWA,GAAWT,EAAS,GAAKa,GAAQb,EAExCS,IAAY,EACdP,EAAOC,CAAC,EAAI,QACP,CACL,MAAMQ,EAAKH,EAAUC,EACrBP,EAAOC,CAAC,EAAI,IAAO,KAAO,EAAIQ,EAChC,CACF,CAEA,OAAOT,CACT,CASO,SAASY,EACdf,EACAgB,EAAqB,GACrBC,EAAqB,GACrBC,EAAuB,EACN,CACjB,MAAMhB,EAAQF,aAAgB,cAAgBA,aAAgB,aAAeA,EAAO,aAAa,KAAKA,CAAI,EAEpGmB,EAAUb,EAAIJ,EAAOc,CAAU,EAC/BI,EAAUd,EAAIJ,EAAOe,CAAU,EAG/BI,EAAW,IAAI,aAAanB,EAAM,MAAM,EAC9C,QAAS,EAAI,EAAG,EAAIA,EAAM,OAAQ,IAChCmB,EAAS,CAAC,EAAIF,EAAQ,CAAC,EAAIC,EAAQ,CAAC,EAItC,MAAME,EAAShB,EAAIe,EAAUH,CAAY,EAGnCK,EAAY,IAAI,aAAarB,EAAM,MAAM,EAC/C,QAAS,EAAI,EAAG,EAAIA,EAAM,OAAQ,IAChCqB,EAAU,CAAC,EAAIF,EAAS,CAAC,EAAIC,EAAO,CAAC,EAGvC,MAAO,CACL,OAAQD,EACR,OAAAC,EACA,UAAAC,CAAA,CAEJ,CAwGO,SAASC,EACdxB,EACAC,EAAiB,GACjBwB,EAAiB,EACA,CACjB,MAAMvB,EAAQF,aAAgB,cAAgBA,aAAgB,aAAeA,EAAO,aAAa,KAAKA,CAAI,EACpG0B,EAAS3B,EAAIG,EAAOD,CAAM,EAC1B0B,EAAQ,IAAI,aAAazB,EAAM,MAAM,EACrC0B,EAAQ,IAAI,aAAa1B,EAAM,MAAM,EAE3C,QAASE,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACrC,GAAIA,EAAIH,EAAS,EAAG,CAClB0B,EAAMvB,CAAC,EAAI,IACXwB,EAAMxB,CAAC,EAAI,IACX,QACF,CAGA,IAAIyB,EAAa,EACjB,QAASC,EAAI1B,EAAIH,EAAS,EAAG6B,GAAK1B,EAAG0B,IAAK,CACxC,MAAMC,EAAO7B,EAAM4B,CAAC,EAAIJ,EAAOtB,CAAC,EAChCyB,GAAcE,EAAOA,CACvB,CACA,MAAMC,EAAM,KAAK,KAAKH,EAAa5B,CAAM,EAEzC0B,EAAMvB,CAAC,EAAIsB,EAAOtB,CAAC,EAAIqB,EAASO,EAChCJ,EAAMxB,CAAC,EAAIsB,EAAOtB,CAAC,EAAIqB,EAASO,CAClC,CAEA,MAAO,CACL,OAAQN,EACR,MAAAC,EACA,MAAAC,CAAA,CAEJ,CCzYA,KAAK,UAAY,SAAUK,EAAoC,CAC7D,MAAMC,EAAUD,EAAM,KAEtB,GAAI,CACF,MAAME,EAAQ,YAAY,IAAA,EAC1B,IAAIC,EAEJ,OAAQF,EAAQ,UAAA,CACd,IAAK,MAAO,CACV,MAAMG,EAAS7B,EAAI0B,EAAQ,KAAMA,EAAQ,QAAU,EAAE,EACrDE,EAAW,CACT,GAAIF,EAAQ,GACZ,KAAM,mBACN,UAAW,MACX,OAAAG,EACA,SAAU,YAAY,MAAQF,CAAA,EAE/B,KAAK,YAAiEC,EAAU,CAACC,EAAO,MAAM,CAAC,EAChG,MACF,CACA,IAAK,MAAO,CACV,MAAMA,EAAStC,EAAImC,EAAQ,KAAMA,EAAQ,QAAU,EAAE,EACrDE,EAAW,CACT,GAAIF,EAAQ,GACZ,KAAM,mBACN,UAAW,MACX,OAAAG,EACA,SAAU,YAAY,MAAQF,CAAA,EAE/B,KAAK,YAAiEC,EAAU,CAACC,EAAO,MAAM,CAAC,EAChG,MACF,CACA,IAAK,MAAO,CACV,MAAMA,EAAS/B,EAAI4B,EAAQ,KAAMA,EAAQ,QAAU,EAAE,EACrDE,EAAW,CACT,GAAIF,EAAQ,GACZ,KAAM,mBACN,UAAW,MACX,OAAAG,EACA,SAAU,YAAY,MAAQF,CAAA,EAE/B,KAAK,YAAiEC,EAAU,CAACC,EAAO,MAAM,CAAC,EAChG,MACF,CACA,IAAK,OAAQ,CACX,MAAMlC,EAASY,EACbmB,EAAQ,KACRA,EAAQ,YAAc,GACtBA,EAAQ,YAAc,GACtBA,EAAQ,cAAgB,CAAA,EAE1BE,EAAW,CACT,GAAIF,EAAQ,GACZ,KAAM,mBACN,UAAW,OACX,OAAQ/B,EAAO,OACf,OAAQA,EAAO,OACf,UAAWA,EAAO,UAClB,SAAU,YAAY,MAAQgC,CAAA,EAEhC,MAAMG,EAA2B,CAACnC,EAAO,OAAO,MAAM,EAClDA,EAAO,QAAQmC,EAAS,KAAKnC,EAAO,OAAO,MAAM,EACjDA,EAAO,WAAWmC,EAAS,KAAKnC,EAAO,UAAU,MAAM,EAC1D,KAAK,YAAiEiC,EAAUE,CAAQ,EACzF,MACF,CACA,IAAK,iBAAkB,CACrB,MAAMnC,EAASqB,EAAeU,EAAQ,KAAMA,EAAQ,QAAU,GAAIA,EAAQ,QAAU,CAAC,EACrFE,EAAW,CACT,GAAIF,EAAQ,GACZ,KAAM,mBACN,UAAW,iBACX,OAAQ/B,EAAO,OACf,MAAOA,EAAO,MACd,MAAOA,EAAO,MACd,SAAU,YAAY,MAAQgC,CAAA,EAEhC,MAAMG,EAA2B,CAACnC,EAAO,OAAO,MAAM,EAClDA,EAAO,OAAOmC,EAAS,KAAKnC,EAAO,MAAM,MAAM,EAC/CA,EAAO,OAAOmC,EAAS,KAAKnC,EAAO,MAAM,MAAM,EAClD,KAAK,YAAiEiC,EAAUE,CAAQ,EACzF,MACF,CACA,QAAS,CACP,MAAMC,EAAoB,CACxB,GAAIL,EAAQ,GACZ,KAAM,QACN,MAAO,sBAAuBA,EAA0B,SAAS,EAAA,EAEnE,KAAK,YAAYK,CAAG,CACtB,CAAA,CAEJ,OAASC,EAAO,CACd,MAAMD,EAAoB,CACxB,GAAIL,EAAQ,GACZ,KAAM,QACN,MAAOM,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAA,EAE9D,KAAK,YAAYD,CAAG,CACtB,CACF"}
1
+ {"version":3,"file":"indicator.worker-bv0zC4EX.js","sources":["../src/plugins/analysis/indicators.ts","../src/workers/indicator.worker.ts"],"sourcesContent":["/**\n * Velo Plot - Financial/Technical Indicators Module\n * \n * Provides common financial and technical analysis indicators:\n * - Moving Averages (SMA, EMA, WMA)\n * - Momentum Indicators (RSI, MACD, Stochastic)\n * - Volatility (Bollinger Bands, ATR)\n * - Volume (VWAP, OBV)\n * - Trend (ADX, Aroon)\n * \n * @module indicators\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport interface IndicatorResult {\n /** Indicator values (NaN for insufficient data) */\n values: Float32Array;\n /** Additional line (e.g., signal line for MACD) */\n signal?: Float32Array;\n /** Upper band (e.g., Bollinger upper) */\n upper?: Float32Array;\n /** Lower band (e.g., Bollinger lower) */\n lower?: Float32Array;\n /** Histogram (e.g., MACD histogram) */\n histogram?: Float32Array;\n}\n\nexport interface OHLCData {\n open: Float32Array | Float64Array;\n high: Float32Array | Float64Array;\n low: Float32Array | Float64Array;\n close: Float32Array | Float64Array;\n volume?: Float32Array | Float64Array;\n}\n\n// ============================================\n// Moving Averages\n// ============================================\n\n/**\n * Simple Moving Average (SMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function sma(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n if (period < 1 || period > input.length) {\n result.fill(NaN);\n return result;\n }\n\n // Fill initial values with NaN\n for (let i = 0; i < period - 1; i++) {\n result[i] = NaN;\n }\n\n // Calculate first SMA\n let sum = 0;\n for (let i = 0; i < period; i++) {\n sum += input[i];\n }\n result[period - 1] = sum / period;\n\n // Calculate remaining SMAs using sliding window\n for (let i = period; i < input.length; i++) {\n sum = sum - input[i - period] + input[i];\n result[i] = sum / period;\n }\n\n return result;\n}\n\n/**\n * Exponential Moving Average (EMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function ema(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n if (period < 1 || period > input.length) {\n result.fill(NaN);\n return result;\n }\n\n const multiplier = 2 / (period + 1);\n\n // Fill initial values with NaN\n for (let i = 0; i < period - 1; i++) {\n result[i] = NaN;\n }\n\n // First EMA is SMA\n let sum = 0;\n for (let i = 0; i < period; i++) {\n sum += input[i];\n }\n result[period - 1] = sum / period;\n\n // Calculate remaining EMAs\n for (let i = period; i < input.length; i++) {\n result[i] = (input[i] - result[i - 1]) * multiplier + result[i - 1];\n }\n\n return result;\n}\n\n/**\n * Weighted Moving Average (WMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function wma(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n if (period < 1 || period > input.length) {\n result.fill(NaN);\n return result;\n }\n\n const weightSum = (period * (period + 1)) / 2;\n\n // Fill initial values with NaN\n for (let i = 0; i < period - 1; i++) {\n result[i] = NaN;\n }\n\n // Calculate WMAs\n for (let i = period - 1; i < input.length; i++) {\n let weightedSum = 0;\n for (let j = 0; j < period; j++) {\n weightedSum += input[i - period + 1 + j] * (j + 1);\n }\n result[i] = weightedSum / weightSum;\n }\n\n return result;\n}\n\n/**\n * Double Exponential Moving Average (DEMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function dema(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const ema1 = ema(data, period);\n const ema2 = ema(ema1, period);\n const result = new Float32Array(data.length);\n\n for (let i = 0; i < data.length; i++) {\n result[i] = 2 * ema1[i] - ema2[i];\n }\n\n return result;\n}\n\n/**\n * Triple Exponential Moving Average (TEMA)\n * @param data Input data array\n * @param period Number of periods\n */\nexport function tema(data: Float32Array | Float64Array | number[], period: number): Float32Array {\n const ema1 = ema(data, period);\n const ema2 = ema(ema1, period);\n const ema3 = ema(ema2, period);\n const result = new Float32Array(data.length);\n\n for (let i = 0; i < data.length; i++) {\n result[i] = 3 * ema1[i] - 3 * ema2[i] + ema3[i];\n }\n\n return result;\n}\n\n// ============================================\n// Momentum Indicators\n// ============================================\n\n/**\n * Relative Strength Index (RSI)\n * @param data Close prices\n * @param period RSI period (default: 14)\n */\nexport function rsi(data: Float32Array | Float64Array | number[], period: number = 14): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n if (period < 1 || input.length < period + 1) {\n result.fill(NaN);\n return result;\n }\n\n // Fill initial values with NaN\n for (let i = 0; i < period; i++) {\n result[i] = NaN;\n }\n\n // Calculate initial average gain/loss\n let avgGain = 0;\n let avgLoss = 0;\n\n for (let i = 1; i <= period; i++) {\n const change = input[i] - input[i - 1];\n if (change > 0) {\n avgGain += change;\n } else {\n avgLoss += Math.abs(change);\n }\n }\n\n avgGain /= period;\n avgLoss /= period;\n\n // First RSI value\n if (avgLoss === 0) {\n result[period] = 100;\n } else {\n const rs = avgGain / avgLoss;\n result[period] = 100 - (100 / (1 + rs));\n }\n\n // Calculate remaining RSI values using smoothed averages\n for (let i = period + 1; i < input.length; i++) {\n const change = input[i] - input[i - 1];\n let gain = 0;\n let loss = 0;\n\n if (change > 0) {\n gain = change;\n } else {\n loss = Math.abs(change);\n }\n\n avgGain = (avgGain * (period - 1) + gain) / period;\n avgLoss = (avgLoss * (period - 1) + loss) / period;\n\n if (avgLoss === 0) {\n result[i] = 100;\n } else {\n const rs = avgGain / avgLoss;\n result[i] = 100 - (100 / (1 + rs));\n }\n }\n\n return result;\n}\n\n/**\n * Moving Average Convergence Divergence (MACD)\n * @param data Close prices\n * @param fastPeriod Fast EMA period (default: 12)\n * @param slowPeriod Slow EMA period (default: 26)\n * @param signalPeriod Signal line period (default: 9)\n */\nexport function macd(\n data: Float32Array | Float64Array | number[],\n fastPeriod: number = 12,\n slowPeriod: number = 26,\n signalPeriod: number = 9\n): IndicatorResult {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n \n const fastEma = ema(input, fastPeriod);\n const slowEma = ema(input, slowPeriod);\n \n // MACD Line = Fast EMA - Slow EMA\n const macdLine = new Float32Array(input.length);\n for (let i = 0; i < input.length; i++) {\n macdLine[i] = fastEma[i] - slowEma[i];\n }\n \n // Signal Line = EMA of MACD Line\n const signal = ema(macdLine, signalPeriod);\n \n // Histogram = MACD Line - Signal Line\n const histogram = new Float32Array(input.length);\n for (let i = 0; i < input.length; i++) {\n histogram[i] = macdLine[i] - signal[i];\n }\n\n return {\n values: macdLine,\n signal,\n histogram,\n };\n}\n\n/**\n * Stochastic Oscillator\n * @param ohlc OHLC data\n * @param kPeriod %K period (default: 14)\n * @param dPeriod %D smoothing period (default: 3)\n */\nexport function stochastic(\n ohlc: OHLCData,\n kPeriod: number = 14,\n dPeriod: number = 3\n): IndicatorResult {\n const { high, low, close } = ohlc;\n const length = close.length;\n const kValues = new Float32Array(length);\n \n // Calculate %K\n for (let i = 0; i < length; i++) {\n if (i < kPeriod - 1) {\n kValues[i] = NaN;\n continue;\n }\n \n let highest = -Infinity;\n let lowest = Infinity;\n \n for (let j = i - kPeriod + 1; j <= i; j++) {\n if (high[j] > highest) highest = high[j];\n if (low[j] < lowest) lowest = low[j];\n }\n \n const range = highest - lowest;\n if (range === 0) {\n kValues[i] = 50; // Neutral when no range\n } else {\n kValues[i] = ((close[i] - lowest) / range) * 100;\n }\n }\n \n // %D is SMA of %K\n const dValues = sma(kValues, dPeriod);\n\n return {\n values: kValues, // %K\n signal: dValues, // %D\n };\n}\n\n/**\n * Rate of Change (ROC)\n * @param data Close prices\n * @param period ROC period (default: 10)\n */\nexport function roc(data: Float32Array | Float64Array | number[], period: number = 10): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n for (let i = 0; i < period; i++) {\n result[i] = NaN;\n }\n \n for (let i = period; i < input.length; i++) {\n const pastValue = input[i - period];\n if (pastValue === 0) {\n result[i] = NaN;\n } else {\n result[i] = ((input[i] - pastValue) / pastValue) * 100;\n }\n }\n\n return result;\n}\n\n/**\n * Momentum\n * @param data Close prices\n * @param period Momentum period (default: 10)\n */\nexport function momentum(data: Float32Array | Float64Array | number[], period: number = 10): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n for (let i = 0; i < period; i++) {\n result[i] = NaN;\n }\n \n for (let i = period; i < input.length; i++) {\n result[i] = input[i] - input[i - period];\n }\n\n return result;\n}\n\n// ============================================\n// Volatility Indicators\n// ============================================\n\n/**\n * Bollinger Bands\n * @param data Close prices\n * @param period SMA period (default: 20)\n * @param stdDev Standard deviation multiplier (default: 2)\n */\nexport function bollingerBands(\n data: Float32Array | Float64Array | number[],\n period: number = 20,\n stdDev: number = 2\n): IndicatorResult {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const middle = sma(input, period);\n const upper = new Float32Array(input.length);\n const lower = new Float32Array(input.length);\n\n for (let i = 0; i < input.length; i++) {\n if (i < period - 1) {\n upper[i] = NaN;\n lower[i] = NaN;\n continue;\n }\n\n // Calculate standard deviation\n let sumSquares = 0;\n for (let j = i - period + 1; j <= i; j++) {\n const diff = input[j] - middle[i];\n sumSquares += diff * diff;\n }\n const std = Math.sqrt(sumSquares / period);\n\n upper[i] = middle[i] + stdDev * std;\n lower[i] = middle[i] - stdDev * std;\n }\n\n return {\n values: middle,\n upper,\n lower,\n };\n}\n\n/**\n * Average True Range (ATR)\n * @param ohlc OHLC data\n * @param period ATR period (default: 14)\n */\nexport function atr(ohlc: OHLCData, period: number = 14): Float32Array {\n const { high, low, close } = ohlc;\n const length = close.length;\n const tr = new Float32Array(length);\n \n // True Range calculation\n tr[0] = high[0] - low[0];\n \n for (let i = 1; i < length; i++) {\n const hl = high[i] - low[i];\n const hc = Math.abs(high[i] - close[i - 1]);\n const lc = Math.abs(low[i] - close[i - 1]);\n tr[i] = Math.max(hl, hc, lc);\n }\n\n // ATR is smoothed average of True Range\n return ema(tr, period);\n}\n\n/**\n * Standard Deviation\n * @param data Input data\n * @param period Period for calculation (default: 20)\n */\nexport function standardDeviation(data: Float32Array | Float64Array | number[], period: number = 20): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n const avg = sma(input, period);\n\n for (let i = 0; i < input.length; i++) {\n if (i < period - 1) {\n result[i] = NaN;\n continue;\n }\n\n let sumSquares = 0;\n for (let j = i - period + 1; j <= i; j++) {\n const diff = input[j] - avg[i];\n sumSquares += diff * diff;\n }\n result[i] = Math.sqrt(sumSquares / period);\n }\n\n return result;\n}\n\n// ============================================\n// Volume Indicators\n// ============================================\n\n/**\n * Volume Weighted Average Price (VWAP)\n * @param ohlc OHLC data with volume\n */\nexport function vwap(ohlc: OHLCData): Float32Array {\n const { high, low, close, volume } = ohlc;\n \n if (!volume) {\n throw new Error('VWAP requires volume data');\n }\n\n const length = close.length;\n const result = new Float32Array(length);\n \n let cumulativeTPV = 0; // Cumulative Typical Price * Volume\n let cumulativeVolume = 0;\n\n for (let i = 0; i < length; i++) {\n const typicalPrice = (high[i] + low[i] + close[i]) / 3;\n cumulativeTPV += typicalPrice * volume[i];\n cumulativeVolume += volume[i];\n \n if (cumulativeVolume === 0) {\n result[i] = typicalPrice;\n } else {\n result[i] = cumulativeTPV / cumulativeVolume;\n }\n }\n\n return result;\n}\n\n/**\n * On-Balance Volume (OBV)\n * @param close Close prices\n * @param volume Volume data\n */\nexport function obv(\n close: Float32Array | Float64Array | number[],\n volume: Float32Array | Float64Array | number[]\n): Float32Array {\n const closeInput = close instanceof Float32Array || close instanceof Float64Array ? close : Float32Array.from(close);\n const volumeInput = volume instanceof Float32Array || volume instanceof Float64Array ? volume : Float32Array.from(volume);\n \n const result = new Float32Array(closeInput.length);\n result[0] = volumeInput[0];\n\n for (let i = 1; i < closeInput.length; i++) {\n if (closeInput[i] > closeInput[i - 1]) {\n result[i] = result[i - 1] + volumeInput[i];\n } else if (closeInput[i] < closeInput[i - 1]) {\n result[i] = result[i - 1] - volumeInput[i];\n } else {\n result[i] = result[i - 1];\n }\n }\n\n return result;\n}\n\n// ============================================\n// Trend Indicators\n// ============================================\n\n/**\n * Average Directional Index (ADX)\n * @param ohlc OHLC data\n * @param period ADX period (default: 14)\n */\nexport function adx(ohlc: OHLCData, period: number = 14): IndicatorResult {\n const { high, low, close } = ohlc;\n const length = close.length;\n \n const plusDM = new Float32Array(length);\n const minusDM = new Float32Array(length);\n const tr = new Float32Array(length);\n \n // Calculate +DM, -DM, TR\n tr[0] = high[0] - low[0];\n plusDM[0] = 0;\n minusDM[0] = 0;\n\n for (let i = 1; i < length; i++) {\n const upMove = high[i] - high[i - 1];\n const downMove = low[i - 1] - low[i];\n \n plusDM[i] = upMove > downMove && upMove > 0 ? upMove : 0;\n minusDM[i] = downMove > upMove && downMove > 0 ? downMove : 0;\n \n const hl = high[i] - low[i];\n const hc = Math.abs(high[i] - close[i - 1]);\n const lc = Math.abs(low[i] - close[i - 1]);\n tr[i] = Math.max(hl, hc, lc);\n }\n\n // Smooth with EMA\n const smoothedTR = ema(tr, period);\n const smoothedPlusDM = ema(plusDM, period);\n const smoothedMinusDM = ema(minusDM, period);\n\n // Calculate +DI and -DI\n const plusDI = new Float32Array(length);\n const minusDI = new Float32Array(length);\n const dx = new Float32Array(length);\n\n for (let i = 0; i < length; i++) {\n if (smoothedTR[i] === 0 || isNaN(smoothedTR[i])) {\n plusDI[i] = NaN;\n minusDI[i] = NaN;\n dx[i] = NaN;\n } else {\n plusDI[i] = (smoothedPlusDM[i] / smoothedTR[i]) * 100;\n minusDI[i] = (smoothedMinusDM[i] / smoothedTR[i]) * 100;\n \n const diSum = plusDI[i] + minusDI[i];\n dx[i] = diSum === 0 ? 0 : (Math.abs(plusDI[i] - minusDI[i]) / diSum) * 100;\n }\n }\n\n // ADX is smoothed DX\n const adxValues = ema(dx, period);\n\n return {\n values: adxValues,\n upper: plusDI, // +DI\n lower: minusDI, // -DI\n };\n}\n\n/**\n * Aroon Indicator\n * @param ohlc OHLC data\n * @param period Aroon period (default: 25)\n */\nexport function aroon(ohlc: OHLCData, period: number = 25): IndicatorResult {\n const { high, low } = ohlc;\n const length = high.length;\n \n const aroonUp = new Float32Array(length);\n const aroonDown = new Float32Array(length);\n\n for (let i = 0; i < length; i++) {\n if (i < period) {\n aroonUp[i] = NaN;\n aroonDown[i] = NaN;\n continue;\n }\n\n let highestIdx = i;\n let lowestIdx = i;\n let highest = -Infinity;\n let lowest = Infinity;\n\n for (let j = i - period; j <= i; j++) {\n if (high[j] > highest) {\n highest = high[j];\n highestIdx = j;\n }\n if (low[j] < lowest) {\n lowest = low[j];\n lowestIdx = j;\n }\n }\n\n aroonUp[i] = ((period - (i - highestIdx)) / period) * 100;\n aroonDown[i] = ((period - (i - lowestIdx)) / period) * 100;\n }\n\n // Aroon Oscillator = Aroon Up - Aroon Down\n const oscillator = new Float32Array(length);\n for (let i = 0; i < length; i++) {\n oscillator[i] = aroonUp[i] - aroonDown[i];\n }\n\n return {\n values: oscillator,\n upper: aroonUp,\n lower: aroonDown,\n };\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\n/**\n * Calculate percentage change\n */\nexport function percentChange(data: Float32Array | Float64Array | number[], period: number = 1): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n for (let i = 0; i < period; i++) {\n result[i] = NaN;\n }\n \n for (let i = period; i < input.length; i++) {\n const prev = input[i - period];\n if (prev === 0) {\n result[i] = NaN;\n } else {\n result[i] = ((input[i] - prev) / prev) * 100;\n }\n }\n\n return result;\n}\n\n/**\n * Calculate cumulative sum\n */\nexport function cumsum(data: Float32Array | Float64Array | number[]): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n result[0] = input[0];\n for (let i = 1; i < input.length; i++) {\n result[i] = result[i - 1] + input[i];\n }\n\n return result;\n}\n\n/**\n * Normalize data to 0-100 range\n */\nexport function normalize(data: Float32Array | Float64Array | number[]): Float32Array {\n const input = data instanceof Float32Array || data instanceof Float64Array ? data : Float32Array.from(data);\n const result = new Float32Array(input.length);\n \n let min = Infinity;\n let max = -Infinity;\n \n for (let i = 0; i < input.length; i++) {\n if (!isNaN(input[i])) {\n if (input[i] < min) min = input[i];\n if (input[i] > max) max = input[i];\n }\n }\n\n const range = max - min;\n if (range === 0) {\n result.fill(50);\n } else {\n for (let i = 0; i < input.length; i++) {\n result[i] = ((input[i] - min) / range) * 100;\n }\n }\n\n return result;\n}\n","/**\n * Indicator calculations in a Web Worker.\n * @module workers/indicator.worker\n */\n\nimport { rsi, macd, bollingerBands, sma, ema } from \"../plugins/analysis/indicators\";\n\ninterface IndicatorTask {\n id: string;\n type: \"indicator\";\n indicator: \"rsi\" | \"macd\" | \"bollingerBands\" | \"sma\" | \"ema\";\n data: Float32Array | Float64Array;\n period?: number;\n fastPeriod?: number;\n slowPeriod?: number;\n signalPeriod?: number;\n stdDev?: number;\n}\n\ninterface IndicatorResultMessage {\n id: string;\n type: \"indicator-result\";\n indicator: string;\n values: Float32Array;\n signal?: Float32Array;\n upper?: Float32Array;\n lower?: Float32Array;\n histogram?: Float32Array;\n duration: number;\n}\n\ninterface ErrorMessage {\n id: string;\n type: \"error\";\n error: string;\n}\n\nself.onmessage = function (event: MessageEvent<IndicatorTask>) {\n const message = event.data;\n\n try {\n const start = performance.now();\n let response: IndicatorResultMessage;\n\n switch (message.indicator) {\n case \"rsi\": {\n const values = rsi(message.data, message.period ?? 14);\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"rsi\",\n values,\n duration: performance.now() - start,\n };\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, [values.buffer]);\n return;\n }\n case \"sma\": {\n const values = sma(message.data, message.period ?? 14);\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"sma\",\n values,\n duration: performance.now() - start,\n };\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, [values.buffer]);\n return;\n }\n case \"ema\": {\n const values = ema(message.data, message.period ?? 14);\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"ema\",\n values,\n duration: performance.now() - start,\n };\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, [values.buffer]);\n return;\n }\n case \"macd\": {\n const result = macd(\n message.data,\n message.fastPeriod ?? 12,\n message.slowPeriod ?? 26,\n message.signalPeriod ?? 9,\n );\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"macd\",\n values: result.values,\n signal: result.signal,\n histogram: result.histogram,\n duration: performance.now() - start,\n };\n const transfer: Transferable[] = [result.values.buffer];\n if (result.signal) transfer.push(result.signal.buffer);\n if (result.histogram) transfer.push(result.histogram.buffer);\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, transfer);\n return;\n }\n case \"bollingerBands\": {\n const result = bollingerBands(message.data, message.period ?? 20, message.stdDev ?? 2);\n response = {\n id: message.id,\n type: \"indicator-result\",\n indicator: \"bollingerBands\",\n values: result.values,\n upper: result.upper,\n lower: result.lower,\n duration: performance.now() - start,\n };\n const transfer: Transferable[] = [result.values.buffer];\n if (result.upper) transfer.push(result.upper.buffer);\n if (result.lower) transfer.push(result.lower.buffer);\n (self.postMessage as (msg: unknown, transfer: Transferable[]) => void)(response, transfer);\n return;\n }\n default: {\n const err: ErrorMessage = {\n id: message.id,\n type: \"error\",\n error: `Unknown indicator: ${(message as IndicatorTask).indicator}`,\n };\n self.postMessage(err);\n }\n }\n } catch (error) {\n const err: ErrorMessage = {\n id: message.id,\n type: \"error\",\n error: error instanceof Error ? error.message : String(error),\n };\n self.postMessage(err);\n }\n};\n\nexport type { IndicatorTask, IndicatorResultMessage, ErrorMessage };\n"],"names":["sma","data","period","input","result","i","sum","ema","multiplier","rsi","avgGain","avgLoss","change","rs","gain","loss","macd","fastPeriod","slowPeriod","signalPeriod","fastEma","slowEma","macdLine","signal","histogram","bollingerBands","stdDev","middle","upper","lower","sumSquares","j","diff","std","event","message","start","response","values","transfer","err","error"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ ---
2
+ import { StackedPlot as StackedPlotReact } from "velo-plot/react";
3
+
4
+ interface Props {
5
+ panes: import("velo-plot").StackedPaneConfig[];
6
+ width?: number | string;
7
+ height?: number | string;
8
+ theme?: string;
9
+ class?: string;
10
+ }
11
+
12
+ const { panes, width = "100%", height = 480, theme, class: className = "" } = Astro.props as Props;
13
+ ---
14
+
15
+ <StackedPlotReact client:only="react" panes={panes} width={width} height={height} theme={theme} className={className} />
16
+
17
+ <noscript>
18
+ <p>Stacked chart requires JavaScript.</p>
19
+ </noscript>
@@ -0,0 +1,23 @@
1
+ ---
2
+ /**
3
+ * Astro island wrapper for velo-plot React VeloPlot.
4
+ * Usage: <VeloPlot client:only="react" series={...} />
5
+ */
6
+ import { VeloPlot as VeloPlotReact } from "velo-plot/react";
7
+
8
+ interface Props {
9
+ series?: import("velo-plot/react").VeloPlotSeries[];
10
+ width?: number | string;
11
+ height?: number | string;
12
+ theme?: string;
13
+ class?: string;
14
+ }
15
+
16
+ const { series = [], width = "100%", height = 400, theme, class: className = "" } = Astro.props as Props;
17
+ ---
18
+
19
+ <VeloPlotReact client:only="react" series={series} width={width} height={height} theme={theme} className={className} />
20
+
21
+ <noscript>
22
+ <p>Chart requires JavaScript. Enable JS to view the interactive chart.</p>
23
+ </noscript>
@@ -158,7 +158,7 @@ function h(t, e) {
158
158
  9: "⁹",
159
159
  "-": "⁻",
160
160
  "+": "⁺"
161
- }, a = i.replace("+", "").replace(/[0-9\-]/g, (f) => c[f]);
161
+ }, a = i.replace("+", "").replace(/[0-9-]/g, (f) => c[f]);
162
162
  return `${r}e${a}`;
163
163
  }
164
164
  function k(t, e, n, r) {
@@ -197,4 +197,4 @@ export {
197
197
  T as i,
198
198
  b as m
199
199
  };
200
- //# sourceMappingURL=axisFormat-CzumxpCL.js.map
200
+ //# sourceMappingURL=axisFormat-Sz4WIJfQ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"axisFormat-CzumxpCL.js","sources":["../src/core/EventEmitter.ts","../src/core/time/TimeScale.ts","../src/core/time/applyTimeScale.ts","../src/core/format/axisFormat.ts"],"sourcesContent":["/**\n * Type-safe event emitter for chart events\n */\n\nexport class EventEmitter<EventMap extends object> {\n private listeners: Map<keyof EventMap, Set<(data: unknown) => void>> =\n new Map();\n\n /**\n * Subscribe to an event\n */\n on<K extends keyof EventMap>(\n event: K,\n handler: (data: EventMap[K]) => void\n ): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as (data: unknown) => void);\n }\n\n /**\n * Unsubscribe from an event\n */\n off<K extends keyof EventMap>(\n event: K,\n handler: (data: EventMap[K]) => void\n ): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n handlers.delete(handler as (data: unknown) => void);\n }\n }\n\n /**\n * Emit an event with data\n */\n emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n console.error(`[EventEmitter] Error in handler for \"${String(event)}\":`, error);\n }\n });\n }\n }\n\n /**\n * Subscribe to an event once\n */\n once<K extends keyof EventMap>(\n event: K,\n handler: (data: EventMap[K]) => void\n ): void {\n const wrappedHandler = (data: EventMap[K]) => {\n this.off(event, wrappedHandler);\n handler(data);\n };\n this.on(event, wrappedHandler);\n }\n\n /**\n * Remove all listeners\n */\n clear(): void {\n this.listeners.clear();\n }\n\n /**\n * Get listener count for an event\n */\n listenerCount(event: keyof EventMap): number {\n return this.listeners.get(event)?.size ?? 0;\n }\n}\n","/**\n * TimeScale — business-day / session-aware X mapping for trading charts.\n * Stage 2.1–2.3\n */\n\nexport type TimeScaleCalendar = \"continuous\" | \"business-day\";\nexport type MarketSession = \"24x7\" | \"NYSE\";\n\nexport interface TimeScaleOptions {\n calendar?: TimeScaleCalendar;\n session?: MarketSession;\n /** IANA timezone (reserved for future session-hour filtering) */\n timezone?: string;\n}\n\nexport interface BusinessDayMapping {\n /** X values for chart (consecutive indices on business days) */\n scaledX: Float64Array;\n /** Original timestamp per scaled index (for tooltips / ticks) */\n timeByIndex: Float64Array;\n /** Original index → scaled index (-1 if skipped) */\n sourceToScaled: Int32Array;\n}\n\nconst MS_DAY = 86_400_000;\n\n/** UTC day-of-week: 0 = Sunday, 6 = Saturday */\nfunction dayOfWeekUtc(ts: number): number {\n return new Date(ts).getUTCDay();\n}\n\n/** Weekend check (NYSE calendar MVP — UTC weekends). */\nexport function isBusinessDay(ts: number, _opts: TimeScaleOptions = {}): boolean {\n const dow = dayOfWeekUtc(ts);\n return dow !== 0 && dow !== 6;\n}\n\n/**\n * Map timestamp series to consecutive business-day indices (skips Sat/Sun bars).\n * NaN in scaledX marks non-business bars (hidden gap).\n */\nexport function mapToBusinessDayScale(\n times: Float32Array | Float64Array,\n opts: TimeScaleOptions = {},\n): BusinessDayMapping {\n const calendar = opts.calendar ?? \"business-day\";\n const n = times.length;\n const scaledX = new Float64Array(n);\n const sourceToScaled = new Int32Array(n);\n sourceToScaled.fill(-1);\n\n if (calendar === \"continuous\") {\n for (let i = 0; i < n; i++) {\n scaledX[i] = times[i];\n sourceToScaled[i] = i;\n }\n return {\n scaledX,\n timeByIndex: times instanceof Float64Array ? times : Float64Array.from(times),\n sourceToScaled,\n };\n }\n\n const timeByIndex: number[] = [];\n let logical = 0;\n for (let i = 0; i < n; i++) {\n const t = times[i];\n if (!Number.isFinite(t) || !isBusinessDay(t, opts)) {\n scaledX[i] = Number.NaN;\n continue;\n }\n scaledX[i] = logical;\n timeByIndex[logical] = t;\n sourceToScaled[i] = logical;\n logical++;\n }\n\n return {\n scaledX,\n timeByIndex: Float64Array.from(timeByIndex),\n sourceToScaled,\n };\n}\n\n/** Resolve timestamp at a scaled business-day index (for axis ticks). */\nexport function timeAtBusinessIndex(mapping: BusinessDayMapping, index: number): number | undefined {\n return mapping.timeByIndex[index];\n}\n\n/** Visible span in ms using business-day mapping. */\nexport function businessDaySpanMs(mapping: BusinessDayMapping, xMin: number, xMax: number): number {\n const i0 = Math.max(0, Math.floor(xMin));\n const i1 = Math.min(mapping.timeByIndex.length - 1, Math.ceil(xMax));\n const t0 = mapping.timeByIndex[i0];\n const t1 = mapping.timeByIndex[i1];\n if (t0 == null || t1 == null) return MS_DAY;\n return Math.abs(t1 - t0) || MS_DAY;\n}\n","/**\n * Wire TimeScale into chart series + axis formatting (Stage 2.2–2.3).\n */\n\nimport type { AxisOptions } from \"../../types\";\nimport { formatTimeTick } from \"../format/axisFormat\";\nimport {\n businessDaySpanMs,\n mapToBusinessDayScale,\n timeAtBusinessIndex,\n type BusinessDayMapping,\n type TimeScaleOptions,\n} from \"./TimeScale\";\n\nexport function isBusinessDayScaleActive(xAxis: AxisOptions): boolean {\n return (\n xAxis.type === \"time\" &&\n (xAxis.timeScale?.calendar ?? \"business-day\") !== \"continuous\"\n );\n}\n\nexport function resolveTimeScaleOpts(xAxis: AxisOptions): TimeScaleOptions {\n return {\n calendar: \"business-day\",\n session: \"24x7\",\n ...xAxis.timeScale,\n };\n}\n\nexport function applyBusinessDayX(\n x: Float32Array | Float64Array,\n xAxis: AxisOptions,\n): { displayX: Float64Array; mapping: BusinessDayMapping } {\n const mapping = mapToBusinessDayScale(x, resolveTimeScaleOpts(xAxis));\n return { displayX: mapping.scaledX, mapping };\n}\n\nexport function formatBusinessDayTick(\n logicalIndex: number,\n mapping: BusinessDayMapping,\n): string | null {\n const idx = Math.round(logicalIndex);\n const t = timeAtBusinessIndex(mapping, idx);\n if (t === undefined) return null;\n const span = businessDaySpanMs(mapping, idx - 1, idx + 1);\n return formatTimeTick(t, span);\n}\n","/**\n * Shared axis tick and tooltip value formatting.\n */\nimport type { AxisOptions } from \"../../types\";\nimport type { BusinessDayMapping } from \"../time/TimeScale\";\nimport { formatBusinessDayTick } from \"../time/applyTimeScale\";\n\nconst PREFIXDivisors: Record<string, number> = {\n n: 1e-9,\n µ: 1e-6,\n m: 1e-3,\n \"\": 1,\n k: 1e3,\n M: 1e6,\n};\n\nexport function autoPrefixFor(value: number): NonNullable<AxisOptions[\"prefix\"]> {\n const absVal = Math.abs(value);\n if (absVal >= 1e6) return \"M\";\n if (absVal >= 1e3) return \"k\";\n if (absVal > 0 && absVal < 1e-6) return \"n\";\n if (absVal > 0 && absVal < 1e-3) return \"µ\";\n if (absVal > 0 && absVal < 1) return \"m\";\n return \"\";\n}\n\nexport function applyPrefix(\n value: number,\n prefix: NonNullable<AxisOptions[\"prefix\"]>,\n): string {\n const resolved = prefix === \"auto\" ? autoPrefixFor(value) : prefix;\n const divisor = PREFIXDivisors[resolved];\n const scaled = value / divisor;\n return `${scaled.toPrecision(3)}${resolved}`;\n}\n\nexport function pickTimeFormatter(spanMs: number): Intl.DateTimeFormat {\n if (spanMs <= 1000 * 60 * 60 * 36) {\n return new Intl.DateTimeFormat(undefined, {\n day: \"2-digit\",\n month: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n }\n if (spanMs <= 1000 * 60 * 60 * 24 * 90) {\n return new Intl.DateTimeFormat(undefined, { day: \"2-digit\", month: \"2-digit\" });\n }\n return new Intl.DateTimeFormat(undefined, { month: \"short\", year: \"2-digit\" });\n}\n\nexport function formatTimeTick(value: number, spanMs?: number): string {\n const span = spanMs ?? 1000 * 60 * 60 * 24;\n return pickTimeFormatter(span).format(new Date(value));\n}\n\nexport function toScientificUnicode(value: number, precision: number): string {\n const str = value.toExponential(precision);\n const [mantissa, exponent] = str.split(\"e\");\n\n const superscriptMap: Record<string, string> = {\n \"0\": \"⁰\",\n \"1\": \"¹\",\n \"2\": \"²\",\n \"3\": \"³\",\n \"4\": \"⁴\",\n \"5\": \"⁵\",\n \"6\": \"⁶\",\n \"7\": \"⁷\",\n \"8\": \"⁸\",\n \"9\": \"⁹\",\n \"-\": \"⁻\",\n \"+\": \"⁺\",\n };\n\n const unicodeExp = exponent\n .replace(\"+\", \"\")\n .replace(/[0-9\\-]/g, (char) => superscriptMap[char]);\n\n return `${mantissa}e${unicodeExp}`;\n}\n\nexport function formatXTickValue(\n value: number,\n options?: AxisOptions,\n domainSpan?: number,\n businessDayMapping?: BusinessDayMapping | null,\n): string {\n if (options?.type === \"time\" && businessDayMapping) {\n const label = formatBusinessDayTick(value, businessDayMapping);\n if (label) return label;\n return \"\";\n }\n if (options?.type === \"time\") {\n return formatTimeTick(value, domainSpan);\n }\n\n if (options?.prefix !== undefined && options.prefix !== \"\") {\n return applyPrefix(value, options.prefix);\n }\n\n const forceScientific = options?.scientific === true;\n const forceLinear = options?.scientific === false;\n const absVal = Math.abs(value);\n\n if (forceScientific || (!forceLinear && absVal !== 0 && absVal < 0.001)) {\n return toScientificUnicode(value, 1);\n }\n\n return value.toFixed(3).replace(/\\.?0+$/, \"\");\n}\n\nexport function formatYTickValue(value: number, options?: AxisOptions): string {\n if (value === 0) return \"0\";\n\n const forceScientific = options?.scientific === true;\n const forceLinear = options?.scientific === false;\n const absVal = Math.abs(value);\n\n if (options?.prefix !== undefined && options.prefix !== \"\") {\n return applyPrefix(value, options.prefix);\n }\n\n if (forceScientific || (!forceLinear && (absVal < 0.0001 || absVal >= 1e6))) {\n return toScientificUnicode(value, 1);\n }\n\n if (absVal >= 1000) {\n return value.toLocaleString(undefined, { maximumFractionDigits: 2 });\n }\n\n return value.toPrecision(3);\n}\n\nexport interface TooltipAxisFormat {\n x?: Partial<AxisOptions>;\n y?: Partial<AxisOptions>;\n xSpan?: number;\n}\n\nexport function formatTooltipX(value: number, axisFormat?: TooltipAxisFormat): string {\n return formatXTickValue(value, axisFormat?.x as AxisOptions | undefined, axisFormat?.xSpan);\n}\n\nexport function formatTooltipY(value: number, axisFormat?: TooltipAxisFormat): string {\n return formatYTickValue(value, axisFormat?.y as AxisOptions | undefined);\n}\n"],"names":["EventEmitter","__publicField","event","handler","handlers","data","error","wrappedHandler","_a","MS_DAY","dayOfWeekUtc","ts","isBusinessDay","_opts","dow","mapToBusinessDayScale","times","opts","calendar","n","scaledX","sourceToScaled","i","timeByIndex","logical","t","timeAtBusinessIndex","mapping","index","businessDaySpanMs","xMin","xMax","i0","i1","t0","t1","isBusinessDayScaleActive","xAxis","resolveTimeScaleOpts","applyBusinessDayX","x","formatBusinessDayTick","logicalIndex","idx","span","formatTimeTick","PREFIXDivisors","autoPrefixFor","value","absVal","applyPrefix","prefix","resolved","divisor","pickTimeFormatter","spanMs","toScientificUnicode","precision","str","mantissa","exponent","superscriptMap","unicodeExp","char","formatXTickValue","options","domainSpan","businessDayMapping","label","forceScientific","forceLinear","formatYTickValue","formatTooltipX","axisFormat","formatTooltipY"],"mappings":";;;AAIO,MAAMA,EAAsC;AAAA,EAA5C;AACG,IAAAC,EAAA,uCACF,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKN,GACEC,GACAC,GACM;AACN,IAAK,KAAK,UAAU,IAAID,CAAK,KAC3B,KAAK,UAAU,IAAIA,GAAO,oBAAI,KAAK,GAErC,KAAK,UAAU,IAAIA,CAAK,EAAG,IAAIC,CAAkC;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,IACED,GACAC,GACM;AACN,UAAMC,IAAW,KAAK,UAAU,IAAIF,CAAK;AACzC,IAAIE,KACFA,EAAS,OAAOD,CAAkC;AAAA,EAEtD;AAAA;AAAA;AAAA;AAAA,EAKA,KAA+BD,GAAUG,GAAyB;AAChE,UAAMD,IAAW,KAAK,UAAU,IAAIF,CAAK;AACzC,IAAIE,KACFA,EAAS,QAAQ,CAACD,MAAY;AAC5B,UAAI;AACF,QAAAA,EAAQE,CAAI;AAAA,MACd,SAASC,GAAO;AACd,gBAAQ,MAAM,wCAAwC,OAAOJ,CAAK,CAAC,MAAMI,CAAK;AAAA,MAChF;AAAA,IACF,CAAC;AAAA,EAEL;AAAA;AAAA;AAAA;AAAA,EAKA,KACEJ,GACAC,GACM;AACN,UAAMI,IAAiB,CAACF,MAAsB;AAC5C,WAAK,IAAIH,GAAOK,CAAc,GAC9BJ,EAAQE,CAAI;AAAA,IACd;AACA,SAAK,GAAGH,GAAOK,CAAc;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,UAAU,MAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAcL,GAA+B;AAtExC,QAAAM;AAuEH,aAAOA,IAAA,KAAK,UAAU,IAAIN,CAAK,MAAxB,gBAAAM,EAA2B,SAAQ;AAAA,EAC5C;AACF;ACrDA,MAAMC,IAAS;AAGf,SAASC,EAAaC,GAAoB;AACxC,SAAO,IAAI,KAAKA,CAAE,EAAE,UAAA;AACtB;AAGO,SAASC,EAAcD,GAAYE,IAA0B,IAAa;AAC/E,QAAMC,IAAMJ,EAAaC,CAAE;AAC3B,SAAOG,MAAQ,KAAKA,MAAQ;AAC9B;AAMO,SAASC,EACdC,GACAC,IAAyB,IACL;AACpB,QAAMC,IAAWD,EAAK,YAAY,gBAC5BE,IAAIH,EAAM,QACVI,IAAU,IAAI,aAAaD,CAAC,GAC5BE,IAAiB,IAAI,WAAWF,CAAC;AAGvC,MAFAE,EAAe,KAAK,EAAE,GAElBH,MAAa,cAAc;AAC7B,aAASI,IAAI,GAAGA,IAAIH,GAAGG;AACrB,MAAAF,EAAQE,CAAC,IAAIN,EAAMM,CAAC,GACpBD,EAAeC,CAAC,IAAIA;AAEtB,WAAO;AAAA,MACL,SAAAF;AAAA,MACA,aAAaJ,aAAiB,eAAeA,IAAQ,aAAa,KAAKA,CAAK;AAAA,MAC5E,gBAAAK;AAAA,IAAA;AAAA,EAEJ;AAEA,QAAME,IAAwB,CAAA;AAC9B,MAAIC,IAAU;AACd,WAASF,IAAI,GAAGA,IAAIH,GAAGG,KAAK;AAC1B,UAAMG,IAAIT,EAAMM,CAAC;AACjB,QAAI,CAAC,OAAO,SAASG,CAAC,KAAK,CAACb,EAAca,GAAGR,CAAI,GAAG;AAClD,MAAAG,EAAQE,CAAC,IAAI,OAAO;AACpB;AAAA,IACF;AACA,IAAAF,EAAQE,CAAC,IAAIE,GACbD,EAAYC,CAAO,IAAIC,GACvBJ,EAAeC,CAAC,IAAIE,GACpBA;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAAJ;AAAA,IACA,aAAa,aAAa,KAAKG,CAAW;AAAA,IAC1C,gBAAAF;AAAA,EAAA;AAEJ;AAGO,SAASK,EAAoBC,GAA6BC,GAAmC;AAClG,SAAOD,EAAQ,YAAYC,CAAK;AAClC;AAGO,SAASC,EAAkBF,GAA6BG,GAAcC,GAAsB;AACjG,QAAMC,IAAK,KAAK,IAAI,GAAG,KAAK,MAAMF,CAAI,CAAC,GACjCG,IAAK,KAAK,IAAIN,EAAQ,YAAY,SAAS,GAAG,KAAK,KAAKI,CAAI,CAAC,GAC7DG,IAAKP,EAAQ,YAAYK,CAAE,GAC3BG,IAAKR,EAAQ,YAAYM,CAAE;AACjC,SAAIC,KAAM,QAAQC,KAAM,OAAa1B,IAC9B,KAAK,IAAI0B,IAAKD,CAAE,KAAKzB;AAC9B;ACnFO,SAAS2B,EAAyBC,GAA6B;AFV/D,MAAA7B;AEWL,SACE6B,EAAM,SAAS,aACd7B,IAAA6B,EAAM,cAAN,gBAAA7B,EAAiB,aAAY,oBAAoB;AAEtD;AAEO,SAAS8B,EAAqBD,GAAsC;AACzE,SAAO;AAAA,IACL,UAAU;AAAA,IACV,SAAS;AAAA,IACT,GAAGA,EAAM;AAAA,EAAA;AAEb;AAEO,SAASE,EACdC,GACAH,GACyD;AACzD,QAAMV,IAAUZ,EAAsByB,GAAGF,EAAqBD,CAAK,CAAC;AACpE,SAAO,EAAE,UAAUV,EAAQ,SAAS,SAAAA,EAAA;AACtC;AAEO,SAASc,EACdC,GACAf,GACe;AACf,QAAMgB,IAAM,KAAK,MAAMD,CAAY,GAC7BjB,IAAIC,EAAoBC,GAASgB,CAAG;AAC1C,MAAIlB,MAAM,OAAW,QAAO;AAC5B,QAAMmB,IAAOf,EAAkBF,GAASgB,IAAM,GAAGA,IAAM,CAAC;AACxD,SAAOE,EAAepB,GAAGmB,CAAI;AAC/B;ACvCA,MAAME,IAAyC;AAAA,EAC7C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,GAAG;AACL;AAEO,SAASC,EAAcC,GAAmD;AAC/E,QAAMC,IAAS,KAAK,IAAID,CAAK;AAC7B,SAAIC,KAAU,MAAY,MACtBA,KAAU,MAAY,MACtBA,IAAS,KAAKA,IAAS,OAAa,MACpCA,IAAS,KAAKA,IAAS,OAAa,MACpCA,IAAS,KAAKA,IAAS,IAAU,MAC9B;AACT;AAEO,SAASC,EACdF,GACAG,GACQ;AACR,QAAMC,IAAWD,MAAW,SAASJ,EAAcC,CAAK,IAAIG,GACtDE,IAAUP,EAAeM,CAAQ;AAEvC,SAAO,IADQJ,IAAQK,GACN,YAAY,CAAC,CAAC,GAAGD,CAAQ;AAC5C;AAEO,SAASE,EAAkBC,GAAqC;AACrE,SAAIA,KAAU,MAAO,KAAK,KAAK,KACtB,IAAI,KAAK,eAAe,QAAW;AAAA,IACxC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,EAAA,CACT,IAECA,KAAU,MAAO,KAAK,KAAK,KAAK,KAC3B,IAAI,KAAK,eAAe,QAAW,EAAE,KAAK,WAAW,OAAO,WAAW,IAEzE,IAAI,KAAK,eAAe,QAAW,EAAE,OAAO,SAAS,MAAM,WAAW;AAC/E;AAEO,SAASV,EAAeG,GAAeO,GAAyB;AAErE,SAAOD,EADMC,KAAU,KACM,EAAE,OAAO,IAAI,KAAKP,CAAK,CAAC;AACvD;AAEO,SAASQ,EAAoBR,GAAeS,GAA2B;AAC5E,QAAMC,IAAMV,EAAM,cAAcS,CAAS,GACnC,CAACE,GAAUC,CAAQ,IAAIF,EAAI,MAAM,GAAG,GAEpCG,IAAyC;AAAA,IAC7C,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EAAA,GAGDC,IAAaF,EAChB,QAAQ,KAAK,EAAE,EACf,QAAQ,YAAY,CAACG,MAASF,EAAeE,CAAI,CAAC;AAErD,SAAO,GAAGJ,CAAQ,IAAIG,CAAU;AAClC;AAEO,SAASE,EACdhB,GACAiB,GACAC,GACAC,GACQ;AACR,OAAIF,KAAA,gBAAAA,EAAS,UAAS,UAAUE,GAAoB;AAClD,UAAMC,IAAQ3B,EAAsBO,GAAOmB,CAAkB;AAC7D,WAAIC,KACG;AAAA,EACT;AACA,OAAIH,KAAA,gBAAAA,EAAS,UAAS;AACpB,WAAOpB,EAAeG,GAAOkB,CAAU;AAGzC,OAAID,KAAA,gBAAAA,EAAS,YAAW,UAAaA,EAAQ,WAAW;AACtD,WAAOf,EAAYF,GAAOiB,EAAQ,MAAM;AAG1C,QAAMI,KAAkBJ,KAAA,gBAAAA,EAAS,gBAAe,IAC1CK,KAAcL,KAAA,gBAAAA,EAAS,gBAAe,IACtChB,IAAS,KAAK,IAAID,CAAK;AAE7B,SAAIqB,KAAoB,CAACC,KAAerB,MAAW,KAAKA,IAAS,OACxDO,EAAoBR,GAAO,CAAC,IAG9BA,EAAM,QAAQ,CAAC,EAAE,QAAQ,UAAU,EAAE;AAC9C;AAEO,SAASuB,EAAiBvB,GAAeiB,GAA+B;AAC7E,MAAIjB,MAAU,EAAG,QAAO;AAExB,QAAMqB,KAAkBJ,KAAA,gBAAAA,EAAS,gBAAe,IAC1CK,KAAcL,KAAA,gBAAAA,EAAS,gBAAe,IACtChB,IAAS,KAAK,IAAID,CAAK;AAE7B,UAAIiB,KAAA,gBAAAA,EAAS,YAAW,UAAaA,EAAQ,WAAW,KAC/Cf,EAAYF,GAAOiB,EAAQ,MAAM,IAGtCI,KAAoB,CAACC,MAAgBrB,IAAS,QAAUA,KAAU,OAC7DO,EAAoBR,GAAO,CAAC,IAGjCC,KAAU,MACLD,EAAM,eAAe,QAAW,EAAE,uBAAuB,GAAG,IAG9DA,EAAM,YAAY,CAAC;AAC5B;AAQO,SAASwB,EAAexB,GAAeyB,GAAwC;AACpF,SAAOT,EAAiBhB,GAAOyB,KAAA,gBAAAA,EAAY,GAA8BA,KAAA,gBAAAA,EAAY,KAAK;AAC5F;AAEO,SAASC,EAAe1B,GAAeyB,GAAwC;AACpF,SAAOF,EAAiBvB,GAAOyB,KAAA,gBAAAA,EAAY,CAA4B;AACzE;"}
1
+ {"version":3,"file":"axisFormat-Sz4WIJfQ.js","sources":["../src/core/EventEmitter.ts","../src/core/time/TimeScale.ts","../src/core/time/applyTimeScale.ts","../src/core/format/axisFormat.ts"],"sourcesContent":["/**\n * Type-safe event emitter for chart events\n */\n\nexport class EventEmitter<EventMap extends object> {\n private listeners: Map<keyof EventMap, Set<(data: unknown) => void>> =\n new Map();\n\n /**\n * Subscribe to an event\n */\n on<K extends keyof EventMap>(\n event: K,\n handler: (data: EventMap[K]) => void\n ): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as (data: unknown) => void);\n }\n\n /**\n * Unsubscribe from an event\n */\n off<K extends keyof EventMap>(\n event: K,\n handler: (data: EventMap[K]) => void\n ): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n handlers.delete(handler as (data: unknown) => void);\n }\n }\n\n /**\n * Emit an event with data\n */\n emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n console.error(`[EventEmitter] Error in handler for \"${String(event)}\":`, error);\n }\n });\n }\n }\n\n /**\n * Subscribe to an event once\n */\n once<K extends keyof EventMap>(\n event: K,\n handler: (data: EventMap[K]) => void\n ): void {\n const wrappedHandler = (data: EventMap[K]) => {\n this.off(event, wrappedHandler);\n handler(data);\n };\n this.on(event, wrappedHandler);\n }\n\n /**\n * Remove all listeners\n */\n clear(): void {\n this.listeners.clear();\n }\n\n /**\n * Get listener count for an event\n */\n listenerCount(event: keyof EventMap): number {\n return this.listeners.get(event)?.size ?? 0;\n }\n}\n","/**\n * TimeScale — business-day / session-aware X mapping for trading charts.\n * Stage 2.1–2.3\n */\n\nexport type TimeScaleCalendar = \"continuous\" | \"business-day\";\nexport type MarketSession = \"24x7\" | \"NYSE\";\n\nexport interface TimeScaleOptions {\n calendar?: TimeScaleCalendar;\n session?: MarketSession;\n /** IANA timezone (reserved for future session-hour filtering) */\n timezone?: string;\n}\n\nexport interface BusinessDayMapping {\n /** X values for chart (consecutive indices on business days) */\n scaledX: Float64Array;\n /** Original timestamp per scaled index (for tooltips / ticks) */\n timeByIndex: Float64Array;\n /** Original index → scaled index (-1 if skipped) */\n sourceToScaled: Int32Array;\n}\n\nconst MS_DAY = 86_400_000;\n\n/** UTC day-of-week: 0 = Sunday, 6 = Saturday */\nfunction dayOfWeekUtc(ts: number): number {\n return new Date(ts).getUTCDay();\n}\n\n/** Weekend check (NYSE calendar MVP — UTC weekends). */\nexport function isBusinessDay(ts: number, _opts: TimeScaleOptions = {}): boolean {\n const dow = dayOfWeekUtc(ts);\n return dow !== 0 && dow !== 6;\n}\n\n/**\n * Map timestamp series to consecutive business-day indices (skips Sat/Sun bars).\n * NaN in scaledX marks non-business bars (hidden gap).\n */\nexport function mapToBusinessDayScale(\n times: Float32Array | Float64Array,\n opts: TimeScaleOptions = {},\n): BusinessDayMapping {\n const calendar = opts.calendar ?? \"business-day\";\n const n = times.length;\n const scaledX = new Float64Array(n);\n const sourceToScaled = new Int32Array(n);\n sourceToScaled.fill(-1);\n\n if (calendar === \"continuous\") {\n for (let i = 0; i < n; i++) {\n scaledX[i] = times[i];\n sourceToScaled[i] = i;\n }\n return {\n scaledX,\n timeByIndex: times instanceof Float64Array ? times : Float64Array.from(times),\n sourceToScaled,\n };\n }\n\n const timeByIndex: number[] = [];\n let logical = 0;\n for (let i = 0; i < n; i++) {\n const t = times[i];\n if (!Number.isFinite(t) || !isBusinessDay(t, opts)) {\n scaledX[i] = Number.NaN;\n continue;\n }\n scaledX[i] = logical;\n timeByIndex[logical] = t;\n sourceToScaled[i] = logical;\n logical++;\n }\n\n return {\n scaledX,\n timeByIndex: Float64Array.from(timeByIndex),\n sourceToScaled,\n };\n}\n\n/** Resolve timestamp at a scaled business-day index (for axis ticks). */\nexport function timeAtBusinessIndex(mapping: BusinessDayMapping, index: number): number | undefined {\n return mapping.timeByIndex[index];\n}\n\n/** Visible span in ms using business-day mapping. */\nexport function businessDaySpanMs(mapping: BusinessDayMapping, xMin: number, xMax: number): number {\n const i0 = Math.max(0, Math.floor(xMin));\n const i1 = Math.min(mapping.timeByIndex.length - 1, Math.ceil(xMax));\n const t0 = mapping.timeByIndex[i0];\n const t1 = mapping.timeByIndex[i1];\n if (t0 == null || t1 == null) return MS_DAY;\n return Math.abs(t1 - t0) || MS_DAY;\n}\n","/**\n * Wire TimeScale into chart series + axis formatting (Stage 2.2–2.3).\n */\n\nimport type { AxisOptions } from \"../../types\";\nimport { formatTimeTick } from \"../format/axisFormat\";\nimport {\n businessDaySpanMs,\n mapToBusinessDayScale,\n timeAtBusinessIndex,\n type BusinessDayMapping,\n type TimeScaleOptions,\n} from \"./TimeScale\";\n\nexport function isBusinessDayScaleActive(xAxis: AxisOptions): boolean {\n return (\n xAxis.type === \"time\" &&\n (xAxis.timeScale?.calendar ?? \"business-day\") !== \"continuous\"\n );\n}\n\nexport function resolveTimeScaleOpts(xAxis: AxisOptions): TimeScaleOptions {\n return {\n calendar: \"business-day\",\n session: \"24x7\",\n ...xAxis.timeScale,\n };\n}\n\nexport function applyBusinessDayX(\n x: Float32Array | Float64Array,\n xAxis: AxisOptions,\n): { displayX: Float64Array; mapping: BusinessDayMapping } {\n const mapping = mapToBusinessDayScale(x, resolveTimeScaleOpts(xAxis));\n return { displayX: mapping.scaledX, mapping };\n}\n\nexport function formatBusinessDayTick(\n logicalIndex: number,\n mapping: BusinessDayMapping,\n): string | null {\n const idx = Math.round(logicalIndex);\n const t = timeAtBusinessIndex(mapping, idx);\n if (t === undefined) return null;\n const span = businessDaySpanMs(mapping, idx - 1, idx + 1);\n return formatTimeTick(t, span);\n}\n","/**\n * Shared axis tick and tooltip value formatting.\n */\nimport type { AxisOptions } from \"../../types\";\nimport type { BusinessDayMapping } from \"../time/TimeScale\";\nimport { formatBusinessDayTick } from \"../time/applyTimeScale\";\n\nconst PREFIXDivisors: Record<string, number> = {\n n: 1e-9,\n µ: 1e-6,\n m: 1e-3,\n \"\": 1,\n k: 1e3,\n M: 1e6,\n};\n\nexport function autoPrefixFor(value: number): NonNullable<AxisOptions[\"prefix\"]> {\n const absVal = Math.abs(value);\n if (absVal >= 1e6) return \"M\";\n if (absVal >= 1e3) return \"k\";\n if (absVal > 0 && absVal < 1e-6) return \"n\";\n if (absVal > 0 && absVal < 1e-3) return \"µ\";\n if (absVal > 0 && absVal < 1) return \"m\";\n return \"\";\n}\n\nexport function applyPrefix(\n value: number,\n prefix: NonNullable<AxisOptions[\"prefix\"]>,\n): string {\n const resolved = prefix === \"auto\" ? autoPrefixFor(value) : prefix;\n const divisor = PREFIXDivisors[resolved];\n const scaled = value / divisor;\n return `${scaled.toPrecision(3)}${resolved}`;\n}\n\nexport function pickTimeFormatter(spanMs: number): Intl.DateTimeFormat {\n if (spanMs <= 1000 * 60 * 60 * 36) {\n return new Intl.DateTimeFormat(undefined, {\n day: \"2-digit\",\n month: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n }\n if (spanMs <= 1000 * 60 * 60 * 24 * 90) {\n return new Intl.DateTimeFormat(undefined, { day: \"2-digit\", month: \"2-digit\" });\n }\n return new Intl.DateTimeFormat(undefined, { month: \"short\", year: \"2-digit\" });\n}\n\nexport function formatTimeTick(value: number, spanMs?: number): string {\n const span = spanMs ?? 1000 * 60 * 60 * 24;\n return pickTimeFormatter(span).format(new Date(value));\n}\n\nexport function toScientificUnicode(value: number, precision: number): string {\n const str = value.toExponential(precision);\n const [mantissa, exponent] = str.split(\"e\");\n\n const superscriptMap: Record<string, string> = {\n \"0\": \"⁰\",\n \"1\": \"¹\",\n \"2\": \"²\",\n \"3\": \"³\",\n \"4\": \"⁴\",\n \"5\": \"⁵\",\n \"6\": \"⁶\",\n \"7\": \"⁷\",\n \"8\": \"⁸\",\n \"9\": \"⁹\",\n \"-\": \"⁻\",\n \"+\": \"⁺\",\n };\n\n const unicodeExp = exponent\n .replace(\"+\", \"\")\n .replace(/[0-9-]/g, (char) => superscriptMap[char]);\n\n return `${mantissa}e${unicodeExp}`;\n}\n\nexport function formatXTickValue(\n value: number,\n options?: AxisOptions,\n domainSpan?: number,\n businessDayMapping?: BusinessDayMapping | null,\n): string {\n if (options?.type === \"time\" && businessDayMapping) {\n const label = formatBusinessDayTick(value, businessDayMapping);\n if (label) return label;\n return \"\";\n }\n if (options?.type === \"time\") {\n return formatTimeTick(value, domainSpan);\n }\n\n if (options?.prefix !== undefined && options.prefix !== \"\") {\n return applyPrefix(value, options.prefix);\n }\n\n const forceScientific = options?.scientific === true;\n const forceLinear = options?.scientific === false;\n const absVal = Math.abs(value);\n\n if (forceScientific || (!forceLinear && absVal !== 0 && absVal < 0.001)) {\n return toScientificUnicode(value, 1);\n }\n\n return value.toFixed(3).replace(/\\.?0+$/, \"\");\n}\n\nexport function formatYTickValue(value: number, options?: AxisOptions): string {\n if (value === 0) return \"0\";\n\n const forceScientific = options?.scientific === true;\n const forceLinear = options?.scientific === false;\n const absVal = Math.abs(value);\n\n if (options?.prefix !== undefined && options.prefix !== \"\") {\n return applyPrefix(value, options.prefix);\n }\n\n if (forceScientific || (!forceLinear && (absVal < 0.0001 || absVal >= 1e6))) {\n return toScientificUnicode(value, 1);\n }\n\n if (absVal >= 1000) {\n return value.toLocaleString(undefined, { maximumFractionDigits: 2 });\n }\n\n return value.toPrecision(3);\n}\n\nexport interface TooltipAxisFormat {\n x?: Partial<AxisOptions>;\n y?: Partial<AxisOptions>;\n xSpan?: number;\n}\n\nexport function formatTooltipX(value: number, axisFormat?: TooltipAxisFormat): string {\n return formatXTickValue(value, axisFormat?.x as AxisOptions | undefined, axisFormat?.xSpan);\n}\n\nexport function formatTooltipY(value: number, axisFormat?: TooltipAxisFormat): string {\n return formatYTickValue(value, axisFormat?.y as AxisOptions | undefined);\n}\n"],"names":["EventEmitter","__publicField","event","handler","handlers","data","error","wrappedHandler","_a","MS_DAY","dayOfWeekUtc","ts","isBusinessDay","_opts","dow","mapToBusinessDayScale","times","opts","calendar","n","scaledX","sourceToScaled","i","timeByIndex","logical","t","timeAtBusinessIndex","mapping","index","businessDaySpanMs","xMin","xMax","i0","i1","t0","t1","isBusinessDayScaleActive","xAxis","resolveTimeScaleOpts","applyBusinessDayX","x","formatBusinessDayTick","logicalIndex","idx","span","formatTimeTick","PREFIXDivisors","autoPrefixFor","value","absVal","applyPrefix","prefix","resolved","divisor","pickTimeFormatter","spanMs","toScientificUnicode","precision","str","mantissa","exponent","superscriptMap","unicodeExp","char","formatXTickValue","options","domainSpan","businessDayMapping","label","forceScientific","forceLinear","formatYTickValue","formatTooltipX","axisFormat","formatTooltipY"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { Bounds } from '../../types';
2
+ import { VeloPlotSeries } from './types';
3
+ import { KeyBindingManager } from '../../core/keybindings';
4
+
5
+ export interface A11yOptions {
6
+ label?: string;
7
+ series?: VeloPlotSeries[];
8
+ bounds?: Bounds | null;
9
+ enableKeyboard?: boolean;
10
+ }
11
+ export interface A11yHandle {
12
+ keyboard?: KeyBindingManager;
13
+ srTable?: HTMLTableElement;
14
+ cleanup: () => void;
15
+ }
16
+ export declare function buildAriaLabel(series?: VeloPlotSeries[], bounds?: Bounds | null, customLabel?: string): string;
17
+ export declare function applyChartA11y(container: HTMLElement, chart: {
18
+ resetZoom?: () => void;
19
+ zoom?: (opts: {
20
+ x?: [number, number];
21
+ y?: [number, number];
22
+ }) => void;
23
+ pan?: (dx: number, dy: number) => void;
24
+ getViewBounds?: () => Bounds;
25
+ }, options?: A11yOptions): A11yHandle;
26
+ export declare function updateA11y(container: HTMLElement, srTable: HTMLTableElement | undefined, options: A11yOptions): void;
@@ -0,0 +1,16 @@
1
+ import { Chart } from '../../core/Chart';
2
+ import { ChartOptions, Bounds } from '../../types';
3
+ import { BindingChartOptions } from './types';
4
+
5
+ export type ChartBindingOptions = Omit<ChartOptions, "container"> & BindingChartOptions;
6
+ export interface ChartLifecycleHandle {
7
+ chart: Chart;
8
+ destroy: () => void;
9
+ getBounds: () => Bounds | null;
10
+ }
11
+ export interface ChartLifecycleCallbacks {
12
+ onBoundsChange?: (bounds: Bounds) => void;
13
+ onError?: (error: Error) => void;
14
+ }
15
+ export declare function createChartLifecycle(container: HTMLDivElement, options: ChartBindingOptions, callbacks?: ChartLifecycleCallbacks): ChartLifecycleHandle;
16
+ export declare function attachZoomListener(chart: Chart, onBoundsChange: (bounds: Bounds) => void): () => void;
@@ -0,0 +1,8 @@
1
+ import { ChartGroup, ChartLike, SyncOptions } from '../../core/sync';
2
+
3
+ export interface ChartSyncHandle {
4
+ group: ChartGroup;
5
+ destroy: () => void;
6
+ }
7
+ export declare function createChartSync(charts: ChartLike[], options?: SyncOptions): ChartSyncHandle;
8
+ export declare function updateChartSync(handle: ChartSyncHandle | null, charts: ChartLike[], options?: SyncOptions): ChartSyncHandle;
@@ -0,0 +1 @@
1
+ export declare function formatBindingDimension(value: number | string): string;
@@ -0,0 +1,9 @@
1
+ export * from './types';
2
+ export * from './chartLifecycle';
3
+ export * from './seriesDiff';
4
+ export * from './optionsSync';
5
+ export * from './stackedSync';
6
+ export * from './indicatorBridge';
7
+ export * from './chartSyncBridge';
8
+ export * from './a11y';
9
+ export * from './dimensions';
@@ -0,0 +1,11 @@
1
+ import { Chart } from '../../core/chart/types';
2
+ import { StackedChart } from '../../core/stacked/types';
3
+ import { AddIndicatorOptions, AddIndicatorResult } from '../../core/indicator/addIndicator';
4
+ import { IndicatorPresetName } from '../../core/indicator/indicatorPresets';
5
+
6
+ export type IndicatorHost = Chart | StackedChart | null;
7
+ export declare function isStackedChart(host: IndicatorHost): host is StackedChart;
8
+ export declare function addIndicatorToHost(host: IndicatorHost, preset: IndicatorPresetName, options?: AddIndicatorOptions): Promise<AddIndicatorResult & {
9
+ paneId?: string;
10
+ }>;
11
+ export declare function removeIndicatorFromChart(chart: Chart, rootId: string): void;
@@ -0,0 +1,7 @@
1
+ import { Chart } from '../../core/chart/types';
2
+ import { ChartOptions } from '../../types';
3
+
4
+ export type SyncableChartOptions = Omit<ChartOptions, "container">;
5
+ export declare function optionsChanged(prev: SyncableChartOptions, next: SyncableChartOptions): boolean;
6
+ export declare function syncChartOptions(chart: Chart, prev: SyncableChartOptions, next: SyncableChartOptions): void;
7
+ export declare function pickSyncableOptions(options: SyncableChartOptions): SyncableChartOptions;
@@ -0,0 +1,8 @@
1
+ import { SeriesOptions } from '../../types';
2
+ import { ChartSeriesActions, VeloPlotSeries } from './types';
3
+
4
+ export declare function veloPlotSeriesToOptions(series: VeloPlotSeries): SeriesOptions;
5
+ export declare function diffSeries(chart: ChartSeriesActions, current: VeloPlotSeries[], previous: Map<string, VeloPlotSeries>): Map<string, VeloPlotSeries>;
6
+ export declare function serializePaneIds(panes: {
7
+ id: string;
8
+ }[]): string;
@@ -0,0 +1,9 @@
1
+ import { StackedChart, StackedChartOptions, StackedPaneConfig } from '../../core/stacked/types';
2
+ import { VeloPlotSeries } from './types';
3
+
4
+ export type SyncableStackedOptions = Omit<StackedChartOptions, "container">;
5
+ export declare function stackedStructureKey(panes: StackedPaneConfig[]): string;
6
+ export declare function syncStackedTheme(stack: StackedChart, theme: StackedChartOptions["theme"]): void;
7
+ export declare function syncStackedSyncOptions(stack: StackedChart, sync: StackedChartOptions["sync"]): void;
8
+ export declare function syncStackedPaneSeries(stack: StackedChart, panes: StackedPaneConfig[], previousSeries: Map<string, Map<string, VeloPlotSeries>>): Map<string, Map<string, VeloPlotSeries>>;
9
+ export declare function syncStackedOptions(stack: StackedChart, options: SyncableStackedOptions): void;
@@ -0,0 +1,46 @@
1
+ import { SeriesOptions, SeriesUpdateData, HeatmapData } from '../../types';
2
+
3
+ export type VeloPlotSeriesType = "line" | "candlestick" | "bar" | "heatmap";
4
+ export interface VeloPlotSeriesBase {
5
+ id: string;
6
+ type?: VeloPlotSeriesType;
7
+ color?: string;
8
+ width?: number;
9
+ visible?: boolean;
10
+ name?: string;
11
+ }
12
+ export interface VeloPlotLineSeries extends VeloPlotSeriesBase {
13
+ type?: "line";
14
+ x: Float32Array | Float64Array;
15
+ y: Float32Array | Float64Array;
16
+ }
17
+ export interface VeloPlotCandlestickSeries extends VeloPlotSeriesBase {
18
+ type: "candlestick";
19
+ x: Float32Array | Float64Array;
20
+ open: Float32Array | Float64Array;
21
+ high: Float32Array | Float64Array;
22
+ low: Float32Array | Float64Array;
23
+ close: Float32Array | Float64Array;
24
+ }
25
+ export interface VeloPlotBarSeries extends VeloPlotSeriesBase {
26
+ type: "bar";
27
+ x: Float32Array | Float64Array;
28
+ y: Float32Array | Float64Array;
29
+ }
30
+ export interface VeloPlotHeatmapSeries extends VeloPlotSeriesBase {
31
+ type: "heatmap";
32
+ data: HeatmapData;
33
+ }
34
+ export type VeloPlotSeries = VeloPlotLineSeries | VeloPlotCandlestickSeries | VeloPlotBarSeries | VeloPlotHeatmapSeries;
35
+ export interface ChartSeriesActions {
36
+ addSeries: (options: SeriesOptions) => void;
37
+ updateSeries: (id: string, data: SeriesUpdateData) => void;
38
+ removeSeries: (id: string) => void;
39
+ autoScale?: () => void;
40
+ }
41
+ export interface BindingChartOptions {
42
+ autoResize?: boolean;
43
+ responsive?: boolean | {
44
+ reducedMotion?: boolean | "auto";
45
+ };
46
+ }
@@ -0,0 +1,35 @@
1
+ import { vi } from 'vitest';
2
+ import { Chart } from '../../core/chart/types';
3
+
4
+ export declare function createMockContainer(): HTMLDivElement;
5
+ export declare function sampleLineData(n?: number): {
6
+ x: Float32Array;
7
+ y: Float32Array;
8
+ };
9
+ export declare function sampleOhlcData(n?: number): {
10
+ x: Float32Array;
11
+ open: Float32Array;
12
+ high: Float32Array;
13
+ low: Float32Array;
14
+ close: Float32Array;
15
+ };
16
+ export declare function buildMockChart(id?: string): Chart & {
17
+ destroy: ReturnType<typeof vi.fn>;
18
+ addSeries: ReturnType<typeof vi.fn>;
19
+ updateSeries: ReturnType<typeof vi.fn>;
20
+ removeSeries: ReturnType<typeof vi.fn>;
21
+ on: ReturnType<typeof vi.fn>;
22
+ off: ReturnType<typeof vi.fn>;
23
+ zoom: ReturnType<typeof vi.fn>;
24
+ resetZoom: ReturnType<typeof vi.fn>;
25
+ autoScale: ReturnType<typeof vi.fn>;
26
+ enableCursor: ReturnType<typeof vi.fn>;
27
+ disableCursor: ReturnType<typeof vi.fn>;
28
+ setTheme: ReturnType<typeof vi.fn>;
29
+ updateXAxis: ReturnType<typeof vi.fn>;
30
+ updateYAxis: ReturnType<typeof vi.fn>;
31
+ resize: ReturnType<typeof vi.fn>;
32
+ getViewBounds: ReturnType<typeof vi.fn>;
33
+ getAllSeries: ReturnType<typeof vi.fn>;
34
+ };
35
+ export declare function expectDestroyCalled(destroyFn: ReturnType<typeof vi.fn>): void;