@tetrascience-npm/tetrascience-react-ui 0.7.0-beta.108.1 → 0.7.0-beta.128.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/README.md +2 -2
  2. package/dist/components/ai/chain-of-thought.cjs +1 -1
  3. package/dist/components/ai/chain-of-thought.cjs.map +1 -1
  4. package/dist/components/ai/chain-of-thought.js +1 -1
  5. package/dist/components/ai/chain-of-thought.js.map +1 -1
  6. package/dist/components/ai/confirmation.cjs +1 -1
  7. package/dist/components/ai/confirmation.cjs.map +1 -1
  8. package/dist/components/ai/confirmation.js +1 -1
  9. package/dist/components/ai/confirmation.js.map +1 -1
  10. package/dist/components/ai/context.cjs +1 -1
  11. package/dist/components/ai/context.cjs.map +1 -1
  12. package/dist/components/ai/context.js +36 -35
  13. package/dist/components/ai/context.js.map +1 -1
  14. package/dist/components/ai/message.cjs +1 -1
  15. package/dist/components/ai/message.cjs.map +1 -1
  16. package/dist/components/ai/message.js +68 -68
  17. package/dist/components/ai/message.js.map +1 -1
  18. package/dist/components/ai/prompt-input.cjs +1 -1
  19. package/dist/components/ai/prompt-input.cjs.map +1 -1
  20. package/dist/components/ai/prompt-input.js +4 -2
  21. package/dist/components/ai/prompt-input.js.map +1 -1
  22. package/dist/components/ai/queue.cjs +1 -1
  23. package/dist/components/ai/queue.cjs.map +1 -1
  24. package/dist/components/ai/queue.js +9 -9
  25. package/dist/components/ai/queue.js.map +1 -1
  26. package/dist/components/ai/reasoning.cjs +1 -1
  27. package/dist/components/ai/reasoning.cjs.map +1 -1
  28. package/dist/components/ai/reasoning.js +67 -67
  29. package/dist/components/ai/reasoning.js.map +1 -1
  30. package/dist/components/ai/stream-status.cjs +1 -1
  31. package/dist/components/ai/stream-status.cjs.map +1 -1
  32. package/dist/components/ai/stream-status.js +41 -39
  33. package/dist/components/ai/stream-status.js.map +1 -1
  34. package/dist/components/ai/streamdown-code-plugin.cjs +2 -0
  35. package/dist/components/ai/streamdown-code-plugin.cjs.map +1 -0
  36. package/dist/components/ai/streamdown-code-plugin.js +42 -0
  37. package/dist/components/ai/streamdown-code-plugin.js.map +1 -0
  38. package/dist/components/ai/streamdown-plugins.cjs +2 -0
  39. package/dist/components/ai/streamdown-plugins.cjs.map +1 -0
  40. package/dist/components/ai/streamdown-plugins.js +14 -0
  41. package/dist/components/ai/streamdown-plugins.js.map +1 -0
  42. package/dist/components/ai/task.cjs +1 -1
  43. package/dist/components/ai/task.cjs.map +1 -1
  44. package/dist/components/ai/task.js +18 -11
  45. package/dist/components/ai/task.js.map +1 -1
  46. package/dist/components/ai/tool.cjs +1 -1
  47. package/dist/components/ai/tool.cjs.map +1 -1
  48. package/dist/components/ai/tool.js +51 -55
  49. package/dist/components/ai/tool.js.map +1 -1
  50. package/dist/components/ai/use-streamdown-plugins.cjs +2 -0
  51. package/dist/components/ai/use-streamdown-plugins.cjs.map +1 -0
  52. package/dist/components/ai/use-streamdown-plugins.js +25 -0
  53. package/dist/components/ai/use-streamdown-plugins.js.map +1 -0
  54. package/dist/components/charts/AreaPlot/AreaPlot.cjs +2 -0
  55. package/dist/components/charts/AreaPlot/AreaPlot.cjs.map +1 -0
  56. package/dist/components/charts/AreaPlot/AreaPlot.js +270 -0
  57. package/dist/components/charts/AreaPlot/AreaPlot.js.map +1 -0
  58. package/dist/components/charts/BarChart/BarChart.cjs +2 -0
  59. package/dist/components/charts/BarChart/BarChart.cjs.map +1 -0
  60. package/dist/components/charts/BarChart/BarChart.js +219 -0
  61. package/dist/components/charts/BarChart/BarChart.js.map +1 -0
  62. package/dist/components/charts/BoxPlot/BoxPlot.cjs +2 -0
  63. package/dist/components/charts/BoxPlot/BoxPlot.cjs.map +1 -0
  64. package/dist/components/charts/{Boxplot/Boxplot.js → BoxPlot/BoxPlot.js} +78 -79
  65. package/dist/components/charts/BoxPlot/BoxPlot.js.map +1 -0
  66. package/dist/components/charts/ChartTooltip/ChartTooltip.cjs +1 -1
  67. package/dist/components/charts/ChartTooltip/ChartTooltip.cjs.map +1 -1
  68. package/dist/components/charts/ChartTooltip/ChartTooltip.js +22 -22
  69. package/dist/components/charts/ChartTooltip/ChartTooltip.js.map +1 -1
  70. package/dist/components/charts/Chromatogram/Chromatogram.cjs +1 -1
  71. package/dist/components/charts/Chromatogram/Chromatogram.cjs.map +1 -1
  72. package/dist/components/charts/Chromatogram/Chromatogram.js +232 -170
  73. package/dist/components/charts/Chromatogram/Chromatogram.js.map +1 -1
  74. package/dist/components/charts/Chromatogram/annotations.cjs +2 -0
  75. package/dist/components/charts/Chromatogram/annotations.cjs.map +1 -0
  76. package/dist/components/charts/Chromatogram/annotations.js +137 -0
  77. package/dist/components/charts/Chromatogram/annotations.js.map +1 -0
  78. package/dist/components/charts/Chromatogram/boundaryMarkers.cjs.map +1 -0
  79. package/dist/components/charts/Chromatogram/boundaryMarkers.js.map +1 -0
  80. package/dist/components/charts/Chromatogram/constants.cjs.map +1 -0
  81. package/dist/components/charts/Chromatogram/constants.js.map +1 -0
  82. package/dist/components/charts/Chromatogram/dataProcessing.cjs.map +1 -0
  83. package/dist/components/charts/Chromatogram/dataProcessing.js.map +1 -0
  84. package/dist/components/charts/Chromatogram/peakDetection.cjs.map +1 -0
  85. package/dist/components/charts/Chromatogram/peakDetection.js.map +1 -0
  86. package/dist/components/charts/Chromatogram/plotBuilder.cjs +2 -0
  87. package/dist/components/charts/Chromatogram/plotBuilder.cjs.map +1 -0
  88. package/dist/components/charts/Chromatogram/plotBuilder.js +216 -0
  89. package/dist/components/charts/Chromatogram/plotBuilder.js.map +1 -0
  90. package/dist/components/charts/Chromatogram/regionOverlays.cjs.map +1 -0
  91. package/dist/components/charts/Chromatogram/regionOverlays.js.map +1 -0
  92. package/dist/components/charts/Electropherogram/Electropherogram.cjs +2 -0
  93. package/dist/components/charts/Electropherogram/Electropherogram.cjs.map +1 -0
  94. package/dist/components/charts/Electropherogram/Electropherogram.js +180 -0
  95. package/dist/components/charts/Electropherogram/Electropherogram.js.map +1 -0
  96. package/dist/components/charts/Histogram/Histogram.cjs +1 -1
  97. package/dist/components/charts/Histogram/Histogram.cjs.map +1 -1
  98. package/dist/components/charts/Histogram/Histogram.js +107 -108
  99. package/dist/components/charts/Histogram/Histogram.js.map +1 -1
  100. package/dist/components/charts/LinePlot/LinePlot.cjs +2 -0
  101. package/dist/components/charts/LinePlot/LinePlot.cjs.map +1 -0
  102. package/dist/components/charts/LinePlot/LinePlot.js +224 -0
  103. package/dist/components/charts/LinePlot/LinePlot.js.map +1 -0
  104. package/dist/components/charts/PieChart/PieChart.cjs +1 -1
  105. package/dist/components/charts/PieChart/PieChart.cjs.map +1 -1
  106. package/dist/components/charts/PieChart/PieChart.js +62 -61
  107. package/dist/components/charts/PieChart/PieChart.js.map +1 -1
  108. package/dist/components/charts/PlateMap/PlateMap.cjs +1 -1
  109. package/dist/components/charts/PlateMap/PlateMap.cjs.map +1 -1
  110. package/dist/components/charts/PlateMap/PlateMap.js +246 -242
  111. package/dist/components/charts/PlateMap/PlateMap.js.map +1 -1
  112. package/dist/components/charts/ScatterPlot/ScatterPlot.cjs +2 -0
  113. package/dist/components/charts/ScatterPlot/ScatterPlot.cjs.map +1 -0
  114. package/dist/components/charts/ScatterPlot/ScatterPlot.js +252 -0
  115. package/dist/components/charts/ScatterPlot/ScatterPlot.js.map +1 -0
  116. package/dist/components/charts/ScatterPlotInteractive/ScatterPlotInteractive.cjs +2 -0
  117. package/dist/components/charts/ScatterPlotInteractive/ScatterPlotInteractive.cjs.map +1 -0
  118. package/dist/components/charts/ScatterPlotInteractive/ScatterPlotInteractive.js +215 -0
  119. package/dist/components/charts/ScatterPlotInteractive/ScatterPlotInteractive.js.map +1 -0
  120. package/dist/components/charts/ScatterPlotInteractive/constants.cjs +2 -0
  121. package/dist/components/charts/ScatterPlotInteractive/constants.cjs.map +1 -0
  122. package/dist/components/charts/ScatterPlotInteractive/constants.js +38 -0
  123. package/dist/components/charts/ScatterPlotInteractive/constants.js.map +1 -0
  124. package/dist/components/charts/ScatterPlotInteractive/utils.cjs +2 -0
  125. package/dist/components/charts/ScatterPlotInteractive/utils.cjs.map +1 -0
  126. package/dist/components/charts/ScatterPlotInteractive/utils.js +261 -0
  127. package/dist/components/charts/ScatterPlotInteractive/utils.js.map +1 -0
  128. package/dist/components/charts/StackedChromatogram/StackedChromatogram.cjs +2 -0
  129. package/dist/components/charts/StackedChromatogram/StackedChromatogram.cjs.map +1 -0
  130. package/dist/components/charts/StackedChromatogram/StackedChromatogram.js +40 -0
  131. package/dist/components/charts/StackedChromatogram/StackedChromatogram.js.map +1 -0
  132. package/dist/components/charts/StackedChromatogram/transforms.cjs.map +1 -0
  133. package/dist/components/charts/StackedChromatogram/transforms.js.map +1 -0
  134. package/dist/components/charts/plotly-loader.cjs +2 -0
  135. package/dist/components/charts/plotly-loader.cjs.map +1 -0
  136. package/dist/components/charts/plotly-loader.js +22 -0
  137. package/dist/components/charts/plotly-loader.js.map +1 -0
  138. package/dist/components/composed/AssistantLayout/AssistantLayout.cjs +2 -0
  139. package/dist/components/composed/AssistantLayout/AssistantLayout.cjs.map +1 -0
  140. package/dist/components/composed/AssistantLayout/AssistantLayout.js +142 -0
  141. package/dist/components/composed/AssistantLayout/AssistantLayout.js.map +1 -0
  142. package/dist/components/composed/AssistantLayout/dockLayout.cjs +2 -0
  143. package/dist/components/composed/AssistantLayout/dockLayout.cjs.map +1 -0
  144. package/dist/components/composed/AssistantLayout/dockLayout.js +10 -0
  145. package/dist/components/composed/AssistantLayout/dockLayout.js.map +1 -0
  146. package/dist/components/composed/Chat/Chat.cjs +1 -1
  147. package/dist/components/composed/Chat/Chat.cjs.map +1 -1
  148. package/dist/components/composed/Chat/Chat.js +23 -23
  149. package/dist/components/composed/Chat/Chat.js.map +1 -1
  150. package/dist/components/composed/ConfirmDialog/ConfirmDialog.cjs +1 -1
  151. package/dist/components/composed/ConfirmDialog/ConfirmDialog.cjs.map +1 -1
  152. package/dist/components/composed/ConfirmDialog/ConfirmDialog.js +33 -29
  153. package/dist/components/composed/ConfirmDialog/ConfirmDialog.js.map +1 -1
  154. package/dist/components/composed/DataAppShell/CollapseButton.cjs +2 -0
  155. package/dist/components/composed/DataAppShell/CollapseButton.cjs.map +1 -0
  156. package/dist/components/composed/DataAppShell/CollapseButton.js +42 -0
  157. package/dist/components/composed/DataAppShell/CollapseButton.js.map +1 -0
  158. package/dist/components/composed/DataAppShell/DataAppShell.cjs +1 -1
  159. package/dist/components/composed/DataAppShell/DataAppShell.cjs.map +1 -1
  160. package/dist/components/composed/DataAppShell/DataAppShell.js +349 -313
  161. package/dist/components/composed/DataAppShell/DataAppShell.js.map +1 -1
  162. package/dist/components/composed/DataAppShell/PrimaryNav.cjs +2 -0
  163. package/dist/components/composed/DataAppShell/PrimaryNav.cjs.map +1 -0
  164. package/dist/components/composed/DataAppShell/PrimaryNav.js +268 -0
  165. package/dist/components/composed/DataAppShell/PrimaryNav.js.map +1 -0
  166. package/dist/components/composed/DataAppShell/RightPanel.cjs +2 -0
  167. package/dist/components/composed/DataAppShell/RightPanel.cjs.map +1 -0
  168. package/dist/components/composed/DataAppShell/RightPanel.js +282 -0
  169. package/dist/components/composed/DataAppShell/RightPanel.js.map +1 -0
  170. package/dist/components/composed/DataAppShell/SecondaryNav.cjs +2 -0
  171. package/dist/components/composed/DataAppShell/SecondaryNav.cjs.map +1 -0
  172. package/dist/components/composed/DataAppShell/SecondaryNav.js +364 -0
  173. package/dist/components/composed/DataAppShell/SecondaryNav.js.map +1 -0
  174. package/dist/components/composed/DataAppShell/ShellContext.cjs +2 -0
  175. package/dist/components/composed/DataAppShell/ShellContext.cjs.map +1 -0
  176. package/dist/components/composed/DataAppShell/ShellContext.js +23 -0
  177. package/dist/components/composed/DataAppShell/ShellContext.js.map +1 -0
  178. package/dist/components/composed/MoleculeStructure/MoleculeStructure.cjs +2 -0
  179. package/dist/components/composed/MoleculeStructure/MoleculeStructure.cjs.map +1 -0
  180. package/dist/components/composed/MoleculeStructure/MoleculeStructure.js +87 -0
  181. package/dist/components/composed/MoleculeStructure/MoleculeStructure.js.map +1 -0
  182. package/dist/components/composed/MoleculeStructure/rdkit-loader.cjs +2 -0
  183. package/dist/components/composed/MoleculeStructure/rdkit-loader.cjs.map +1 -0
  184. package/dist/components/composed/MoleculeStructure/rdkit-loader.js +89 -0
  185. package/dist/components/composed/MoleculeStructure/rdkit-loader.js.map +1 -0
  186. package/dist/components/composed/MoleculeStructure/use-rdkit.cjs +2 -0
  187. package/dist/components/composed/MoleculeStructure/use-rdkit.cjs.map +1 -0
  188. package/dist/components/composed/MoleculeStructure/use-rdkit.js +19 -0
  189. package/dist/components/composed/MoleculeStructure/use-rdkit.js.map +1 -0
  190. package/dist/components/composed/PlateMapEditor/ManifestFilterPopover.cjs +1 -1
  191. package/dist/components/composed/PlateMapEditor/ManifestFilterPopover.cjs.map +1 -1
  192. package/dist/components/composed/PlateMapEditor/ManifestFilterPopover.js +17 -17
  193. package/dist/components/composed/PlateMapEditor/ManifestFilterPopover.js.map +1 -1
  194. package/dist/components/composed/PlateMapEditor/PlateMapActionsMenu.cjs +1 -1
  195. package/dist/components/composed/PlateMapEditor/PlateMapActionsMenu.cjs.map +1 -1
  196. package/dist/components/composed/PlateMapEditor/PlateMapActionsMenu.js +33 -33
  197. package/dist/components/composed/PlateMapEditor/PlateMapActionsMenu.js.map +1 -1
  198. package/dist/components/composed/PlateMapEditor/PlateMapPlateSelector.cjs +1 -1
  199. package/dist/components/composed/PlateMapEditor/PlateMapPlateSelector.cjs.map +1 -1
  200. package/dist/components/composed/PlateMapEditor/PlateMapPlateSelector.js +7 -7
  201. package/dist/components/composed/PlateMapEditor/PlateMapPlateSelector.js.map +1 -1
  202. package/dist/components/composed/PlateMapEditor/PlatePaintGrid.cjs +1 -1
  203. package/dist/components/composed/PlateMapEditor/PlatePaintGrid.cjs.map +1 -1
  204. package/dist/components/composed/PlateMapEditor/PlatePaintGrid.js +1 -1
  205. package/dist/components/composed/PlateMapEditor/PlatePaintGrid.js.map +1 -1
  206. package/dist/components/composed/PlateMapEditor/WellLegend.cjs +1 -1
  207. package/dist/components/composed/PlateMapEditor/WellLegend.cjs.map +1 -1
  208. package/dist/components/composed/PlateMapEditor/WellLegend.js +24 -12
  209. package/dist/components/composed/PlateMapEditor/WellLegend.js.map +1 -1
  210. package/dist/components/composed/PlateMapEditor/WellManifestTable.cjs +1 -1
  211. package/dist/components/composed/PlateMapEditor/WellManifestTable.cjs.map +1 -1
  212. package/dist/components/composed/PlateMapEditor/WellManifestTable.js +1 -1
  213. package/dist/components/composed/PlateMapEditor/WellManifestTable.js.map +1 -1
  214. package/dist/components/composed/TdpSearch/components/DefaultFilters.cjs +1 -1
  215. package/dist/components/composed/TdpSearch/components/DefaultFilters.cjs.map +1 -1
  216. package/dist/components/composed/TdpSearch/components/DefaultFilters.js +3 -3
  217. package/dist/components/composed/TdpSearch/components/DefaultFilters.js.map +1 -1
  218. package/dist/components/composed/TopBar/TopBar.cjs +2 -0
  219. package/dist/components/composed/TopBar/TopBar.cjs.map +1 -0
  220. package/dist/components/composed/TopBar/TopBar.js +56 -0
  221. package/dist/components/composed/TopBar/TopBar.js.map +1 -0
  222. package/dist/components/composed/UserMenu/UserMenu.cjs +2 -0
  223. package/dist/components/composed/UserMenu/UserMenu.cjs.map +1 -0
  224. package/dist/components/composed/UserMenu/UserMenu.js +99 -0
  225. package/dist/components/composed/UserMenu/UserMenu.js.map +1 -0
  226. package/dist/components/composed/tdp-link.cjs +1 -1
  227. package/dist/components/composed/tdp-link.cjs.map +1 -1
  228. package/dist/components/composed/tdp-link.js +5 -5
  229. package/dist/components/composed/tdp-link.js.map +1 -1
  230. package/dist/components/ui/alert.cjs +1 -1
  231. package/dist/components/ui/alert.cjs.map +1 -1
  232. package/dist/components/ui/alert.js +12 -12
  233. package/dist/components/ui/alert.js.map +1 -1
  234. package/dist/components/ui/badge.cjs +1 -1
  235. package/dist/components/ui/badge.cjs.map +1 -1
  236. package/dist/components/ui/badge.js +14 -14
  237. package/dist/components/ui/badge.js.map +1 -1
  238. package/dist/components/ui/banner.cjs +1 -1
  239. package/dist/components/ui/banner.cjs.map +1 -1
  240. package/dist/components/ui/banner.js +17 -17
  241. package/dist/components/ui/banner.js.map +1 -1
  242. package/dist/components/ui/button.cjs +1 -1
  243. package/dist/components/ui/button.cjs.map +1 -1
  244. package/dist/components/ui/button.js +16 -16
  245. package/dist/components/ui/button.js.map +1 -1
  246. package/dist/components/ui/calendar.cjs +1 -1
  247. package/dist/components/ui/calendar.cjs.map +1 -1
  248. package/dist/components/ui/calendar.js +3 -3
  249. package/dist/components/ui/calendar.js.map +1 -1
  250. package/dist/components/ui/code-block.cjs +3 -3
  251. package/dist/components/ui/code-block.cjs.map +1 -1
  252. package/dist/components/ui/code-block.js +136 -118
  253. package/dist/components/ui/code-block.js.map +1 -1
  254. package/dist/components/ui/code-editor.cjs +1 -1
  255. package/dist/components/ui/code-editor.cjs.map +1 -1
  256. package/dist/components/ui/code-editor.js +14 -12
  257. package/dist/components/ui/code-editor.js.map +1 -1
  258. package/dist/components/ui/combobox.cjs +1 -1
  259. package/dist/components/ui/combobox.cjs.map +1 -1
  260. package/dist/components/ui/combobox.js +33 -29
  261. package/dist/components/ui/combobox.js.map +1 -1
  262. package/dist/components/ui/command.cjs +1 -1
  263. package/dist/components/ui/command.cjs.map +1 -1
  264. package/dist/components/ui/command.js +81 -77
  265. package/dist/components/ui/command.js.map +1 -1
  266. package/dist/components/ui/context-menu.cjs +1 -1
  267. package/dist/components/ui/context-menu.cjs.map +1 -1
  268. package/dist/components/ui/context-menu.js +13 -13
  269. package/dist/components/ui/context-menu.js.map +1 -1
  270. package/dist/components/ui/data-table/data-table-column-toggle.cjs +1 -1
  271. package/dist/components/ui/data-table/data-table-column-toggle.cjs.map +1 -1
  272. package/dist/components/ui/data-table/data-table-column-toggle.js +70 -62
  273. package/dist/components/ui/data-table/data-table-column-toggle.js.map +1 -1
  274. package/dist/components/ui/data-table/data-table-filter.cjs +1 -1
  275. package/dist/components/ui/data-table/data-table-filter.cjs.map +1 -1
  276. package/dist/components/ui/data-table/data-table-filter.js +24 -23
  277. package/dist/components/ui/data-table/data-table-filter.js.map +1 -1
  278. package/dist/components/ui/data-table/data-table-group.cjs +1 -1
  279. package/dist/components/ui/data-table/data-table-group.cjs.map +1 -1
  280. package/dist/components/ui/data-table/data-table-group.js +17 -16
  281. package/dist/components/ui/data-table/data-table-group.js.map +1 -1
  282. package/dist/components/ui/data-table/data-table-pagination.cjs +1 -1
  283. package/dist/components/ui/data-table/data-table-pagination.cjs.map +1 -1
  284. package/dist/components/ui/data-table/data-table-pagination.js +15 -15
  285. package/dist/components/ui/data-table/data-table-pagination.js.map +1 -1
  286. package/dist/components/ui/data-table/data-table.cjs +1 -1
  287. package/dist/components/ui/data-table/data-table.cjs.map +1 -1
  288. package/dist/components/ui/data-table/data-table.js +191 -190
  289. package/dist/components/ui/data-table/data-table.js.map +1 -1
  290. package/dist/components/ui/dialog.cjs +1 -1
  291. package/dist/components/ui/dialog.cjs.map +1 -1
  292. package/dist/components/ui/dialog.js +1 -1
  293. package/dist/components/ui/dialog.js.map +1 -1
  294. package/dist/components/ui/dropdown-menu.cjs +1 -1
  295. package/dist/components/ui/dropdown-menu.cjs.map +1 -1
  296. package/dist/components/ui/dropdown-menu.js +12 -4
  297. package/dist/components/ui/dropdown-menu.js.map +1 -1
  298. package/dist/components/ui/hover-card.cjs +1 -1
  299. package/dist/components/ui/hover-card.cjs.map +1 -1
  300. package/dist/components/ui/hover-card.js +3 -3
  301. package/dist/components/ui/hover-card.js.map +1 -1
  302. package/dist/components/ui/item.cjs +1 -1
  303. package/dist/components/ui/item.cjs.map +1 -1
  304. package/dist/components/ui/item.js +44 -36
  305. package/dist/components/ui/item.js.map +1 -1
  306. package/dist/components/ui/menubar.cjs +1 -1
  307. package/dist/components/ui/menubar.cjs.map +1 -1
  308. package/dist/components/ui/menubar.js +2 -2
  309. package/dist/components/ui/menubar.js.map +1 -1
  310. package/dist/components/ui/navigation-menu.cjs +1 -1
  311. package/dist/components/ui/navigation-menu.cjs.map +1 -1
  312. package/dist/components/ui/navigation-menu.js +1 -1
  313. package/dist/components/ui/navigation-menu.js.map +1 -1
  314. package/dist/components/ui/popover.cjs +1 -1
  315. package/dist/components/ui/popover.cjs.map +1 -1
  316. package/dist/components/ui/popover.js +1 -1
  317. package/dist/components/ui/popover.js.map +1 -1
  318. package/dist/components/ui/scroll-area.cjs +1 -1
  319. package/dist/components/ui/scroll-area.cjs.map +1 -1
  320. package/dist/components/ui/scroll-area.js +1 -0
  321. package/dist/components/ui/scroll-area.js.map +1 -1
  322. package/dist/components/ui/select.cjs +1 -1
  323. package/dist/components/ui/select.cjs.map +1 -1
  324. package/dist/components/ui/select.js +1 -1
  325. package/dist/components/ui/select.js.map +1 -1
  326. package/dist/components/ui/sheet.cjs +1 -1
  327. package/dist/components/ui/sheet.cjs.map +1 -1
  328. package/dist/components/ui/sheet.js +5 -5
  329. package/dist/components/ui/sheet.js.map +1 -1
  330. package/dist/components/ui/sidebar.cjs +1 -1
  331. package/dist/components/ui/sidebar.cjs.map +1 -1
  332. package/dist/components/ui/sidebar.js +2 -2
  333. package/dist/components/ui/sidebar.js.map +1 -1
  334. package/dist/components/ui/slider.cjs +1 -1
  335. package/dist/components/ui/slider.cjs.map +1 -1
  336. package/dist/components/ui/slider.js +10 -9
  337. package/dist/components/ui/slider.js.map +1 -1
  338. package/dist/components/ui/sonner.cjs +1 -1
  339. package/dist/components/ui/sonner.cjs.map +1 -1
  340. package/dist/components/ui/sonner.js +25 -10
  341. package/dist/components/ui/sonner.js.map +1 -1
  342. package/dist/components/ui/table.cjs +1 -1
  343. package/dist/components/ui/table.cjs.map +1 -1
  344. package/dist/components/ui/table.js +1 -0
  345. package/dist/components/ui/table.js.map +1 -1
  346. package/dist/components/ui/tabs.cjs +1 -1
  347. package/dist/components/ui/tabs.cjs.map +1 -1
  348. package/dist/components/ui/tabs.js +18 -18
  349. package/dist/components/ui/tabs.js.map +1 -1
  350. package/dist/components/ui/tetra-molecule-icon.cjs +2 -0
  351. package/dist/components/ui/tetra-molecule-icon.cjs.map +1 -0
  352. package/dist/components/ui/tetra-molecule-icon.js +49 -0
  353. package/dist/components/ui/tetra-molecule-icon.js.map +1 -0
  354. package/dist/components/ui/toggle-group.cjs +1 -1
  355. package/dist/components/ui/toggle-group.cjs.map +1 -1
  356. package/dist/components/ui/toggle-group.js +35 -31
  357. package/dist/components/ui/toggle-group.js.map +1 -1
  358. package/dist/hooks/use-plotly-theme.cjs +1 -1
  359. package/dist/hooks/use-plotly-theme.cjs.map +1 -1
  360. package/dist/hooks/use-plotly-theme.js +4 -3
  361. package/dist/hooks/use-plotly-theme.js.map +1 -1
  362. package/dist/index.cjs +1 -1
  363. package/dist/index.css +1 -1
  364. package/dist/index.d.ts +1073 -136
  365. package/dist/index.js +698 -647
  366. package/dist/index.js.map +1 -1
  367. package/dist/index.tailwind.css +1 -1
  368. package/dist/lib/shiki.cjs +2 -0
  369. package/dist/lib/shiki.cjs.map +1 -0
  370. package/dist/lib/shiki.js +72 -0
  371. package/dist/lib/shiki.js.map +1 -0
  372. package/package.json +23 -12
  373. package/dist/components/charts/AreaGraph/AreaGraph.cjs +0 -2
  374. package/dist/components/charts/AreaGraph/AreaGraph.cjs.map +0 -1
  375. package/dist/components/charts/AreaGraph/AreaGraph.js +0 -271
  376. package/dist/components/charts/AreaGraph/AreaGraph.js.map +0 -1
  377. package/dist/components/charts/BarGraph/BarGraph.cjs +0 -2
  378. package/dist/components/charts/BarGraph/BarGraph.cjs.map +0 -1
  379. package/dist/components/charts/BarGraph/BarGraph.js +0 -220
  380. package/dist/components/charts/BarGraph/BarGraph.js.map +0 -1
  381. package/dist/components/charts/Boxplot/Boxplot.cjs +0 -2
  382. package/dist/components/charts/Boxplot/Boxplot.cjs.map +0 -1
  383. package/dist/components/charts/Boxplot/Boxplot.js.map +0 -1
  384. package/dist/components/charts/ChromatogramChart/ChromatogramChart.cjs +0 -2
  385. package/dist/components/charts/ChromatogramChart/ChromatogramChart.cjs.map +0 -1
  386. package/dist/components/charts/ChromatogramChart/ChromatogramChart.js +0 -241
  387. package/dist/components/charts/ChromatogramChart/ChromatogramChart.js.map +0 -1
  388. package/dist/components/charts/ChromatogramChart/annotations.cjs +0 -2
  389. package/dist/components/charts/ChromatogramChart/annotations.cjs.map +0 -1
  390. package/dist/components/charts/ChromatogramChart/annotations.js +0 -136
  391. package/dist/components/charts/ChromatogramChart/annotations.js.map +0 -1
  392. package/dist/components/charts/ChromatogramChart/boundaryMarkers.cjs.map +0 -1
  393. package/dist/components/charts/ChromatogramChart/boundaryMarkers.js.map +0 -1
  394. package/dist/components/charts/ChromatogramChart/constants.cjs.map +0 -1
  395. package/dist/components/charts/ChromatogramChart/constants.js.map +0 -1
  396. package/dist/components/charts/ChromatogramChart/dataProcessing.cjs.map +0 -1
  397. package/dist/components/charts/ChromatogramChart/dataProcessing.js.map +0 -1
  398. package/dist/components/charts/ChromatogramChart/peakDetection.cjs.map +0 -1
  399. package/dist/components/charts/ChromatogramChart/peakDetection.js.map +0 -1
  400. package/dist/components/charts/ChromatogramChart/plotBuilder.cjs +0 -2
  401. package/dist/components/charts/ChromatogramChart/plotBuilder.cjs.map +0 -1
  402. package/dist/components/charts/ChromatogramChart/plotBuilder.js +0 -207
  403. package/dist/components/charts/ChromatogramChart/plotBuilder.js.map +0 -1
  404. package/dist/components/charts/ChromatogramChart/regionOverlays.cjs.map +0 -1
  405. package/dist/components/charts/ChromatogramChart/regionOverlays.js.map +0 -1
  406. package/dist/components/charts/DotPlot/DotPlot.cjs +0 -2
  407. package/dist/components/charts/DotPlot/DotPlot.cjs.map +0 -1
  408. package/dist/components/charts/DotPlot/DotPlot.js +0 -208
  409. package/dist/components/charts/DotPlot/DotPlot.js.map +0 -1
  410. package/dist/components/charts/Heatmap/Heatmap.cjs +0 -2
  411. package/dist/components/charts/Heatmap/Heatmap.cjs.map +0 -1
  412. package/dist/components/charts/Heatmap/Heatmap.js +0 -67
  413. package/dist/components/charts/Heatmap/Heatmap.js.map +0 -1
  414. package/dist/components/charts/LineGraph/LineGraph.cjs +0 -2
  415. package/dist/components/charts/LineGraph/LineGraph.cjs.map +0 -1
  416. package/dist/components/charts/LineGraph/LineGraph.js +0 -225
  417. package/dist/components/charts/LineGraph/LineGraph.js.map +0 -1
  418. package/dist/components/charts/ScatterGraph/ScatterGraph.cjs +0 -2
  419. package/dist/components/charts/ScatterGraph/ScatterGraph.cjs.map +0 -1
  420. package/dist/components/charts/ScatterGraph/ScatterGraph.js +0 -234
  421. package/dist/components/charts/ScatterGraph/ScatterGraph.js.map +0 -1
  422. package/dist/components/charts/StackedChromatogramChart/StackedChromatogramChart.cjs +0 -2
  423. package/dist/components/charts/StackedChromatogramChart/StackedChromatogramChart.cjs.map +0 -1
  424. package/dist/components/charts/StackedChromatogramChart/StackedChromatogramChart.js +0 -40
  425. package/dist/components/charts/StackedChromatogramChart/StackedChromatogramChart.js.map +0 -1
  426. package/dist/components/charts/StackedChromatogramChart/transforms.cjs.map +0 -1
  427. package/dist/components/charts/StackedChromatogramChart/transforms.js.map +0 -1
  428. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/boundaryMarkers.cjs +0 -0
  429. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/boundaryMarkers.js +0 -0
  430. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/constants.cjs +0 -0
  431. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/constants.js +0 -0
  432. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/dataProcessing.cjs +0 -0
  433. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/dataProcessing.js +0 -0
  434. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/peakDetection.cjs +0 -0
  435. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/peakDetection.js +0 -0
  436. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/regionOverlays.cjs +0 -0
  437. /package/dist/components/charts/{ChromatogramChart → Chromatogram}/regionOverlays.js +0 -0
  438. /package/dist/components/charts/{StackedChromatogramChart → StackedChromatogram}/transforms.cjs +0 -0
  439. /package/dist/components/charts/{StackedChromatogramChart → StackedChromatogram}/transforms.js +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"BarGraph.cjs","sources":["../../../../src/components/charts/BarGraph/BarGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport { useElementSize } from \"@/hooks/use-element-size\";\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { cn } from \"@/lib/utils\";\nimport { seriesColor } from \"@/utils/colors\";\n\ninterface BarDataSeries {\n x: number[];\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n error_y?: {\n type: \"data\";\n array: number[];\n visible: boolean;\n };\n}\n\ntype BarGraphVariant = \"group\" | \"stack\" | \"overlay\";\n\n/** Top margin reserving room for the 32px title; reduced when no title is set */\nconst TITLE_MARGIN_TOP = 60;\nconst NO_TITLE_MARGIN_TOP = 30;\n\ninterface BarGraphProps {\n dataSeries: BarDataSeries[];\n /**\n * Fixed width in pixels. When omitted, the chart fills its container and\n * tracks the container's width via a `ResizeObserver`.\n */\n width?: number;\n /**\n * Fixed height in pixels. When omitted, the chart fills its container and\n * tracks the container's height via a `ResizeObserver`.\n */\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: BarGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n barWidth?: number;\n /**\n * Categorical labels for the x-axis ticks. When provided, the x data values\n * still drive bar positioning but the displayed tick labels match these\n * strings in order (e.g. [\"Mon\", \"Tue\", …]). Should align 1:1 with the\n * unique, ordered x values across all series.\n */\n xTickText?: string[];\n}\n\nconst BarGraph: React.FC<BarGraphProps> = ({\n dataSeries,\n width,\n height,\n xRange,\n yRange,\n variant = \"group\",\n xTitle,\n yTitle,\n title,\n barWidth = 24,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({ xLabel: xTitle, yLabel: yTitle });\n\n // Omitted width/height → fill the container and track its measured size;\n // explicit pixel values override. See AreaGraph for the reference pattern.\n const [containerRef, measured] = useElementSize<HTMLDivElement>();\n const resolvedWidth = width ?? measured.width;\n const resolvedHeight = height ?? measured.height;\n const hasSize = resolvedWidth > 0 && resolvedHeight > 0;\n // Fill is per-dimension: omit width to fill the container width, omit height\n // to fill its height (so e.g. a fixed width with a container-driven height works).\n const fillWidth = width === undefined;\n const fillHeight = height === undefined;\n const sizeRef = useRef({ width: resolvedWidth, height: resolvedHeight });\n sizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n const plotInitedRef = useRef(false);\n // Size last applied to the plot, so the resize effect can skip a redundant\n // relayout right after newPlot already drew at that size.\n const appliedSizeRef = useRef({ width: 0, height: 0 });\n\n const { yMin, yMax } = useMemo(() => {\n let minX = Number.MAX_VALUE;\n let maxX = Number.MIN_VALUE;\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.x.forEach((x) => {\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n });\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const xPadding = (maxX - minX) * 0.1;\n const yPadding = (maxY - minY) * 0.1;\n\n return {\n xMin: minX - xPadding,\n xMax: maxX + xPadding,\n yMin: variant === \"stack\" ? 0 : minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries, variant]);\n\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const xTicks = useMemo(\n () => [...new Set(dataSeries.flatMap((s) => s.x))].sort((a, b) => a - b),\n [dataSeries],\n );\n\n // Only apply categorical labels when they align 1:1 with the tick positions;\n // a mismatch would silently mis-label ticks, so fall back to numeric ticks.\n const useCategoricalX = !!xTickText && xTickText.length === xTicks.length;\n\n const yTicks = useMemo(() => {\n const range = effectiveYRange[1] - effectiveYRange[0];\n let step = Math.pow(10, Math.floor(Math.log10(range)));\n\n if (range / step > 10) step = step * 2;\n if (range / step < 4) step = step / 2;\n\n const ticks = [];\n let current = Math.ceil(effectiveYRange[0] / step) * step;\n while (current <= effectiveYRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveYRange]);\n\n const barMode = useMemo((): \"group\" | \"stack\" | \"overlay\" => {\n switch (variant) {\n case \"stack\":\n return \"stack\";\n case \"overlay\":\n return \"overlay\";\n case \"group\":\n default:\n return \"group\";\n }\n }, [variant]);\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: 12,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: 16,\n color: theme.textColor,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme],\n );\n\n useEffect(() => {\n if (!plotRef.current || !hasSize) return;\n\n const data = dataSeries.map((series, index) => ({\n x: series.x,\n y: series.y,\n type: \"bar\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n marker: {\n color: seriesColor(index, series.color),\n },\n width: barWidth,\n error_y: series.error_y,\n }));\n\n const layout = {\n ...(title\n ? {\n title: {\n text: title,\n font: {\n size: 32,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n },\n }\n : {}),\n width: sizeRef.current.width,\n height: sizeRef.current.height,\n margin: {\n l: 80,\n r: 30,\n // Reserve room for tick labels, the x-axis title, and the\n // container-anchored bottom legend stacked beneath them.\n b: 96,\n t: title ? TITLE_MARGIN_TOP : NO_TITLE_MARGIN_TOP,\n pad: 0,\n },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n barmode: barMode,\n bargap: 0.15,\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 32,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\n tickmode: \"array\" as const,\n tickvals: xTicks,\n ...(useCategoricalX ? { ticktext: xTickText } : {}),\n showgrid: true,\n // Reserve space for tick labels + the axis title so the bottom legend\n // can't overlap them at small sizes (SW-2157).\n automargin: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 30,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTicks,\n showgrid: true,\n automargin: true,\n ...tickOptions,\n },\n legend: {\n // Anchor to the bottom of the container (not the plot area) so the\n // legend always clears the x-axis tick labels + title — a paper-relative\n // fractional offset collapses into the ticks at small heights (SW-2157).\n x: 0.5,\n y: 0,\n xanchor: \"center\" as const,\n yanchor: \"bottom\" as const,\n yref: \"container\" as const,\n orientation: \"h\" as const,\n font: {\n size: 16,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n },\n },\n showlegend: dataSeries.length > 1,\n };\n\n const config = {\n // Sizing is driven from the measured container; disable Plotly's own\n // window-resize responsiveness (it can't see container resizes).\n responsive: false,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, data, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n plotInitedRef.current = true;\n appliedSizeRef.current = { ...sizeRef.current };\n\n // Cleanup function\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n plotInitedRef.current = false;\n }\n };\n }, [dataSeries, hasSize, xRange, yRange, xTitle, yTitle, title, barWidth, barMode, tickOptions, xTicks, yTicks, useCategoricalX, xTickText, theme, bindTooltip]);\n\n // Resize in place when the measured/overridden size changes — cheaper than\n // recreating the plot, and it preserves tooltip/event bindings.\n useEffect(() => {\n const plotElement = plotRef.current;\n if (!plotElement || !plotInitedRef.current || resolvedWidth <= 0 || resolvedHeight <= 0) {\n return;\n }\n // newPlot already drew at the current size; skip the redundant relayout\n // (it would queue an automargin redraw that can reject if we unmount first).\n if (\n appliedSizeRef.current.width === resolvedWidth &&\n appliedSizeRef.current.height === resolvedHeight\n ) {\n return;\n }\n appliedSizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n // Swallow rejections from a relayout that races an unmount/purge.\n void Plotly.relayout(plotElement, { width: resolvedWidth, height: resolvedHeight }).catch(\n () => {},\n );\n }, [resolvedWidth, resolvedHeight]);\n\n return (\n <div\n ref={containerRef}\n className={cn(\"bar-graph-container relative\", fillWidth && \"w-full\", fillHeight && \"h-full\")}\n >\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { BarGraph };\nexport type { BarDataSeries, BarGraphVariant, BarGraphProps };\n"],"names":["TITLE_MARGIN_TOP","NO_TITLE_MARGIN_TOP","BarGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","barWidth","xTickText","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","containerRef","measured","useElementSize","resolvedWidth","resolvedHeight","hasSize","fillWidth","fillHeight","sizeRef","plotInitedRef","appliedSizeRef","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","xTicks","s","a","b","useCategoricalX","yTicks","range","step","ticks","current","barMode","tickOptions","useEffect","data","index","seriesColor","layout","config","Plotly","plotElement","jsxs","cn","jsx"],"mappings":"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"}
