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":"index-Cv6ZDLWf.js","sources":["../src/core/chart/heikinAshi.ts","../src/trading/datafeed.ts","../src/trading/mockDatafeed.ts","../src/plugins/drawing-tools/snapToCandle.ts","../src/plugins/drawing-tools/measure.ts","../src/plugins/drawing-tools/index.ts","../src/plugins/replay/index.ts"],"sourcesContent":["/**\n * Heikin-Ashi OHLC transform (Stage 2.20).\n */\n\nexport interface OhlcArrays {\n open: Float32Array | Float64Array;\n high: Float32Array | Float64Array;\n low: Float32Array | Float64Array;\n close: Float32Array | Float64Array;\n}\n\nexport function computeHeikinAshi(ohlc: OhlcArrays): OhlcArrays {\n const n = ohlc.close.length;\n const haOpen = new Float32Array(n);\n const haHigh = new Float32Array(n);\n const haLow = new Float32Array(n);\n const haClose = new Float32Array(n);\n\n for (let i = 0; i < n; i++) {\n const o = ohlc.open[i];\n const h = ohlc.high[i];\n const l = ohlc.low[i];\n const c = ohlc.close[i];\n\n haClose[i] = (o + h + l + c) / 4;\n haOpen[i] = i === 0 ? (o + c) / 2 : (haOpen[i - 1] + haClose[i - 1]) / 2;\n haHigh[i] = Math.max(h, haOpen[i], haClose[i]);\n haLow[i] = Math.min(l, haOpen[i], haClose[i]);\n }\n\n return { open: haOpen, high: haHigh, low: haLow, close: haClose };\n}\n","/**\n * UDF-inspired datafeed contract for trading charts (Stage 2.24).\n */\n\nexport interface SymbolInfo {\n symbol: string;\n name: string;\n description?: string;\n timezone?: string;\n session?: string;\n pricescale?: number;\n minmov?: number;\n}\n\nexport interface Bar {\n time: number;\n open: number;\n high: number;\n low: number;\n close: number;\n volume?: number;\n}\n\nexport interface HistoryRequest {\n symbol: string;\n resolution: string;\n from: number;\n to: number;\n}\n\nexport interface SubscribeBarsRequest {\n symbol: string;\n resolution: string;\n onBar: (bar: Bar) => void;\n}\n\n/**\n * TradingView UDF-style adapter surface.\n */\nexport interface DatafeedAdapter {\n resolveSymbol(symbol: string): Promise<SymbolInfo>;\n getBars(request: HistoryRequest): Promise<Bar[]>;\n subscribeBars(request: SubscribeBarsRequest): () => void;\n}\n\n/** Convert bars to typed OHLC arrays for velo-plot series. */\nexport function barsToOhlc(bars: Bar[]): {\n x: Float64Array;\n open: Float32Array;\n high: Float32Array;\n low: Float32Array;\n close: Float32Array;\n volume: Float32Array;\n} {\n const n = bars.length;\n const x = new Float64Array(n);\n const open = new Float32Array(n);\n const high = new Float32Array(n);\n const low = new Float32Array(n);\n const close = new Float32Array(n);\n const volume = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n const b = bars[i];\n x[i] = b.time;\n open[i] = b.open;\n high[i] = b.high;\n low[i] = b.low;\n close[i] = b.close;\n volume[i] = b.volume ?? 0;\n }\n return { x, open, high, low, close, volume };\n}\n","/**\n * Mock datafeed for demos and tests (Stage 2.25).\n */\n\nimport type {\n Bar,\n DatafeedAdapter,\n HistoryRequest,\n SubscribeBarsRequest,\n SymbolInfo,\n} from \"./datafeed\";\n\nexport interface MockDatafeedOptions {\n symbol?: string;\n barMs?: number;\n basePrice?: number;\n seed?: number;\n}\n\nfunction pseudoRandom(seed: number): () => number {\n let s = seed;\n return () => {\n s = (s * 16807) % 2147483647;\n return (s - 1) / 2147483646;\n };\n}\n\nfunction generateBars(from: number, to: number, barMs: number, base: number, rand: () => number): Bar[] {\n const bars: Bar[] = [];\n let price = base;\n for (let t = from; t <= to; t += barMs) {\n const open = price;\n const delta = (rand() - 0.48) * 2;\n const close = Math.max(1, open + delta);\n const high = Math.max(open, close) + rand() * 1.5;\n const low = Math.min(open, close) - rand() * 1.5;\n bars.push({\n time: t,\n open,\n high,\n low,\n close,\n volume: 1000 + rand() * 5000,\n });\n price = close;\n }\n return bars;\n}\n\nexport function createMockDatafeed(options: MockDatafeedOptions = {}): DatafeedAdapter {\n const barMs = options.barMs ?? 60_000;\n const basePrice = options.basePrice ?? 100;\n const rand = pseudoRandom(options.seed ?? 42);\n const cache = new Map<string, Bar[]>();\n\n return {\n async resolveSymbol(sym: string): Promise<SymbolInfo> {\n return {\n symbol: sym,\n name: sym,\n description: `Mock symbol ${sym}`,\n timezone: \"UTC\",\n session: \"24x7\",\n pricescale: 100,\n };\n },\n\n async getBars(request: HistoryRequest): Promise<Bar[]> {\n const key = `${request.symbol}:${request.from}:${request.to}`;\n if (!cache.has(key)) {\n cache.set(\n key,\n generateBars(request.from, request.to, barMs, basePrice, rand),\n );\n }\n return cache.get(key)!;\n },\n\n subscribeBars(request: SubscribeBarsRequest): () => void {\n let last = basePrice + rand() * 5;\n const timer = setInterval(() => {\n const open = last;\n const close = Math.max(1, open + (rand() - 0.5) * 2);\n const high = Math.max(open, close) + rand();\n const low = Math.min(open, close) - rand();\n request.onBar({\n time: Date.now(),\n open,\n high,\n low,\n close,\n volume: 1000 + rand() * 3000,\n });\n last = close;\n }, barMs);\n return () => clearInterval(timer);\n },\n };\n}\n","/**\n * Snap drawing points to nearest candlestick O/H/L/C (TradingView-style magnet).\n */\n\nexport interface CandleSnapInput {\n x: number;\n y: number;\n barX: Float32Array | Float64Array;\n open: Float32Array | Float64Array;\n high: Float32Array | Float64Array;\n low: Float32Array | Float64Array;\n close: Float32Array | Float64Array;\n dataToPixelX: (x: number) => number;\n dataToPixelY: (y: number) => number;\n pixelThreshold?: number;\n enabled?: boolean;\n}\n\nexport function findNearestBarIndex(\n barX: Float32Array | Float64Array,\n x: number,\n): number {\n if (barX.length === 0) return -1;\n let bestIdx = 0;\n let bestDist = Math.abs(barX[0] - x);\n for (let i = 1; i < barX.length; i++) {\n const d = Math.abs(barX[i] - x);\n if (d < bestDist) {\n bestDist = d;\n bestIdx = i;\n }\n }\n return bestIdx;\n}\n\nexport function snapToCandle(input: CandleSnapInput): { x: number; y: number } {\n if (input.enabled === false || input.barX.length === 0) {\n return { x: input.x, y: input.y };\n }\n\n const idx = findNearestBarIndex(input.barX, input.x);\n if (idx < 0) return { x: input.x, y: input.y };\n\n const barX = input.barX[idx];\n const candidates = [\n input.open[idx],\n input.high[idx],\n input.low[idx],\n input.close[idx],\n ];\n\n const clickPy = input.dataToPixelY(input.y);\n const threshold = input.pixelThreshold ?? 12;\n let bestY = input.y;\n let bestPyDist = Infinity;\n\n for (const cy of candidates) {\n const py = input.dataToPixelY(cy);\n const dist = Math.abs(py - clickPy);\n if (dist < bestPyDist && dist <= threshold) {\n bestPyDist = dist;\n bestY = cy;\n }\n }\n\n return { x: barX, y: bestY };\n}\n","/**\n * Measurement helper for the price-range / measure tool (TradingView-style).\n */\n\nexport interface MeasurePoint {\n x: number;\n y: number;\n}\n\nexport interface Measurement {\n /** Absolute price change (end - start) */\n change: number;\n /** Percentage change relative to the start price */\n percent: number;\n /** Number of bars spanned (rounded X distance) */\n bars: number;\n /** True when the range moves up (change >= 0) */\n up: boolean;\n}\n\nexport function computeMeasurement(a: MeasurePoint, b: MeasurePoint): Measurement {\n const change = b.y - a.y;\n const denom = Math.abs(a.y);\n const percent = denom > 0 ? (change / denom) * 100 : 0;\n const bars = Math.round(Math.abs(b.x - a.x));\n return { change, percent, bars, up: change >= 0 };\n}\n\nexport function formatMeasurement(m: Measurement): string {\n const sign = m.change >= 0 ? \"+\" : \"\";\n return `${sign}${m.change.toFixed(2)} (${sign}${m.percent.toFixed(2)}%) · ${m.bars} bars`;\n}\n\n/** Compact price formatting used for level labels. */\nexport function formatPrice(value: number): string {\n const abs = Math.abs(value);\n const decimals = abs >= 1000 ? 0 : abs >= 1 ? 2 : 4;\n return value.toLocaleString(\"en-US\", {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n}\n","/**\n * PluginDrawingTools — interactive drawing on chart (Stage 2.9).\n * TradingView-style live preview, drag-to-draw, optional candle magnet.\n */\n\nimport type { ChartPlugin, InteractionEvent, PluginContext, PluginManifest } from \"../types\";\nimport type { Annotation } from \"../../core/annotations/types\";\nimport type { Series } from \"../../core/Series\";\nimport { snapToCandle } from \"./snapToCandle\";\nimport { computeMeasurement, formatMeasurement, formatPrice } from \"./measure\";\n\nexport type DrawingMode =\n | \"none\"\n | \"pan\"\n | \"trendline\"\n | \"horizontal\"\n | \"vertical\"\n | \"rectangle\"\n | \"fibonacci\"\n | \"measure\";\n\nconst FIB_LEVELS = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1];\nconst DRAG_THRESHOLD_PX = 4;\nconst DEFAULT_MEASURE_UP = \"#26a69a\";\nconst DEFAULT_MEASURE_DOWN = \"#ef5350\";\n\nexport interface PluginDrawingToolsConfig {\n /** Default stroke color */\n color?: string;\n /** Enable candle magnet by default */\n magnet?: boolean;\n /** Return to pan mode after each completed stroke (default true) */\n autoDeselect?: boolean;\n /** Notified when drawing mode changes (including auto-deselect to none) */\n onModeChange?: (mode: DrawingMode) => void;\n /** Color for upward measurements (default green) */\n measureUpColor?: string;\n /** Color for downward measurements (default red) */\n measureDownColor?: string;\n}\n\nfunction withAlpha(color: string, alpha: string): string {\n return color.startsWith(\"#\") && color.length === 7 ? color + alpha : color;\n}\n\nexport interface DrawingToolsAPI {\n setMode(mode: DrawingMode): void;\n getMode(): DrawingMode;\n setMagnet(enabled: boolean): void;\n isMagnet(): boolean;\n undo(): boolean;\n redo(): boolean;\n clear(): void;\n}\n\nconst manifest: PluginManifest = {\n name: \"velo-plot-drawing-tools\",\n version: \"1.0.0\",\n description: \"Interactive trendline, horizontal, vertical, rectangle, and fibonacci drawing\",\n provides: [\"drawing\"],\n tags: [\"drawing\", \"annotations\", \"trading\"],\n};\n\ninterface DrawPoint {\n x: number;\n y: number;\n}\n\ninterface DrawState {\n mode: DrawingMode;\n pending: DrawPoint | null;\n start: DrawPoint | null;\n dragging: boolean;\n dragMoved: boolean;\n dragStartPixel: { x: number; y: number } | null;\n cursor: DrawPoint | null;\n magnet: boolean;\n undoStack: Annotation[][];\n redoStack: Annotation[][];\n}\n\nfunction isDrawingMode(mode: DrawingMode): boolean {\n return mode !== \"none\" && mode !== \"pan\";\n}\n\nfunction findCandlestickSeries(ctx: PluginContext): Series | undefined {\n for (const s of ctx.data.getAllSeries()) {\n if (s.getType() === \"candlestick\") return s;\n }\n return undefined;\n}\n\nexport function PluginDrawingTools(\n config: PluginDrawingToolsConfig = {},\n): ChartPlugin<PluginDrawingToolsConfig> {\n let ctx: PluginContext | null = null;\n const autoDeselect = config.autoDeselect !== false;\n const state: DrawState = {\n mode: \"none\",\n pending: null,\n start: null,\n dragging: false,\n dragMoved: false,\n dragStartPixel: null,\n cursor: null,\n magnet: config.magnet ?? false,\n undoStack: [],\n redoStack: [],\n };\n\n const stroke = config.color ?? \"#38bdf8\";\n const measureUp = config.measureUpColor ?? DEFAULT_MEASURE_UP;\n const measureDown = config.measureDownColor ?? DEFAULT_MEASURE_DOWN;\n\n function snapshot(): Annotation[] {\n return ctx?.chart.getAnnotations?.() ?? [];\n }\n\n function pushUndo(): void {\n state.undoStack.push(snapshot());\n state.redoStack = [];\n }\n\n function resetInteractionState(): void {\n state.pending = null;\n state.start = null;\n state.dragging = false;\n state.dragMoved = false;\n state.dragStartPixel = null;\n }\n\n function setModeInternal(mode: DrawingMode): void {\n state.mode = mode;\n resetInteractionState();\n config.onModeChange?.(mode);\n ctx?.requestRender?.();\n }\n\n function finishStroke(): void {\n resetInteractionState();\n if (autoDeselect) {\n setModeInternal(\"none\");\n } else {\n ctx?.requestRender?.();\n }\n }\n\n function resolvePoint(x: number, y: number): DrawPoint {\n if (!ctx || !state.magnet) return { x, y };\n const series = findCandlestickSeries(ctx);\n if (!series) return { x, y };\n const d = series.getData();\n if (!d.open || !d.high || !d.low || !d.close) return { x, y };\n return snapToCandle({\n x,\n y,\n barX: d.x,\n open: d.open,\n high: d.high,\n low: d.low,\n close: d.close,\n dataToPixelX: ctx.coords.dataToPixelX,\n dataToPixelY: (dy) => ctx!.coords.dataToPixelY(dy),\n enabled: true,\n });\n }\n\n function pointFromEvent(pluginCtx: PluginContext, event: InteractionEvent): DrawPoint {\n return resolvePoint(\n pluginCtx.coords.pixelToDataX(event.pixelX),\n pluginCtx.coords.pixelToDataY(event.pixelY),\n );\n }\n\n function commitHorizontal(y: number): void {\n if (!ctx) return;\n pushUndo();\n ctx.chart.addAnnotation({\n type: \"horizontal-line\",\n y,\n color: stroke,\n interactive: true,\n });\n }\n\n function commitVertical(x: number): void {\n if (!ctx) return;\n pushUndo();\n ctx.chart.addAnnotation({\n type: \"vertical-line\",\n x,\n color: stroke,\n interactive: true,\n });\n }\n\n function commitMeasure(p0: DrawPoint, p1: DrawPoint): void {\n if (!ctx) return;\n pushUndo();\n\n const m = computeMeasurement(p0, p1);\n const color = m.up ? measureUp : measureDown;\n const midX = (p0.x + p1.x) / 2;\n ctx.chart.addAnnotation({\n type: \"rectangle\",\n xMin: Math.min(p0.x, p1.x),\n xMax: Math.max(p0.x, p1.x),\n yMin: Math.min(p0.y, p1.y),\n yMax: Math.max(p0.y, p1.y),\n strokeColor: color,\n fillColor: withAlpha(color, \"33\"),\n interactive: true,\n });\n ctx.chart.addAnnotation({\n type: \"arrow\",\n x1: midX,\n y1: p0.y,\n x2: midX,\n y2: p1.y,\n color,\n headStyle: \"filled\",\n interactive: true,\n });\n ctx.chart.addAnnotation({\n type: \"text\",\n x: midX,\n y: p1.y,\n text: formatMeasurement(m),\n color: \"#ffffff\",\n backgroundColor: color,\n padding: 4,\n fontWeight: \"bold\",\n anchor: m.up ? \"bottom-center\" : \"top-center\",\n interactive: true,\n });\n }\n\n function commitTwoPoint(p0: DrawPoint, p1: DrawPoint): void {\n if (!ctx) return;\n\n if (state.mode === \"measure\") {\n commitMeasure(p0, p1);\n return;\n }\n\n pushUndo();\n\n if (state.mode === \"trendline\") {\n ctx.chart.addAnnotation({\n type: \"arrow\",\n x1: p0.x,\n y1: p0.y,\n x2: p1.x,\n y2: p1.y,\n color: stroke,\n interactive: true,\n });\n } else if (state.mode === \"rectangle\") {\n ctx.chart.addAnnotation({\n type: \"rectangle\",\n xMin: Math.min(p0.x, p1.x),\n xMax: Math.max(p0.x, p1.x),\n yMin: Math.min(p0.y, p1.y),\n yMax: Math.max(p0.y, p1.y),\n strokeColor: stroke,\n fillColor: stroke + \"22\",\n interactive: true,\n });\n } else if (state.mode === \"fibonacci\") {\n const yMin = Math.min(p0.y, p1.y);\n const yMax = Math.max(p0.y, p1.y);\n for (const level of FIB_LEVELS) {\n const fy = yMax - (yMax - yMin) * level;\n ctx.chart.addAnnotation({\n type: \"horizontal-line\",\n y: fy,\n color: stroke,\n lineDash: level === 0 || level === 1 ? undefined : [4, 4],\n label: `${(level * 100).toFixed(1)}% ${formatPrice(fy)}`,\n labelPosition: \"right\",\n interactive: true,\n });\n }\n }\n }\n\n function drawPreview(\n c2d: CanvasRenderingContext2D,\n plotArea: { x: number; y: number; width: number; height: number },\n coords: PluginContext[\"coords\"],\n ): void {\n const mode = state.mode;\n if (!isDrawingMode(mode) || !state.cursor) return;\n\n const cursor = state.cursor;\n const anchor = state.pending ?? state.start;\n\n c2d.save();\n c2d.strokeStyle = stroke;\n c2d.lineWidth = 1.5;\n c2d.setLineDash([6, 4]);\n c2d.globalAlpha = 0.85;\n\n const toPx = (x: number, y: number) => ({\n px: coords.dataToPixelX(x),\n py: coords.dataToPixelY(y),\n });\n\n if (mode === \"horizontal\") {\n const { py } = toPx(0, cursor.y);\n c2d.beginPath();\n c2d.moveTo(plotArea.x, py);\n c2d.lineTo(plotArea.x + plotArea.width, py);\n c2d.stroke();\n } else if (mode === \"vertical\") {\n const { px } = toPx(cursor.x, 0);\n c2d.beginPath();\n c2d.moveTo(px, plotArea.y);\n c2d.lineTo(px, plotArea.y + plotArea.height);\n c2d.stroke();\n } else if (anchor) {\n const a = toPx(anchor.x, anchor.y);\n const b = toPx(cursor.x, cursor.y);\n\n if (mode === \"trendline\") {\n c2d.beginPath();\n c2d.moveTo(a.px, a.py);\n c2d.lineTo(b.px, b.py);\n c2d.stroke();\n } else if (mode === \"rectangle\") {\n const x = Math.min(a.px, b.px);\n const y = Math.min(a.py, b.py);\n const w = Math.abs(b.px - a.px);\n const h = Math.abs(b.py - a.py);\n c2d.strokeRect(x, y, w, h);\n c2d.fillStyle = stroke + \"22\";\n c2d.fillRect(x, y, w, h);\n } else if (mode === \"fibonacci\") {\n const yMin = Math.min(anchor.y, cursor.y);\n const yMax = Math.max(anchor.y, cursor.y);\n c2d.font = \"11px sans-serif\";\n c2d.textAlign = \"left\";\n c2d.textBaseline = \"bottom\";\n for (const level of FIB_LEVELS) {\n const fy = yMax - (yMax - yMin) * level;\n const { py } = toPx(0, fy);\n c2d.beginPath();\n c2d.moveTo(plotArea.x, py);\n c2d.lineTo(plotArea.x + plotArea.width, py);\n c2d.stroke();\n c2d.save();\n c2d.setLineDash([]);\n c2d.globalAlpha = 1;\n c2d.fillStyle = stroke;\n c2d.fillText(\n `${(level * 100).toFixed(1)}% ${formatPrice(fy)}`,\n plotArea.x + 4,\n py - 2,\n );\n c2d.restore();\n }\n } else if (mode === \"measure\") {\n drawMeasurePreview(c2d, a, b, anchor, cursor);\n }\n }\n\n c2d.restore();\n }\n\n function drawMeasurePreview(\n c2d: CanvasRenderingContext2D,\n a: { px: number; py: number },\n b: { px: number; py: number },\n anchor: DrawPoint,\n cursor: DrawPoint,\n ): void {\n const m = computeMeasurement(anchor, cursor);\n const color = m.up ? measureUp : measureDown;\n const x = Math.min(a.px, b.px);\n const y = Math.min(a.py, b.py);\n const w = Math.abs(b.px - a.px);\n const h = Math.abs(b.py - a.py);\n\n c2d.setLineDash([]);\n c2d.globalAlpha = 0.9;\n c2d.fillStyle = withAlpha(color, \"33\");\n c2d.fillRect(x, y, w, h);\n c2d.strokeStyle = color;\n c2d.lineWidth = 1.5;\n c2d.strokeRect(x, y, w, h);\n\n // Vertical direction arrow at the horizontal center.\n const midX = (a.px + b.px) / 2;\n c2d.beginPath();\n c2d.moveTo(midX, a.py);\n c2d.lineTo(midX, b.py);\n c2d.stroke();\n const headLen = 7;\n const dir = b.py >= a.py ? 1 : -1;\n c2d.beginPath();\n c2d.moveTo(midX, b.py);\n c2d.lineTo(midX - 4, b.py - dir * headLen);\n c2d.lineTo(midX + 4, b.py - dir * headLen);\n c2d.closePath();\n c2d.fillStyle = color;\n c2d.fill();\n\n // Label with change / percent / bars.\n const label = formatMeasurement(m);\n c2d.font = \"12px sans-serif\";\n const textW = c2d.measureText(label).width;\n const padX = 6;\n const boxW = textW + padX * 2;\n const boxH = 20;\n const boxX = midX - boxW / 2;\n const boxY = m.up ? b.py - boxH - 8 : b.py + 8;\n c2d.globalAlpha = 1;\n c2d.fillStyle = color;\n c2d.fillRect(boxX, boxY, boxW, boxH);\n c2d.fillStyle = \"#ffffff\";\n c2d.textAlign = \"center\";\n c2d.textBaseline = \"middle\";\n c2d.fillText(label, midX, boxY + boxH / 2);\n }\n\n function handleMouseDown(pluginCtx: PluginContext, event: InteractionEvent): void {\n if (!event.inPlotArea) return;\n\n event.preventDefault();\n const point = pointFromEvent(pluginCtx, event);\n\n if (state.mode === \"horizontal\") {\n commitHorizontal(point.y);\n finishStroke();\n return;\n }\n\n if (state.mode === \"vertical\") {\n commitVertical(point.x);\n finishStroke();\n return;\n }\n\n if (state.pending) {\n commitTwoPoint(state.pending, point);\n finishStroke();\n return;\n }\n\n state.start = point;\n state.dragging = true;\n state.dragMoved = false;\n state.dragStartPixel = { x: event.pixelX, y: event.pixelY };\n state.cursor = point;\n pluginCtx.requestRender?.();\n }\n\n function handleMouseMove(pluginCtx: PluginContext, event: InteractionEvent): void {\n const point = pointFromEvent(pluginCtx, event);\n state.cursor = point;\n\n if (state.dragging && state.dragStartPixel) {\n const dx = event.pixelX - state.dragStartPixel.x;\n const dy = event.pixelY - state.dragStartPixel.y;\n if (Math.hypot(dx, dy) >= DRAG_THRESHOLD_PX) {\n state.dragMoved = true;\n }\n }\n\n event.preventDefault();\n pluginCtx.requestRender?.();\n }\n\n function handleMouseUp(pluginCtx: PluginContext, event: InteractionEvent): void {\n if (!state.dragging || !state.start) return;\n\n const point = pointFromEvent(pluginCtx, event);\n const start = state.start;\n state.dragging = false;\n state.dragStartPixel = null;\n\n if (state.dragMoved) {\n commitTwoPoint(start, point);\n finishStroke();\n return;\n }\n\n state.pending = start;\n state.start = null;\n state.cursor = point;\n pluginCtx.requestRender?.();\n }\n\n const api: DrawingToolsAPI & Record<string, unknown> = {\n setMode(mode) {\n setModeInternal(mode);\n },\n getMode() {\n return state.mode;\n },\n setMagnet(enabled) {\n state.magnet = enabled;\n },\n isMagnet() {\n return state.magnet;\n },\n undo() {\n if (!ctx || state.undoStack.length === 0) return false;\n state.redoStack.push(snapshot());\n const prev = state.undoStack.pop()!;\n const current = snapshot();\n for (const a of current) ctx.chart.removeAnnotation(a.id!);\n for (const a of prev) ctx.chart.addAnnotation(a);\n return true;\n },\n redo() {\n if (!ctx || state.redoStack.length === 0) return false;\n state.undoStack.push(snapshot());\n const next = state.redoStack.pop()!;\n const current = snapshot();\n for (const a of current) ctx.chart.removeAnnotation(a.id!);\n for (const a of next) ctx.chart.addAnnotation(a);\n return true;\n },\n clear() {\n if (!ctx) return;\n pushUndo();\n for (const a of snapshot()) ctx.chart.removeAnnotation(a.id!);\n },\n };\n\n return {\n manifest,\n api,\n onInit(pluginCtx) {\n ctx = pluginCtx;\n },\n onDestroy() {\n ctx = null;\n },\n onInteraction(pluginCtx, event) {\n if (!isDrawingMode(state.mode)) return;\n\n if (event.type === \"mousedown\") {\n handleMouseDown(pluginCtx, event);\n return;\n }\n\n if (event.type === \"mousemove\") {\n handleMouseMove(pluginCtx, event);\n return;\n }\n\n if (event.type === \"mouseup\") {\n handleMouseUp(pluginCtx, event);\n }\n },\n onRenderOverlay(pluginCtx) {\n const c2d = pluginCtx.render.ctx2d;\n if (!c2d) return;\n drawPreview(c2d, pluginCtx.render.plotArea, pluginCtx.coords);\n },\n };\n}\n\nexport { snapToCandle, findNearestBarIndex } from \"./snapToCandle\";\nexport default PluginDrawingTools;\n","/**\n * PluginReplay — bar-by-bar playback (Stage 2.17 MVP).\n */\n\nimport type { ChartPlugin, PluginContext, PluginManifest } from \"../types\";\n\nexport interface PluginReplayConfig {\n /** Series id to replay */\n seriesId: string;\n /** Milliseconds between frames at 1x speed */\n frameMs?: number;\n}\n\nexport interface ReplayAPI {\n play(speed?: number): void;\n pause(): void;\n step(count?: number): void;\n seek(index: number): void;\n getIndex(): number;\n getLength(): number;\n isPlaying(): boolean;\n}\n\nconst manifest: PluginManifest = {\n name: \"velo-plot-replay\",\n version: \"1.0.0\",\n description: \"Bar-by-bar chart replay with speed control\",\n provides: [\"replay\"],\n tags: [\"replay\", \"trading\"],\n};\n\ninterface ReplayBuffer {\n x: Float32Array;\n open?: Float32Array;\n high?: Float32Array;\n low?: Float32Array;\n close?: Float32Array;\n y?: Float32Array;\n}\n\nexport function PluginReplay(config: PluginReplayConfig): ChartPlugin<PluginReplayConfig> {\n let ctx: PluginContext | null = null;\n let buffer: ReplayBuffer | null = null;\n let index = 0;\n let timer: ReturnType<typeof setInterval> | null = null;\n let speed = 1;\n const frameMs = config.frameMs ?? 250;\n\n function applyWindow(end: number): void {\n const c = ctx!;\n const buf = buffer!;\n const n = Math.min(end + 1, buf.x.length);\n const slice = (arr?: Float32Array) => (arr ? arr.subarray(0, n) : undefined);\n c.chart.updateSeries(config.seriesId, {\n x: slice(buf.x)!,\n y: slice(buf.y),\n open: slice(buf.open),\n high: slice(buf.high),\n low: slice(buf.low),\n close: slice(buf.close),\n });\n }\n\n const api: ReplayAPI & Record<string, unknown> = {\n play(s = 1) {\n if (!buffer) return;\n speed = Math.max(0.1, s);\n if (timer) clearInterval(timer);\n timer = setInterval(() => {\n if (!ctx || !buffer) {\n api.pause();\n return;\n }\n if (index >= buffer.x.length - 1) {\n api.pause();\n return;\n }\n index++;\n applyWindow(index);\n }, frameMs / speed);\n },\n pause() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n },\n step(count = 1) {\n if (!buffer) return;\n index = Math.min(buffer.x.length - 1, index + count);\n applyWindow(index);\n },\n seek(i) {\n if (!buffer) return;\n index = Math.max(0, Math.min(buffer.x.length - 1, i));\n applyWindow(index);\n },\n getIndex() {\n return index;\n },\n getLength() {\n return buffer?.x.length ?? 0;\n },\n isPlaying() {\n return timer != null;\n },\n };\n\n return {\n manifest,\n api,\n onInit(pluginCtx) {\n ctx = pluginCtx;\n const series = ctx.chart.getSeries(config.seriesId);\n if (!series) {\n console.warn(`[PluginReplay] Series \"${config.seriesId}\" not found`);\n return;\n }\n const d = series.getData();\n buffer = {\n x: Float32Array.from(d.x),\n y: d.y ? Float32Array.from(d.y) : undefined,\n open: d.open ? Float32Array.from(d.open) : undefined,\n high: d.high ? Float32Array.from(d.high) : undefined,\n low: d.low ? Float32Array.from(d.low) : undefined,\n close: d.close ? Float32Array.from(d.close) : undefined,\n };\n index = Math.max(0, buffer.x.length - 1);\n },\n onDestroy() {\n api.pause();\n ctx = null;\n buffer = null;\n },\n };\n}\n\nexport default PluginReplay;\n"],"names":["computeHeikinAshi","ohlc","n","haOpen","haHigh","haLow","haClose","i","o","l","c","barsToOhlc","bars","x","open","high","low","close","volume","b","pseudoRandom","seed","s","generateBars","from","to","barMs","base","rand","price","t","delta","createMockDatafeed","options","basePrice","cache","sym","request","key","last","timer","findNearestBarIndex","barX","bestIdx","bestDist","d","snapToCandle","input","idx","candidates","clickPy","threshold","bestY","bestPyDist","cy","py","dist","computeMeasurement","a","change","denom","percent","formatMeasurement","m","sign","formatPrice","value","abs","decimals","FIB_LEVELS","DRAG_THRESHOLD_PX","DEFAULT_MEASURE_UP","DEFAULT_MEASURE_DOWN","withAlpha","color","alpha","manifest","isDrawingMode","mode","findCandlestickSeries","ctx","PluginDrawingTools","config","autoDeselect","state","stroke","measureUp","measureDown","snapshot","_a","_b","pushUndo","resetInteractionState","setModeInternal","finishStroke","resolvePoint","y","series","dy","pointFromEvent","pluginCtx","event","commitHorizontal","commitVertical","commitMeasure","p0","p1","midX","commitTwoPoint","yMin","yMax","level","fy","drawPreview","c2d","plotArea","coords","cursor","anchor","toPx","px","w","h","drawMeasurePreview","headLen","dir","label","boxW","boxH","boxX","boxY","handleMouseDown","point","handleMouseMove","dx","handleMouseUp","start","enabled","prev","current","next","PluginReplay","buffer","index","speed","frameMs","applyWindow","end","buf","slice","arr","api","count"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index-Dag88bW4.js","sources":["../src/core/theme-editor/index.ts","../src/plugins/theme-editor/index.ts"],"sourcesContent":["/**\n * Sci Plot - Theme Editor Module\n * \n * Provides a visual theme editor for customizing chart appearance:\n * - Color pickers for all theme elements\n * - Live preview\n * - Theme export/import\n * - Preset theme gallery\n * \n * @module theme-editor\n */\n\n// Use a flexible internal type to avoid strict EditorTheme compatibility issues\n// The editor works with partial theme configs that can be applied via createTheme()\nexport type EditorTheme = Record<string, unknown>;\n\n// ============================================\n// Types\n// ============================================\n\nexport interface ThemeEditorOptions {\n /** Base theme to start from */\n baseTheme?: EditorTheme | string;\n /** Enable live preview (default: true) */\n livePreview?: boolean;\n /** Show advanced options (default: false) */\n showAdvanced?: boolean;\n /** Custom CSS class for the editor */\n className?: string;\n /** Callback when theme changes */\n onChange?: (theme: EditorTheme) => void;\n /** Callback when export is requested */\n onExport?: (theme: EditorTheme, json: string) => void;\n}\n\nexport interface ThemePreset {\n /** Preset name */\n name: string;\n /** Description */\n description?: string;\n /** Theme configuration */\n theme: EditorTheme;\n /** Preview colors (for UI) */\n previewColors?: string[];\n /** Tags for filtering */\n tags?: string[];\n}\n\nexport interface ColorGroup {\n /** Group label */\n label: string;\n /** Group description */\n description?: string;\n /** Color properties in this group */\n colors: ColorProperty[];\n}\n\nexport interface ColorProperty {\n /** Property key path (e.g., 'background', 'axis.color') */\n key: string;\n /** Display label */\n label: string;\n /** Description/tooltip */\n description?: string;\n /** Current value */\n value: string;\n /** Default value */\n defaultValue?: string;\n}\n\n// ============================================\n// Default Theme Structure\n// ============================================\n\nconst THEME_COLOR_GROUPS: ColorGroup[] = [\n {\n label: \"Background & Canvas\",\n description: \"Chart background and canvas colors\",\n colors: [\n { key: \"backgroundColor\", label: \"Background\", value: \"\", description: \"Main chart background\" },\n { key: \"plotAreaBackground\", label: \"Plot Area\", value: \"\", description: \"Data plotting area background\" },\n ],\n },\n {\n label: \"Axes\",\n description: \"Axis lines, ticks, and labels\",\n colors: [\n { key: \"axis.color\", label: \"Axis Lines\", value: \"\", description: \"Axis line color\" },\n { key: \"axis.labelColor\", label: \"Axis Labels\", value: \"\", description: \"Axis label text color\" },\n { key: \"axis.titleColor\", label: \"Axis Titles\", value: \"\", description: \"Axis title text color\" },\n ],\n },\n {\n label: \"Grid\",\n description: \"Grid lines and markers\",\n colors: [\n { key: \"grid.color\", label: \"Grid Lines\", value: \"\", description: \"Major grid line color\" },\n { key: \"grid.minorColor\", label: \"Minor Grid\", value: \"\", description: \"Minor grid line color\" },\n ],\n },\n {\n label: \"Series Palette\",\n description: \"Default colors for data series\",\n colors: [\n { key: \"seriesPalette.0\", label: \"Series 1\", value: \"\", description: \"First series color\" },\n { key: \"seriesPalette.1\", label: \"Series 2\", value: \"\", description: \"Second series color\" },\n { key: \"seriesPalette.2\", label: \"Series 3\", value: \"\", description: \"Third series color\" },\n { key: \"seriesPalette.3\", label: \"Series 4\", value: \"\", description: \"Fourth series color\" },\n { key: \"seriesPalette.4\", label: \"Series 5\", value: \"\", description: \"Fifth series color\" },\n { key: \"seriesPalette.5\", label: \"Series 6\", value: \"\", description: \"Sixth series color\" },\n ],\n },\n {\n label: \"Legend\",\n description: \"Legend styling\",\n colors: [\n { key: \"legend.backgroundColor\", label: \"Legend Background\", value: \"\", description: \"Legend panel background\" },\n { key: \"legend.textColor\", label: \"Legend Text\", value: \"\", description: \"Legend text color\" },\n { key: \"legend.borderColor\", label: \"Legend Border\", value: \"\", description: \"Legend border color\" },\n ],\n },\n {\n label: \"Cursor & Selection\",\n description: \"Interactive elements\",\n colors: [\n { key: \"cursor.color\", label: \"Crosshair\", value: \"\", description: \"Cursor crosshair color\" },\n { key: \"cursor.labelBackground\", label: \"Cursor Label BG\", value: \"\", description: \"Cursor label background\" },\n { key: \"selection.color\", label: \"Selection\", value: \"\", description: \"Selection highlight color\" },\n { key: \"selection.handleColor\", label: \"Selection Handles\", value: \"\", description: \"Selection handle color\" },\n ],\n },\n {\n label: \"Annotations\",\n description: \"Annotation default colors\",\n colors: [\n { key: \"annotation.lineColor\", label: \"Line Annotations\", value: \"\", description: \"Default line annotation color\" },\n { key: \"annotation.fillColor\", label: \"Fill Annotations\", value: \"\", description: \"Default fill annotation color\" },\n { key: \"annotation.textColor\", label: \"Text Annotations\", value: \"\", description: \"Default text annotation color\" },\n ],\n },\n];\n\n// ============================================\n// Theme Presets\n// ============================================\n\nexport const THEME_PRESETS: ThemePreset[] = [\n {\n name: \"Dark\",\n description: \"Classic dark theme with cyan accents\",\n previewColors: [\"#1a1a2e\", \"#00f2ff\", \"#4ecdc4\"],\n tags: [\"dark\", \"default\"],\n theme: {\n backgroundColor: \"#1a1a2e\",\n plotAreaBackground: \"#16213e\",\n axis: {\n color: \"#4a5568\",\n labelColor: \"#a0aec0\",\n titleColor: \"#e2e8f0\",\n labelFontSize: 11,\n titleFontSize: 13,\n },\n grid: {\n color: \"rgba(74, 85, 104, 0.3)\",\n opacity: 0.3,\n },\n legend: {\n background: \"rgba(26, 26, 46, 0.9)\",\n textColor: \"#e2e8f0\",\n borderColor: \"rgba(255, 255, 255, 0.1)\",\n },\n cursor: {\n color: \"#00f2ff\",\n labelBackground: \"rgba(0, 242, 255, 0.9)\",\n labelColor: \"#000000\",\n },\n seriesPalette: [\"#00f2ff\", \"#4ecdc4\", \"#ff6b6b\", \"#ffd93d\", \"#6c5ce7\", \"#a29bfe\", \"#fd79a8\", \"#00cec9\"],\n highlightColor: \"#00f2ff\",\n },\n },\n {\n name: \"Light\",\n description: \"Clean light theme for publications\",\n previewColors: [\"#ffffff\", \"#2563eb\", \"#4f46e5\"],\n tags: [\"light\", \"publication\"],\n theme: {\n backgroundColor: \"#ffffff\",\n plotAreaBackground: \"#f8fafc\",\n axis: {\n color: \"#94a3b8\",\n labelColor: \"#475569\",\n titleColor: \"#1e293b\",\n labelFontSize: 11,\n titleFontSize: 13,\n },\n grid: {\n color: \"rgba(148, 163, 184, 0.3)\",\n opacity: 0.3,\n },\n legend: {\n backgroundColor: \"rgba(255, 255, 255, 0.95)\",\n textColor: \"#1e293b\",\n borderColor: \"rgba(0, 0, 0, 0.1)\",\n },\n cursor: {\n color: \"#2563eb\",\n labelBackground: \"rgba(37, 99, 235, 0.95)\",\n labelColor: \"#ffffff\",\n },\n seriesPalette: [\"#2563eb\", \"#7c3aed\", \"#db2777\", \"#ea580c\", \"#16a34a\", \"#0891b2\", \"#4f46e5\", \"#be185d\"],\n highlightColor: \"#2563eb\",\n },\n },\n {\n name: \"Midnight\",\n description: \"Deep blue dark theme\",\n previewColors: [\"#0f172a\", \"#3b82f6\", \"#8b5cf6\"],\n tags: [\"dark\", \"blue\"],\n theme: {\n backgroundColor: \"#0f172a\",\n plotAreaBackground: \"#1e293b\",\n axis: {\n color: \"#475569\",\n labelColor: \"#94a3b8\",\n titleColor: \"#f1f5f9\",\n labelFontSize: 11,\n titleFontSize: 13,\n },\n grid: {\n color: \"rgba(71, 85, 105, 0.25)\",\n opacity: 0.25,\n },\n legend: {\n backgroundColor: \"rgba(15, 23, 42, 0.95)\",\n textColor: \"#f1f5f9\",\n borderColor: \"rgba(255, 255, 255, 0.08)\",\n },\n cursor: {\n color: \"#3b82f6\",\n labelBackground: \"rgba(59, 130, 246, 0.95)\",\n labelColor: \"#ffffff\",\n },\n seriesPalette: [\"#3b82f6\", \"#8b5cf6\", \"#ec4899\", \"#f59e0b\", \"#10b981\", \"#06b6d4\", \"#6366f1\", \"#f43f5e\"],\n highlightColor: \"#3b82f6\",\n },\n },\n {\n name: \"Scientific\",\n description: \"Clean theme for scientific publications\",\n previewColors: [\"#fafafa\", \"#1f2937\", \"#059669\"],\n tags: [\"light\", \"scientific\", \"publication\"],\n theme: {\n backgroundColor: \"#fafafa\",\n plotAreaBackground: \"#ffffff\",\n axis: {\n color: \"#374151\",\n labelColor: \"#1f2937\",\n titleColor: \"#111827\",\n labelFontSize: 12,\n titleFontSize: 14,\n },\n grid: {\n color: \"rgba(156, 163, 175, 0.4)\",\n opacity: 0.4,\n },\n legend: {\n backgroundColor: \"#ffffff\",\n textColor: \"#111827\",\n borderColor: \"#e5e7eb\",\n },\n cursor: {\n color: \"#059669\",\n labelBackground: \"#059669\",\n labelColor: \"#ffffff\",\n },\n seriesPalette: [\"#1f2937\", \"#059669\", \"#dc2626\", \"#2563eb\", \"#7c3aed\", \"#ea580c\", \"#0891b2\", \"#be123c\"],\n highlightColor: \"#059669\",\n },\n },\n {\n name: \"Electrochemistry\",\n description: \"Theme optimized for electrochemical data\",\n previewColors: [\"#0d1117\", \"#00f2ff\", \"#ff6b6b\"],\n tags: [\"dark\", \"scientific\", \"electrochemistry\"],\n theme: {\n backgroundColor: \"#0d1117\",\n plotAreaBackground: \"#161b22\",\n axis: {\n color: \"#30363d\",\n labelColor: \"#8b949e\",\n titleColor: \"#c9d1d9\",\n labelFontSize: 11,\n titleFontSize: 13,\n },\n grid: {\n color: \"rgba(48, 54, 61, 0.5)\",\n opacity: 0.5,\n },\n legend: {\n backgroundColor: \"rgba(13, 17, 23, 0.95)\",\n textColor: \"#c9d1d9\",\n borderColor: \"rgba(48, 54, 61, 0.8)\",\n },\n cursor: {\n color: \"#00f2ff\",\n labelBackground: \"rgba(0, 242, 255, 0.95)\",\n labelColor: \"#000000\",\n },\n seriesPalette: [\"#00f2ff\", \"#ff6b6b\", \"#4ecdc4\", \"#feca57\", \"#a29bfe\", \"#fd79a8\", \"#00cec9\", \"#e17055\"],\n highlightColor: \"#00f2ff\",\n },\n },\n {\n name: \"High Contrast\",\n description: \"Maximum visibility theme\",\n previewColors: [\"#000000\", \"#ffffff\", \"#ffff00\"],\n tags: [\"dark\", \"accessibility\", \"high-contrast\"],\n theme: {\n backgroundColor: \"#000000\",\n plotAreaBackground: \"#0a0a0a\",\n axis: {\n color: \"#ffffff\",\n labelColor: \"#ffffff\",\n titleColor: \"#ffffff\",\n labelFontSize: 12,\n titleFontSize: 14,\n },\n grid: {\n color: \"rgba(255, 255, 255, 0.2)\",\n opacity: 0.2,\n },\n legend: {\n backgroundColor: \"#000000\",\n textColor: \"#ffffff\",\n borderColor: \"#ffffff\",\n },\n cursor: {\n color: \"#ffff00\",\n labelBackground: \"#ffff00\",\n labelColor: \"#000000\",\n },\n seriesPalette: [\"#ffff00\", \"#00ffff\", \"#ff00ff\", \"#00ff00\", \"#ff8800\", \"#00ff88\", \"#8800ff\", \"#ff0088\"],\n highlightColor: \"#ffff00\",\n },\n },\n];\n\n// ============================================\n// Theme Editor Class\n// ============================================\n\nexport class ThemeEditor {\n private container: HTMLElement;\n private options: Required<ThemeEditorOptions>;\n private currentTheme: EditorTheme;\n private element: HTMLDivElement | null = null;\n\n constructor(container: HTMLElement, options?: ThemeEditorOptions) {\n this.container = container;\n this.options = {\n baseTheme: THEME_PRESETS[0].theme,\n livePreview: true,\n showAdvanced: false,\n className: 'velo-plot-theme-editor',\n onChange: undefined,\n onExport: undefined,\n ...options,\n } as Required<ThemeEditorOptions>;\n\n this.currentTheme = this.resolveTheme(this.options.baseTheme);\n this.render();\n }\n\n /**\n * Get current theme\n */\n getTheme(): EditorTheme {\n return { ...this.currentTheme };\n }\n\n /**\n * Set theme\n */\n setTheme(theme: EditorTheme | string): void {\n this.currentTheme = this.resolveTheme(theme);\n this.render();\n this.notifyChange();\n }\n\n /**\n * Update a specific theme property\n */\n updateProperty(key: string, value: string): void {\n this.setNestedValue(this.currentTheme, key, value);\n this.notifyChange();\n }\n\n /**\n * Export theme as JSON\n */\n exportTheme(): string {\n const json = JSON.stringify(this.currentTheme, null, 2);\n this.options.onExport?.(this.currentTheme, json);\n return json;\n }\n\n /**\n * Import theme from JSON\n */\n importTheme(json: string): void {\n try {\n const theme = JSON.parse(json) as EditorTheme;\n this.currentTheme = theme;\n this.render();\n this.notifyChange();\n } catch (e) {\n console.error('[ThemeEditor] Failed to import theme:', e);\n }\n }\n\n /**\n * Get theme preset by name\n */\n getPreset(name: string): ThemePreset | undefined {\n return THEME_PRESETS.find(p => p.name.toLowerCase() === name.toLowerCase());\n }\n\n /**\n * Apply a preset\n */\n applyPreset(name: string): void {\n const preset = this.getPreset(name);\n if (preset) {\n this.currentTheme = { ...preset.theme };\n this.render();\n this.notifyChange();\n }\n }\n\n /**\n * Get all available presets\n */\n getPresets(): ThemePreset[] {\n return THEME_PRESETS;\n }\n\n /**\n * Destroy the editor\n */\n destroy(): void {\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n this.element = null;\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private resolveTheme(theme: EditorTheme | string): EditorTheme {\n if (typeof theme === 'string') {\n const preset = this.getPreset(theme);\n return preset ? { ...preset.theme } : { ...THEME_PRESETS[0].theme };\n }\n return { ...theme };\n }\n\n private setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void {\n const keys = path.split('.');\n let current = obj;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current)) {\n current[key] = {};\n }\n current = current[key] as Record<string, unknown>;\n }\n \n current[keys[keys.length - 1]] = value;\n }\n\n private getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const keys = path.split('.');\n let current: unknown = obj;\n \n for (const key of keys) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n \n return current;\n }\n\n private notifyChange(): void {\n if (this.options.livePreview) {\n this.options.onChange?.(this.currentTheme);\n }\n }\n\n private render(): void {\n // This creates an HTML structure that can be styled with CSS\n // In a real implementation, this would create interactive color pickers\n if (!this.element) {\n this.element = document.createElement('div');\n this.element.className = this.options.className;\n this.container.appendChild(this.element);\n }\n\n this.element.innerHTML = this.generateHTML();\n this.attachEventListeners();\n }\n\n private generateHTML(): string {\n const presetButtons = THEME_PRESETS.map(preset => `\n <button class=\"preset-btn\" data-preset=\"${preset.name}\" title=\"${preset.description || preset.name}\">\n <div class=\"preset-colors\">\n ${(preset.previewColors || []).map(c => `<span style=\"background:${c}\"></span>`).join('')}\n </div>\n <span class=\"preset-name\">${preset.name}</span>\n </button>\n `).join('');\n\n const colorGroups = THEME_COLOR_GROUPS.map(group => {\n const colorInputs = group.colors.map(color => {\n const value = this.getNestedValue(this.currentTheme as Record<string, unknown>, color.key) as string || '#000000';\n return `\n <div class=\"color-row\">\n <label title=\"${color.description || ''}\">${color.label}</label>\n <input type=\"color\" data-key=\"${color.key}\" value=\"${this.normalizeColor(value)}\" />\n <input type=\"text\" data-key=\"${color.key}\" value=\"${value}\" class=\"color-text\" />\n </div>\n `;\n }).join('');\n\n return `\n <div class=\"color-group\">\n <h4>${group.label}</h4>\n ${group.description ? `<p class=\"group-desc\">${group.description}</p>` : ''}\n ${colorInputs}\n </div>\n `;\n }).join('');\n\n return `\n <div class=\"theme-editor-inner\">\n <div class=\"presets-section\">\n <h3>Presets</h3>\n <div class=\"presets-grid\">${presetButtons}</div>\n </div>\n <div class=\"colors-section\">\n <h3>Customize</h3>\n ${colorGroups}\n </div>\n <div class=\"actions-section\">\n <button class=\"export-btn\">Export JSON</button>\n <button class=\"import-btn\">Import JSON</button>\n </div>\n </div>\n `;\n }\n\n private normalizeColor(color: string): string {\n // Convert rgba/rgb to hex for color picker\n if (color.startsWith('rgba') || color.startsWith('rgb')) {\n const match = color.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (match) {\n const r = parseInt(match[1]).toString(16).padStart(2, '0');\n const g = parseInt(match[2]).toString(16).padStart(2, '0');\n const b = parseInt(match[3]).toString(16).padStart(2, '0');\n return `#${r}${g}${b}`;\n }\n }\n return color;\n }\n\n private attachEventListeners(): void {\n if (!this.element) return;\n\n // Preset buttons\n this.element.querySelectorAll('.preset-btn').forEach(btn => {\n btn.addEventListener('click', () => {\n const presetName = btn.getAttribute('data-preset');\n if (presetName) {\n this.applyPreset(presetName);\n }\n });\n });\n\n // Color inputs\n this.element.querySelectorAll('input[type=\"color\"], input.color-text').forEach(input => {\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n const key = target.getAttribute('data-key');\n if (key) {\n this.updateProperty(key, target.value);\n // Sync color picker and text input\n const sibling = target.type === 'color' \n ? target.nextElementSibling as HTMLInputElement\n : target.previousElementSibling as HTMLInputElement;\n if (sibling) {\n sibling.value = target.type === 'color' ? target.value : this.normalizeColor(target.value);\n }\n }\n });\n });\n\n // Export button\n this.element.querySelector('.export-btn')?.addEventListener('click', () => {\n const json = this.exportTheme();\n navigator.clipboard?.writeText(json).then(() => {\n });\n });\n\n // Import button\n this.element.querySelector('.import-btn')?.addEventListener('click', () => {\n const json = prompt('Paste theme JSON:');\n if (json) {\n this.importTheme(json);\n }\n });\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a theme editor instance\n */\nexport function createThemeEditor(\n container: HTMLElement,\n options?: ThemeEditorOptions\n): ThemeEditor {\n return new ThemeEditor(container, options);\n}\n\n/**\n * Get a preset theme by name\n */\nexport function getPresetTheme(name: string): EditorTheme | undefined {\n const preset = THEME_PRESETS.find(p => p.name.toLowerCase() === name.toLowerCase());\n return preset ? { ...preset.theme } : undefined;\n}\n\n/**\n * Get all preset names\n */\nexport function getPresetNames(): string[] {\n return THEME_PRESETS.map(p => p.name);\n}\n","/**\n * Sci Plot - Theme Editor Plugin\n * \n * Provides a visual interface for editing chart themes in real-time.\n * \n * @module plugins/theme-editor\n */\n\nimport { ThemeEditor } from \"../../core/theme-editor\";\nimport type { EditorTheme, ThemePreset } from \"../../core/theme-editor\";\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\n\nexport interface PluginThemeEditorConfig {\n /** Initial theme to edit */\n initialTheme?: string;\n /** Position in the UI */\n position?: \"left\" | \"right\";\n}\n\nconst manifestThemeEditor: PluginManifest = {\n name: \"velo-plot-theme-editor\",\n version: \"1.0.0\",\n description: \"Visual theme editor for velo-plot\",\n provides: [\"ui\", \"theme\"],\n tags: [\"theme\", \"editor\", \"styling\", \"ui\"],\n};\n\n/**\n * SciPlot Theme Editor Plugin\n * \n * Adds a visual panel to customize chart colors and styles.\n */\nexport function PluginThemeEditor(_config: PluginThemeEditorConfig = {}): ChartPlugin<PluginThemeEditorConfig> {\n return {\n manifest: manifestThemeEditor,\n\n onInit(_ctx: PluginContext) {\n },\n\n onDestroy(_ctx: PluginContext) {\n }\n };\n}\n\nexport { ThemeEditor };\nexport type { EditorTheme, ThemePreset };\nexport default PluginThemeEditor;\n"],"names":["THEME_COLOR_GROUPS","THEME_PRESETS","ThemeEditor","container","options","__publicField","theme","key","value","_a","_b","json","e","name","p","preset","obj","path","keys","current","i","presetButtons","c","colorGroups","group","colorInputs","color","match","r","g","b","btn","presetName","input","target","sibling","createThemeEditor","getPresetTheme","getPresetNames","manifestThemeEditor","PluginThemeEditor","_config","_ctx"],"mappings":";;;AA0EA,MAAMA,IAAmC;AAAA,EACvC;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,KAAK,mBAAmB,OAAO,cAAc,OAAO,IAAI,aAAa,wBAAA;AAAA,MACvE,EAAE,KAAK,sBAAsB,OAAO,aAAa,OAAO,IAAI,aAAa,gCAAA;AAAA,IAAgC;AAAA,EAC3G;AAAA,EAEF;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,KAAK,cAAc,OAAO,cAAc,OAAO,IAAI,aAAa,kBAAA;AAAA,MAClE,EAAE,KAAK,mBAAmB,OAAO,eAAe,OAAO,IAAI,aAAa,wBAAA;AAAA,MACxE,EAAE,KAAK,mBAAmB,OAAO,eAAe,OAAO,IAAI,aAAa,wBAAA;AAAA,IAAwB;AAAA,EAClG;AAAA,EAEF;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,KAAK,cAAc,OAAO,cAAc,OAAO,IAAI,aAAa,wBAAA;AAAA,MAClE,EAAE,KAAK,mBAAmB,OAAO,cAAc,OAAO,IAAI,aAAa,wBAAA;AAAA,IAAwB;AAAA,EACjG;AAAA,EAEF;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,KAAK,mBAAmB,OAAO,YAAY,OAAO,IAAI,aAAa,qBAAA;AAAA,MACrE,EAAE,KAAK,mBAAmB,OAAO,YAAY,OAAO,IAAI,aAAa,sBAAA;AAAA,MACrE,EAAE,KAAK,mBAAmB,OAAO,YAAY,OAAO,IAAI,aAAa,qBAAA;AAAA,MACrE,EAAE,KAAK,mBAAmB,OAAO,YAAY,OAAO,IAAI,aAAa,sBAAA;AAAA,MACrE,EAAE,KAAK,mBAAmB,OAAO,YAAY,OAAO,IAAI,aAAa,qBAAA;AAAA,MACrE,EAAE,KAAK,mBAAmB,OAAO,YAAY,OAAO,IAAI,aAAa,qBAAA;AAAA,IAAqB;AAAA,EAC5F;AAAA,EAEF;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,KAAK,0BAA0B,OAAO,qBAAqB,OAAO,IAAI,aAAa,0BAAA;AAAA,MACrF,EAAE,KAAK,oBAAoB,OAAO,eAAe,OAAO,IAAI,aAAa,oBAAA;AAAA,MACzE,EAAE,KAAK,sBAAsB,OAAO,iBAAiB,OAAO,IAAI,aAAa,sBAAA;AAAA,IAAsB;AAAA,EACrG;AAAA,EAEF;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,KAAK,gBAAgB,OAAO,aAAa,OAAO,IAAI,aAAa,yBAAA;AAAA,MACnE,EAAE,KAAK,0BAA0B,OAAO,mBAAmB,OAAO,IAAI,aAAa,0BAAA;AAAA,MACnF,EAAE,KAAK,mBAAmB,OAAO,aAAa,OAAO,IAAI,aAAa,4BAAA;AAAA,MACtE,EAAE,KAAK,yBAAyB,OAAO,qBAAqB,OAAO,IAAI,aAAa,yBAAA;AAAA,IAAyB;AAAA,EAC/G;AAAA,EAEF;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,KAAK,wBAAwB,OAAO,oBAAoB,OAAO,IAAI,aAAa,gCAAA;AAAA,MAClF,EAAE,KAAK,wBAAwB,OAAO,oBAAoB,OAAO,IAAI,aAAa,gCAAA;AAAA,MAClF,EAAE,KAAK,wBAAwB,OAAO,oBAAoB,OAAO,IAAI,aAAa,gCAAA;AAAA,IAAgC;AAAA,EACpH;AAEJ,GAMaC,IAA+B;AAAA,EAC1C;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,eAAe,CAAC,WAAW,WAAW,SAAS;AAAA,IAC/C,MAAM,CAAC,QAAQ,SAAS;AAAA,IACxB,OAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,oBAAoB;AAAA,MACpB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,MAAA;AAAA,MAEjB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,MAEX,QAAQ;AAAA,QACN,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,aAAa;AAAA,MAAA;AAAA,MAEf,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,iBAAiB;AAAA,QACjB,YAAY;AAAA,MAAA;AAAA,MAEd,eAAe,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,MACtG,gBAAgB;AAAA,IAAA;AAAA,EAClB;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,eAAe,CAAC,WAAW,WAAW,SAAS;AAAA,IAC/C,MAAM,CAAC,SAAS,aAAa;AAAA,IAC7B,OAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,oBAAoB;AAAA,MACpB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,MAAA;AAAA,MAEjB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,MAEX,QAAQ;AAAA,QACN,iBAAiB;AAAA,QACjB,WAAW;AAAA,QACX,aAAa;AAAA,MAAA;AAAA,MAEf,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,iBAAiB;AAAA,QACjB,YAAY;AAAA,MAAA;AAAA,MAEd,eAAe,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,MACtG,gBAAgB;AAAA,IAAA;AAAA,EAClB;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,eAAe,CAAC,WAAW,WAAW,SAAS;AAAA,IAC/C,MAAM,CAAC,QAAQ,MAAM;AAAA,IACrB,OAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,oBAAoB;AAAA,MACpB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,MAAA;AAAA,MAEjB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,MAEX,QAAQ;AAAA,QACN,iBAAiB;AAAA,QACjB,WAAW;AAAA,QACX,aAAa;AAAA,MAAA;AAAA,MAEf,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,iBAAiB;AAAA,QACjB,YAAY;AAAA,MAAA;AAAA,MAEd,eAAe,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,MACtG,gBAAgB;AAAA,IAAA;AAAA,EAClB;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,eAAe,CAAC,WAAW,WAAW,SAAS;AAAA,IAC/C,MAAM,CAAC,SAAS,cAAc,aAAa;AAAA,IAC3C,OAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,oBAAoB;AAAA,MACpB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,MAAA;AAAA,MAEjB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,MAEX,QAAQ;AAAA,QACN,iBAAiB;AAAA,QACjB,WAAW;AAAA,QACX,aAAa;AAAA,MAAA;AAAA,MAEf,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,iBAAiB;AAAA,QACjB,YAAY;AAAA,MAAA;AAAA,MAEd,eAAe,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,MACtG,gBAAgB;AAAA,IAAA;AAAA,EAClB;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,eAAe,CAAC,WAAW,WAAW,SAAS;AAAA,IAC/C,MAAM,CAAC,QAAQ,cAAc,kBAAkB;AAAA,IAC/C,OAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,oBAAoB;AAAA,MACpB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,MAAA;AAAA,MAEjB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,MAEX,QAAQ;AAAA,QACN,iBAAiB;AAAA,QACjB,WAAW;AAAA,QACX,aAAa;AAAA,MAAA;AAAA,MAEf,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,iBAAiB;AAAA,QACjB,YAAY;AAAA,MAAA;AAAA,MAEd,eAAe,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,MACtG,gBAAgB;AAAA,IAAA;AAAA,EAClB;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,eAAe,CAAC,WAAW,WAAW,SAAS;AAAA,IAC/C,MAAM,CAAC,QAAQ,iBAAiB,eAAe;AAAA,IAC/C,OAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,oBAAoB;AAAA,MACpB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,MAAA;AAAA,MAEjB,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,MAEX,QAAQ;AAAA,QACN,iBAAiB;AAAA,QACjB,WAAW;AAAA,QACX,aAAa;AAAA,MAAA;AAAA,MAEf,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,iBAAiB;AAAA,QACjB,YAAY;AAAA,MAAA;AAAA,MAEd,eAAe,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,MACtG,gBAAgB;AAAA,IAAA;AAAA,EAClB;AAEJ;AAMO,MAAMC,EAAY;AAAA,EAMvB,YAAYC,GAAwBC,GAA8B;AAL1D,IAAAC,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,iBAAiC;AAGvC,SAAK,YAAYF,GACjB,KAAK,UAAU;AAAA,MACb,WAAWF,EAAc,CAAC,EAAE;AAAA,MAC5B,aAAa;AAAA,MACb,cAAc;AAAA,MACd,WAAW;AAAA,MACX,UAAU;AAAA,MACV,UAAU;AAAA,MACV,GAAGG;AAAA,IAAA,GAGL,KAAK,eAAe,KAAK,aAAa,KAAK,QAAQ,SAAS,GAC5D,KAAK,OAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,WAAwB;AACtB,WAAO,EAAE,GAAG,KAAK,aAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,SAASE,GAAmC;AAC1C,SAAK,eAAe,KAAK,aAAaA,CAAK,GAC3C,KAAK,OAAA,GACL,KAAK,aAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,eAAeC,GAAaC,GAAqB;AAC/C,SAAK,eAAe,KAAK,cAAcD,GAAKC,CAAK,GACjD,KAAK,aAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,cAAsB;AAtUxB,QAAAC,GAAAC;AAuUI,UAAMC,IAAO,KAAK,UAAU,KAAK,cAAc,MAAM,CAAC;AACtD,YAAAD,KAAAD,IAAA,KAAK,SAAQ,aAAb,QAAAC,EAAA,KAAAD,GAAwB,KAAK,cAAcE,IACpCA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAYA,GAAoB;AAC9B,QAAI;AACF,YAAML,IAAQ,KAAK,MAAMK,CAAI;AAC7B,WAAK,eAAeL,GACpB,KAAK,OAAA,GACL,KAAK,aAAA;AAAA,IACP,SAASM,GAAG;AACV,cAAQ,MAAM,yCAAyCA,CAAC;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAUC,GAAuC;AAC/C,WAAOZ,EAAc,KAAK,CAAAa,MAAKA,EAAE,KAAK,YAAA,MAAkBD,EAAK,aAAa;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,YAAYA,GAAoB;AAC9B,UAAME,IAAS,KAAK,UAAUF,CAAI;AAClC,IAAIE,MACF,KAAK,eAAe,EAAE,GAAGA,EAAO,MAAA,GAChC,KAAK,OAAA,GACL,KAAK,aAAA;AAAA,EAET;AAAA;AAAA;AAAA;AAAA,EAKA,aAA4B;AAC1B,WAAOd;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,IAAI,KAAK,WAAW,KAAK,QAAQ,cAC/B,KAAK,QAAQ,WAAW,YAAY,KAAK,OAAO,GAElD,KAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAMQ,aAAaK,GAA0C;AAC7D,QAAI,OAAOA,KAAU,UAAU;AAC7B,YAAMS,IAAS,KAAK,UAAUT,CAAK;AACnC,aAAOS,IAAS,EAAE,GAAGA,EAAO,MAAA,IAAU,EAAE,GAAGd,EAAc,CAAC,EAAE,MAAA;AAAA,IAC9D;AACA,WAAO,EAAE,GAAGK,EAAA;AAAA,EACd;AAAA,EAEQ,eAAeU,GAA8BC,GAAcT,GAAsB;AACvF,UAAMU,IAAOD,EAAK,MAAM,GAAG;AAC3B,QAAIE,IAAUH;AAEd,aAASI,IAAI,GAAGA,IAAIF,EAAK,SAAS,GAAGE,KAAK;AACxC,YAAMb,IAAMW,EAAKE,CAAC;AAClB,MAAMb,KAAOY,MACXA,EAAQZ,CAAG,IAAI,CAAA,IAEjBY,IAAUA,EAAQZ,CAAG;AAAA,IACvB;AAEA,IAAAY,EAAQD,EAAKA,EAAK,SAAS,CAAC,CAAC,IAAIV;AAAA,EACnC;AAAA,EAEQ,eAAeQ,GAA8BC,GAAuB;AAC1E,UAAMC,IAAOD,EAAK,MAAM,GAAG;AAC3B,QAAIE,IAAmBH;AAEvB,eAAWT,KAAOW,GAAM;AACtB,UAAIC,KAAY,QAAiC,OAAOA,KAAY;AAClE;AAEF,MAAAA,IAAWA,EAAoCZ,CAAG;AAAA,IACpD;AAEA,WAAOY;AAAA,EACT;AAAA,EAEQ,eAAqB;AAva/B,QAAAV,GAAAC;AAwaI,IAAI,KAAK,QAAQ,iBACfA,KAAAD,IAAA,KAAK,SAAQ,aAAb,QAAAC,EAAA,KAAAD,GAAwB,KAAK;AAAA,EAEjC;AAAA,EAEQ,SAAe;AAGrB,IAAK,KAAK,YACR,KAAK,UAAU,SAAS,cAAc,KAAK,GAC3C,KAAK,QAAQ,YAAY,KAAK,QAAQ,WACtC,KAAK,UAAU,YAAY,KAAK,OAAO,IAGzC,KAAK,QAAQ,YAAY,KAAK,aAAA,GAC9B,KAAK,qBAAA;AAAA,EACP;AAAA,EAEQ,eAAuB;AAC7B,UAAMY,IAAgBpB,EAAc,IAAI,CAAAc,MAAU;AAAA,gDACNA,EAAO,IAAI,YAAYA,EAAO,eAAeA,EAAO,IAAI;AAAA;AAAA,aAE3FA,EAAO,iBAAiB,CAAA,GAAI,IAAI,CAAAO,MAAK,2BAA2BA,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;AAAA;AAAA,oCAE/DP,EAAO,IAAI;AAAA;AAAA,KAE1C,EAAE,KAAK,EAAE,GAEJQ,IAAcvB,EAAmB,IAAI,CAAAwB,MAAS;AAClD,YAAMC,IAAcD,EAAM,OAAO,IAAI,CAAAE,MAAS;AAC5C,cAAMlB,IAAQ,KAAK,eAAe,KAAK,cAAyCkB,EAAM,GAAG,KAAe;AACxG,eAAO;AAAA;AAAA,4BAEaA,EAAM,eAAe,EAAE,KAAKA,EAAM,KAAK;AAAA,4CACvBA,EAAM,GAAG,YAAY,KAAK,eAAelB,CAAK,CAAC;AAAA,2CAChDkB,EAAM,GAAG,YAAYlB,CAAK;AAAA;AAAA;AAAA,MAG/D,CAAC,EAAE,KAAK,EAAE;AAEV,aAAO;AAAA;AAAA,gBAEGgB,EAAM,KAAK;AAAA,YACfA,EAAM,cAAc,yBAAyBA,EAAM,WAAW,SAAS,EAAE;AAAA,YACzEC,CAAW;AAAA;AAAA;AAAA,IAGnB,CAAC,EAAE,KAAK,EAAE;AAEV,WAAO;AAAA;AAAA;AAAA;AAAA,sCAI2BJ,CAAa;AAAA;AAAA;AAAA;AAAA,YAIvCE,CAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrB;AAAA,EAEQ,eAAeG,GAAuB;AAE5C,QAAIA,EAAM,WAAW,MAAM,KAAKA,EAAM,WAAW,KAAK,GAAG;AACvD,YAAMC,IAAQD,EAAM,MAAM,gCAAgC;AAC1D,UAAIC,GAAO;AACT,cAAMC,IAAI,SAASD,EAAM,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,GACnDE,IAAI,SAASF,EAAM,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,GACnDG,IAAI,SAASH,EAAM,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AACzD,eAAO,IAAIC,CAAC,GAAGC,CAAC,GAAGC,CAAC;AAAA,MACtB;AAAA,IACF;AACA,WAAOJ;AAAA,EACT;AAAA,EAEQ,uBAA6B;AAzfvC,QAAAjB,GAAAC;AA0fI,IAAK,KAAK,YAGV,KAAK,QAAQ,iBAAiB,aAAa,EAAE,QAAQ,CAAAqB,MAAO;AAC1D,MAAAA,EAAI,iBAAiB,SAAS,MAAM;AAClC,cAAMC,IAAaD,EAAI,aAAa,aAAa;AACjD,QAAIC,KACF,KAAK,YAAYA,CAAU;AAAA,MAE/B,CAAC;AAAA,IACH,CAAC,GAGD,KAAK,QAAQ,iBAAiB,uCAAuC,EAAE,QAAQ,CAAAC,MAAS;AACtF,MAAAA,EAAM,iBAAiB,SAAS,CAACrB,MAAM;AACrC,cAAMsB,IAAStB,EAAE,QACXL,IAAM2B,EAAO,aAAa,UAAU;AAC1C,YAAI3B,GAAK;AACP,eAAK,eAAeA,GAAK2B,EAAO,KAAK;AAErC,gBAAMC,IAAUD,EAAO,SAAS,UAC5BA,EAAO,qBACPA,EAAO;AACX,UAAIC,MACFA,EAAQ,QAAQD,EAAO,SAAS,UAAUA,EAAO,QAAQ,KAAK,eAAeA,EAAO,KAAK;AAAA,QAE7F;AAAA,MACF,CAAC;AAAA,IACH,CAAC,IAGDzB,IAAA,KAAK,QAAQ,cAAc,aAAa,MAAxC,QAAAA,EAA2C,iBAAiB,SAAS,MAAM;AAzhB/E,UAAAA;AA0hBM,YAAME,IAAO,KAAK,YAAA;AAClB,OAAAF,IAAA,UAAU,cAAV,QAAAA,EAAqB,UAAUE,GAAM,KAAK,MAAM;AAAA,MAChD;AAAA,IACF,KAGAD,IAAA,KAAK,QAAQ,cAAc,aAAa,MAAxC,QAAAA,EAA2C,iBAAiB,SAAS,MAAM;AACzE,YAAMC,IAAO,OAAO,mBAAmB;AACvC,MAAIA,KACF,KAAK,YAAYA,CAAI;AAAA,IAEzB;AAAA,EACF;AACF;AASO,SAASyB,EACdjC,GACAC,GACa;AACb,SAAO,IAAIF,EAAYC,GAAWC,CAAO;AAC3C;AAKO,SAASiC,EAAexB,GAAuC;AACpE,QAAME,IAASd,EAAc,KAAK,CAAAa,MAAKA,EAAE,KAAK,YAAA,MAAkBD,EAAK,YAAA,CAAa;AAClF,SAAOE,IAAS,EAAE,GAAGA,EAAO,UAAU;AACxC;AAKO,SAASuB,IAA2B;AACzC,SAAOrC,EAAc,IAAI,CAAAa,MAAKA,EAAE,IAAI;AACtC;AC3nBA,MAAMyB,IAAsC;AAAA,EACxC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU,CAAC,MAAM,OAAO;AAAA,EACxB,MAAM,CAAC,SAAS,UAAU,WAAW,IAAI;AAC7C;AAOO,SAASC,EAAkBC,IAAmC,IAA0C;AAC3G,SAAO;AAAA,IACH,UAAUF;AAAA,IAEV,OAAOG,GAAqB;AAAA,IAC5B;AAAA,IAEA,UAAUA,GAAqB;AAAA,IAC/B;AAAA,EAAA;AAER;"}
1
+ {"version":3,"file":"index-Dag88bW4.js","sources":["../src/core/theme-editor/index.ts","../src/plugins/theme-editor/index.ts"],"sourcesContent":["/**\n * Velo Plot - Theme Editor Module\n * \n * Provides a visual theme editor for customizing chart appearance:\n * - Color pickers for all theme elements\n * - Live preview\n * - Theme export/import\n * - Preset theme gallery\n * \n * @module theme-editor\n */\n\n// Use a flexible internal type to avoid strict EditorTheme compatibility issues\n// The editor works with partial theme configs that can be applied via createTheme()\nexport type EditorTheme = Record<string, unknown>;\n\n// ============================================\n// Types\n// ============================================\n\nexport interface ThemeEditorOptions {\n /** Base theme to start from */\n baseTheme?: EditorTheme | string;\n /** Enable live preview (default: true) */\n livePreview?: boolean;\n /** Show advanced options (default: false) */\n showAdvanced?: boolean;\n /** Custom CSS class for the editor */\n className?: string;\n /** Callback when theme changes */\n onChange?: (theme: EditorTheme) => void;\n /** Callback when export is requested */\n onExport?: (theme: EditorTheme, json: string) => void;\n}\n\nexport interface ThemePreset {\n /** Preset name */\n name: string;\n /** Description */\n description?: string;\n /** Theme configuration */\n theme: EditorTheme;\n /** Preview colors (for UI) */\n previewColors?: string[];\n /** Tags for filtering */\n tags?: string[];\n}\n\nexport interface ColorGroup {\n /** Group label */\n label: string;\n /** Group description */\n description?: string;\n /** Color properties in this group */\n colors: ColorProperty[];\n}\n\nexport interface ColorProperty {\n /** Property key path (e.g., 'background', 'axis.color') */\n key: string;\n /** Display label */\n label: string;\n /** Description/tooltip */\n description?: string;\n /** Current value */\n value: string;\n /** Default value */\n defaultValue?: string;\n}\n\n// ============================================\n// Default Theme Structure\n// ============================================\n\nconst THEME_COLOR_GROUPS: ColorGroup[] = [\n {\n label: \"Background & Canvas\",\n description: \"Chart background and canvas colors\",\n colors: [\n { key: \"backgroundColor\", label: \"Background\", value: \"\", description: \"Main chart background\" },\n { key: \"plotAreaBackground\", label: \"Plot Area\", value: \"\", description: \"Data plotting area background\" },\n ],\n },\n {\n label: \"Axes\",\n description: \"Axis lines, ticks, and labels\",\n colors: [\n { key: \"axis.color\", label: \"Axis Lines\", value: \"\", description: \"Axis line color\" },\n { key: \"axis.labelColor\", label: \"Axis Labels\", value: \"\", description: \"Axis label text color\" },\n { key: \"axis.titleColor\", label: \"Axis Titles\", value: \"\", description: \"Axis title text color\" },\n ],\n },\n {\n label: \"Grid\",\n description: \"Grid lines and markers\",\n colors: [\n { key: \"grid.color\", label: \"Grid Lines\", value: \"\", description: \"Major grid line color\" },\n { key: \"grid.minorColor\", label: \"Minor Grid\", value: \"\", description: \"Minor grid line color\" },\n ],\n },\n {\n label: \"Series Palette\",\n description: \"Default colors for data series\",\n colors: [\n { key: \"seriesPalette.0\", label: \"Series 1\", value: \"\", description: \"First series color\" },\n { key: \"seriesPalette.1\", label: \"Series 2\", value: \"\", description: \"Second series color\" },\n { key: \"seriesPalette.2\", label: \"Series 3\", value: \"\", description: \"Third series color\" },\n { key: \"seriesPalette.3\", label: \"Series 4\", value: \"\", description: \"Fourth series color\" },\n { key: \"seriesPalette.4\", label: \"Series 5\", value: \"\", description: \"Fifth series color\" },\n { key: \"seriesPalette.5\", label: \"Series 6\", value: \"\", description: \"Sixth series color\" },\n ],\n },\n {\n label: \"Legend\",\n description: \"Legend styling\",\n colors: [\n { key: \"legend.backgroundColor\", label: \"Legend Background\", value: \"\", description: \"Legend panel background\" },\n { key: \"legend.textColor\", label: \"Legend Text\", value: \"\", description: \"Legend text color\" },\n { key: \"legend.borderColor\", label: \"Legend Border\", value: \"\", description: \"Legend border color\" },\n ],\n },\n {\n label: \"Cursor & Selection\",\n description: \"Interactive elements\",\n colors: [\n { key: \"cursor.color\", label: \"Crosshair\", value: \"\", description: \"Cursor crosshair color\" },\n { key: \"cursor.labelBackground\", label: \"Cursor Label BG\", value: \"\", description: \"Cursor label background\" },\n { key: \"selection.color\", label: \"Selection\", value: \"\", description: \"Selection highlight color\" },\n { key: \"selection.handleColor\", label: \"Selection Handles\", value: \"\", description: \"Selection handle color\" },\n ],\n },\n {\n label: \"Annotations\",\n description: \"Annotation default colors\",\n colors: [\n { key: \"annotation.lineColor\", label: \"Line Annotations\", value: \"\", description: \"Default line annotation color\" },\n { key: \"annotation.fillColor\", label: \"Fill Annotations\", value: \"\", description: \"Default fill annotation color\" },\n { key: \"annotation.textColor\", label: \"Text Annotations\", value: \"\", description: \"Default text annotation color\" },\n ],\n },\n];\n\n// ============================================\n// Theme Presets\n// ============================================\n\nexport const THEME_PRESETS: ThemePreset[] = [\n {\n name: \"Dark\",\n description: \"Classic dark theme with cyan accents\",\n previewColors: [\"#1a1a2e\", \"#00f2ff\", \"#4ecdc4\"],\n tags: [\"dark\", \"default\"],\n theme: {\n backgroundColor: \"#1a1a2e\",\n plotAreaBackground: \"#16213e\",\n axis: {\n color: \"#4a5568\",\n labelColor: \"#a0aec0\",\n titleColor: \"#e2e8f0\",\n labelFontSize: 11,\n titleFontSize: 13,\n },\n grid: {\n color: \"rgba(74, 85, 104, 0.3)\",\n opacity: 0.3,\n },\n legend: {\n background: \"rgba(26, 26, 46, 0.9)\",\n textColor: \"#e2e8f0\",\n borderColor: \"rgba(255, 255, 255, 0.1)\",\n },\n cursor: {\n color: \"#00f2ff\",\n labelBackground: \"rgba(0, 242, 255, 0.9)\",\n labelColor: \"#000000\",\n },\n seriesPalette: [\"#00f2ff\", \"#4ecdc4\", \"#ff6b6b\", \"#ffd93d\", \"#6c5ce7\", \"#a29bfe\", \"#fd79a8\", \"#00cec9\"],\n highlightColor: \"#00f2ff\",\n },\n },\n {\n name: \"Light\",\n description: \"Clean light theme for publications\",\n previewColors: [\"#ffffff\", \"#2563eb\", \"#4f46e5\"],\n tags: [\"light\", \"publication\"],\n theme: {\n backgroundColor: \"#ffffff\",\n plotAreaBackground: \"#f8fafc\",\n axis: {\n color: \"#94a3b8\",\n labelColor: \"#475569\",\n titleColor: \"#1e293b\",\n labelFontSize: 11,\n titleFontSize: 13,\n },\n grid: {\n color: \"rgba(148, 163, 184, 0.3)\",\n opacity: 0.3,\n },\n legend: {\n backgroundColor: \"rgba(255, 255, 255, 0.95)\",\n textColor: \"#1e293b\",\n borderColor: \"rgba(0, 0, 0, 0.1)\",\n },\n cursor: {\n color: \"#2563eb\",\n labelBackground: \"rgba(37, 99, 235, 0.95)\",\n labelColor: \"#ffffff\",\n },\n seriesPalette: [\"#2563eb\", \"#7c3aed\", \"#db2777\", \"#ea580c\", \"#16a34a\", \"#0891b2\", \"#4f46e5\", \"#be185d\"],\n highlightColor: \"#2563eb\",\n },\n },\n {\n name: \"Midnight\",\n description: \"Deep blue dark theme\",\n previewColors: [\"#0f172a\", \"#3b82f6\", \"#8b5cf6\"],\n tags: [\"dark\", \"blue\"],\n theme: {\n backgroundColor: \"#0f172a\",\n plotAreaBackground: \"#1e293b\",\n axis: {\n color: \"#475569\",\n labelColor: \"#94a3b8\",\n titleColor: \"#f1f5f9\",\n labelFontSize: 11,\n titleFontSize: 13,\n },\n grid: {\n color: \"rgba(71, 85, 105, 0.25)\",\n opacity: 0.25,\n },\n legend: {\n backgroundColor: \"rgba(15, 23, 42, 0.95)\",\n textColor: \"#f1f5f9\",\n borderColor: \"rgba(255, 255, 255, 0.08)\",\n },\n cursor: {\n color: \"#3b82f6\",\n labelBackground: \"rgba(59, 130, 246, 0.95)\",\n labelColor: \"#ffffff\",\n },\n seriesPalette: [\"#3b82f6\", \"#8b5cf6\", \"#ec4899\", \"#f59e0b\", \"#10b981\", \"#06b6d4\", \"#6366f1\", \"#f43f5e\"],\n highlightColor: \"#3b82f6\",\n },\n },\n {\n name: \"Scientific\",\n description: \"Clean theme for scientific publications\",\n previewColors: [\"#fafafa\", \"#1f2937\", \"#059669\"],\n tags: [\"light\", \"scientific\", \"publication\"],\n theme: {\n backgroundColor: \"#fafafa\",\n plotAreaBackground: \"#ffffff\",\n axis: {\n color: \"#374151\",\n labelColor: \"#1f2937\",\n titleColor: \"#111827\",\n labelFontSize: 12,\n titleFontSize: 14,\n },\n grid: {\n color: \"rgba(156, 163, 175, 0.4)\",\n opacity: 0.4,\n },\n legend: {\n backgroundColor: \"#ffffff\",\n textColor: \"#111827\",\n borderColor: \"#e5e7eb\",\n },\n cursor: {\n color: \"#059669\",\n labelBackground: \"#059669\",\n labelColor: \"#ffffff\",\n },\n seriesPalette: [\"#1f2937\", \"#059669\", \"#dc2626\", \"#2563eb\", \"#7c3aed\", \"#ea580c\", \"#0891b2\", \"#be123c\"],\n highlightColor: \"#059669\",\n },\n },\n {\n name: \"Electrochemistry\",\n description: \"Theme optimized for electrochemical data\",\n previewColors: [\"#0d1117\", \"#00f2ff\", \"#ff6b6b\"],\n tags: [\"dark\", \"scientific\", \"electrochemistry\"],\n theme: {\n backgroundColor: \"#0d1117\",\n plotAreaBackground: \"#161b22\",\n axis: {\n color: \"#30363d\",\n labelColor: \"#8b949e\",\n titleColor: \"#c9d1d9\",\n labelFontSize: 11,\n titleFontSize: 13,\n },\n grid: {\n color: \"rgba(48, 54, 61, 0.5)\",\n opacity: 0.5,\n },\n legend: {\n backgroundColor: \"rgba(13, 17, 23, 0.95)\",\n textColor: \"#c9d1d9\",\n borderColor: \"rgba(48, 54, 61, 0.8)\",\n },\n cursor: {\n color: \"#00f2ff\",\n labelBackground: \"rgba(0, 242, 255, 0.95)\",\n labelColor: \"#000000\",\n },\n seriesPalette: [\"#00f2ff\", \"#ff6b6b\", \"#4ecdc4\", \"#feca57\", \"#a29bfe\", \"#fd79a8\", \"#00cec9\", \"#e17055\"],\n highlightColor: \"#00f2ff\",\n },\n },\n {\n name: \"High Contrast\",\n description: \"Maximum visibility theme\",\n previewColors: [\"#000000\", \"#ffffff\", \"#ffff00\"],\n tags: [\"dark\", \"accessibility\", \"high-contrast\"],\n theme: {\n backgroundColor: \"#000000\",\n plotAreaBackground: \"#0a0a0a\",\n axis: {\n color: \"#ffffff\",\n labelColor: \"#ffffff\",\n titleColor: \"#ffffff\",\n labelFontSize: 12,\n titleFontSize: 14,\n },\n grid: {\n color: \"rgba(255, 255, 255, 0.2)\",\n opacity: 0.2,\n },\n legend: {\n backgroundColor: \"#000000\",\n textColor: \"#ffffff\",\n borderColor: \"#ffffff\",\n },\n cursor: {\n color: \"#ffff00\",\n labelBackground: \"#ffff00\",\n labelColor: \"#000000\",\n },\n seriesPalette: [\"#ffff00\", \"#00ffff\", \"#ff00ff\", \"#00ff00\", \"#ff8800\", \"#00ff88\", \"#8800ff\", \"#ff0088\"],\n highlightColor: \"#ffff00\",\n },\n },\n];\n\n// ============================================\n// Theme Editor Class\n// ============================================\n\nexport class ThemeEditor {\n private container: HTMLElement;\n private options: Required<ThemeEditorOptions>;\n private currentTheme: EditorTheme;\n private element: HTMLDivElement | null = null;\n\n constructor(container: HTMLElement, options?: ThemeEditorOptions) {\n this.container = container;\n this.options = {\n baseTheme: THEME_PRESETS[0].theme,\n livePreview: true,\n showAdvanced: false,\n className: 'velo-plot-theme-editor',\n onChange: undefined,\n onExport: undefined,\n ...options,\n } as Required<ThemeEditorOptions>;\n\n this.currentTheme = this.resolveTheme(this.options.baseTheme);\n this.render();\n }\n\n /**\n * Get current theme\n */\n getTheme(): EditorTheme {\n return { ...this.currentTheme };\n }\n\n /**\n * Set theme\n */\n setTheme(theme: EditorTheme | string): void {\n this.currentTheme = this.resolveTheme(theme);\n this.render();\n this.notifyChange();\n }\n\n /**\n * Update a specific theme property\n */\n updateProperty(key: string, value: string): void {\n this.setNestedValue(this.currentTheme, key, value);\n this.notifyChange();\n }\n\n /**\n * Export theme as JSON\n */\n exportTheme(): string {\n const json = JSON.stringify(this.currentTheme, null, 2);\n this.options.onExport?.(this.currentTheme, json);\n return json;\n }\n\n /**\n * Import theme from JSON\n */\n importTheme(json: string): void {\n try {\n const theme = JSON.parse(json) as EditorTheme;\n this.currentTheme = theme;\n this.render();\n this.notifyChange();\n } catch (e) {\n console.error('[ThemeEditor] Failed to import theme:', e);\n }\n }\n\n /**\n * Get theme preset by name\n */\n getPreset(name: string): ThemePreset | undefined {\n return THEME_PRESETS.find(p => p.name.toLowerCase() === name.toLowerCase());\n }\n\n /**\n * Apply a preset\n */\n applyPreset(name: string): void {\n const preset = this.getPreset(name);\n if (preset) {\n this.currentTheme = { ...preset.theme };\n this.render();\n this.notifyChange();\n }\n }\n\n /**\n * Get all available presets\n */\n getPresets(): ThemePreset[] {\n return THEME_PRESETS;\n }\n\n /**\n * Destroy the editor\n */\n destroy(): void {\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n this.element = null;\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private resolveTheme(theme: EditorTheme | string): EditorTheme {\n if (typeof theme === 'string') {\n const preset = this.getPreset(theme);\n return preset ? { ...preset.theme } : { ...THEME_PRESETS[0].theme };\n }\n return { ...theme };\n }\n\n private setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void {\n const keys = path.split('.');\n let current = obj;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current)) {\n current[key] = {};\n }\n current = current[key] as Record<string, unknown>;\n }\n \n current[keys[keys.length - 1]] = value;\n }\n\n private getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const keys = path.split('.');\n let current: unknown = obj;\n \n for (const key of keys) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n \n return current;\n }\n\n private notifyChange(): void {\n if (this.options.livePreview) {\n this.options.onChange?.(this.currentTheme);\n }\n }\n\n private render(): void {\n // This creates an HTML structure that can be styled with CSS\n // In a real implementation, this would create interactive color pickers\n if (!this.element) {\n this.element = document.createElement('div');\n this.element.className = this.options.className;\n this.container.appendChild(this.element);\n }\n\n this.element.innerHTML = this.generateHTML();\n this.attachEventListeners();\n }\n\n private generateHTML(): string {\n const presetButtons = THEME_PRESETS.map(preset => `\n <button class=\"preset-btn\" data-preset=\"${preset.name}\" title=\"${preset.description || preset.name}\">\n <div class=\"preset-colors\">\n ${(preset.previewColors || []).map(c => `<span style=\"background:${c}\"></span>`).join('')}\n </div>\n <span class=\"preset-name\">${preset.name}</span>\n </button>\n `).join('');\n\n const colorGroups = THEME_COLOR_GROUPS.map(group => {\n const colorInputs = group.colors.map(color => {\n const value = this.getNestedValue(this.currentTheme as Record<string, unknown>, color.key) as string || '#000000';\n return `\n <div class=\"color-row\">\n <label title=\"${color.description || ''}\">${color.label}</label>\n <input type=\"color\" data-key=\"${color.key}\" value=\"${this.normalizeColor(value)}\" />\n <input type=\"text\" data-key=\"${color.key}\" value=\"${value}\" class=\"color-text\" />\n </div>\n `;\n }).join('');\n\n return `\n <div class=\"color-group\">\n <h4>${group.label}</h4>\n ${group.description ? `<p class=\"group-desc\">${group.description}</p>` : ''}\n ${colorInputs}\n </div>\n `;\n }).join('');\n\n return `\n <div class=\"theme-editor-inner\">\n <div class=\"presets-section\">\n <h3>Presets</h3>\n <div class=\"presets-grid\">${presetButtons}</div>\n </div>\n <div class=\"colors-section\">\n <h3>Customize</h3>\n ${colorGroups}\n </div>\n <div class=\"actions-section\">\n <button class=\"export-btn\">Export JSON</button>\n <button class=\"import-btn\">Import JSON</button>\n </div>\n </div>\n `;\n }\n\n private normalizeColor(color: string): string {\n // Convert rgba/rgb to hex for color picker\n if (color.startsWith('rgba') || color.startsWith('rgb')) {\n const match = color.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (match) {\n const r = parseInt(match[1]).toString(16).padStart(2, '0');\n const g = parseInt(match[2]).toString(16).padStart(2, '0');\n const b = parseInt(match[3]).toString(16).padStart(2, '0');\n return `#${r}${g}${b}`;\n }\n }\n return color;\n }\n\n private attachEventListeners(): void {\n if (!this.element) return;\n\n // Preset buttons\n this.element.querySelectorAll('.preset-btn').forEach(btn => {\n btn.addEventListener('click', () => {\n const presetName = btn.getAttribute('data-preset');\n if (presetName) {\n this.applyPreset(presetName);\n }\n });\n });\n\n // Color inputs\n this.element.querySelectorAll('input[type=\"color\"], input.color-text').forEach(input => {\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n const key = target.getAttribute('data-key');\n if (key) {\n this.updateProperty(key, target.value);\n // Sync color picker and text input\n const sibling = target.type === 'color' \n ? target.nextElementSibling as HTMLInputElement\n : target.previousElementSibling as HTMLInputElement;\n if (sibling) {\n sibling.value = target.type === 'color' ? target.value : this.normalizeColor(target.value);\n }\n }\n });\n });\n\n // Export button\n this.element.querySelector('.export-btn')?.addEventListener('click', () => {\n const json = this.exportTheme();\n navigator.clipboard?.writeText(json).then(() => {\n });\n });\n\n // Import button\n this.element.querySelector('.import-btn')?.addEventListener('click', () => {\n const json = prompt('Paste theme JSON:');\n if (json) {\n this.importTheme(json);\n }\n });\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a theme editor instance\n */\nexport function createThemeEditor(\n container: HTMLElement,\n options?: ThemeEditorOptions\n): ThemeEditor {\n return new ThemeEditor(container, options);\n}\n\n/**\n * Get a preset theme by name\n */\nexport function getPresetTheme(name: string): EditorTheme | undefined {\n const preset = THEME_PRESETS.find(p => p.name.toLowerCase() === name.toLowerCase());\n return preset ? { ...preset.theme } : undefined;\n}\n\n/**\n * Get all preset names\n */\nexport function getPresetNames(): string[] {\n return THEME_PRESETS.map(p => p.name);\n}\n","/**\n * Velo Plot - Theme Editor Plugin\n * \n * Provides a visual interface for editing chart themes in real-time.\n * \n * @module plugins/theme-editor\n */\n\nimport { ThemeEditor } from \"../../core/theme-editor\";\nimport type { EditorTheme, ThemePreset } from \"../../core/theme-editor\";\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\n\nexport interface PluginThemeEditorConfig {\n /** Initial theme to edit */\n initialTheme?: string;\n /** Position in the UI */\n position?: \"left\" | \"right\";\n}\n\nconst manifestThemeEditor: PluginManifest = {\n name: \"velo-plot-theme-editor\",\n version: \"1.0.0\",\n description: \"Visual theme editor for velo-plot\",\n provides: [\"ui\", \"theme\"],\n tags: [\"theme\", \"editor\", \"styling\", \"ui\"],\n};\n\n/**\n * VeloPlot Theme Editor Plugin\n * \n * Adds a visual panel to customize chart colors and styles.\n */\nexport function PluginThemeEditor(_config: PluginThemeEditorConfig = {}): ChartPlugin<PluginThemeEditorConfig> {\n return {\n manifest: manifestThemeEditor,\n\n onInit(_ctx: PluginContext) {\n },\n\n onDestroy(_ctx: PluginContext) {\n }\n };\n}\n\nexport { ThemeEditor };\nexport type { EditorTheme, ThemePreset };\nexport default PluginThemeEditor;\n"],"names":["THEME_COLOR_GROUPS","THEME_PRESETS","ThemeEditor","container","options","__publicField","theme","key","value","_a","_b","json","e","name","p","preset","obj","path","keys","current","i","presetButtons","c","colorGroups","group","colorInputs","color","match","r","g","b","btn","presetName","input","target","sibling","createThemeEditor","getPresetTheme","getPresetNames","manifestThemeEditor","PluginThemeEditor","_config","_ctx"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index-qhscKTDy.js","sources":["../src/core/loading/index.ts","../src/plugins/loading/index.ts"],"sourcesContent":["/**\n * Sci Plot - Loading Indicator Module\n * \n * Provides visual loading/progress indicators for chart operations.\n * Supports progress bars, spinners, and skeleton placeholders.\n * \n * @module loading\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport type LoadingIndicatorType = 'spinner' | 'progress' | 'skeleton' | 'pulse';\n\nexport interface LoadingIndicatorOptions {\n /** Indicator type (default: 'spinner') */\n type?: LoadingIndicatorType;\n /** Message to display (default: 'Loading...') */\n message?: string;\n /** Show percentage for progress type (default: true) */\n showPercentage?: boolean;\n /** Background overlay opacity (0-1, default: 0.7) */\n overlayOpacity?: number;\n /** Accent color for spinner/progress (default: '#00f2ff') */\n accentColor?: string;\n /** Background color (default: 'rgba(0,0,0,0.7)') */\n backgroundColor?: string;\n /** Text color (default: '#ffffff') */\n textColor?: string;\n /** Size: 'small', 'medium', 'large' (default: 'medium') */\n size?: 'small' | 'medium' | 'large';\n /** Custom CSS class */\n className?: string;\n /** Auto-hide after completion (default: true) */\n autoHide?: boolean;\n /** Hide delay in ms after completion (default: 300) */\n hideDelay?: number;\n}\n\nexport interface LoadingState {\n /** Whether loading is in progress */\n isLoading: boolean;\n /** Progress value (0-100) */\n progress: number;\n /** Current message */\n message: string;\n /** Start time of loading */\n startTime: number | null;\n /** Estimated time remaining in ms */\n eta: number | null;\n}\n\n// ============================================\n// Loading Indicator Implementation\n// ============================================\n\nexport class LoadingIndicator {\n private container: HTMLElement;\n private element: HTMLDivElement | null = null;\n private options: Required<LoadingIndicatorOptions>;\n private state: LoadingState = {\n isLoading: false,\n progress: 0,\n message: '',\n startTime: null,\n eta: null,\n };\n\n // For ETA calculation\n private progressHistory: { time: number; progress: number }[] = [];\n\n constructor(container: HTMLElement, options?: LoadingIndicatorOptions) {\n this.container = container;\n this.options = {\n type: 'spinner',\n message: 'Loading...',\n showPercentage: true,\n overlayOpacity: 0.7,\n accentColor: '#00f2ff',\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n textColor: '#ffffff',\n size: 'medium',\n className: 'velo-plot-loading',\n autoHide: true,\n hideDelay: 200,\n ...options,\n };\n this.state.message = this.options.message;\n }\n\n /**\n * Show the loading indicator\n */\n show(message?: string): void {\n this.state.isLoading = true;\n this.state.progress = 0;\n this.state.startTime = performance.now();\n this.state.eta = null;\n this.progressHistory = [];\n \n if (message) {\n this.state.message = message;\n }\n\n this.createElement();\n this.render();\n }\n\n /**\n * Hide the loading indicator\n */\n hide(): void {\n if (!this.state.isLoading) return;\n this.state.isLoading = false;\n \n if (this.element) {\n this.element.style.opacity = '0';\n }\n\n if (this.options.autoHide) {\n setTimeout(() => {\n this.destroyElement();\n }, this.options.hideDelay);\n } else {\n this.destroyElement();\n }\n }\n\n /**\n * Update progress (0-100)\n */\n setProgress(progress: number, message?: string): void {\n const clampedProgress = Math.max(0, Math.min(100, progress));\n this.state.progress = clampedProgress;\n \n if (message) {\n this.state.message = message;\n }\n\n // Track progress for ETA\n this.progressHistory.push({\n time: performance.now(),\n progress: clampedProgress,\n });\n\n // Keep only recent history\n if (this.progressHistory.length > 10) {\n this.progressHistory.shift();\n }\n\n // Calculate ETA\n this.calculateEta();\n \n this.render();\n\n // Auto-complete\n if (clampedProgress >= 100 && this.options.autoHide) {\n this.hide();\n }\n }\n\n /**\n * Update message only\n */\n setMessage(message: string): void {\n this.state.message = message;\n this.render();\n }\n\n /**\n * Check if loading is in progress\n */\n isLoading(): boolean {\n return this.state.isLoading;\n }\n\n /**\n * Get current progress\n */\n getProgress(): number {\n return this.state.progress;\n }\n\n /**\n * Get current state\n */\n getState(): LoadingState {\n return { ...this.state };\n }\n\n /**\n * Destroy the indicator\n */\n destroy(): void {\n this.hide();\n this.destroyElement();\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private createElement(): void {\n if (this.element) return;\n\n this.element = document.createElement('div');\n this.element.className = this.options.className;\n \n // Apply overlay styles\n Object.assign(this.element.style, {\n position: 'absolute',\n top: '0',\n left: '0',\n right: '0',\n bottom: '0',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: this.options.backgroundColor,\n zIndex: '9998',\n transition: 'opacity 0.2s ease',\n });\n\n // Create inner content\n this.element.innerHTML = this.getInnerHtml();\n \n // Inject styles\n this.injectStyles();\n\n this.container.style.position = 'relative';\n this.container.appendChild(this.element);\n }\n\n private destroyElement(): void {\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n this.element = null;\n }\n\n private render(): void {\n if (!this.element) return;\n this.element.innerHTML = this.getInnerHtml();\n }\n\n private getInnerHtml(): string {\n const { type, accentColor, textColor, size, showPercentage } = this.options;\n const { progress, message, eta } = this.state;\n \n const sizeMap = { small: 24, medium: 40, large: 56 };\n const spinnerSize = sizeMap[size];\n const fontSize = size === 'small' ? 12 : size === 'large' ? 16 : 14;\n\n let content = '';\n\n switch (type) {\n case 'spinner':\n content = `\n <div class=\"velo-plot-loading-spinner\" style=\"\n width: ${spinnerSize}px;\n height: ${spinnerSize}px;\n border: 3px solid rgba(255,255,255,0.2);\n border-top-color: ${accentColor};\n border-radius: 50%;\n animation: velo-plot-spin 0.8s linear infinite;\n \"></div>\n `;\n break;\n\n case 'progress':\n content = `\n <div class=\"velo-plot-loading-progress\" style=\"\n width: 200px;\n height: 8px;\n background: rgba(255,255,255,0.2);\n border-radius: 4px;\n overflow: hidden;\n \">\n <div style=\"\n width: ${progress}%;\n height: 100%;\n background: ${accentColor};\n transition: width 0.2s ease;\n \"></div>\n </div>\n ${showPercentage ? `\n <div style=\"\n color: ${textColor};\n font-size: ${fontSize}px;\n margin-top: 8px;\n font-family: system-ui, sans-serif;\n \">${Math.round(progress)}%</div>\n ` : ''}\n `;\n break;\n\n case 'skeleton':\n content = `\n <div class=\"velo-plot-loading-skeleton\" style=\"\n width: 80%;\n max-width: 300px;\n \">\n <div class=\"velo-plot-skeleton-line\" style=\"height: 20px; margin-bottom: 8px;\"></div>\n <div class=\"velo-plot-skeleton-line\" style=\"height: 16px; width: 60%; margin-bottom: 8px;\"></div>\n <div class=\"velo-plot-skeleton-line\" style=\"height: 40px;\"></div>\n </div>\n `;\n break;\n\n case 'pulse':\n content = `\n <div class=\"velo-plot-loading-pulse\" style=\"\n width: ${spinnerSize}px;\n height: ${spinnerSize}px;\n background: ${accentColor};\n border-radius: 50%;\n animation: velo-plot-pulse 1.2s ease-in-out infinite;\n \"></div>\n `;\n break;\n }\n\n // Add message\n if (message) {\n content += `\n <div style=\"\n color: ${textColor};\n font-size: ${fontSize}px;\n margin-top: 12px;\n font-family: system-ui, sans-serif;\n \">${message}</div>\n `;\n }\n\n // Add ETA if available\n if (eta !== null && eta > 0 && type === 'progress') {\n content += `\n <div style=\"\n color: rgba(255,255,255,0.6);\n font-size: ${fontSize - 2}px;\n margin-top: 4px;\n font-family: system-ui, sans-serif;\n \">~${this.formatTime(eta)} remaining</div>\n `;\n }\n\n return content;\n }\n\n private injectStyles(): void {\n const styleId = 'velo-plot-loading-styles';\n if (document.getElementById(styleId)) return;\n\n const style = document.createElement('style');\n style.id = styleId;\n style.textContent = `\n @keyframes velo-plot-spin {\n to { transform: rotate(360deg); }\n }\n \n @keyframes velo-plot-pulse {\n 0%, 100% { transform: scale(1); opacity: 1; }\n 50% { transform: scale(1.2); opacity: 0.7; }\n }\n \n @keyframes velo-plot-skeleton-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n }\n \n .velo-plot-skeleton-line {\n background: linear-gradient(\n 90deg,\n rgba(255,255,255,0.1) 25%,\n rgba(255,255,255,0.2) 50%,\n rgba(255,255,255,0.1) 75%\n );\n background-size: 200% 100%;\n animation: velo-plot-skeleton-shimmer 1.5s infinite;\n border-radius: 4px;\n }\n `;\n document.head.appendChild(style);\n }\n\n private calculateEta(): void {\n if (this.progressHistory.length < 2) {\n this.state.eta = null;\n return;\n }\n\n const first = this.progressHistory[0];\n const last = this.progressHistory[this.progressHistory.length - 1];\n \n const progressDelta = last.progress - first.progress;\n const timeDelta = last.time - first.time;\n\n if (progressDelta <= 0) {\n this.state.eta = null;\n return;\n }\n\n const remainingProgress = 100 - last.progress;\n const rate = progressDelta / timeDelta;\n this.state.eta = remainingProgress / rate;\n }\n\n private formatTime(ms: number): string {\n const seconds = Math.ceil(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n return `${minutes}m ${remainingSeconds}s`;\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a loading indicator for a container\n */\nexport function createLoadingIndicator(\n container: HTMLElement,\n options?: LoadingIndicatorOptions\n): LoadingIndicator {\n return new LoadingIndicator(container, options);\n}\n\n/**\n * Show loading with a simple spinner\n */\nexport function showLoading(\n container: HTMLElement,\n message?: string\n): LoadingIndicator {\n const indicator = new LoadingIndicator(container, { message });\n indicator.show();\n return indicator;\n}\n\n/**\n * Show progress loading\n */\nexport function showProgress(\n container: HTMLElement,\n message?: string\n): LoadingIndicator {\n const indicator = new LoadingIndicator(container, {\n type: 'progress',\n message,\n });\n indicator.show();\n return indicator;\n}\n","/**\n * SciPlot Engine - Loading Indicator Plugin\n * \n * Provides customizable loading and progress indicators.\n * \n * @module plugins/loading\n */\n\nimport { LoadingIndicator } from \"../../core/loading\";\nimport type { LoadingIndicatorOptions } from \"../../core/loading\";\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\n\nexport interface PluginLoadingConfig extends Partial<LoadingIndicatorOptions> {\n /** Auto-show on heavy data operations */\n autoShow?: boolean;\n}\n\nconst manifestLoading: PluginManifest = {\n name: \"velo-plot-loading\",\n version: \"1.0.0\",\n description: \"Loading and progress indicators for velo-plot\",\n provides: [\"ui\"],\n tags: [\"loading\", \"progress\", \"ui\", \"ux\"],\n};\n\n/**\n * SciPlot Loading Plugin\n * \n * Adds sleek loading indicators and progress trackers to the chart.\n */\nexport function PluginLoading(_config: PluginLoadingConfig = {}): ChartPlugin<PluginLoadingConfig> {\n let indicator: LoadingIndicator | null = null;\n\n return {\n manifest: manifestLoading,\n\n onInit(ctx: PluginContext) { \n // Create the indicator using the container from the UI context\n indicator = new LoadingIndicator(ctx.ui.container, {\n ..._config,\n // Inherit theme colors if not explicitly provided\n accentColor: _config.accentColor || (ctx.ui.theme.isDark ? '#00f2ff' : '#00b4d8'),\n });\n\n // If autoShow is enabled (or by default during init), show it\n if (_config.autoShow !== false) {\n indicator.show(_config.message || 'Initializing Chart...');\n }\n\n // Optional: Auto-hide on first successful render WITH data\n if (_config.autoHide !== false) {\n const off = ctx.events.on('render', () => {\n const hasData = ctx.data.getAllSeries().some(s => s.getPointCount() > 0);\n if (hasData) {\n indicator?.hide();\n off();\n }\n });\n }\n },\n\n onDestroy(_ctx: PluginContext) {\n indicator?.destroy();\n indicator = null;\n },\n\n api: {\n show(message?: string) {\n indicator?.show(message);\n },\n hide() {\n indicator?.hide();\n },\n setProgress(progress: number, message?: string) {\n indicator?.setProgress(progress, message);\n },\n setMessage(message: string) {\n indicator?.setMessage(message);\n },\n getIndicator: () => indicator\n }\n };\n}\n\nexport { LoadingIndicator };\nexport default PluginLoading;\n"],"names":["LoadingIndicator","container","options","__publicField","message","progress","clampedProgress","type","accentColor","textColor","size","showPercentage","eta","spinnerSize","fontSize","content","styleId","style","first","last","progressDelta","timeDelta","remainingProgress","rate","ms","seconds","minutes","remainingSeconds","createLoadingIndicator","showLoading","indicator","showProgress","manifestLoading","PluginLoading","_config","ctx","off","s","_ctx"],"mappings":"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"}
1
+ {"version":3,"file":"index-qhscKTDy.js","sources":["../src/core/loading/index.ts","../src/plugins/loading/index.ts"],"sourcesContent":["/**\n * Velo Plot - Loading Indicator Module\n * \n * Provides visual loading/progress indicators for chart operations.\n * Supports progress bars, spinners, and skeleton placeholders.\n * \n * @module loading\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport type LoadingIndicatorType = 'spinner' | 'progress' | 'skeleton' | 'pulse';\n\nexport interface LoadingIndicatorOptions {\n /** Indicator type (default: 'spinner') */\n type?: LoadingIndicatorType;\n /** Message to display (default: 'Loading...') */\n message?: string;\n /** Show percentage for progress type (default: true) */\n showPercentage?: boolean;\n /** Background overlay opacity (0-1, default: 0.7) */\n overlayOpacity?: number;\n /** Accent color for spinner/progress (default: '#00f2ff') */\n accentColor?: string;\n /** Background color (default: 'rgba(0,0,0,0.7)') */\n backgroundColor?: string;\n /** Text color (default: '#ffffff') */\n textColor?: string;\n /** Size: 'small', 'medium', 'large' (default: 'medium') */\n size?: 'small' | 'medium' | 'large';\n /** Custom CSS class */\n className?: string;\n /** Auto-hide after completion (default: true) */\n autoHide?: boolean;\n /** Hide delay in ms after completion (default: 300) */\n hideDelay?: number;\n}\n\nexport interface LoadingState {\n /** Whether loading is in progress */\n isLoading: boolean;\n /** Progress value (0-100) */\n progress: number;\n /** Current message */\n message: string;\n /** Start time of loading */\n startTime: number | null;\n /** Estimated time remaining in ms */\n eta: number | null;\n}\n\n// ============================================\n// Loading Indicator Implementation\n// ============================================\n\nexport class LoadingIndicator {\n private container: HTMLElement;\n private element: HTMLDivElement | null = null;\n private options: Required<LoadingIndicatorOptions>;\n private state: LoadingState = {\n isLoading: false,\n progress: 0,\n message: '',\n startTime: null,\n eta: null,\n };\n\n // For ETA calculation\n private progressHistory: { time: number; progress: number }[] = [];\n\n constructor(container: HTMLElement, options?: LoadingIndicatorOptions) {\n this.container = container;\n this.options = {\n type: 'spinner',\n message: 'Loading...',\n showPercentage: true,\n overlayOpacity: 0.7,\n accentColor: '#00f2ff',\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n textColor: '#ffffff',\n size: 'medium',\n className: 'velo-plot-loading',\n autoHide: true,\n hideDelay: 200,\n ...options,\n };\n this.state.message = this.options.message;\n }\n\n /**\n * Show the loading indicator\n */\n show(message?: string): void {\n this.state.isLoading = true;\n this.state.progress = 0;\n this.state.startTime = performance.now();\n this.state.eta = null;\n this.progressHistory = [];\n \n if (message) {\n this.state.message = message;\n }\n\n this.createElement();\n this.render();\n }\n\n /**\n * Hide the loading indicator\n */\n hide(): void {\n if (!this.state.isLoading) return;\n this.state.isLoading = false;\n \n if (this.element) {\n this.element.style.opacity = '0';\n }\n\n if (this.options.autoHide) {\n setTimeout(() => {\n this.destroyElement();\n }, this.options.hideDelay);\n } else {\n this.destroyElement();\n }\n }\n\n /**\n * Update progress (0-100)\n */\n setProgress(progress: number, message?: string): void {\n const clampedProgress = Math.max(0, Math.min(100, progress));\n this.state.progress = clampedProgress;\n \n if (message) {\n this.state.message = message;\n }\n\n // Track progress for ETA\n this.progressHistory.push({\n time: performance.now(),\n progress: clampedProgress,\n });\n\n // Keep only recent history\n if (this.progressHistory.length > 10) {\n this.progressHistory.shift();\n }\n\n // Calculate ETA\n this.calculateEta();\n \n this.render();\n\n // Auto-complete\n if (clampedProgress >= 100 && this.options.autoHide) {\n this.hide();\n }\n }\n\n /**\n * Update message only\n */\n setMessage(message: string): void {\n this.state.message = message;\n this.render();\n }\n\n /**\n * Check if loading is in progress\n */\n isLoading(): boolean {\n return this.state.isLoading;\n }\n\n /**\n * Get current progress\n */\n getProgress(): number {\n return this.state.progress;\n }\n\n /**\n * Get current state\n */\n getState(): LoadingState {\n return { ...this.state };\n }\n\n /**\n * Destroy the indicator\n */\n destroy(): void {\n this.hide();\n this.destroyElement();\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private createElement(): void {\n if (this.element) return;\n\n this.element = document.createElement('div');\n this.element.className = this.options.className;\n \n // Apply overlay styles\n Object.assign(this.element.style, {\n position: 'absolute',\n top: '0',\n left: '0',\n right: '0',\n bottom: '0',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: this.options.backgroundColor,\n zIndex: '9998',\n transition: 'opacity 0.2s ease',\n });\n\n // Create inner content\n this.element.innerHTML = this.getInnerHtml();\n \n // Inject styles\n this.injectStyles();\n\n this.container.style.position = 'relative';\n this.container.appendChild(this.element);\n }\n\n private destroyElement(): void {\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n this.element = null;\n }\n\n private render(): void {\n if (!this.element) return;\n this.element.innerHTML = this.getInnerHtml();\n }\n\n private getInnerHtml(): string {\n const { type, accentColor, textColor, size, showPercentage } = this.options;\n const { progress, message, eta } = this.state;\n \n const sizeMap = { small: 24, medium: 40, large: 56 };\n const spinnerSize = sizeMap[size];\n const fontSize = size === 'small' ? 12 : size === 'large' ? 16 : 14;\n\n let content = '';\n\n switch (type) {\n case 'spinner':\n content = `\n <div class=\"velo-plot-loading-spinner\" style=\"\n width: ${spinnerSize}px;\n height: ${spinnerSize}px;\n border: 3px solid rgba(255,255,255,0.2);\n border-top-color: ${accentColor};\n border-radius: 50%;\n animation: velo-plot-spin 0.8s linear infinite;\n \"></div>\n `;\n break;\n\n case 'progress':\n content = `\n <div class=\"velo-plot-loading-progress\" style=\"\n width: 200px;\n height: 8px;\n background: rgba(255,255,255,0.2);\n border-radius: 4px;\n overflow: hidden;\n \">\n <div style=\"\n width: ${progress}%;\n height: 100%;\n background: ${accentColor};\n transition: width 0.2s ease;\n \"></div>\n </div>\n ${showPercentage ? `\n <div style=\"\n color: ${textColor};\n font-size: ${fontSize}px;\n margin-top: 8px;\n font-family: system-ui, sans-serif;\n \">${Math.round(progress)}%</div>\n ` : ''}\n `;\n break;\n\n case 'skeleton':\n content = `\n <div class=\"velo-plot-loading-skeleton\" style=\"\n width: 80%;\n max-width: 300px;\n \">\n <div class=\"velo-plot-skeleton-line\" style=\"height: 20px; margin-bottom: 8px;\"></div>\n <div class=\"velo-plot-skeleton-line\" style=\"height: 16px; width: 60%; margin-bottom: 8px;\"></div>\n <div class=\"velo-plot-skeleton-line\" style=\"height: 40px;\"></div>\n </div>\n `;\n break;\n\n case 'pulse':\n content = `\n <div class=\"velo-plot-loading-pulse\" style=\"\n width: ${spinnerSize}px;\n height: ${spinnerSize}px;\n background: ${accentColor};\n border-radius: 50%;\n animation: velo-plot-pulse 1.2s ease-in-out infinite;\n \"></div>\n `;\n break;\n }\n\n // Add message\n if (message) {\n content += `\n <div style=\"\n color: ${textColor};\n font-size: ${fontSize}px;\n margin-top: 12px;\n font-family: system-ui, sans-serif;\n \">${message}</div>\n `;\n }\n\n // Add ETA if available\n if (eta !== null && eta > 0 && type === 'progress') {\n content += `\n <div style=\"\n color: rgba(255,255,255,0.6);\n font-size: ${fontSize - 2}px;\n margin-top: 4px;\n font-family: system-ui, sans-serif;\n \">~${this.formatTime(eta)} remaining</div>\n `;\n }\n\n return content;\n }\n\n private injectStyles(): void {\n const styleId = 'velo-plot-loading-styles';\n if (document.getElementById(styleId)) return;\n\n const style = document.createElement('style');\n style.id = styleId;\n style.textContent = `\n @keyframes velo-plot-spin {\n to { transform: rotate(360deg); }\n }\n \n @keyframes velo-plot-pulse {\n 0%, 100% { transform: scale(1); opacity: 1; }\n 50% { transform: scale(1.2); opacity: 0.7; }\n }\n \n @keyframes velo-plot-skeleton-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n }\n \n .velo-plot-skeleton-line {\n background: linear-gradient(\n 90deg,\n rgba(255,255,255,0.1) 25%,\n rgba(255,255,255,0.2) 50%,\n rgba(255,255,255,0.1) 75%\n );\n background-size: 200% 100%;\n animation: velo-plot-skeleton-shimmer 1.5s infinite;\n border-radius: 4px;\n }\n `;\n document.head.appendChild(style);\n }\n\n private calculateEta(): void {\n if (this.progressHistory.length < 2) {\n this.state.eta = null;\n return;\n }\n\n const first = this.progressHistory[0];\n const last = this.progressHistory[this.progressHistory.length - 1];\n \n const progressDelta = last.progress - first.progress;\n const timeDelta = last.time - first.time;\n\n if (progressDelta <= 0) {\n this.state.eta = null;\n return;\n }\n\n const remainingProgress = 100 - last.progress;\n const rate = progressDelta / timeDelta;\n this.state.eta = remainingProgress / rate;\n }\n\n private formatTime(ms: number): string {\n const seconds = Math.ceil(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n return `${minutes}m ${remainingSeconds}s`;\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a loading indicator for a container\n */\nexport function createLoadingIndicator(\n container: HTMLElement,\n options?: LoadingIndicatorOptions\n): LoadingIndicator {\n return new LoadingIndicator(container, options);\n}\n\n/**\n * Show loading with a simple spinner\n */\nexport function showLoading(\n container: HTMLElement,\n message?: string\n): LoadingIndicator {\n const indicator = new LoadingIndicator(container, { message });\n indicator.show();\n return indicator;\n}\n\n/**\n * Show progress loading\n */\nexport function showProgress(\n container: HTMLElement,\n message?: string\n): LoadingIndicator {\n const indicator = new LoadingIndicator(container, {\n type: 'progress',\n message,\n });\n indicator.show();\n return indicator;\n}\n","/**\n * VeloPlot Engine - Loading Indicator Plugin\n * \n * Provides customizable loading and progress indicators.\n * \n * @module plugins/loading\n */\n\nimport { LoadingIndicator } from \"../../core/loading\";\nimport type { LoadingIndicatorOptions } from \"../../core/loading\";\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\n\nexport interface PluginLoadingConfig extends Partial<LoadingIndicatorOptions> {\n /** Auto-show on heavy data operations */\n autoShow?: boolean;\n}\n\nconst manifestLoading: PluginManifest = {\n name: \"velo-plot-loading\",\n version: \"1.0.0\",\n description: \"Loading and progress indicators for velo-plot\",\n provides: [\"ui\"],\n tags: [\"loading\", \"progress\", \"ui\", \"ux\"],\n};\n\n/**\n * VeloPlot Loading Plugin\n * \n * Adds sleek loading indicators and progress trackers to the chart.\n */\nexport function PluginLoading(_config: PluginLoadingConfig = {}): ChartPlugin<PluginLoadingConfig> {\n let indicator: LoadingIndicator | null = null;\n\n return {\n manifest: manifestLoading,\n\n onInit(ctx: PluginContext) { \n // Create the indicator using the container from the UI context\n indicator = new LoadingIndicator(ctx.ui.container, {\n ..._config,\n // Inherit theme colors if not explicitly provided\n accentColor: _config.accentColor || (ctx.ui.theme.isDark ? '#00f2ff' : '#00b4d8'),\n });\n\n // If autoShow is enabled (or by default during init), show it\n if (_config.autoShow !== false) {\n indicator.show(_config.message || 'Initializing Chart...');\n }\n\n // Optional: Auto-hide on first successful render WITH data\n if (_config.autoHide !== false) {\n const off = ctx.events.on('render', () => {\n const hasData = ctx.data.getAllSeries().some(s => s.getPointCount() > 0);\n if (hasData) {\n indicator?.hide();\n off();\n }\n });\n }\n },\n\n onDestroy(_ctx: PluginContext) {\n indicator?.destroy();\n indicator = null;\n },\n\n api: {\n show(message?: string) {\n indicator?.show(message);\n },\n hide() {\n indicator?.hide();\n },\n setProgress(progress: number, message?: string) {\n indicator?.setProgress(progress, message);\n },\n setMessage(message: string) {\n indicator?.setMessage(message);\n },\n getIndicator: () => indicator\n }\n };\n}\n\nexport default PluginLoading;\n"],"names":["LoadingIndicator","container","options","__publicField","message","progress","clampedProgress","type","accentColor","textColor","size","showPercentage","eta","spinnerSize","fontSize","content","styleId","style","first","last","progressDelta","timeDelta","remainingProgress","rate","ms","seconds","minutes","remainingSeconds","createLoadingIndicator","showLoading","indicator","showProgress","manifestLoading","PluginLoading","_config","ctx","off","s","_ctx"],"mappings":"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"}
@@ -1,8 +1,7 @@
1
1
  /**
2
- * Sci Plot - Core Bundle
2
+ * Velo Plot - Core Bundle
3
3
  *
4
4
  * Minimal bundle containing only the essential features for 2D charts.
5
- * Achieve ~60KB gzipped by excluding optional plugins.
6
5
  */
7
6
  export { createChart } from './core/Chart';
8
7
  export { Series } from './core/Series';
@@ -11,10 +10,13 @@ export type { Chart, ChartOptions, ExportOptions } from './core/Chart';
11
10
  export type { AxisOptions, SeriesOptions, SeriesData, SeriesStyle, ZoomOptions, Point, Bounds, Range, ScaleType, SeriesType, } from './types';
12
11
  export { LinearScale, LogScale, createScale } from './scales';
13
12
  export type { Scale } from './scales';
14
- export { NativeWebGLRenderer, parseColor, createRenderer, createNativeRenderer, } from './renderer';
15
- export type { IWebGLRenderer, SeriesRenderData, RenderOptions } from './renderer';
13
+ export { NativeWebGLRenderer, parseColor, } from './renderer/NativeWebGLRenderer';
14
+ export { createRenderer, createNativeRenderer, } from './renderer/RendererInterface';
15
+ export type { IWebGLRenderer, SeriesRenderData, RenderOptions, } from './renderer/RendererInterface';
16
16
  export { DARK_THEME, LIGHT_THEME, DEFAULT_THEME, createTheme, getThemeByName, } from './theme';
17
17
  export type { ChartTheme, GridTheme, AxisTheme } from './theme';
18
- export { AnimationEngine, easings, DEFAULT_ANIMATION_CONFIG, getSharedAnimationEngine, } from './core/animation';
19
- export { createPluginContext, PluginManagerImpl, getPluginRegistry, registerPlugin, definePlugin, createPlugin, createConfigurablePlugin, } from './plugins';
20
- export type { PluginManifest, PluginContext, ChartPlugin, PluginFactory, PluginManager, } from './plugins';
18
+ export { createPluginContext } from './plugins/PluginContext';
19
+ export { PluginManagerImpl } from './plugins/PluginManager';
20
+ export { getPluginRegistry, registerPlugin, definePlugin, } from './plugins/PluginRegistry';
21
+ export { createPlugin, createConfigurablePlugin } from './plugins/createPlugin';
22
+ export type { PluginManifest, PluginContext, ChartPlugin, PluginFactory, PluginManager, } from './plugins/types';
package/dist/index.d.ts CHANGED
@@ -1,17 +1,4 @@
1
- /**
2
- * Sci Plot - High-Performance Scientific Charting
3
- *
4
- * A WebGL-based charting engine designed for scientific data visualization
5
- * and high-performance rendering of large datasets.
6
- *
7
- * Features:
8
- * - 10⁵–10⁶ points at 60 FPS
9
- * - Zoom/pan via GPU uniforms (no buffer recreation)
10
- * - Scientific precision with Float32/Float64 arrays
11
- * - Data analysis utilities (peak detection, cycle detection, etc.)
12
- *
13
- * @packageDocumentation
14
- */
1
+
15
2
  export { createChart } from './core/Chart';
16
3
  export { Series } from './core/Series';
17
4
  export { EventEmitter } from './core/EventEmitter';
@@ -38,7 +25,7 @@ export { WorkerPool, nextTaskId } from './workers/pool';
38
25
  export type { WorkerPoolOptions } from './workers/pool';
39
26
  export { formatWithPrefix, formatValue, formatScientific, getBestPrefix, detectCycles, generateCycleColors, detectPeaks, validateData, calculateStats, movingAverage, downsampleLTTB, subtractBaseline, integrate, derivative, cumulativeIntegral, calculateR2, solveLinearSystem, fft, ifft, analyzeSpectrum, powerSpectrum, dominantFrequency, analyzeComplexSpectrum, fftFromComplexInput, hanningWindow, hammingWindow, blackmanWindow, nextPowerOf2, complexToArrays, arraysToComplex, ifftFromArrays, ifftComplex, getPositiveFrequencies, lowPassFilter, highPassFilter, bandPassFilter, bandStopFilter, butterworth, exponentialMovingAverage, gaussianSmooth, savitzkyGolay, medianFilter, singleFrequencyFilter, crossCorrelation, autoCorrelation, detectAnomalies, trapezoidalIntegration, simpsonsIntegration, tTest, generateContours, joinSegments, type ContourLine, type ContourPoint, type ContourLabel, type ContourOptions, type CycleInfo, type Peak, type PrefixInfo, type ValidationResult, type DataStats, type FFTResult, type ComplexFFTResult, type PowerSpectrumResult, type FilterOptions, type ButterworthOptions, type SingleFrequencyFilterOptions, } from './plugins/analysis';
40
27
  export { createWebSocketStream, connectStreamToChart, createMessageParser, createMockStream, type WebSocketStream, type WebSocketStreamConfig, type DataPoint, type StreamStats, type WebSocketState, } from './streaming';
41
- export { SciPlot, useSciPlot, type SciPlotProps, type SciPlotRef, type SciPlotSeries, type UseSciPlotOptions, type UseSciPlotReturn, } from './react';
28
+ export { VeloPlot, StackedPlot, useVeloPlot, useStackedPlot, useIndicator, useChartSync, useChartGroup, SciPlot, SciChart, useSciPlot, useSciChart, type VeloPlotProps, type VeloPlotRef, type VeloPlotSeries, type StackedPlotProps, type StackedPlotRef, type UseVeloPlotOptions, type UseVeloPlotReturn, type UseStackedPlotOptions, type UseStackedPlotReturn, type UseIndicatorReturn, type UseChartSyncReturn, type SciPlotProps, type SciPlotRef, type SciPlotSeries, type SciChartProps, type SciChartRef, type SciChartSeries, type UseSciPlotOptions, type UseSciPlotReturn, type UseSciChartOptions, type UseSciChartReturn, } from './react';
42
29
  export { WebGPUBackend, WebGLBackend, GpuRenderer, createGpuRenderer, SeriesAdapter, parseColorToRGBA, PipelineCache, BaseBufferStore, BaseTextureStore, GpuBenchmark, GpuCompute, } from './gpu';
43
30
  export type { GpuBackendType, RGBA, GpuViewport, GpuBackend, BufferId, TextureId, FrameUniforms, DrawKind, DrawCall, DrawList, PointSymbol, SeriesData as GpuSeriesData, Bounds as GpuBounds, GpuRenderOptions, GpuRendererOptions, BackendPreference, WebGPUBackendOptions, BenchmarkResult, BenchmarkOptions, DataStats as GpuDataStats, DataBounds as GpuDataBounds, Peak as GpuPeak, GpuComputeOptions, } from './gpu';
44
31
  export { setGlobalLocale, getGlobalLocale, getLocale, registerLocale, createLocaleFormatter, LOCALE_EN_US, LOCALE_ES_ES, LOCALE_DE_DE, LOCALE_FR_FR, LOCALE_PT_BR, LOCALE_ZH_CN, LOCALE_JA_JP, type LocaleConfig, type LocaleFormatter, } from './core/locale';