@@ -1,220 +0,0 @@
1
- import { jsxs as q, jsx as D } from "react/jsx-runtime";
2
- import z from "plotly.js-dist";
3
- import { useRef as x, useMemo as h, useEffect as Y } from "react";
4
- import { useChartTooltip as F } from "../ChartTooltip/ChartTooltip.js";
5
- import { useElementSize as J } from "../../../hooks/use-element-size.js";
6
- import { usePlotlyTheme as K } from "../../../hooks/use-plotly-theme.js";
7
- import { cn as Q } from "../../../lib/utils.js";
8
- import { seriesColor as S } from "../../../utils/colors.js";
9
- const Z = 60, $ = 30, st = ({
10
- dataSeries: s,
11
- width: C,
12
- height: N,
13
- xRange: k,
14
- yRange: f,
15
- variant: d = "group",
16
- xTitle: b,
17
- yTitle: E,
18
- title: g,
19
- barWidth: A = 24,
20
- xTickText: p
21
- }) => {
22
- const a = x(null), e = K(), { bindTooltip: L, tooltipElement: j } = F({ xLabel: b, yLabel: E }), [H, P] = J(), i = C ?? P.width, c = N ?? P.height, X = i > 0 && c > 0, T = C === void 0, W = N === void 0, y = x({ width: i, height: c });
23
- y.current = { width: i, height: c };
24
- const I = x(!1), w = x({ width: 0, height: 0 }), { yMin: B, yMax: O } = h(() => {
25
- let o = Number.MAX_VALUE, t = Number.MIN_VALUE, n = Number.MAX_VALUE, r = Number.MIN_VALUE;
26
- s.forEach((R) => {
27
- R.x.forEach((m) => {
28
- o = Math.min(o, m), t = Math.max(t, m);
29
- }), R.y.forEach((m) => {
30
- n = Math.min(n, m), r = Math.max(r, m);
31
- });
32
- });
33
- const l = (t - o) * 0.1, M = (r - n) * 0.1;
34
- return {
35
- xMin: o - l,
36
- xMax: t + l,
37
- yMin: d === "stack" ? 0 : n - M,
38
- yMax: r + M
39
- };
40
- }, [s, d]), u = h(
41
- () => f || [B, O],
42
- [f, B, O]
43
- ), _ = h(
44
- () => [...new Set(s.flatMap((o) => o.x))].sort((o, t) => o - t),
45
- [s]
46
- ), U = !!p && p.length === _.length, V = h(() => {
47
- const o = u[1] - u[0];
48
- let t = Math.pow(10, Math.floor(Math.log10(o)));
49
- o / t > 10 && (t = t * 2), o / t < 4 && (t = t / 2);
50
- const n = [];
51
- let r = Math.ceil(u[0] / t) * t;
52
- for (; r <= u[1]; )
53
- n.push(r), r += t;
54
- return n;
55
- }, [u]), G = h(() => {
56
- switch (d) {
57
- case "stack":
58
- return "stack";
59
- case "overlay":
60
- return "overlay";
61
- default:
62
- return "group";
63
- }
64
- }, [d]), v = h(
65
- () => ({
66
- tickcolor: e.tickColor,
67
- ticklen: 12,
68
- tickwidth: 1,
69
- ticks: "outside",
70
- tickfont: {
71
- size: 16,
72
- color: e.textColor,
73
- family: "Inter, sans-serif",
74
- weight: 400
75
- },
76
- linecolor: e.lineColor,
77
- linewidth: 1,
78
- position: 0,
79
- zeroline: !1
80
- }),
81
- [e]
82
- );
83
- return Y(() => {
84
- if (!a.current || !X) return;
85
- const o = s.map((l, M) => ({
86
- x: l.x,
87
- y: l.y,
88
- type: "bar",
89
- name: l.name,
90
- hoverinfo: "none",
91
- marker: {
92
- color: S(M, l.color)
93
- },
94
- width: A,
95
- error_y: l.error_y
96
- })), t = {
97
- ...g ? {
98
- title: {
99
- text: g,
100
- font: {
101
- size: 32,
102
- family: "Inter, sans-serif",
103
- color: e.textColor
104
- }
105
- }
106
- } : {},
107
- width: y.current.width,
108
- height: y.current.height,
109
- margin: {
110
- l: 80,
111
- r: 30,
112
- // Reserve room for tick labels, the x-axis title, and the
113
- // container-anchored bottom legend stacked beneath them.
114
- b: 96,
115
- t: g ? Z : $,
116
- pad: 0
117
- },
118
- paper_bgcolor: e.paperBg,
119
- plot_bgcolor: e.plotBg,
120
- font: {
121
- family: "Inter, sans-serif"
122
- },
123
- barmode: G,
124
- bargap: 0.15,
125
- dragmode: !1,
126
- xaxis: {
127
- title: {
128
- text: b,
129
- font: {
130
- size: 16,
131
- color: e.textSecondary,
132
- family: "Inter, sans-serif",
133
- weight: 400
134
- },
135
- standoff: 32
136
- },
137
- gridcolor: e.gridColor,
138
- range: k,
139
- autorange: !k,
140
- tickmode: "array",
141
- tickvals: _,
142
- ...U ? { ticktext: p } : {},
143
- showgrid: !0,
144
- // Reserve space for tick labels + the axis title so the bottom legend
145
- // can't overlap them at small sizes (SW-2157).
146
- automargin: !0,
147
- ...v
148
- },
149
- yaxis: {
150
- title: {
151
- text: E,
152
- font: {
153
- size: 16,
154
- color: e.textSecondary,
155
- family: "Inter, sans-serif",
156
- weight: 400
157
- },
158
- standoff: 30
159
- },
160
- gridcolor: e.gridColor,
161
- range: f,
162
- autorange: !f,
163
- tickmode: "array",
164
- tickvals: V,
165
- showgrid: !0,
166
- automargin: !0,
167
- ...v
168
- },
169
- legend: {
170
- // Anchor to the bottom of the container (not the plot area) so the
171
- // legend always clears the x-axis tick labels + title — a paper-relative
172
- // fractional offset collapses into the ticks at small heights (SW-2157).
173
- x: 0.5,
174
- y: 0,
175
- xanchor: "center",
176
- yanchor: "bottom",
177
- yref: "container",
178
- orientation: "h",
179
- font: {
180
- size: 16,
181
- color: e.legendColor,
182
- family: "Inter, sans-serif",
183
- weight: 500
184
- }
185
- },
186
- showlegend: s.length > 1
187
- }, n = {
188
- // Sizing is driven from the measured container; disable Plotly's own
189
- // window-resize responsiveness (it can't see container resizes).
190
- responsive: !1,
191
- displayModeBar: !1,
192
- displaylogo: !1
193
- };
194
- z.newPlot(a.current, o, t, n), L(a.current);
195
- const r = a.current;
196
- return I.current = !0, w.current = { ...y.current }, () => {
197
- r && (z.purge(r), I.current = !1);
198
- };
199
- }, [s, X, k, f, b, E, g, A, G, v, _, V, U, p, e, L]), Y(() => {
200
- const o = a.current;
201
- !o || !I.current || i <= 0 || c <= 0 || w.current.width === i && w.current.height === c || (w.current = { width: i, height: c }, z.relayout(o, { width: i, height: c }).catch(
202
- () => {
203
- }
204
- ));
205
- }, [i, c]), /* @__PURE__ */ q(
206
- "div",
207
- {
208
- ref: H,
209
- className: Q("bar-graph-container relative", T && "w-full", W && "h-full"),
210
- children: [
211
- /* @__PURE__ */ D("div", { ref: a, style: { width: "100%", height: "100%" } }),
212
- j
213
- ]
214
- }
215
- );
216
- };
217
- export {
218
- st as BarGraph
219
- };
220
- //# sourceMappingURL=BarGraph.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BarGraph.js","sources":["../../../../src/components/charts/BarGraph/BarGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport { useElementSize } from \"@/hooks/use-element-size\";\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { cn } from \"@/lib/utils\";\nimport { seriesColor } from \"@/utils/colors\";\n\ninterface BarDataSeries {\n x: number[];\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n error_y?: {\n type: \"data\";\n array: number[];\n visible: boolean;\n };\n}\n\ntype BarGraphVariant = \"group\" | \"stack\" | \"overlay\";\n\n/** Top margin reserving room for the 32px title; reduced when no title is set */\nconst TITLE_MARGIN_TOP = 60;\nconst NO_TITLE_MARGIN_TOP = 30;\n\ninterface BarGraphProps {\n dataSeries: BarDataSeries[];\n /**\n * Fixed width in pixels. When omitted, the chart fills its container and\n * tracks the container's width via a `ResizeObserver`.\n */\n width?: number;\n /**\n * Fixed height in pixels. When omitted, the chart fills its container and\n * tracks the container's height via a `ResizeObserver`.\n */\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: BarGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n barWidth?: number;\n /**\n * Categorical labels for the x-axis ticks. When provided, the x data values\n * still drive bar positioning but the displayed tick labels match these\n * strings in order (e.g. [\"Mon\", \"Tue\", …]). Should align 1:1 with the\n * unique, ordered x values across all series.\n */\n xTickText?: string[];\n}\n\nconst BarGraph: React.FC<BarGraphProps> = ({\n dataSeries,\n width,\n height,\n xRange,\n yRange,\n variant = \"group\",\n xTitle,\n yTitle,\n title,\n barWidth = 24,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({ xLabel: xTitle, yLabel: yTitle });\n\n // Omitted width/height → fill the container and track its measured size;\n // explicit pixel values override. See AreaGraph for the reference pattern.\n const [containerRef, measured] = useElementSize<HTMLDivElement>();\n const resolvedWidth = width ?? measured.width;\n const resolvedHeight = height ?? measured.height;\n const hasSize = resolvedWidth > 0 && resolvedHeight > 0;\n // Fill is per-dimension: omit width to fill the container width, omit height\n // to fill its height (so e.g. a fixed width with a container-driven height works).\n const fillWidth = width === undefined;\n const fillHeight = height === undefined;\n const sizeRef = useRef({ width: resolvedWidth, height: resolvedHeight });\n sizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n const plotInitedRef = useRef(false);\n // Size last applied to the plot, so the resize effect can skip a redundant\n // relayout right after newPlot already drew at that size.\n const appliedSizeRef = useRef({ width: 0, height: 0 });\n\n const { yMin, yMax } = useMemo(() => {\n let minX = Number.MAX_VALUE;\n let maxX = Number.MIN_VALUE;\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.x.forEach((x) => {\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n });\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const xPadding = (maxX - minX) * 0.1;\n const yPadding = (maxY - minY) * 0.1;\n\n return {\n xMin: minX - xPadding,\n xMax: maxX + xPadding,\n yMin: variant === \"stack\" ? 0 : minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries, variant]);\n\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const xTicks = useMemo(\n () => [...new Set(dataSeries.flatMap((s) => s.x))].sort((a, b) => a - b),\n [dataSeries],\n );\n\n // Only apply categorical labels when they align 1:1 with the tick positions;\n // a mismatch would silently mis-label ticks, so fall back to numeric ticks.\n const useCategoricalX = !!xTickText && xTickText.length === xTicks.length;\n\n const yTicks = useMemo(() => {\n const range = effectiveYRange[1] - effectiveYRange[0];\n let step = Math.pow(10, Math.floor(Math.log10(range)));\n\n if (range / step > 10) step = step * 2;\n if (range / step < 4) step = step / 2;\n\n const ticks = [];\n let current = Math.ceil(effectiveYRange[0] / step) * step;\n while (current <= effectiveYRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveYRange]);\n\n const barMode = useMemo((): \"group\" | \"stack\" | \"overlay\" => {\n switch (variant) {\n case \"stack\":\n return \"stack\";\n case \"overlay\":\n return \"overlay\";\n case \"group\":\n default:\n return \"group\";\n }\n }, [variant]);\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: 12,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: 16,\n color: theme.textColor,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme],\n );\n\n useEffect(() => {\n if (!plotRef.current || !hasSize) return;\n\n const data = dataSeries.map((series, index) => ({\n x: series.x,\n y: series.y,\n type: \"bar\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n marker: {\n color: seriesColor(index, series.color),\n },\n width: barWidth,\n error_y: series.error_y,\n }));\n\n const layout = {\n ...(title\n ? {\n title: {\n text: title,\n font: {\n size: 32,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n },\n }\n : {}),\n width: sizeRef.current.width,\n height: sizeRef.current.height,\n margin: {\n l: 80,\n r: 30,\n // Reserve room for tick labels, the x-axis title, and the\n // container-anchored bottom legend stacked beneath them.\n b: 96,\n t: title ? TITLE_MARGIN_TOP : NO_TITLE_MARGIN_TOP,\n pad: 0,\n },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n barmode: barMode,\n bargap: 0.15,\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 32,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\n tickmode: \"array\" as const,\n tickvals: xTicks,\n ...(useCategoricalX ? { ticktext: xTickText } : {}),\n showgrid: true,\n // Reserve space for tick labels + the axis title so the bottom legend\n // can't overlap them at small sizes (SW-2157).\n automargin: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 30,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTicks,\n showgrid: true,\n automargin: true,\n ...tickOptions,\n },\n legend: {\n // Anchor to the bottom of the container (not the plot area) so the\n // legend always clears the x-axis tick labels + title — a paper-relative\n // fractional offset collapses into the ticks at small heights (SW-2157).\n x: 0.5,\n y: 0,\n xanchor: \"center\" as const,\n yanchor: \"bottom\" as const,\n yref: \"container\" as const,\n orientation: \"h\" as const,\n font: {\n size: 16,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n },\n },\n showlegend: dataSeries.length > 1,\n };\n\n const config = {\n // Sizing is driven from the measured container; disable Plotly's own\n // window-resize responsiveness (it can't see container resizes).\n responsive: false,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, data, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n plotInitedRef.current = true;\n appliedSizeRef.current = { ...sizeRef.current };\n\n // Cleanup function\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n plotInitedRef.current = false;\n }\n };\n }, [dataSeries, hasSize, xRange, yRange, xTitle, yTitle, title, barWidth, barMode, tickOptions, xTicks, yTicks, useCategoricalX, xTickText, theme, bindTooltip]);\n\n // Resize in place when the measured/overridden size changes — cheaper than\n // recreating the plot, and it preserves tooltip/event bindings.\n useEffect(() => {\n const plotElement = plotRef.current;\n if (!plotElement || !plotInitedRef.current || resolvedWidth <= 0 || resolvedHeight <= 0) {\n return;\n }\n // newPlot already drew at the current size; skip the redundant relayout\n // (it would queue an automargin redraw that can reject if we unmount first).\n if (\n appliedSizeRef.current.width === resolvedWidth &&\n appliedSizeRef.current.height === resolvedHeight\n ) {\n return;\n }\n appliedSizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n // Swallow rejections from a relayout that races an unmount/purge.\n void Plotly.relayout(plotElement, { width: resolvedWidth, height: resolvedHeight }).catch(\n () => {},\n );\n }, [resolvedWidth, resolvedHeight]);\n\n return (\n <div\n ref={containerRef}\n className={cn(\"bar-graph-container relative\", fillWidth && \"w-full\", fillHeight && \"h-full\")}\n >\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { BarGraph };\nexport type { BarDataSeries, BarGraphVariant, BarGraphProps };\n"],"names":["TITLE_MARGIN_TOP","NO_TITLE_MARGIN_TOP","BarGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","barWidth","xTickText","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","containerRef","measured","useElementSize","resolvedWidth","resolvedHeight","hasSize","fillWidth","fillHeight","sizeRef","plotInitedRef","appliedSizeRef","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","xTicks","s","a","b","useCategoricalX","yTicks","range","step","ticks","current","barMode","tickOptions","useEffect","data","index","seriesColor","layout","config","Plotly","plotElement","jsxs","cn","jsx"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const O=require("react/jsx-runtime"),b=require("plotly.js-dist"),r=require("react"),A=require("../ChartTooltip/ChartTooltip.cjs"),U=require("../../../hooks/use-element-size.cjs"),W=require("../../../hooks/use-plotly-theme.cjs"),Y=require("../../../lib/utils.cjs"),H=require("../../../utils/colors.cjs"),V=-1.8,D=({dataSeries:d,width:v,height:k,xRange:m,yRange:f,xTitle:y,yTitle:x,title:E="Boxplot",showPoints:z=!1})=>{const u=r.useRef(null),e=W.usePlotlyTheme(),{bindTooltip:I,tooltipElement:R}=A.useChartTooltip({xLabel:y,yLabel:x}),[S,C]=U.useElementSize(),i=v??C.width,l=k??C.height,q=i>0&&l>0,T=v===void 0,_=k===void 0,g=r.useRef({width:i,height:l});g.current={width:i,height:l};const w=r.useRef(!1),p=r.useRef({width:0,height:0}),{yMin:P,yMax:j}=r.useMemo(()=>{let o=Number.MAX_VALUE,t=Number.MIN_VALUE;d.forEach(s=>{s.y.forEach(n=>{o=Math.min(o,n),t=Math.max(t,n)})});const c=(t-o)*.1;return{yMin:o-c,yMax:t+c}},[d]),h=r.useMemo(()=>f||[P,j],[f,P,j]),B=r.useMemo(()=>{const o=h[1]-h[0];let t=Math.pow(10,Math.floor(Math.log10(o)));o/t>10&&(t=t*2),o/t<4&&(t=t/2);const c=[];let s=Math.ceil(h[0]/t)*t;for(;s<=h[1];)c.push(s),s+=t;return c},[h]),M=r.useMemo(()=>({tickcolor:e.tickColor,ticklen:12,tickwidth:1,ticks:"outside",tickfont:{size:16,color:e.textColor,family:"Inter, sans-serif",weight:400},linecolor:e.lineColor,linewidth:1,position:0,zeroline:!1}),[e]),N=r.useMemo(()=>({text:E,x:.5,y:.95,xanchor:"center",yanchor:"top",font:{size:32,weight:600,family:"Inter, sans-serif",color:e.textColor,lineheight:1.2,standoff:30}}),[E,e]);return r.useEffect(()=>{if(!u.current||!q)return;const o=d.map((n,L)=>{const a=H.seriesColor(L,n.color);return{y:n.y,x:n.x,type:"box",name:n.name,hoverinfo:"none",marker:{color:a},line:{color:a},fillcolor:typeof a=="string"&&a.startsWith("#")&&a.length===7?`${a}40`:a,boxpoints:z?n.boxpoints||"outliers":!1,jitter:n.jitter||.3,pointpos:n.pointpos||V}}),t={width:g.current.width,height:g.current.height,title:N,margin:{l:80,r:40,b:96,t:80,pad:0},paper_bgcolor:e.paperBg,plot_bgcolor:e.plotBg,font:{family:"Inter, sans-serif"},dragmode:!1,xaxis:{title:{text:y,font:{size:16,color:e.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:e.gridColor,range:m,autorange:!m,showgrid:!0,automargin:!0,...M},yaxis:{title:{text:x,font:{size:16,color:e.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:e.gridColor,range:f,autorange:!f,tickmode:"array",tickvals:B,showgrid:!0,automargin:!0,...M},legend:{x:.5,y:0,xanchor:"center",yanchor:"bottom",yref:"container",orientation:"h",font:{size:13,color:e.legendColor,family:"Inter, sans-serif",weight:500,lineheight:18}},showlegend:!0},c={responsive:!1,displayModeBar:!1,displaylogo:!1};b.newPlot(u.current,o,t,c),I(u.current);const s=u.current;return w.current=!0,p.current={...g.current},()=>{s&&(b.purge(s),w.current=!1)}},[d,q,m,f,h,y,x,z,N,M,B,e,I]),r.useEffect(()=>{const o=u.current;!o||!w.current||i<=0||l<=0||p.current.width===i&&p.current.height===l||(p.current={width:i,height:l},b.relayout(o,{width:i,height:l}).catch(()=>{}))},[i,l]),O.jsxs("div",{ref:S,className:Y.cn("boxplot-container relative",T&&"w-full",_&&"h-full"),children:[O.jsx("div",{ref:u,style:{width:"100%",height:"100%"}}),R]})};exports.Boxplot=D;
2
- //# sourceMappingURL=Boxplot.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Boxplot.cjs","sources":["../../../../src/components/charts/Boxplot/Boxplot.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport { useElementSize } from \"@/hooks/use-element-size\";\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { cn } from \"@/lib/utils\";\nimport { seriesColor } from \"@/utils/colors\";\n\n/** Default point position offset from the box edge */\nconst DEFAULT_POINT_POSITION = -1.8;\n\ninterface BoxDataSeries {\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n x?: string[] | number[];\n boxpoints?: \"all\" | \"outliers\" | \"suspectedoutliers\" | false;\n jitter?: number;\n pointpos?: number;\n}\n\ninterface BoxplotProps {\n dataSeries: BoxDataSeries[];\n /**\n * Fixed width in pixels. When omitted, the chart fills its container and\n * tracks the container's width via a `ResizeObserver`.\n */\n width?: number;\n /**\n * Fixed height in pixels. When omitted, the chart fills its container and\n * tracks the container's height via a `ResizeObserver`.\n */\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n xTitle?: string;\n yTitle?: string;\n title?: string;\n showPoints?: boolean;\n}\n\nconst Boxplot: React.FC<BoxplotProps> = ({\n dataSeries,\n width,\n height,\n xRange,\n yRange,\n xTitle,\n yTitle,\n title = \"Boxplot\",\n showPoints = false,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({ xLabel: xTitle, yLabel: yTitle });\n\n // Omitted width/height → fill the container and track its measured size;\n // explicit pixel values override. See AreaGraph for the reference pattern.\n const [containerRef, measured] = useElementSize<HTMLDivElement>();\n const resolvedWidth = width ?? measured.width;\n const resolvedHeight = height ?? measured.height;\n const hasSize = resolvedWidth > 0 && resolvedHeight > 0;\n // Fill is per-dimension: omit width to fill the container width, omit height\n // to fill its height (so e.g. a fixed width with a container-driven height works).\n const fillWidth = width === undefined;\n const fillHeight = height === undefined;\n const sizeRef = useRef({ width: resolvedWidth, height: resolvedHeight });\n sizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n const plotInitedRef = useRef(false);\n // Size last applied to the plot, so the resize effect can skip a redundant\n // relayout right after newPlot already drew at that size.\n const appliedSizeRef = useRef({ width: 0, height: 0 });\n\n const { yMin, yMax } = useMemo(() => {\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const yPadding = (maxY - minY) * 0.1;\n\n return {\n yMin: minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries]);\n\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const yTicks = useMemo(() => {\n const range = effectiveYRange[1] - effectiveYRange[0];\n let step = Math.pow(10, Math.floor(Math.log10(range)));\n\n if (range / step > 10) step = step * 2;\n if (range / step < 4) step = step / 2;\n\n const ticks = [];\n let current = Math.ceil(effectiveYRange[0] / step) * step;\n while (current <= effectiveYRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveYRange]);\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: 12,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: 16,\n color: theme.textColor,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme],\n );\n\n const titleOptions = useMemo(\n () => ({\n text: title,\n x: 0.5,\n y: 0.95,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n font: {\n size: 32,\n weight: 600,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n lineheight: 1.2,\n standoff: 30,\n },\n }),\n [title, theme],\n );\n\n useEffect(() => {\n if (!plotRef.current || !hasSize) return;\n\n const data = dataSeries.map((series, index) => {\n const color = seriesColor(index, series.color);\n return {\n y: series.y,\n x: series.x,\n type: \"box\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n marker: {\n color,\n },\n line: {\n color,\n },\n fillcolor:\n typeof color === \"string\" && color.startsWith(\"#\") && color.length === 7\n ? `${color}40`\n : color, // Add transparency for hex colors only\n boxpoints: showPoints\n ? series.boxpoints || \"outliers\"\n : (false as const),\n jitter: series.jitter || 0.3,\n pointpos: series.pointpos || DEFAULT_POINT_POSITION,\n };\n });\n\n const layout = {\n width: sizeRef.current.width,\n height: sizeRef.current.height,\n title: titleOptions,\n // Bottom margin reserves room for tick labels, the x-axis title, and the\n // container-anchored bottom legend stacked beneath them.\n margin: { l: 80, r: 40, b: 96, t: 80, pad: 0 },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 15,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\n showgrid: true,\n // Reserve space for tick labels + the axis title so the bottom legend\n // can't overlap them at small sizes (SW-2157).\n automargin: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 15,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTicks,\n showgrid: true,\n automargin: true,\n ...tickOptions,\n },\n legend: {\n // Anchor to the bottom of the container (not the plot area) so the\n // legend always clears the x-axis tick labels + title — a paper-relative\n // fractional offset collapses into the ticks at small heights (SW-2157).\n x: 0.5,\n y: 0,\n xanchor: \"center\" as const,\n yanchor: \"bottom\" as const,\n yref: \"container\" as const,\n orientation: \"h\" as const,\n font: {\n size: 13,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n lineheight: 18,\n },\n },\n showlegend: true,\n };\n\n const config = {\n // Sizing is driven from the measured container; disable Plotly's own\n // window-resize responsiveness (it can't see container resizes).\n responsive: false,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, data, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n plotInitedRef.current = true;\n appliedSizeRef.current = { ...sizeRef.current };\n\n // Cleanup function\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n plotInitedRef.current = false;\n }\n };\n }, [dataSeries, hasSize, xRange, yRange, effectiveYRange, xTitle, yTitle, showPoints, titleOptions, tickOptions, yTicks, theme, bindTooltip]);\n\n // Resize in place when the measured/overridden size changes — cheaper than\n // recreating the plot, and it preserves tooltip/event bindings.\n useEffect(() => {\n const plotElement = plotRef.current;\n if (!plotElement || !plotInitedRef.current || resolvedWidth <= 0 || resolvedHeight <= 0) {\n return;\n }\n // newPlot already drew at the current size; skip the redundant relayout\n // (it would queue an automargin redraw that can reject if we unmount first).\n if (\n appliedSizeRef.current.width === resolvedWidth &&\n appliedSizeRef.current.height === resolvedHeight\n ) {\n return;\n }\n appliedSizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n // Swallow rejections from a relayout that races an unmount/purge.\n void Plotly.relayout(plotElement, { width: resolvedWidth, height: resolvedHeight }).catch(\n () => {},\n );\n }, [resolvedWidth, resolvedHeight]);\n\n return (\n <div\n ref={containerRef}\n className={cn(\"boxplot-container relative\", fillWidth && \"w-full\", fillHeight && \"h-full\")}\n >\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { Boxplot };\nexport type { BoxDataSeries, BoxplotProps };\n"],"names":["DEFAULT_POINT_POSITION","Boxplot","dataSeries","width","height","xRange","yRange","xTitle","yTitle","title","showPoints","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","containerRef","measured","useElementSize","resolvedWidth","resolvedHeight","hasSize","fillWidth","fillHeight","sizeRef","plotInitedRef","appliedSizeRef","yMin","yMax","useMemo","minY","maxY","series","y","yPadding","effectiveYRange","yTicks","range","step","ticks","current","tickOptions","titleOptions","useEffect","data","index","color","seriesColor","layout","config","Plotly","plotElement","jsxs","cn","jsx"],"mappings":"+XAWMA,EAAyB,KAiCzBC,EAAkC,CAAC,CACvC,WAAAC,EACA,MAAAC,EACA,OAAAC,EACA,OAAAC,EACA,OAAAC,EACA,OAAAC,EACA,OAAAC,EACA,MAAAC,EAAQ,UACR,WAAAC,EAAa,EACf,IAAM,CACJ,MAAMC,EAAUC,EAAAA,OAAuB,IAAI,EACrCC,EAAQC,EAAAA,eAAA,EACR,CAAE,YAAAC,EAAa,eAAAC,CAAA,EAAmBC,EAAAA,gBAAgB,CAAE,OAAQV,EAAQ,OAAQC,EAAQ,EAIpF,CAACU,EAAcC,CAAQ,EAAIC,iBAAA,EAC3BC,EAAgBlB,GAASgB,EAAS,MAClCG,EAAiBlB,GAAUe,EAAS,OACpCI,EAAUF,EAAgB,GAAKC,EAAiB,EAGhDE,EAAYrB,IAAU,OACtBsB,EAAarB,IAAW,OACxBsB,EAAUd,EAAAA,OAAO,CAAE,MAAOS,EAAe,OAAQC,EAAgB,EACvEI,EAAQ,QAAU,CAAE,MAAOL,EAAe,OAAQC,CAAA,EAClD,MAAMK,EAAgBf,EAAAA,OAAO,EAAK,EAG5BgB,EAAiBhB,EAAAA,OAAO,CAAE,MAAO,EAAG,OAAQ,EAAG,EAE/C,CAAE,KAAAiB,EAAM,KAAAC,CAAA,EAASC,EAAAA,QAAQ,IAAM,CACnC,IAAIC,EAAO,OAAO,UACdC,EAAO,OAAO,UAElB/B,EAAW,QAASgC,GAAW,CAC7BA,EAAO,EAAE,QAASC,GAAM,CACtBH,EAAO,KAAK,IAAIA,EAAMG,CAAC,EACvBF,EAAO,KAAK,IAAIA,EAAME,CAAC,CACzB,CAAC,CACH,CAAC,EAED,MAAMC,GAAYH,EAAOD,GAAQ,GAEjC,MAAO,CACL,KAAMA,EAAOI,EACb,KAAMH,EAAOG,CAAA,CAEjB,EAAG,CAAClC,CAAU,CAAC,EAETmC,EAAkBN,EAAAA,QACtB,IAAMzB,GAAU,CAACuB,EAAMC,CAAI,EAC3B,CAACxB,EAAQuB,EAAMC,CAAI,CAAA,EAGfQ,EAASP,EAAAA,QAAQ,IAAM,CAC3B,MAAMQ,EAAQF,EAAgB,CAAC,EAAIA,EAAgB,CAAC,EACpD,IAAIG,EAAO,KAAK,IAAI,GAAI,KAAK,MAAM,KAAK,MAAMD,CAAK,CAAC,CAAC,EAEjDA,EAAQC,EAAO,KAAIA,EAAOA,EAAO,GACjCD,EAAQC,EAAO,IAAGA,EAAOA,EAAO,GAEpC,MAAMC,EAAQ,CAAA,EACd,IAAIC,EAAU,KAAK,KAAKL,EAAgB,CAAC,EAAIG,CAAI,EAAIA,EACrD,KAAOE,GAAWL,EAAgB,CAAC,GACjCI,EAAM,KAAKC,CAAO,EAClBA,GAAWF,EAEb,OAAOC,CACT,EAAG,CAACJ,CAAe,CAAC,EAEdM,EAAcZ,EAAAA,QAClB,KAAO,CACL,UAAWlB,EAAM,UACjB,QAAS,GACT,UAAW,EACX,MAAO,UACP,SAAU,CACR,KAAM,GACN,MAAOA,EAAM,UACb,OAAQ,oBACR,OAAQ,GAAA,EAEV,UAAWA,EAAM,UACjB,UAAW,EACX,SAAU,EACV,SAAU,EAAA,GAEZ,CAACA,CAAK,CAAA,EAGF+B,EAAeb,EAAAA,QACnB,KAAO,CACL,KAAMtB,EACN,EAAG,GACH,EAAG,IACH,QAAS,SACT,QAAS,MACT,KAAM,CACJ,KAAM,GACN,OAAQ,IACR,OAAQ,oBACR,MAAOI,EAAM,UACb,WAAY,IACZ,SAAU,EAAA,CACZ,GAEF,CAACJ,EAAOI,CAAK,CAAA,EAGfgC,OAAAA,EAAAA,UAAU,IAAM,CACd,GAAI,CAAClC,EAAQ,SAAW,CAACY,EAAS,OAElC,MAAMuB,EAAO5C,EAAW,IAAI,CAACgC,EAAQa,IAAU,CAC7C,MAAMC,EAAQC,EAAAA,YAAYF,EAAOb,EAAO,KAAK,EAC7C,MAAO,CACL,EAAGA,EAAO,EACV,EAAGA,EAAO,EACV,KAAM,MACN,KAAMA,EAAO,KACb,UAAW,OACX,OAAQ,CACN,MAAAc,CAAA,EAEF,KAAM,CACJ,MAAAA,CAAA,EAEF,UACE,OAAOA,GAAU,UAAYA,EAAM,WAAW,GAAG,GAAKA,EAAM,SAAW,EACnE,GAAGA,CAAK,KACRA,EACN,UAAWtC,EACPwB,EAAO,WAAa,WACnB,GACL,OAAQA,EAAO,QAAU,GACzB,SAAUA,EAAO,UAAYlC,CAAA,CAEjC,CAAC,EAEKkD,EAAS,CACb,MAAOxB,EAAQ,QAAQ,MACvB,OAAQA,EAAQ,QAAQ,OACxB,MAAOkB,EAGP,OAAQ,CAAE,EAAG,GAAI,EAAG,GAAI,EAAG,GAAI,EAAG,GAAI,IAAK,CAAA,EAC3C,cAAe/B,EAAM,QACrB,aAAcA,EAAM,OACpB,KAAM,CACJ,OAAQ,mBAAA,EAEV,SAAU,GACV,MAAO,CACL,MAAO,CACL,KAAMN,EACN,KAAM,CACJ,KAAM,GACN,MAAOM,EAAM,cACb,OAAQ,oBACR,OAAQ,GAAA,EAEV,SAAU,EAAA,EAEZ,UAAWA,EAAM,UACjB,MAAOR,EACP,UAAW,CAACA,EACZ,SAAU,GAGV,WAAY,GACZ,GAAGsC,CAAA,EAEL,MAAO,CACL,MAAO,CACL,KAAMnC,EACN,KAAM,CACJ,KAAM,GACN,MAAOK,EAAM,cACb,OAAQ,oBACR,OAAQ,GAAA,EAEV,SAAU,EAAA,EAEZ,UAAWA,EAAM,UACjB,MAAOP,EACP,UAAW,CAACA,EACZ,SAAU,QACV,SAAUgC,EACV,SAAU,GACV,WAAY,GACZ,GAAGK,CAAA,EAEL,OAAQ,CAIN,EAAG,GACH,EAAG,EACH,QAAS,SACT,QAAS,SACT,KAAM,YACN,YAAa,IACb,KAAM,CACJ,KAAM,GACN,MAAO9B,EAAM,YACb,OAAQ,oBACR,OAAQ,IACR,WAAY,EAAA,CACd,EAEF,WAAY,EAAA,EAGRsC,EAAS,CAGb,WAAY,GACZ,eAAgB,GAChB,YAAa,EAAA,EAGfC,EAAO,QAAQzC,EAAQ,QAASmC,EAAMI,EAAQC,CAAM,EACpDpC,EAAYJ,EAAQ,OAAO,EAG3B,MAAM0C,EAAc1C,EAAQ,QAC5B,OAAAgB,EAAc,QAAU,GACxBC,EAAe,QAAU,CAAE,GAAGF,EAAQ,OAAA,EAG/B,IAAM,CACP2B,IACFD,EAAO,MAAMC,CAAW,EACxB1B,EAAc,QAAU,GAE5B,CACF,EAAG,CAACzB,EAAYqB,EAASlB,EAAQC,EAAQ+B,EAAiB9B,EAAQC,EAAQE,EAAYkC,EAAcD,EAAaL,EAAQzB,EAAOE,CAAW,CAAC,EAI5I8B,EAAAA,UAAU,IAAM,CACd,MAAMQ,EAAc1C,EAAQ,QACxB,CAAC0C,GAAe,CAAC1B,EAAc,SAAWN,GAAiB,GAAKC,GAAkB,GAMpFM,EAAe,QAAQ,QAAUP,GACjCO,EAAe,QAAQ,SAAWN,IAIpCM,EAAe,QAAU,CAAE,MAAOP,EAAe,OAAQC,CAAA,EAEpD8B,EAAO,SAASC,EAAa,CAAE,MAAOhC,EAAe,OAAQC,CAAA,CAAgB,EAAE,MAClF,IAAM,CAAC,CAAA,EAEX,EAAG,CAACD,EAAeC,CAAc,CAAC,EAGhCgC,EAAAA,KAAC,MAAA,CACC,IAAKpC,EACL,UAAWqC,EAAAA,GAAG,6BAA8B/B,GAAa,SAAUC,GAAc,QAAQ,EAEzF,SAAA,CAAA+B,EAAAA,IAAC,MAAA,CAAI,IAAK7C,EAAS,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAA,CAAO,CAAG,EAC5DK,CAAA,CAAA,CAAA,CAGP"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Boxplot.js","sources":["../../../../src/components/charts/Boxplot/Boxplot.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport { useElementSize } from \"@/hooks/use-element-size\";\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { cn } from \"@/lib/utils\";\nimport { seriesColor } from \"@/utils/colors\";\n\n/** Default point position offset from the box edge */\nconst DEFAULT_POINT_POSITION = -1.8;\n\ninterface BoxDataSeries {\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n x?: string[] | number[];\n boxpoints?: \"all\" | \"outliers\" | \"suspectedoutliers\" | false;\n jitter?: number;\n pointpos?: number;\n}\n\ninterface BoxplotProps {\n dataSeries: BoxDataSeries[];\n /**\n * Fixed width in pixels. When omitted, the chart fills its container and\n * tracks the container's width via a `ResizeObserver`.\n */\n width?: number;\n /**\n * Fixed height in pixels. When omitted, the chart fills its container and\n * tracks the container's height via a `ResizeObserver`.\n */\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n xTitle?: string;\n yTitle?: string;\n title?: string;\n showPoints?: boolean;\n}\n\nconst Boxplot: React.FC<BoxplotProps> = ({\n dataSeries,\n width,\n height,\n xRange,\n yRange,\n xTitle,\n yTitle,\n title = \"Boxplot\",\n showPoints = false,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({ xLabel: xTitle, yLabel: yTitle });\n\n // Omitted width/height → fill the container and track its measured size;\n // explicit pixel values override. See AreaGraph for the reference pattern.\n const [containerRef, measured] = useElementSize<HTMLDivElement>();\n const resolvedWidth = width ?? measured.width;\n const resolvedHeight = height ?? measured.height;\n const hasSize = resolvedWidth > 0 && resolvedHeight > 0;\n // Fill is per-dimension: omit width to fill the container width, omit height\n // to fill its height (so e.g. a fixed width with a container-driven height works).\n const fillWidth = width === undefined;\n const fillHeight = height === undefined;\n const sizeRef = useRef({ width: resolvedWidth, height: resolvedHeight });\n sizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n const plotInitedRef = useRef(false);\n // Size last applied to the plot, so the resize effect can skip a redundant\n // relayout right after newPlot already drew at that size.\n const appliedSizeRef = useRef({ width: 0, height: 0 });\n\n const { yMin, yMax } = useMemo(() => {\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const yPadding = (maxY - minY) * 0.1;\n\n return {\n yMin: minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries]);\n\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const yTicks = useMemo(() => {\n const range = effectiveYRange[1] - effectiveYRange[0];\n let step = Math.pow(10, Math.floor(Math.log10(range)));\n\n if (range / step > 10) step = step * 2;\n if (range / step < 4) step = step / 2;\n\n const ticks = [];\n let current = Math.ceil(effectiveYRange[0] / step) * step;\n while (current <= effectiveYRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveYRange]);\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: 12,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: 16,\n color: theme.textColor,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme],\n );\n\n const titleOptions = useMemo(\n () => ({\n text: title,\n x: 0.5,\n y: 0.95,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n font: {\n size: 32,\n weight: 600,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n lineheight: 1.2,\n standoff: 30,\n },\n }),\n [title, theme],\n );\n\n useEffect(() => {\n if (!plotRef.current || !hasSize) return;\n\n const data = dataSeries.map((series, index) => {\n const color = seriesColor(index, series.color);\n return {\n y: series.y,\n x: series.x,\n type: \"box\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n marker: {\n color,\n },\n line: {\n color,\n },\n fillcolor:\n typeof color === \"string\" && color.startsWith(\"#\") && color.length === 7\n ? `${color}40`\n : color, // Add transparency for hex colors only\n boxpoints: showPoints\n ? series.boxpoints || \"outliers\"\n : (false as const),\n jitter: series.jitter || 0.3,\n pointpos: series.pointpos || DEFAULT_POINT_POSITION,\n };\n });\n\n const layout = {\n width: sizeRef.current.width,\n height: sizeRef.current.height,\n title: titleOptions,\n // Bottom margin reserves room for tick labels, the x-axis title, and the\n // container-anchored bottom legend stacked beneath them.\n margin: { l: 80, r: 40, b: 96, t: 80, pad: 0 },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 15,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\n showgrid: true,\n // Reserve space for tick labels + the axis title so the bottom legend\n // can't overlap them at small sizes (SW-2157).\n automargin: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 15,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTicks,\n showgrid: true,\n automargin: true,\n ...tickOptions,\n },\n legend: {\n // Anchor to the bottom of the container (not the plot area) so the\n // legend always clears the x-axis tick labels + title — a paper-relative\n // fractional offset collapses into the ticks at small heights (SW-2157).\n x: 0.5,\n y: 0,\n xanchor: \"center\" as const,\n yanchor: \"bottom\" as const,\n yref: \"container\" as const,\n orientation: \"h\" as const,\n font: {\n size: 13,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n lineheight: 18,\n },\n },\n showlegend: true,\n };\n\n const config = {\n // Sizing is driven from the measured container; disable Plotly's own\n // window-resize responsiveness (it can't see container resizes).\n responsive: false,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, data, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n plotInitedRef.current = true;\n appliedSizeRef.current = { ...sizeRef.current };\n\n // Cleanup function\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n plotInitedRef.current = false;\n }\n };\n }, [dataSeries, hasSize, xRange, yRange, effectiveYRange, xTitle, yTitle, showPoints, titleOptions, tickOptions, yTicks, theme, bindTooltip]);\n\n // Resize in place when the measured/overridden size changes — cheaper than\n // recreating the plot, and it preserves tooltip/event bindings.\n useEffect(() => {\n const plotElement = plotRef.current;\n if (!plotElement || !plotInitedRef.current || resolvedWidth <= 0 || resolvedHeight <= 0) {\n return;\n }\n // newPlot already drew at the current size; skip the redundant relayout\n // (it would queue an automargin redraw that can reject if we unmount first).\n if (\n appliedSizeRef.current.width === resolvedWidth &&\n appliedSizeRef.current.height === resolvedHeight\n ) {\n return;\n }\n appliedSizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n // Swallow rejections from a relayout that races an unmount/purge.\n void Plotly.relayout(plotElement, { width: resolvedWidth, height: resolvedHeight }).catch(\n () => {},\n );\n }, [resolvedWidth, resolvedHeight]);\n\n return (\n <div\n ref={containerRef}\n className={cn(\"boxplot-container relative\", fillWidth && \"w-full\", fillHeight && \"h-full\")}\n >\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { Boxplot };\nexport type { BoxDataSeries, BoxplotProps };\n"],"names":["DEFAULT_POINT_POSITION","Boxplot","dataSeries","width","height","xRange","yRange","xTitle","yTitle","title","showPoints","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","containerRef","measured","useElementSize","resolvedWidth","resolvedHeight","hasSize","fillWidth","fillHeight","sizeRef","plotInitedRef","appliedSizeRef","yMin","yMax","useMemo","minY","maxY","series","y","yPadding","effectiveYRange","yTicks","range","step","ticks","current","tickOptions","titleOptions","useEffect","data","index","color","seriesColor","layout","config","Plotly","plotElement","jsxs","cn","jsx"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("react/jsx-runtime"),_=require("plotly.js-dist"),r=require("react"),ie=require("../ChartTooltip/ChartTooltip.cjs"),B=require("./annotations.cjs"),D=require("./dataProcessing.cjs"),de=require("./peakDetection.cjs"),h=require("./plotBuilder.cjs"),fe=require("../../composed/EmptyState/EmptyState.cjs"),pe=require("../../../hooks/use-plotly-theme.cjs"),me=[],he=({series:n,width:y=900,height:g=500,title:$,xAxisTitle:v="Retention Time (min)",yAxisTitle:k="Signal (mAU)",annotations:C=me,xRange:H,yRange:T,showLegend:U=!0,showGridX:W=!0,showGridY:A=!0,showMarkers:x=!1,markerSize:F=4,showCrosshairs:I=!1,baselineCorrection:J="none",baselineWindowSize:K=50,peakDetectionOptions:f,showPeakAreas:R=!1,boundaryMarkers:Q="none",annotationOverlapThreshold:P=.4,showExportButton:V=!0,selectedPeakIds:q,onPeakClick:Y,onPeakHover:Z,selectionAppearance:p,annotationStyle:G="arrow",titleFontSize:O=20,titleTopMargin:X})=>{const m=f!==void 0,M=r.useRef(null),z=pe.usePlotlyTheme(),{bindTooltip:w,tooltipElement:ae}=ie.useChartTooltip({xLabel:v,yLabel:k}),N=r.useRef(Y),S=r.useRef(Z);N.current=Y,S.current=Z;const j=r.useRef(null),ee=r.useRef([]),u=r.useMemo(()=>n.map(e=>{const t=D.validateSeriesData(e.x,e.y);return{...e,x:t.x,y:D.applyBaselineCorrection(t.y,J,K)}}),[n,J,K]),l=r.useMemo(()=>{if(C.length===0||u.length===0)return C;const{x:e,y:t}=u[0];return D.processUserAnnotations(C,e,t)},[C,u]),s=r.useMemo(()=>{const e=[];return m&&f&&u.forEach((t,o)=>{const a=de.detectPeaks(t.x,t.y,f);a.length>0&&e.push({peaks:a,seriesIndex:o})}),e},[u,m,f]),te=p?.selected?.borderColor,oe=p?.selected?.backgroundColor,re=p?.selected?.bold,ne=p?.unselected?.opacity,ce=p?.hoverLineWidthMultiplier,b=r.useMemo(()=>B.resolveSelectionAppearance({selected:{borderColor:te,backgroundColor:oe,bold:re},unselected:{opacity:ne},hoverLineWidthMultiplier:ce}),[te,oe,re,ne,ce]),ue=r.useMemo(()=>{const e=[];return l.forEach((t,o)=>{e.push({peak:{...t,id:t.id??`user-ann-${o}`},seriesIndex:0,seriesName:n[0]?.name??"",isAutoDetected:!1})}),s.forEach(({peaks:t,seriesIndex:o})=>{t.forEach((a,i)=>{e.push({peak:{...a,id:`peak-${o}-${i}`},seriesIndex:o,seriesName:n[o]?.name??`Series ${o+1}`,isAutoDetected:!0})})}),e},[l,s,n]),L=r.useMemo(()=>{const e=(q?.length??0)>0,t={selectedPeakIds:q??[],anySelected:e,appearance:b,annotationStyle:G},o=[];l.forEach((c,d)=>{o.push({peak:{...c,id:c.id??`user-ann-${d}`},seriesIndex:-1})}),R&&m&&s.forEach(({peaks:c,seriesIndex:d})=>{c.forEach((le,se)=>{o.push({peak:{...le,id:`peak-${d}-${se}`},seriesIndex:d})})});const a=B.groupOverlappingPeaks(o,P),i=[];for(const c of a)i.push(...B.createGroupAnnotations(c,t));return i},[l,s,R,m,P,q,b,G]);return ee.current=L,r.useEffect(()=>{const e=M.current;if(!e||n.length===0)return;const t=h.buildTraceData({processedSeries:u,processedAnnotations:l,allDetectedPeaks:s,allPeaksForInteraction:ue,showMarkers:x,markerSize:F,xAxisTitle:v,yAxisTitle:k,boundaryMarkers:Q}),o=h.buildLayout({title:$,titleFontSize:O,titleTopMargin:X,width:y,height:g,xAxisTitle:v,yAxisTitle:k,xRange:H,yRange:T,showLegend:U,seriesCount:n.length,showGridX:W,showGridY:A,showCrosshairs:I,theme:z,peakAnnotations:ee.current}),a=h.buildConfig({showExportButton:V,width:y,height:g});return _.newPlot(e,t,o,a),w(e),e.on("plotly_click",i=>{if(!N.current)return;const c=i.points.find(d=>d.customdata!=null);c&&N.current(c.customdata)}),e.on("plotly_hover",h.createHoverHandler(e,u.length,j,S,b.hoverLineWidthMultiplier)),e.on("plotly_unhover",h.createUnhoverHandler(e,j,S)),()=>{j.current=null,e&&_.purge(e)}},[u,s,ue,n.length,y,g,$,O,X,v,k,l,H,T,U,W,A,x,F,I,m,f,R,Q,P,V,z,w,b]),r.useEffect(()=>{const e=M.current;e&&e._fullLayout&&_.relayout(e,{annotations:L})},[L]),n.length===0?E.jsx("div",{className:"chromatogram-chart-container relative flex items-center justify-center",style:{width:y,height:g},children:E.jsx(fe.EmptyState,{variant:"no-data",title:"No chromatogram data",description:"There is no signal data to display yet."})}):E.jsxs("div",{className:"chromatogram-chart-container relative",children:[E.jsx("div",{ref:M,style:{width:"100%",height:"100%"}}),ae]})};exports.ChromatogramChart=he;
2
- //# sourceMappingURL=ChromatogramChart.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ChromatogramChart.cjs","sources":["../../../../src/components/charts/ChromatogramChart/ChromatogramChart.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useMemo, useRef } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport {\n groupOverlappingPeaks,\n createGroupAnnotations,\n resolveSelectionAppearance,\n} from \"./annotations\";\nimport {\n validateSeriesData,\n applyBaselineCorrection,\n processUserAnnotations,\n} from \"./dataProcessing\";\nimport { detectPeaks } from \"./peakDetection\";\nimport {\n buildTraceData,\n buildLayout,\n buildConfig,\n createHoverHandler,\n createUnhoverHandler,\n} from \"./plotBuilder\";\n\nimport type {\n ChromatogramSeries,\n PeakAnnotation,\n PeakSelectEvent,\n PeakSelectionAppearance,\n BaselineCorrectionMethod,\n BoundaryMarkerStyle,\n BoundaryMarkerType,\n PeakDetectionOptions,\n ChromatogramChartProps,\n PeakWithMeta,\n} from \"./types\";\n\nimport { EmptyState } from \"@/components/composed/EmptyState\";\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\n\n// Re-export types for external use\nexport type {\n ChromatogramSeries,\n PeakAnnotation,\n PeakSelectEvent,\n PeakSelectionAppearance,\n BaselineCorrectionMethod,\n BoundaryMarkerStyle,\n BoundaryMarkerType,\n PeakDetectionOptions,\n ChromatogramChartProps,\n};\n\n\n// Stable default so the no-annotations case keeps a constant identity; an\n// inline `[]` default would change every render, re-running the plot effect\n// (and tearing down the hover tooltip) on each re-render.\nconst EMPTY_ANNOTATIONS: PeakAnnotation[] = [];\n\nconst ChromatogramChart: React.FC<ChromatogramChartProps> = ({\n series,\n width = 900,\n height = 500,\n title,\n xAxisTitle = \"Retention Time (min)\",\n yAxisTitle = \"Signal (mAU)\",\n annotations = EMPTY_ANNOTATIONS,\n xRange,\n yRange,\n showLegend = true,\n showGridX = true,\n showGridY = true,\n showMarkers = false,\n markerSize = 4,\n showCrosshairs = false,\n baselineCorrection = \"none\",\n baselineWindowSize = 50,\n peakDetectionOptions,\n showPeakAreas = false,\n boundaryMarkers = \"none\",\n annotationOverlapThreshold = 0.4,\n showExportButton = true,\n selectedPeakIds,\n onPeakClick,\n onPeakHover,\n selectionAppearance,\n annotationStyle = \"arrow\",\n titleFontSize = 20,\n titleTopMargin,\n}) => {\n const enablePeakDetection = peakDetectionOptions !== undefined;\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({\n xLabel: xAxisTitle,\n yLabel: yAxisTitle,\n });\n // Stable refs for callbacks — avoids including them in effect dep arrays\n // (consumers often pass arrow functions that change identity every render).\n const onPeakClickRef = useRef(onPeakClick);\n const onPeakHoverRef = useRef(onPeakHover);\n onPeakClickRef.current = onPeakClick;\n onPeakHoverRef.current = onPeakHover;\n\n // Tracks the series index whose line is currently thickened on hover.\n const thickenedSeriesRef = useRef<number | null>(null);\n\n // Holds the latest peak Plotly annotations so that closures in effects always\n // read the latest selection-styled annotations.\n const peakAnnotationsRef = useRef<Partial<Plotly.Annotations>[]>([]);\n\n // Memoize processed series with baseline correction\n const processedSeries = useMemo(() => {\n return series.map((s) => {\n const validated = validateSeriesData(s.x, s.y);\n return {\n ...s,\n x: validated.x,\n y: applyBaselineCorrection(validated.y, baselineCorrection, baselineWindowSize),\n };\n });\n }, [series, baselineCorrection, baselineWindowSize]);\n\n // Process user annotations to convert startX/endX to indices and compute areas\n const processedAnnotations = useMemo(() => {\n if (annotations.length === 0 || processedSeries.length === 0) {\n return annotations;\n }\n const { x, y } = processedSeries[0];\n return processUserAnnotations(annotations, x, y);\n }, [annotations, processedSeries]);\n\n // Memoize peak detection results\n const allDetectedPeaks = useMemo(() => {\n const peaks: { peaks: PeakAnnotation[]; seriesIndex: number }[] = [];\n if (enablePeakDetection && peakDetectionOptions) {\n processedSeries.forEach((s, index) => {\n const detected = detectPeaks(s.x, s.y, peakDetectionOptions);\n if (detected.length > 0) {\n peaks.push({ peaks: detected, seriesIndex: index });\n }\n });\n }\n return peaks;\n }, [processedSeries, enablePeakDetection, peakDetectionOptions]);\n\n // Normalize the selection appearance into primitive fields up front so the\n // memo below depends on stable values rather than the (possibly unstable)\n // selectionAppearance object reference. This keeps the dependency array\n // exhaustive-deps clean without requiring callers to memoize the prop.\n const selectedBorderColor = selectionAppearance?.selected?.borderColor;\n const selectedBackgroundColor = selectionAppearance?.selected?.backgroundColor;\n const selectedBold = selectionAppearance?.selected?.bold;\n const unselectedOpacity = selectionAppearance?.unselected?.opacity;\n const hoverLineWidthMultiplier = selectionAppearance?.hoverLineWidthMultiplier;\n\n // Resolve selection appearance defaults once (stable as long as the\n // individual fields above don't change).\n const resolvedAppearance = useMemo(\n () =>\n resolveSelectionAppearance({\n selected: {\n borderColor: selectedBorderColor,\n backgroundColor: selectedBackgroundColor,\n bold: selectedBold,\n },\n unselected: { opacity: unselectedOpacity },\n hoverLineWidthMultiplier,\n }),\n [\n selectedBorderColor,\n selectedBackgroundColor,\n selectedBold,\n unselectedOpacity,\n hoverLineWidthMultiplier,\n ]\n );\n\n // All peaks that can be interacted with (clicked / hovered / selected),\n // each with a stable ID and the metadata needed for PeakSelectEvent.\n const allPeaksForInteraction = useMemo(() => {\n const result: Array<{\n peak: PeakAnnotation & { id: string };\n seriesIndex: number;\n seriesName: string;\n isAutoDetected: boolean;\n }> = [];\n\n processedAnnotations.forEach((ann, i) => {\n result.push({\n peak: { ...ann, id: ann.id ?? `user-ann-${i}` },\n seriesIndex: 0,\n seriesName: series[0]?.name ?? \"\",\n isAutoDetected: false,\n });\n });\n\n allDetectedPeaks.forEach(({ peaks, seriesIndex }) => {\n peaks.forEach((peak, peakIndex) => {\n result.push({\n peak: { ...peak, id: `peak-${seriesIndex}-${peakIndex}` },\n seriesIndex,\n seriesName: series[seriesIndex]?.name ?? `Series ${seriesIndex + 1}`,\n isAutoDetected: true,\n });\n });\n });\n\n return result;\n }, [processedAnnotations, allDetectedPeaks, series]);\n\n // Build Plotly annotation objects for all peaks, applying selection styling.\n // This memo re-runs when selectedPeakIds or resolvedAppearance changes so the\n // selection effect can call Plotly.relayout with updated annotations without\n // triggering a full chart rebuild.\n const peakAnnotations = useMemo(() => {\n const anySelected = (selectedPeakIds?.length ?? 0) > 0;\n const options = {\n selectedPeakIds: selectedPeakIds ?? [],\n anySelected,\n appearance: resolvedAppearance,\n annotationStyle,\n };\n\n const allPeaksWithMeta: PeakWithMeta[] = [];\n\n processedAnnotations.forEach((ann, i) => {\n allPeaksWithMeta.push({\n peak: { ...ann, id: ann.id ?? `user-ann-${i}` },\n seriesIndex: -1,\n });\n });\n\n if (showPeakAreas && enablePeakDetection) {\n allDetectedPeaks.forEach(({ peaks, seriesIndex }) => {\n peaks.forEach((peak, peakIndex) => {\n allPeaksWithMeta.push({\n peak: { ...peak, id: `peak-${seriesIndex}-${peakIndex}` },\n seriesIndex,\n });\n });\n });\n }\n\n const groups = groupOverlappingPeaks(allPeaksWithMeta, annotationOverlapThreshold);\n const result: Partial<Plotly.Annotations>[] = [];\n for (const group of groups) {\n result.push(...createGroupAnnotations(group, options));\n }\n return result;\n }, [\n processedAnnotations,\n allDetectedPeaks,\n showPeakAreas,\n enablePeakDetection,\n annotationOverlapThreshold,\n selectedPeakIds,\n resolvedAppearance,\n annotationStyle,\n ]);\n\n // Keep the ref in sync every render so that closures in effects always read\n // the latest selection-styled annotations.\n peakAnnotationsRef.current = peakAnnotations;\n\n // ── Main chart effect ──────────────────────────────────────────────────────\n // Rebuilds the full chart when structural props change (data, size, axes, …).\n // selectedPeakIds and selectionAppearance are intentionally excluded from\n // deps — selection changes are handled by the lightweight selection effect\n // below via Plotly.relayout, which preserves the user's current zoom/pan.\n useEffect(() => {\n const currentRef = plotRef.current;\n if (!currentRef || series.length === 0) return;\n\n // Build trace data (line traces + boundary markers + region overlays +\n // the invisible hit-area trace that carries peak customdata for\n // click/hover interaction).\n const plotData = buildTraceData({\n processedSeries,\n processedAnnotations,\n allDetectedPeaks,\n allPeaksForInteraction,\n showMarkers,\n markerSize,\n xAxisTitle,\n yAxisTitle,\n boundaryMarkers,\n });\n\n const layout = buildLayout({\n title,\n titleFontSize,\n titleTopMargin,\n width,\n height,\n xAxisTitle,\n yAxisTitle,\n xRange,\n yRange,\n showLegend,\n seriesCount: series.length,\n showGridX,\n showGridY,\n showCrosshairs,\n theme,\n peakAnnotations: peakAnnotationsRef.current,\n });\n\n const config = buildConfig({ showExportButton, width, height });\n\n Plotly.newPlot(currentRef, plotData, layout, config);\n bindTooltip(currentRef);\n\n // ── Event: peak click ──────────────────────────────────────────────────\n (currentRef as unknown as Plotly.PlotlyHTMLElement).on(\n \"plotly_click\",\n (eventData: Plotly.PlotMouseEvent) => {\n if (!onPeakClickRef.current) return;\n const peakPoint = eventData.points.find((p) => p.customdata != null);\n if (!peakPoint) return;\n onPeakClickRef.current(peakPoint.customdata as unknown as PeakSelectEvent);\n }\n );\n\n (currentRef as unknown as Plotly.PlotlyHTMLElement).on(\n \"plotly_hover\",\n createHoverHandler(currentRef, processedSeries.length, thickenedSeriesRef, onPeakHoverRef, resolvedAppearance.hoverLineWidthMultiplier)\n );\n\n (currentRef as unknown as Plotly.PlotlyHTMLElement).on(\n \"plotly_unhover\",\n createUnhoverHandler(currentRef, thickenedSeriesRef, onPeakHoverRef)\n );\n\n return () => {\n thickenedSeriesRef.current = null;\n if (currentRef) Plotly.purge(currentRef);\n };\n }, [\n processedSeries, allDetectedPeaks, allPeaksForInteraction, series.length,\n width, height, title, titleFontSize, titleTopMargin, xAxisTitle, yAxisTitle,\n processedAnnotations, xRange, yRange, showLegend, showGridX, showGridY,\n showMarkers, markerSize, showCrosshairs, enablePeakDetection, peakDetectionOptions,\n showPeakAreas, boundaryMarkers, annotationOverlapThreshold, showExportButton,\n theme, bindTooltip,\n // resolvedAppearance included so hover multiplier stays in sync with the\n // event handler closure without it being in a ref itself.\n resolvedAppearance,\n ]);\n\n // ── Selection update effect ────────────────────────────────────────────────\n // Runs when selectedPeakIds / selectionAppearance change (peakAnnotations\n // recomputes). Uses Plotly.relayout so the user's zoom/pan state is preserved.\n useEffect(() => {\n const el = plotRef.current;\n if (!el) return;\n // Guard: skip if the chart hasn't been initialized by the main effect yet.\n if (!(el as { _fullLayout?: unknown })._fullLayout) return;\n\n Plotly.relayout(el, {\n annotations: peakAnnotations,\n } as unknown as Partial<Plotly.Layout>);\n }, [peakAnnotations]);\n\n // No data: render an explicit empty state instead of an uninitialized\n // (blank) Plotly container, so the chart reads as \"no data yet\" rather\n // than looking broken while data is still loading.\n if (series.length === 0) {\n return (\n <div\n className=\"chromatogram-chart-container relative flex items-center justify-center\"\n style={{ width, height }}\n >\n <EmptyState\n variant=\"no-data\"\n title=\"No chromatogram data\"\n description=\"There is no signal data to display yet.\"\n />\n </div>\n );\n }\n\n return (\n <div className=\"chromatogram-chart-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { ChromatogramChart };\n"],"names":["EMPTY_ANNOTATIONS","ChromatogramChart","series","width","height","title","xAxisTitle","yAxisTitle","annotations","xRange","yRange","showLegend","showGridX","showGridY","showMarkers","markerSize","showCrosshairs","baselineCorrection","baselineWindowSize","peakDetectionOptions","showPeakAreas","boundaryMarkers","annotationOverlapThreshold","showExportButton","selectedPeakIds","onPeakClick","onPeakHover","selectionAppearance","annotationStyle","titleFontSize","titleTopMargin","enablePeakDetection","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","onPeakClickRef","onPeakHoverRef","thickenedSeriesRef","peakAnnotationsRef","processedSeries","useMemo","s","validated","validateSeriesData","applyBaselineCorrection","processedAnnotations","x","y","processUserAnnotations","allDetectedPeaks","peaks","index","detected","detectPeaks","selectedBorderColor","selectedBackgroundColor","selectedBold","unselectedOpacity","hoverLineWidthMultiplier","resolvedAppearance","resolveSelectionAppearance","allPeaksForInteraction","result","ann","i","seriesIndex","peak","peakIndex","peakAnnotations","anySelected","options","allPeaksWithMeta","groups","groupOverlappingPeaks","group","createGroupAnnotations","useEffect","currentRef","plotData","buildTraceData","layout","buildLayout","config","buildConfig","Plotly","eventData","peakPoint","p","createHoverHandler","createUnhoverHandler","el","jsx","EmptyState","jsxs"],"mappings":"8bAyDMA,GAAsC,CAAA,EAEtCC,GAAsD,CAAC,CAC3D,OAAAC,EACA,MAAAC,EAAQ,IACR,OAAAC,EAAS,IACT,MAAAC,EACA,WAAAC,EAAa,uBACb,WAAAC,EAAa,eAAA,YACbC,EAAcR,GACd,OAAAS,EACA,OAAAC,EACA,WAAAC,EAAa,GACb,UAAAC,EAAY,GACZ,UAAAC,EAAY,GACZ,YAAAC,EAAc,GACd,WAAAC,EAAa,EACb,eAAAC,EAAiB,GACjB,mBAAAC,EAAqB,OACrB,mBAAAC,EAAqB,GACrB,qBAAAC,EACA,cAAAC,EAAgB,GAChB,gBAAAC,EAAkB,OAClB,2BAAAC,EAA6B,GAC7B,iBAAAC,EAAmB,GACnB,gBAAAC,EACA,YAAAC,EACA,YAAAC,EACA,oBAAAC,EACA,gBAAAC,EAAkB,QAClB,cAAAC,EAAgB,GAChB,eAAAC,CACF,IAAM,CACJ,MAAMC,EAAsBZ,IAAyB,OAC/Ca,EAAUC,EAAAA,OAAuB,IAAI,EACrCC,EAAQC,GAAAA,eAAA,EACR,CAAE,YAAAC,EAAa,eAAAC,EAAA,EAAmBC,mBAAgB,CACtD,OAAQhC,EACR,OAAQC,CAAA,CACT,EAGKgC,EAAiBN,EAAAA,OAAOR,CAAW,EACnCe,EAAiBP,EAAAA,OAAOP,CAAW,EACzCa,EAAe,QAAUd,EACzBe,EAAe,QAAUd,EAGzB,MAAMe,EAAqBR,EAAAA,OAAsB,IAAI,EAI/CS,GAAqBT,EAAAA,OAAsC,EAAE,EAG7DU,EAAkBC,EAAAA,QAAQ,IACvB1C,EAAO,IAAK2C,GAAM,CACvB,MAAMC,EAAYC,EAAAA,mBAAmBF,EAAE,EAAGA,EAAE,CAAC,EAC7C,MAAO,CACL,GAAGA,EACH,EAAGC,EAAU,EACb,EAAGE,EAAAA,wBAAwBF,EAAU,EAAG7B,EAAoBC,CAAkB,CAAA,CAElF,CAAC,EACA,CAAChB,EAAQe,EAAoBC,CAAkB,CAAC,EAG7C+B,EAAuBL,EAAAA,QAAQ,IAAM,CACzC,GAAIpC,EAAY,SAAW,GAAKmC,EAAgB,SAAW,EACzD,OAAOnC,EAET,KAAM,CAAE,EAAA0C,EAAG,EAAAC,GAAMR,EAAgB,CAAC,EAClC,OAAOS,yBAAuB5C,EAAa0C,EAAGC,CAAC,CACjD,EAAG,CAAC3C,EAAamC,CAAe,CAAC,EAG3BU,EAAmBT,EAAAA,QAAQ,IAAM,CACrC,MAAMU,EAA4D,CAAA,EAClE,OAAIvB,GAAuBZ,GACzBwB,EAAgB,QAAQ,CAACE,EAAGU,IAAU,CACpC,MAAMC,EAAWC,GAAAA,YAAYZ,EAAE,EAAGA,EAAE,EAAG1B,CAAoB,EACvDqC,EAAS,OAAS,GACpBF,EAAM,KAAK,CAAE,MAAOE,EAAU,YAAaD,EAAO,CAEtD,CAAC,EAEID,CACT,EAAG,CAACX,EAAiBZ,EAAqBZ,CAAoB,CAAC,EAMzDuC,GAAsB/B,GAAqB,UAAU,YACrDgC,GAA0BhC,GAAqB,UAAU,gBACzDiC,GAAejC,GAAqB,UAAU,KAC9CkC,GAAoBlC,GAAqB,YAAY,QACrDmC,GAA2BnC,GAAqB,yBAIhDoC,EAAqBnB,EAAAA,QACzB,IACEoB,6BAA2B,CACzB,SAAU,CACR,YAAaN,GACb,gBAAiBC,GACjB,KAAMC,EAAA,EAER,WAAY,CAAE,QAASC,EAAA,EACvB,yBAAAC,EAAA,CACD,EACH,CACEJ,GACAC,GACAC,GACAC,GACAC,EAAA,CACF,EAKIG,GAAyBrB,EAAAA,QAAQ,IAAM,CAC3C,MAAMsB,EAKD,CAAA,EAEL,OAAAjB,EAAqB,QAAQ,CAACkB,EAAKC,IAAM,CACvCF,EAAO,KAAK,CACV,KAAM,CAAE,GAAGC,EAAK,GAAIA,EAAI,IAAM,YAAYC,CAAC,EAAA,EAC3C,YAAa,EACb,WAAYlE,EAAO,CAAC,GAAG,MAAQ,GAC/B,eAAgB,EAAA,CACjB,CACH,CAAC,EAEDmD,EAAiB,QAAQ,CAAC,CAAE,MAAAC,EAAO,YAAAe,KAAkB,CACnDf,EAAM,QAAQ,CAACgB,EAAMC,IAAc,CACjCL,EAAO,KAAK,CACV,KAAM,CAAE,GAAGI,EAAM,GAAI,QAAQD,CAAW,IAAIE,CAAS,EAAA,EACrD,YAAAF,EACA,WAAYnE,EAAOmE,CAAW,GAAG,MAAQ,UAAUA,EAAc,CAAC,GAClE,eAAgB,EAAA,CACjB,CACH,CAAC,CACH,CAAC,EAEMH,CACT,EAAG,CAACjB,EAAsBI,EAAkBnD,CAAM,CAAC,EAM7CsE,EAAkB5B,EAAAA,QAAQ,IAAM,CACpC,MAAM6B,GAAejD,GAAiB,QAAU,GAAK,EAC/CkD,EAAU,CACd,gBAAiBlD,GAAmB,CAAA,EACpC,YAAAiD,EACA,WAAYV,EACZ,gBAAAnC,CAAA,EAGI+C,EAAmC,CAAA,EAEzC1B,EAAqB,QAAQ,CAACkB,EAAKC,IAAM,CACvCO,EAAiB,KAAK,CACpB,KAAM,CAAE,GAAGR,EAAK,GAAIA,EAAI,IAAM,YAAYC,CAAC,EAAA,EAC3C,YAAa,EAAA,CACd,CACH,CAAC,EAEGhD,GAAiBW,GACnBsB,EAAiB,QAAQ,CAAC,CAAE,MAAAC,EAAO,YAAAe,KAAkB,CACnDf,EAAM,QAAQ,CAACgB,GAAMC,KAAc,CACjCI,EAAiB,KAAK,CACpB,KAAM,CAAE,GAAGL,GAAM,GAAI,QAAQD,CAAW,IAAIE,EAAS,EAAA,EACrD,YAAAF,CAAA,CACD,CACH,CAAC,CACH,CAAC,EAGH,MAAMO,EAASC,EAAAA,sBAAsBF,EAAkBrD,CAA0B,EAC3E4C,EAAwC,CAAA,EAC9C,UAAWY,KAASF,EAClBV,EAAO,KAAK,GAAGa,EAAAA,uBAAuBD,EAAOJ,CAAO,CAAC,EAEvD,OAAOR,CACT,EAAG,CACDjB,EACAI,EACAjC,EACAW,EACAT,EACAE,EACAuC,EACAnC,CAAA,CACD,EA4GD,OAxGAc,GAAmB,QAAU8B,EAO7BQ,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAajD,EAAQ,QAC3B,GAAI,CAACiD,GAAc/E,EAAO,SAAW,EAAG,OAKxC,MAAMgF,EAAWC,EAAAA,eAAe,CAC9B,gBAAAxC,EACA,qBAAAM,EACA,iBAAAI,EACA,uBAAAY,GACA,YAAAnD,EACA,WAAAC,EACA,WAAAT,EACA,WAAAC,EACA,gBAAAc,CAAA,CACD,EAEK+D,EAASC,EAAAA,YAAY,CACzB,MAAAhF,EACA,cAAAwB,EACA,eAAAC,EACA,MAAA3B,EACA,OAAAC,EACA,WAAAE,EACA,WAAAC,EACA,OAAAE,EACA,OAAAC,EACA,WAAAC,EACA,YAAaT,EAAO,OACpB,UAAAU,EACA,UAAAC,EACA,eAAAG,EACA,MAAAkB,EACA,gBAAiBQ,GAAmB,OAAA,CACrC,EAEK4C,EAASC,EAAAA,YAAY,CAAE,iBAAAhE,EAAkB,MAAApB,EAAO,OAAAC,EAAQ,EAE9D,OAAAoF,EAAO,QAAQP,EAAYC,EAAUE,EAAQE,CAAM,EACnDlD,EAAY6C,CAAU,EAGrBA,EAAmD,GAClD,eACCQ,GAAqC,CACpC,GAAI,CAAClD,EAAe,QAAS,OAC7B,MAAMmD,EAAYD,EAAU,OAAO,KAAME,GAAMA,EAAE,YAAc,IAAI,EAC9DD,GACLnD,EAAe,QAAQmD,EAAU,UAAwC,CAC3E,CAAA,EAGDT,EAAmD,GAClD,eACAW,EAAAA,mBAAmBX,EAAYtC,EAAgB,OAAQF,EAAoBD,EAAgBuB,EAAmB,wBAAwB,CAAA,EAGvIkB,EAAmD,GAClD,iBACAY,uBAAqBZ,EAAYxC,EAAoBD,CAAc,CAAA,EAG9D,IAAM,CACXC,EAAmB,QAAU,KACzBwC,GAAYO,EAAO,MAAMP,CAAU,CACzC,CACF,EAAG,CACDtC,EAAiBU,EAAkBY,GAAwB/D,EAAO,OAClEC,EAAOC,EAAQC,EAAOwB,EAAeC,EAAgBxB,EAAYC,EACjE0C,EAAsBxC,EAAQC,EAAQC,EAAYC,EAAWC,EAC7DC,EAAaC,EAAYC,EAAgBe,EAAqBZ,EAC9DC,EAAeC,EAAiBC,EAA4BC,EAC5DW,EAAOE,EAGP2B,CAAA,CACD,EAKDiB,EAAAA,UAAU,IAAM,CACd,MAAMc,EAAK9D,EAAQ,QACd8D,GAECA,EAAiC,aAEvCN,EAAO,SAASM,EAAI,CAClB,YAAatB,CAAA,CACuB,CACxC,EAAG,CAACA,CAAe,CAAC,EAKhBtE,EAAO,SAAW,EAElB6F,EAAAA,IAAC,MAAA,CACC,UAAU,yEACV,MAAO,CAAE,MAAA5F,EAAO,OAAAC,CAAA,EAEhB,SAAA2F,EAAAA,IAACC,GAAAA,WAAA,CACC,QAAQ,UACR,MAAM,uBACN,YAAY,yCAAA,CAAA,CACd,CAAA,EAMJC,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAF,EAAAA,IAAC,MAAA,CAAI,IAAK/D,EAAS,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAA,CAAO,CAAG,EAC5DK,EAAA,EACH,CAEJ"}