matterviz 0.3.6 → 0.3.7

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 (863) hide show
  1. package/dist/EmptyState.svelte.d.ts +9 -0
  2. package/dist/FilePicker.svelte +360 -0
  3. package/dist/FilePicker.svelte.d.ts +17 -0
  4. package/dist/Icon.svelte.d.ts +13 -0
  5. package/dist/MillerIndexInput.svelte +66 -0
  6. package/dist/MillerIndexInput.svelte.d.ts +7 -0
  7. package/dist/api/mp.d.ts +6 -0
  8. package/dist/api/mp.js +22 -0
  9. package/dist/api/optimade.d.ts +45 -0
  10. package/dist/api/optimade.js +135 -0
  11. package/dist/brillouin/BrillouinZone.svelte +549 -0
  12. package/dist/brillouin/BrillouinZone.svelte.d.ts +83 -0
  13. package/dist/brillouin/BrillouinZoneControls.svelte +144 -0
  14. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +17 -0
  15. package/dist/brillouin/BrillouinZoneExportPane.svelte +146 -0
  16. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
  17. package/dist/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  18. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
  19. package/dist/brillouin/BrillouinZoneScene.svelte +476 -0
  20. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +48 -0
  21. package/dist/brillouin/BrillouinZoneTooltip.svelte +92 -0
  22. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +8 -0
  23. package/dist/brillouin/compute.d.ts +17 -0
  24. package/dist/brillouin/compute.js +426 -0
  25. package/dist/brillouin/index.d.ts +8 -0
  26. package/dist/brillouin/index.js +7 -0
  27. package/dist/brillouin/types.d.ts +43 -0
  28. package/dist/brillouin/types.js +1 -0
  29. package/dist/chempot-diagram/ChemPotDiagram.svelte +327 -0
  30. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  31. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +846 -0
  32. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  33. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3193 -0
  34. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  35. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  36. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  37. package/dist/chempot-diagram/async-compute.svelte.js +78 -0
  38. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  39. package/dist/chempot-diagram/chempot-worker.js +11 -0
  40. package/dist/chempot-diagram/color.d.ts +10 -0
  41. package/dist/chempot-diagram/color.js +32 -0
  42. package/dist/chempot-diagram/compute.d.ts +48 -0
  43. package/dist/chempot-diagram/compute.js +806 -0
  44. package/dist/chempot-diagram/index.d.ts +6 -0
  45. package/dist/chempot-diagram/index.js +6 -0
  46. package/dist/chempot-diagram/pointer.d.ts +16 -0
  47. package/dist/chempot-diagram/pointer.js +40 -0
  48. package/dist/chempot-diagram/temperature.d.ts +15 -0
  49. package/dist/chempot-diagram/temperature.js +34 -0
  50. package/dist/chempot-diagram/types.d.ts +81 -0
  51. package/dist/chempot-diagram/types.js +28 -0
  52. package/dist/colors/index.d.ts +47 -0
  53. package/dist/colors/index.js +203 -0
  54. package/dist/composition/BarChart.svelte +297 -0
  55. package/dist/composition/BarChart.svelte.d.ts +39 -0
  56. package/dist/composition/BubbleChart.svelte +218 -0
  57. package/dist/composition/BubbleChart.svelte.d.ts +28 -0
  58. package/dist/composition/Composition.svelte +165 -0
  59. package/dist/composition/Composition.svelte.d.ts +15 -0
  60. package/dist/composition/Formula.svelte +268 -0
  61. package/dist/composition/Formula.svelte.d.ts +19 -0
  62. package/dist/composition/FormulaFilter.svelte +1257 -0
  63. package/dist/composition/FormulaFilter.svelte.d.ts +51 -0
  64. package/dist/composition/PieChart.svelte +323 -0
  65. package/dist/composition/PieChart.svelte.d.ts +37 -0
  66. package/dist/composition/format.d.ts +15 -0
  67. package/dist/composition/format.js +109 -0
  68. package/dist/composition/index.d.ts +20 -0
  69. package/dist/composition/index.js +14 -0
  70. package/dist/composition/parse.d.ts +56 -0
  71. package/dist/composition/parse.js +474 -0
  72. package/dist/constants.d.ts +29 -0
  73. package/dist/constants.js +99 -0
  74. package/dist/controls.d.ts +14 -0
  75. package/dist/controls.js +30 -0
  76. package/dist/convex-hull/ConvexHull.svelte +157 -0
  77. package/dist/convex-hull/ConvexHull.svelte.d.ts +13 -0
  78. package/dist/convex-hull/ConvexHull2D.svelte +825 -0
  79. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +11 -0
  80. package/dist/convex-hull/ConvexHull3D.svelte +1801 -0
  81. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +8 -0
  82. package/dist/convex-hull/ConvexHull4D.svelte +1398 -0
  83. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +8 -0
  84. package/dist/convex-hull/ConvexHullControls.svelte +535 -0
  85. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +48 -0
  86. package/dist/convex-hull/ConvexHullInfoPane.svelte +125 -0
  87. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +20 -0
  88. package/dist/convex-hull/ConvexHullStats.svelte +929 -0
  89. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +17 -0
  90. package/dist/convex-hull/ConvexHullTooltip.svelte +131 -0
  91. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +33 -0
  92. package/dist/convex-hull/GasPressureControls.svelte +247 -0
  93. package/dist/convex-hull/GasPressureControls.svelte.d.ts +11 -0
  94. package/dist/convex-hull/StructurePopup.svelte +151 -0
  95. package/dist/convex-hull/StructurePopup.svelte.d.ts +18 -0
  96. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +8 -0
  97. package/dist/convex-hull/barycentric-coords.d.ts +18 -0
  98. package/dist/convex-hull/barycentric-coords.js +182 -0
  99. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  100. package/dist/convex-hull/demo-temperature.js +40 -0
  101. package/dist/convex-hull/gas-thermodynamics.d.ts +16 -0
  102. package/dist/convex-hull/gas-thermodynamics.js +314 -0
  103. package/dist/convex-hull/helpers.d.ts +114 -0
  104. package/dist/convex-hull/helpers.js +710 -0
  105. package/dist/convex-hull/index.d.ts +119 -0
  106. package/dist/convex-hull/index.js +58 -0
  107. package/dist/convex-hull/thermodynamics.d.ts +67 -0
  108. package/dist/convex-hull/thermodynamics.js +1752 -0
  109. package/dist/convex-hull/types.d.ts +162 -0
  110. package/dist/convex-hull/types.js +36 -0
  111. package/dist/coordination/CoordinationBarPlot.svelte +311 -0
  112. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +30 -0
  113. package/dist/coordination/calc-coordination.d.ts +15 -0
  114. package/dist/coordination/calc-coordination.js +63 -0
  115. package/dist/coordination/index.d.ts +8 -0
  116. package/dist/coordination/index.js +7 -0
  117. package/dist/effects.svelte.d.ts +12 -0
  118. package/dist/effects.svelte.js +37 -0
  119. package/dist/element/BohrAtom.svelte.d.ts +20 -0
  120. package/dist/element/ElementHeading.svelte +26 -0
  121. package/dist/element/ElementHeading.svelte.d.ts +8 -0
  122. package/dist/element/ElementPhoto.svelte +57 -0
  123. package/dist/element/ElementPhoto.svelte.d.ts +9 -0
  124. package/dist/element/ElementStats.svelte +80 -0
  125. package/dist/element/ElementStats.svelte.d.ts +8 -0
  126. package/dist/element/ElementTile.svelte +484 -0
  127. package/dist/element/ElementTile.svelte.d.ts +29 -0
  128. package/dist/element/Nucleus.svelte.d.ts +17 -0
  129. package/dist/element/data.d.ts +2 -0
  130. package/dist/element/data.js +2 -0
  131. package/dist/element/index.d.ts +8 -0
  132. package/dist/element/index.js +7 -0
  133. package/dist/element/types.d.ts +57 -0
  134. package/dist/element/types.js +1 -0
  135. package/dist/feedback/ClickFeedback.svelte +58 -0
  136. package/dist/feedback/ClickFeedback.svelte.d.ts +12 -0
  137. package/dist/feedback/DragOverlay.svelte +42 -0
  138. package/dist/feedback/DragOverlay.svelte.d.ts +7 -0
  139. package/dist/feedback/Spinner.svelte.d.ts +7 -0
  140. package/dist/feedback/StatusMessage.svelte.d.ts +9 -0
  141. package/dist/feedback/index.d.ts +4 -0
  142. package/dist/feedback/index.js +4 -0
  143. package/dist/fermi-surface/FermiSlice.svelte +189 -0
  144. package/dist/fermi-surface/FermiSlice.svelte.d.ts +24 -0
  145. package/dist/fermi-surface/FermiSurface.svelte +600 -0
  146. package/dist/fermi-surface/FermiSurface.svelte.d.ts +83 -0
  147. package/dist/fermi-surface/FermiSurfaceControls.svelte +448 -0
  148. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +35 -0
  149. package/dist/fermi-surface/FermiSurfaceScene.svelte +794 -0
  150. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +50 -0
  151. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +111 -0
  152. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +8 -0
  153. package/dist/fermi-surface/compute.d.ts +5 -0
  154. package/dist/fermi-surface/compute.js +538 -0
  155. package/dist/fermi-surface/constants.d.ts +9 -0
  156. package/dist/fermi-surface/constants.js +27 -0
  157. package/dist/fermi-surface/export.d.ts +5 -0
  158. package/dist/fermi-surface/export.js +50 -0
  159. package/dist/fermi-surface/index.d.ts +12 -0
  160. package/dist/fermi-surface/index.js +13 -0
  161. package/dist/fermi-surface/marching-cubes.d.ts +2 -0
  162. package/dist/fermi-surface/marching-cubes.js +2 -0
  163. package/dist/fermi-surface/parse.d.ts +2 -0
  164. package/dist/fermi-surface/parse.js +491 -0
  165. package/dist/fermi-surface/symmetry.d.ts +3 -0
  166. package/dist/fermi-surface/symmetry.js +46 -0
  167. package/dist/fermi-surface/types.d.ts +110 -0
  168. package/dist/fermi-surface/types.js +4 -0
  169. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1545 -0
  170. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  171. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  172. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  173. package/dist/heatmap-matrix/index.d.ts +53 -0
  174. package/dist/heatmap-matrix/index.js +100 -0
  175. package/dist/heatmap-matrix/shared.d.ts +2 -0
  176. package/dist/heatmap-matrix/shared.js +4 -0
  177. package/dist/icons.d.ts +569 -0
  178. package/dist/icons.js +648 -0
  179. package/dist/index.d.ts +39 -0
  180. package/dist/index.js +39 -0
  181. package/dist/io/decompress.d.ts +11 -0
  182. package/dist/io/decompress.js +74 -0
  183. package/dist/io/export.d.ts +16 -0
  184. package/dist/io/export.js +316 -0
  185. package/dist/io/fetch.d.ts +5 -0
  186. package/dist/io/fetch.js +39 -0
  187. package/dist/io/file-drop.d.ts +7 -0
  188. package/dist/io/file-drop.js +43 -0
  189. package/dist/io/index.d.ts +7 -0
  190. package/dist/io/index.js +6 -0
  191. package/dist/io/is-binary.d.ts +1 -0
  192. package/dist/io/is-binary.js +20 -0
  193. package/dist/io/types.d.ts +8 -0
  194. package/dist/io/types.js +1 -0
  195. package/dist/io/url-drop.d.ts +2 -0
  196. package/dist/io/url-drop.js +123 -0
  197. package/dist/isosurface/Isosurface.svelte +285 -0
  198. package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
  199. package/dist/isosurface/IsosurfaceControls.svelte +277 -0
  200. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
  201. package/dist/isosurface/index.d.ts +5 -0
  202. package/dist/isosurface/index.js +6 -0
  203. package/dist/isosurface/parse.d.ts +6 -0
  204. package/dist/isosurface/parse.js +553 -0
  205. package/dist/isosurface/slice.d.ts +11 -0
  206. package/dist/isosurface/slice.js +140 -0
  207. package/dist/isosurface/types.d.ts +56 -0
  208. package/dist/isosurface/types.js +227 -0
  209. package/dist/labels.d.ts +53 -0
  210. package/dist/labels.js +277 -0
  211. package/dist/layout/FullscreenToggle.svelte +50 -0
  212. package/dist/layout/FullscreenToggle.svelte.d.ts +7 -0
  213. package/dist/layout/InfoCard.svelte +120 -0
  214. package/dist/layout/InfoCard.svelte.d.ts +21 -0
  215. package/dist/layout/InfoTag.svelte +185 -0
  216. package/dist/layout/InfoTag.svelte.d.ts +19 -0
  217. package/dist/layout/PropertyFilter.svelte +246 -0
  218. package/dist/layout/PropertyFilter.svelte.d.ts +24 -0
  219. package/dist/layout/SettingsSection.svelte +148 -0
  220. package/dist/layout/SettingsSection.svelte.d.ts +17 -0
  221. package/dist/layout/SubpageGrid.svelte +82 -0
  222. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  223. package/dist/layout/fullscreen.d.ts +9 -0
  224. package/dist/layout/fullscreen.js +53 -0
  225. package/dist/layout/index.d.ts +10 -0
  226. package/dist/layout/index.js +8 -0
  227. package/dist/layout/json-tree/JsonNode.svelte +548 -0
  228. package/dist/layout/json-tree/JsonNode.svelte.d.ts +11 -0
  229. package/dist/layout/json-tree/JsonTree.svelte +1230 -0
  230. package/dist/layout/json-tree/JsonTree.svelte.d.ts +6 -0
  231. package/dist/layout/json-tree/JsonValue.svelte.d.ts +9 -0
  232. package/dist/layout/json-tree/index.d.ts +3 -0
  233. package/dist/layout/json-tree/index.js +3 -0
  234. package/dist/layout/json-tree/types.d.ts +74 -0
  235. package/dist/layout/json-tree/types.js +2 -0
  236. package/dist/layout/json-tree/utils.d.ts +29 -0
  237. package/dist/layout/json-tree/utils.js +641 -0
  238. package/dist/marching-cubes.d.ts +14 -0
  239. package/dist/marching-cubes.js +540 -0
  240. package/dist/math.d.ts +101 -0
  241. package/dist/math.js +905 -0
  242. package/dist/overlays/ContextMenu.svelte +162 -0
  243. package/dist/overlays/ContextMenu.svelte.d.ts +25 -0
  244. package/dist/overlays/CopyButton.svelte +45 -0
  245. package/dist/overlays/CopyButton.svelte.d.ts +8 -0
  246. package/dist/overlays/DragControlTab.svelte +98 -0
  247. package/dist/overlays/DragControlTab.svelte.d.ts +8 -0
  248. package/dist/overlays/DraggablePane.svelte +487 -0
  249. package/dist/overlays/DraggablePane.svelte.d.ts +36 -0
  250. package/dist/overlays/InfoPaneCards.svelte +149 -0
  251. package/dist/overlays/InfoPaneCards.svelte.d.ts +22 -0
  252. package/dist/overlays/index.d.ts +3 -0
  253. package/dist/overlays/index.js +3 -0
  254. package/dist/periodic-table/PeriodicTable.svelte +469 -0
  255. package/dist/periodic-table/PeriodicTable.svelte.d.ts +55 -0
  256. package/dist/periodic-table/PeriodicTableControls.svelte +557 -0
  257. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +24 -0
  258. package/dist/periodic-table/PropertySelect.svelte +37 -0
  259. package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
  260. package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
  261. package/dist/periodic-table/index.d.ts +10 -0
  262. package/dist/periodic-table/index.js +4 -0
  263. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1086 -0
  264. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +44 -0
  265. package/dist/phase-diagram/PhaseDiagramControls.svelte +444 -0
  266. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +30 -0
  267. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  268. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  269. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  270. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +19 -0
  271. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  272. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +16 -0
  273. package/dist/phase-diagram/TdbInfoPanel.svelte +203 -0
  274. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +12 -0
  275. package/dist/phase-diagram/build-diagram.d.ts +11 -0
  276. package/dist/phase-diagram/build-diagram.js +160 -0
  277. package/dist/phase-diagram/colors.d.ts +35 -0
  278. package/dist/phase-diagram/colors.js +51 -0
  279. package/dist/phase-diagram/diagram-input.d.ts +29 -0
  280. package/dist/phase-diagram/diagram-input.js +3 -0
  281. package/dist/phase-diagram/index.d.ts +13 -0
  282. package/dist/phase-diagram/index.js +11 -0
  283. package/dist/phase-diagram/parse.d.ts +55 -0
  284. package/dist/phase-diagram/parse.js +272 -0
  285. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  286. package/dist/phase-diagram/svg-to-diagram.js +867 -0
  287. package/dist/phase-diagram/types.d.ts +93 -0
  288. package/dist/phase-diagram/types.js +1 -0
  289. package/dist/phase-diagram/utils.d.ts +118 -0
  290. package/dist/phase-diagram/utils.js +604 -0
  291. package/dist/plot/AxisLabel.svelte +51 -0
  292. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  293. package/dist/plot/BarPlot.svelte +2113 -0
  294. package/dist/plot/BarPlot.svelte.d.ts +84 -0
  295. package/dist/plot/BarPlotControls.svelte +66 -0
  296. package/dist/plot/BarPlotControls.svelte.d.ts +18 -0
  297. package/dist/plot/BinnedScatterPlot.svelte +1114 -0
  298. package/dist/plot/BinnedScatterPlot.svelte.d.ts +66 -0
  299. package/dist/plot/ColorBar.svelte +721 -0
  300. package/dist/plot/ColorBar.svelte.d.ts +31 -0
  301. package/dist/plot/ColorScaleSelect.svelte +54 -0
  302. package/dist/plot/ColorScaleSelect.svelte.d.ts +15 -0
  303. package/dist/plot/ElementScatter.svelte +63 -0
  304. package/dist/plot/ElementScatter.svelte.d.ts +14 -0
  305. package/dist/plot/FillArea.svelte.d.ts +21 -0
  306. package/dist/plot/Histogram.svelte +1558 -0
  307. package/dist/plot/Histogram.svelte.d.ts +50 -0
  308. package/dist/plot/HistogramControls.svelte +212 -0
  309. package/dist/plot/HistogramControls.svelte.d.ts +22 -0
  310. package/dist/plot/InteractiveAxisLabel.svelte +96 -0
  311. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +14 -0
  312. package/dist/plot/Line.svelte +84 -0
  313. package/dist/plot/Line.svelte.d.ts +15 -0
  314. package/dist/plot/PlotAxis.svelte +169 -0
  315. package/dist/plot/PlotAxis.svelte.d.ts +24 -0
  316. package/dist/plot/PlotControls.svelte +537 -0
  317. package/dist/plot/PlotControls.svelte.d.ts +4 -0
  318. package/dist/plot/PlotLegend.svelte +569 -0
  319. package/dist/plot/PlotLegend.svelte.d.ts +29 -0
  320. package/dist/plot/PlotTooltip.svelte +67 -0
  321. package/dist/plot/PlotTooltip.svelte.d.ts +17 -0
  322. package/dist/plot/PortalSelect.svelte +253 -0
  323. package/dist/plot/PortalSelect.svelte.d.ts +16 -0
  324. package/dist/plot/ReferenceLine.svelte.d.ts +20 -0
  325. package/dist/plot/ReferenceLine3D.svelte +156 -0
  326. package/dist/plot/ReferenceLine3D.svelte.d.ts +14 -0
  327. package/dist/plot/ReferencePlane.svelte +175 -0
  328. package/dist/plot/ReferencePlane.svelte.d.ts +14 -0
  329. package/dist/plot/ScatterPlot.svelte +2778 -0
  330. package/dist/plot/ScatterPlot.svelte.d.ts +96 -0
  331. package/dist/plot/ScatterPlot3D.svelte +529 -0
  332. package/dist/plot/ScatterPlot3D.svelte.d.ts +95 -0
  333. package/dist/plot/ScatterPlot3DControls.svelte +437 -0
  334. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +20 -0
  335. package/dist/plot/ScatterPlot3DScene.svelte +912 -0
  336. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +74 -0
  337. package/dist/plot/ScatterPlotControls.svelte +306 -0
  338. package/dist/plot/ScatterPlotControls.svelte.d.ts +17 -0
  339. package/dist/plot/ScatterPoint.svelte +182 -0
  340. package/dist/plot/ScatterPoint.svelte.d.ts +22 -0
  341. package/dist/plot/SpacegroupBarPlot.svelte +293 -0
  342. package/dist/plot/SpacegroupBarPlot.svelte.d.ts +9 -0
  343. package/dist/plot/Surface3D.svelte +197 -0
  344. package/dist/plot/Surface3D.svelte.d.ts +13 -0
  345. package/dist/plot/ZeroLines.svelte +97 -0
  346. package/dist/plot/ZeroLines.svelte.d.ts +33 -0
  347. package/dist/plot/ZoomRect.svelte +23 -0
  348. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  349. package/dist/plot/adaptive-density.d.ts +69 -0
  350. package/dist/plot/adaptive-density.js +191 -0
  351. package/dist/plot/auto-place.d.ts +43 -0
  352. package/dist/plot/auto-place.js +122 -0
  353. package/dist/plot/axis-utils.d.ts +19 -0
  354. package/dist/plot/axis-utils.js +78 -0
  355. package/dist/plot/binned-scatter-types.d.ts +59 -0
  356. package/dist/plot/binned-scatter-types.js +1 -0
  357. package/dist/plot/data-cleaning.d.ts +37 -0
  358. package/dist/plot/data-cleaning.js +855 -0
  359. package/dist/plot/data-transform.d.ts +16 -0
  360. package/dist/plot/data-transform.js +45 -0
  361. package/dist/plot/defaults.d.ts +19 -0
  362. package/dist/plot/defaults.js +9 -0
  363. package/dist/plot/fill-utils.d.ts +46 -0
  364. package/dist/plot/fill-utils.js +322 -0
  365. package/dist/plot/hover-lock.svelte.d.ts +14 -0
  366. package/dist/plot/hover-lock.svelte.js +46 -0
  367. package/dist/plot/index.d.ts +41 -0
  368. package/dist/plot/index.js +39 -0
  369. package/dist/plot/interactions.d.ts +12 -0
  370. package/dist/plot/interactions.js +101 -0
  371. package/dist/plot/layout.d.ts +78 -0
  372. package/dist/plot/layout.js +273 -0
  373. package/dist/plot/reference-line.d.ts +60 -0
  374. package/dist/plot/reference-line.js +314 -0
  375. package/dist/plot/scales.d.ts +48 -0
  376. package/dist/plot/scales.js +481 -0
  377. package/dist/plot/svg.d.ts +1 -0
  378. package/dist/plot/svg.js +11 -0
  379. package/dist/plot/types.d.ts +831 -0
  380. package/dist/plot/types.js +99 -0
  381. package/dist/plot/utils/label-placement.d.ts +68 -0
  382. package/dist/plot/utils/label-placement.js +326 -0
  383. package/dist/plot/utils/series-visibility.d.ts +15 -0
  384. package/dist/plot/utils/series-visibility.js +85 -0
  385. package/dist/plot/utils.d.ts +1 -0
  386. package/dist/plot/utils.js +14 -0
  387. package/dist/rdf/RdfPlot.svelte +247 -0
  388. package/dist/rdf/RdfPlot.svelte.d.ts +27 -0
  389. package/dist/rdf/calc-rdf.d.ts +4 -0
  390. package/dist/rdf/calc-rdf.js +111 -0
  391. package/dist/rdf/index.d.ts +23 -0
  392. package/dist/rdf/index.js +2 -0
  393. package/dist/sanitize.d.ts +6 -0
  394. package/dist/sanitize.js +116 -0
  395. package/dist/settings.d.ts +255 -0
  396. package/dist/settings.js +1132 -0
  397. package/dist/spectral/Bands.svelte +1040 -0
  398. package/dist/spectral/Bands.svelte.d.ts +40 -0
  399. package/dist/spectral/BandsAndDos.svelte +134 -0
  400. package/dist/spectral/BandsAndDos.svelte.d.ts +18 -0
  401. package/dist/spectral/BrillouinBandsDos.svelte +252 -0
  402. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +20 -0
  403. package/dist/spectral/Dos.svelte +697 -0
  404. package/dist/spectral/Dos.svelte.d.ts +29 -0
  405. package/dist/spectral/helpers.d.ts +119 -0
  406. package/dist/spectral/helpers.js +1032 -0
  407. package/dist/spectral/index.d.ts +6 -0
  408. package/dist/spectral/index.js +6 -0
  409. package/dist/spectral/types.d.ts +84 -0
  410. package/dist/spectral/types.js +2 -0
  411. package/dist/state.svelte.d.ts +25 -0
  412. package/dist/state.svelte.js +45 -0
  413. package/dist/structure/Arrow.svelte +72 -0
  414. package/dist/structure/Arrow.svelte.d.ts +15 -0
  415. package/dist/structure/AtomLegend.svelte +815 -0
  416. package/dist/structure/AtomLegend.svelte.d.ts +35 -0
  417. package/dist/structure/Bond.svelte +140 -0
  418. package/dist/structure/Bond.svelte.d.ts +9 -0
  419. package/dist/structure/CanvasTooltip.svelte +33 -0
  420. package/dist/structure/CanvasTooltip.svelte.d.ts +12 -0
  421. package/dist/structure/CellSelect.svelte +349 -0
  422. package/dist/structure/CellSelect.svelte.d.ts +13 -0
  423. package/dist/structure/Cylinder.svelte +45 -0
  424. package/dist/structure/Cylinder.svelte.d.ts +10 -0
  425. package/dist/structure/Lattice.svelte +196 -0
  426. package/dist/structure/Lattice.svelte.d.ts +17 -0
  427. package/dist/structure/Structure.svelte +2248 -0
  428. package/dist/structure/Structure.svelte.d.ts +89 -0
  429. package/dist/structure/StructureControls.svelte +1273 -0
  430. package/dist/structure/StructureControls.svelte.d.ts +31 -0
  431. package/dist/structure/StructureExportPane.svelte +252 -0
  432. package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
  433. package/dist/structure/StructureInfoPane.svelte +737 -0
  434. package/dist/structure/StructureInfoPane.svelte.d.ts +19 -0
  435. package/dist/structure/StructureScene.svelte +2255 -0
  436. package/dist/structure/StructureScene.svelte.d.ts +111 -0
  437. package/dist/structure/atom-properties.d.ts +37 -0
  438. package/dist/structure/atom-properties.js +200 -0
  439. package/dist/structure/bond-order-perception.d.ts +13 -0
  440. package/dist/structure/bond-order-perception.js +384 -0
  441. package/dist/structure/bonding.d.ts +68 -0
  442. package/dist/structure/bonding.js +696 -0
  443. package/dist/structure/export.d.ts +20 -0
  444. package/dist/structure/export.js +727 -0
  445. package/dist/structure/index.d.ts +126 -0
  446. package/dist/structure/index.js +169 -0
  447. package/dist/structure/label-placement.d.ts +14 -0
  448. package/dist/structure/label-placement.js +72 -0
  449. package/dist/structure/measure.d.ts +6 -0
  450. package/dist/structure/measure.js +29 -0
  451. package/dist/structure/parse.d.ts +66 -0
  452. package/dist/structure/parse.js +1392 -0
  453. package/dist/structure/partial-occupancy.d.ts +25 -0
  454. package/dist/structure/partial-occupancy.js +99 -0
  455. package/dist/structure/pbc.d.ts +9 -0
  456. package/dist/structure/pbc.js +123 -0
  457. package/dist/structure/supercell.d.ts +8 -0
  458. package/dist/structure/supercell.js +170 -0
  459. package/dist/structure/validation.d.ts +2 -0
  460. package/dist/structure/validation.js +10 -0
  461. package/dist/symmetry/SymmetryStats.svelte +226 -0
  462. package/dist/symmetry/SymmetryStats.svelte.d.ts +21 -0
  463. package/dist/symmetry/WyckoffTable.svelte +120 -0
  464. package/dist/symmetry/WyckoffTable.svelte.d.ts +11 -0
  465. package/dist/symmetry/cell-transform.d.ts +12 -0
  466. package/dist/symmetry/cell-transform.js +91 -0
  467. package/dist/symmetry/index.d.ts +43 -0
  468. package/dist/symmetry/index.js +228 -0
  469. package/dist/symmetry/spacegroups.d.ts +9 -0
  470. package/dist/symmetry/spacegroups.js +394 -0
  471. package/dist/table/HeatmapTable.svelte +1833 -0
  472. package/dist/table/HeatmapTable.svelte.d.ts +49 -0
  473. package/dist/table/ToggleMenu.svelte +385 -0
  474. package/dist/table/ToggleMenu.svelte.d.ts +11 -0
  475. package/dist/table/index.d.ts +74 -0
  476. package/dist/table/index.js +38 -0
  477. package/dist/theme/ThemeControl.svelte +53 -0
  478. package/dist/theme/ThemeControl.svelte.d.ts +9 -0
  479. package/dist/theme/index.d.ts +29 -0
  480. package/dist/theme/index.js +79 -0
  481. package/dist/time.d.ts +4 -0
  482. package/dist/time.js +70 -0
  483. package/dist/tooltip/TooltipContent.svelte +58 -0
  484. package/dist/tooltip/TooltipContent.svelte.d.ts +31 -0
  485. package/dist/tooltip/index.d.ts +2 -0
  486. package/dist/tooltip/index.js +1 -0
  487. package/dist/tooltip/types.d.ts +8 -0
  488. package/dist/tooltip/types.js +1 -0
  489. package/dist/trajectory/Trajectory.svelte +1545 -0
  490. package/dist/trajectory/Trajectory.svelte.d.ts +77 -0
  491. package/dist/trajectory/TrajectoryError.svelte +128 -0
  492. package/dist/trajectory/TrajectoryError.svelte.d.ts +13 -0
  493. package/dist/trajectory/TrajectoryExportPane.svelte +357 -0
  494. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +17 -0
  495. package/dist/trajectory/TrajectoryInfoPane.svelte +313 -0
  496. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +17 -0
  497. package/dist/trajectory/constants.d.ts +6 -0
  498. package/dist/trajectory/constants.js +7 -0
  499. package/dist/trajectory/extract.d.ts +5 -0
  500. package/dist/trajectory/extract.js +162 -0
  501. package/dist/trajectory/format-detect.d.ts +9 -0
  502. package/dist/trajectory/format-detect.js +76 -0
  503. package/dist/trajectory/frame-reader.d.ts +17 -0
  504. package/dist/trajectory/frame-reader.js +332 -0
  505. package/dist/trajectory/helpers.d.ts +15 -0
  506. package/dist/trajectory/helpers.js +164 -0
  507. package/dist/trajectory/index.d.ts +63 -0
  508. package/dist/trajectory/index.js +126 -0
  509. package/dist/trajectory/parse/ase.d.ts +2 -0
  510. package/dist/trajectory/parse/ase.js +73 -0
  511. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  512. package/dist/trajectory/parse/hdf5.js +127 -0
  513. package/dist/trajectory/parse/index.d.ts +12 -0
  514. package/dist/trajectory/parse/index.js +298 -0
  515. package/dist/trajectory/parse/lammps.d.ts +5 -0
  516. package/dist/trajectory/parse/lammps.js +179 -0
  517. package/dist/trajectory/parse/vasp.d.ts +2 -0
  518. package/dist/trajectory/parse/vasp.js +68 -0
  519. package/dist/trajectory/parse/xyz.d.ts +2 -0
  520. package/dist/trajectory/parse/xyz.js +110 -0
  521. package/dist/trajectory/plotting.d.ts +28 -0
  522. package/dist/trajectory/plotting.js +423 -0
  523. package/dist/trajectory/types.d.ts +11 -0
  524. package/dist/trajectory/types.js +1 -0
  525. package/dist/utils.d.ts +6 -0
  526. package/dist/utils.js +45 -0
  527. package/dist/xrd/XrdPlot.svelte +615 -0
  528. package/dist/xrd/XrdPlot.svelte.d.ts +28 -0
  529. package/dist/xrd/broadening.d.ts +20 -0
  530. package/dist/xrd/broadening.js +97 -0
  531. package/dist/xrd/calc-xrd.d.ts +37 -0
  532. package/dist/xrd/calc-xrd.js +336 -0
  533. package/dist/xrd/index.d.ts +37 -0
  534. package/dist/xrd/index.js +4 -0
  535. package/dist/xrd/parse.d.ts +13 -0
  536. package/dist/xrd/parse.js +749 -0
  537. package/license +1 -1
  538. package/package.json +232 -1457
  539. package/readme.md +98 -171
  540. package/.vscode/launch.json +0 -13
  541. package/.vscodeignore +0 -7
  542. package/dist/assets/STLExporter-BpTH3YHE.js +0 -8
  543. package/dist/assets/browser-DdDecX_W.js +0 -1
  544. package/dist/assets/export-qgn-H9y6.js +0 -2
  545. package/dist/assets/main-DiKYzti2.css +0 -1
  546. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  547. package/dist/extension.js +0 -31293
  548. package/dist/src/lib/FilePicker.svelte +0 -360
  549. package/dist/src/lib/MillerIndexInput.svelte +0 -66
  550. package/dist/src/lib/api/mp.ts +0 -26
  551. package/dist/src/lib/api/optimade.ts +0 -204
  552. package/dist/src/lib/brillouin/BrillouinZone.svelte +0 -549
  553. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +0 -144
  554. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +0 -146
  555. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  556. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +0 -476
  557. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +0 -92
  558. package/dist/src/lib/brillouin/compute.ts +0 -529
  559. package/dist/src/lib/brillouin/index.ts +0 -8
  560. package/dist/src/lib/brillouin/types.ts +0 -51
  561. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +0 -327
  562. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +0 -846
  563. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +0 -3193
  564. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +0 -94
  565. package/dist/src/lib/chempot-diagram/chempot-worker.ts +0 -11
  566. package/dist/src/lib/chempot-diagram/color.ts +0 -42
  567. package/dist/src/lib/chempot-diagram/compute.ts +0 -1014
  568. package/dist/src/lib/chempot-diagram/index.ts +0 -6
  569. package/dist/src/lib/chempot-diagram/pointer.ts +0 -56
  570. package/dist/src/lib/chempot-diagram/temperature.ts +0 -77
  571. package/dist/src/lib/chempot-diagram/types.ts +0 -130
  572. package/dist/src/lib/colors/index.ts +0 -249
  573. package/dist/src/lib/composition/BarChart.svelte +0 -297
  574. package/dist/src/lib/composition/BubbleChart.svelte +0 -218
  575. package/dist/src/lib/composition/Composition.svelte +0 -165
  576. package/dist/src/lib/composition/Formula.svelte +0 -268
  577. package/dist/src/lib/composition/FormulaFilter.svelte +0 -1257
  578. package/dist/src/lib/composition/PieChart.svelte +0 -323
  579. package/dist/src/lib/composition/format.ts +0 -155
  580. package/dist/src/lib/composition/index.ts +0 -37
  581. package/dist/src/lib/composition/parse.ts +0 -605
  582. package/dist/src/lib/constants.ts +0 -134
  583. package/dist/src/lib/controls.ts +0 -42
  584. package/dist/src/lib/convex-hull/ConvexHull.svelte +0 -157
  585. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +0 -825
  586. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +0 -1801
  587. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +0 -1398
  588. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +0 -535
  589. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +0 -125
  590. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +0 -929
  591. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +0 -131
  592. package/dist/src/lib/convex-hull/GasPressureControls.svelte +0 -247
  593. package/dist/src/lib/convex-hull/StructurePopup.svelte +0 -151
  594. package/dist/src/lib/convex-hull/barycentric-coords.ts +0 -246
  595. package/dist/src/lib/convex-hull/demo-temperature.ts +0 -63
  596. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +0 -405
  597. package/dist/src/lib/convex-hull/helpers.ts +0 -932
  598. package/dist/src/lib/convex-hull/index.ts +0 -202
  599. package/dist/src/lib/convex-hull/thermodynamics.ts +0 -2192
  600. package/dist/src/lib/convex-hull/types.ts +0 -267
  601. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +0 -311
  602. package/dist/src/lib/coordination/calc-coordination.ts +0 -93
  603. package/dist/src/lib/coordination/index.ts +0 -9
  604. package/dist/src/lib/effects.svelte.ts +0 -48
  605. package/dist/src/lib/element/ElementHeading.svelte +0 -26
  606. package/dist/src/lib/element/ElementPhoto.svelte +0 -57
  607. package/dist/src/lib/element/ElementStats.svelte +0 -80
  608. package/dist/src/lib/element/ElementTile.svelte +0 -484
  609. package/dist/src/lib/element/data.ts +0 -14
  610. package/dist/src/lib/element/index.ts +0 -8
  611. package/dist/src/lib/element/types.ts +0 -62
  612. package/dist/src/lib/feedback/ClickFeedback.svelte +0 -58
  613. package/dist/src/lib/feedback/DragOverlay.svelte +0 -42
  614. package/dist/src/lib/feedback/index.ts +0 -4
  615. package/dist/src/lib/fermi-surface/FermiSlice.svelte +0 -189
  616. package/dist/src/lib/fermi-surface/FermiSurface.svelte +0 -600
  617. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +0 -448
  618. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +0 -794
  619. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  620. package/dist/src/lib/fermi-surface/compute.ts +0 -728
  621. package/dist/src/lib/fermi-surface/constants.ts +0 -32
  622. package/dist/src/lib/fermi-surface/export.ts +0 -64
  623. package/dist/src/lib/fermi-surface/index.ts +0 -14
  624. package/dist/src/lib/fermi-surface/marching-cubes.ts +0 -3
  625. package/dist/src/lib/fermi-surface/parse.ts +0 -574
  626. package/dist/src/lib/fermi-surface/symmetry.ts +0 -56
  627. package/dist/src/lib/fermi-surface/types.ts +0 -159
  628. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +0 -1545
  629. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  630. package/dist/src/lib/heatmap-matrix/index.ts +0 -167
  631. package/dist/src/lib/heatmap-matrix/shared.ts +0 -7
  632. package/dist/src/lib/icons.ts +0 -650
  633. package/dist/src/lib/index.ts +0 -61
  634. package/dist/src/lib/io/decompress.ts +0 -92
  635. package/dist/src/lib/io/export.ts +0 -385
  636. package/dist/src/lib/io/fetch.ts +0 -46
  637. package/dist/src/lib/io/file-drop.ts +0 -51
  638. package/dist/src/lib/io/index.ts +0 -7
  639. package/dist/src/lib/io/is-binary.ts +0 -24
  640. package/dist/src/lib/io/types.ts +0 -8
  641. package/dist/src/lib/io/url-drop.ts +0 -141
  642. package/dist/src/lib/isosurface/Isosurface.svelte +0 -285
  643. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +0 -277
  644. package/dist/src/lib/isosurface/index.ts +0 -7
  645. package/dist/src/lib/isosurface/parse.ts +0 -656
  646. package/dist/src/lib/isosurface/slice.ts +0 -175
  647. package/dist/src/lib/isosurface/types.ts +0 -309
  648. package/dist/src/lib/labels.ts +0 -320
  649. package/dist/src/lib/layout/FullscreenToggle.svelte +0 -50
  650. package/dist/src/lib/layout/InfoCard.svelte +0 -120
  651. package/dist/src/lib/layout/InfoTag.svelte +0 -185
  652. package/dist/src/lib/layout/PropertyFilter.svelte +0 -246
  653. package/dist/src/lib/layout/SettingsSection.svelte +0 -148
  654. package/dist/src/lib/layout/SubpageGrid.svelte +0 -82
  655. package/dist/src/lib/layout/fullscreen.ts +0 -65
  656. package/dist/src/lib/layout/index.ts +0 -11
  657. package/dist/src/lib/layout/json-tree/JsonNode.svelte +0 -548
  658. package/dist/src/lib/layout/json-tree/JsonTree.svelte +0 -1230
  659. package/dist/src/lib/layout/json-tree/index.ts +0 -3
  660. package/dist/src/lib/layout/json-tree/types.ts +0 -126
  661. package/dist/src/lib/layout/json-tree/utils.ts +0 -682
  662. package/dist/src/lib/marching-cubes.ts +0 -614
  663. package/dist/src/lib/math.ts +0 -1081
  664. package/dist/src/lib/overlays/ContextMenu.svelte +0 -162
  665. package/dist/src/lib/overlays/CopyButton.svelte +0 -45
  666. package/dist/src/lib/overlays/DragControlTab.svelte +0 -98
  667. package/dist/src/lib/overlays/DraggablePane.svelte +0 -487
  668. package/dist/src/lib/overlays/InfoPaneCards.svelte +0 -149
  669. package/dist/src/lib/overlays/index.ts +0 -3
  670. package/dist/src/lib/periodic-table/PeriodicTable.svelte +0 -469
  671. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +0 -557
  672. package/dist/src/lib/periodic-table/PropertySelect.svelte +0 -37
  673. package/dist/src/lib/periodic-table/index.ts +0 -12
  674. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1086
  675. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +0 -444
  676. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  677. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +0 -184
  678. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +0 -391
  679. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +0 -203
  680. package/dist/src/lib/phase-diagram/build-diagram.ts +0 -186
  681. package/dist/src/lib/phase-diagram/colors.ts +0 -58
  682. package/dist/src/lib/phase-diagram/diagram-input.ts +0 -40
  683. package/dist/src/lib/phase-diagram/index.ts +0 -13
  684. package/dist/src/lib/phase-diagram/parse.ts +0 -348
  685. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +0 -1023
  686. package/dist/src/lib/phase-diagram/types.ts +0 -144
  687. package/dist/src/lib/phase-diagram/utils.ts +0 -775
  688. package/dist/src/lib/plot/AxisLabel.svelte +0 -51
  689. package/dist/src/lib/plot/BarPlot.svelte +0 -2113
  690. package/dist/src/lib/plot/BarPlotControls.svelte +0 -66
  691. package/dist/src/lib/plot/BinnedScatterPlot.svelte +0 -1114
  692. package/dist/src/lib/plot/ColorBar.svelte +0 -721
  693. package/dist/src/lib/plot/ColorScaleSelect.svelte +0 -54
  694. package/dist/src/lib/plot/ElementScatter.svelte +0 -63
  695. package/dist/src/lib/plot/Histogram.svelte +0 -1558
  696. package/dist/src/lib/plot/HistogramControls.svelte +0 -212
  697. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +0 -96
  698. package/dist/src/lib/plot/Line.svelte +0 -84
  699. package/dist/src/lib/plot/PlotAxis.svelte +0 -169
  700. package/dist/src/lib/plot/PlotControls.svelte +0 -537
  701. package/dist/src/lib/plot/PlotLegend.svelte +0 -569
  702. package/dist/src/lib/plot/PlotTooltip.svelte +0 -67
  703. package/dist/src/lib/plot/PortalSelect.svelte +0 -253
  704. package/dist/src/lib/plot/ReferenceLine3D.svelte +0 -156
  705. package/dist/src/lib/plot/ReferencePlane.svelte +0 -175
  706. package/dist/src/lib/plot/ScatterPlot.svelte +0 -2778
  707. package/dist/src/lib/plot/ScatterPlot3D.svelte +0 -529
  708. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +0 -437
  709. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +0 -912
  710. package/dist/src/lib/plot/ScatterPlotControls.svelte +0 -306
  711. package/dist/src/lib/plot/ScatterPoint.svelte +0 -182
  712. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +0 -293
  713. package/dist/src/lib/plot/Surface3D.svelte +0 -197
  714. package/dist/src/lib/plot/ZeroLines.svelte +0 -97
  715. package/dist/src/lib/plot/ZoomRect.svelte +0 -23
  716. package/dist/src/lib/plot/adaptive-density.ts +0 -316
  717. package/dist/src/lib/plot/auto-place.ts +0 -184
  718. package/dist/src/lib/plot/axis-utils.ts +0 -122
  719. package/dist/src/lib/plot/binned-scatter-types.ts +0 -83
  720. package/dist/src/lib/plot/data-cleaning.ts +0 -1069
  721. package/dist/src/lib/plot/data-transform.ts +0 -69
  722. package/dist/src/lib/plot/defaults.ts +0 -9
  723. package/dist/src/lib/plot/fill-utils.ts +0 -494
  724. package/dist/src/lib/plot/hover-lock.svelte.ts +0 -60
  725. package/dist/src/lib/plot/index.ts +0 -53
  726. package/dist/src/lib/plot/interactions.ts +0 -119
  727. package/dist/src/lib/plot/layout.ts +0 -425
  728. package/dist/src/lib/plot/reference-line.ts +0 -426
  729. package/dist/src/lib/plot/scales.ts +0 -654
  730. package/dist/src/lib/plot/svg.ts +0 -23
  731. package/dist/src/lib/plot/types.ts +0 -1144
  732. package/dist/src/lib/plot/utils/label-placement.ts +0 -541
  733. package/dist/src/lib/plot/utils/series-visibility.ts +0 -140
  734. package/dist/src/lib/plot/utils.ts +0 -11
  735. package/dist/src/lib/rdf/RdfPlot.svelte +0 -247
  736. package/dist/src/lib/rdf/calc-rdf.ts +0 -167
  737. package/dist/src/lib/rdf/index.ts +0 -27
  738. package/dist/src/lib/sanitize.ts +0 -126
  739. package/dist/src/lib/settings.ts +0 -1479
  740. package/dist/src/lib/spectral/Bands.svelte +0 -1040
  741. package/dist/src/lib/spectral/BandsAndDos.svelte +0 -134
  742. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +0 -252
  743. package/dist/src/lib/spectral/Dos.svelte +0 -697
  744. package/dist/src/lib/spectral/helpers.ts +0 -1381
  745. package/dist/src/lib/spectral/index.ts +0 -8
  746. package/dist/src/lib/spectral/types.ts +0 -112
  747. package/dist/src/lib/state.svelte.ts +0 -64
  748. package/dist/src/lib/structure/Arrow.svelte +0 -72
  749. package/dist/src/lib/structure/AtomLegend.svelte +0 -815
  750. package/dist/src/lib/structure/Bond.svelte +0 -140
  751. package/dist/src/lib/structure/CanvasTooltip.svelte +0 -33
  752. package/dist/src/lib/structure/CellSelect.svelte +0 -349
  753. package/dist/src/lib/structure/Cylinder.svelte +0 -45
  754. package/dist/src/lib/structure/Lattice.svelte +0 -196
  755. package/dist/src/lib/structure/Structure.svelte +0 -2248
  756. package/dist/src/lib/structure/StructureControls.svelte +0 -1273
  757. package/dist/src/lib/structure/StructureExportPane.svelte +0 -252
  758. package/dist/src/lib/structure/StructureInfoPane.svelte +0 -737
  759. package/dist/src/lib/structure/StructureScene.svelte +0 -2255
  760. package/dist/src/lib/structure/atom-properties.ts +0 -316
  761. package/dist/src/lib/structure/bond-order-perception.ts +0 -447
  762. package/dist/src/lib/structure/bonding.ts +0 -944
  763. package/dist/src/lib/structure/export.ts +0 -861
  764. package/dist/src/lib/structure/index.ts +0 -291
  765. package/dist/src/lib/structure/label-placement.ts +0 -130
  766. package/dist/src/lib/structure/measure.ts +0 -45
  767. package/dist/src/lib/structure/parse.ts +0 -1705
  768. package/dist/src/lib/structure/partial-occupancy.ts +0 -183
  769. package/dist/src/lib/structure/pbc.ts +0 -164
  770. package/dist/src/lib/structure/supercell.ts +0 -226
  771. package/dist/src/lib/structure/validation.ts +0 -11
  772. package/dist/src/lib/symmetry/SymmetryStats.svelte +0 -226
  773. package/dist/src/lib/symmetry/WyckoffTable.svelte +0 -120
  774. package/dist/src/lib/symmetry/cell-transform.ts +0 -118
  775. package/dist/src/lib/symmetry/index.ts +0 -348
  776. package/dist/src/lib/symmetry/spacegroups.ts +0 -404
  777. package/dist/src/lib/table/HeatmapTable.svelte +0 -1833
  778. package/dist/src/lib/table/ToggleMenu.svelte +0 -385
  779. package/dist/src/lib/table/index.ts +0 -139
  780. package/dist/src/lib/theme/ThemeControl.svelte +0 -53
  781. package/dist/src/lib/theme/index.ts +0 -107
  782. package/dist/src/lib/time.ts +0 -71
  783. package/dist/src/lib/tooltip/TooltipContent.svelte +0 -58
  784. package/dist/src/lib/tooltip/index.ts +0 -2
  785. package/dist/src/lib/tooltip/types.ts +0 -13
  786. package/dist/src/lib/trajectory/Trajectory.svelte +0 -1545
  787. package/dist/src/lib/trajectory/TrajectoryError.svelte +0 -128
  788. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +0 -357
  789. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +0 -313
  790. package/dist/src/lib/trajectory/constants.ts +0 -7
  791. package/dist/src/lib/trajectory/extract.ts +0 -196
  792. package/dist/src/lib/trajectory/format-detect.ts +0 -96
  793. package/dist/src/lib/trajectory/frame-reader.ts +0 -456
  794. package/dist/src/lib/trajectory/helpers.ts +0 -217
  795. package/dist/src/lib/trajectory/index.ts +0 -218
  796. package/dist/src/lib/trajectory/parse/ase.ts +0 -109
  797. package/dist/src/lib/trajectory/parse/hdf5.ts +0 -173
  798. package/dist/src/lib/trajectory/parse/index.ts +0 -411
  799. package/dist/src/lib/trajectory/parse/lammps.ts +0 -215
  800. package/dist/src/lib/trajectory/parse/vasp.ts +0 -102
  801. package/dist/src/lib/trajectory/parse/xyz.ts +0 -143
  802. package/dist/src/lib/trajectory/plotting.ts +0 -599
  803. package/dist/src/lib/trajectory/types.ts +0 -13
  804. package/dist/src/lib/utils.ts +0 -56
  805. package/dist/src/lib/xrd/XrdPlot.svelte +0 -615
  806. package/dist/src/lib/xrd/broadening.ts +0 -130
  807. package/dist/src/lib/xrd/calc-xrd.ts +0 -397
  808. package/dist/src/lib/xrd/index.ts +0 -38
  809. package/dist/src/lib/xrd/parse.ts +0 -858
  810. package/dist/webview.js +0 -29421
  811. package/icon.png +0 -0
  812. package/matterviz-0.3.2.vsix +0 -0
  813. package/matterviz-0.3.4.vsix +0 -0
  814. package/matterviz-0.3.5.vsix +0 -0
  815. package/scripts/sync-config.ts +0 -101
  816. package/src/declarations.d.ts +0 -2
  817. package/src/extension.ts +0 -972
  818. package/src/node-io.ts +0 -65
  819. package/src/types.ts +0 -17
  820. package/src/webview/JsonBrowser.svelte +0 -1079
  821. package/src/webview/PlotPanel.svelte +0 -346
  822. package/src/webview/detect.ts +0 -444
  823. package/src/webview/main.ts +0 -764
  824. package/src/webview/plot-utils.ts +0 -250
  825. package/test-fixtures/all-viz-types.json.gz +0 -0
  826. package/test-fixtures/plot-demo-data.json.gz +0 -0
  827. package/tests/detect.test.ts +0 -604
  828. package/tests/extension.test.ts +0 -2041
  829. package/tests/node-io.test.ts +0 -39
  830. package/tests/plot-utils.test.ts +0 -302
  831. package/tests/vite-plugin-json-gz.test.ts +0 -114
  832. package/tests/vscode-mock.ts +0 -18
  833. package/tests/webview.test.ts +0 -231
  834. package/tsconfig.json +0 -20
  835. package/vite-plugin-json-gz.ts +0 -29
  836. package/vite.config.ts +0 -34
  837. package/vite.extension.config.ts +0 -34
  838. /package/dist/{src/lib/EmptyState.svelte → EmptyState.svelte} +0 -0
  839. /package/dist/{src/lib/Icon.svelte → Icon.svelte} +0 -0
  840. /package/dist/{src/lib/app.css → app.css} +0 -0
  841. /package/dist/{src/lib/chempot-diagram → chempot-diagram}/ChemPotScene3D.svelte +0 -0
  842. /package/dist/{src/lib/colors → colors}/alloy-colors.json +0 -0
  843. /package/dist/{src/lib/colors → colors}/dark-mode-colors.json +0 -0
  844. /package/dist/{src/lib/colors → colors}/jmol-colors.json +0 -0
  845. /package/dist/{src/lib/colors → colors}/muted-colors.json +0 -0
  846. /package/dist/{src/lib/colors → colors}/pastel-colors.json +0 -0
  847. /package/dist/{src/lib/colors → colors}/vesta-colors.json +0 -0
  848. /package/dist/{src/lib/convex-hull → convex-hull}/TemperatureSlider.svelte +0 -0
  849. /package/dist/{src/lib/element → element}/BohrAtom.svelte +0 -0
  850. /package/dist/{src/lib/element → element}/Nucleus.svelte +0 -0
  851. /package/dist/{src/lib/element → element}/data.json +0 -0
  852. /package/dist/{src/lib/element → element}/data.json.gz +0 -0
  853. /package/dist/{src/lib/element → element}/data.json.gz.d.ts +0 -0
  854. /package/dist/{src/lib/element → element}/data.schema.json +0 -0
  855. /package/dist/{src/lib/element-image-urls.json → element-image-urls.json} +0 -0
  856. /package/dist/{src/lib/feedback → feedback}/Spinner.svelte +0 -0
  857. /package/dist/{src/lib/feedback → feedback}/StatusMessage.svelte +0 -0
  858. /package/dist/{src/lib/layout → layout}/json-tree/JsonValue.svelte +0 -0
  859. /package/dist/{src/lib/periodic-table → periodic-table}/TableInset.svelte +0 -0
  860. /package/dist/{src/lib/plot → plot}/FillArea.svelte +0 -0
  861. /package/dist/{src/lib/plot → plot}/ReferenceLine.svelte +0 -0
  862. /package/dist/{src/lib/theme → theme}/themes.mjs +0 -0
  863. /package/dist/{src/lib/xrd → xrd}/atomic_scattering_params.json +0 -0
@@ -0,0 +1,1545 @@
1
+ <script lang="ts">
2
+ import type { D3InterpolateName } from '../colors'
3
+ import { is_color, pick_contrast_color } from '../colors'
4
+ import { format_num } from '../labels'
5
+ import type { AxisConfig } from '../plot'
6
+ import ColorBar from '../plot/ColorBar.svelte'
7
+ import { make_change_detector } from '../utils'
8
+ import * as d3_sc from 'd3-scale-chromatic'
9
+ import { type ComponentProps, onDestroy, onMount, type Snippet } from 'svelte'
10
+ import type { HTMLAttributes } from 'svelte/elements'
11
+ import { SvelteMap, SvelteSet } from 'svelte/reactivity'
12
+ import HeatmapMatrixControls from './HeatmapMatrixControls.svelte'
13
+ import type {
14
+ AxisItem,
15
+ CellContext,
16
+ DomainMode,
17
+ HeatmapExportFormat,
18
+ HeatmapTooltipProp,
19
+ LegendPosition,
20
+ NormalizeMode,
21
+ SymmetricMode,
22
+ } from './index'
23
+ import { matrix_to_rows, rows_to_csv } from './index'
24
+ import { make_color_override_key } from './shared'
25
+
26
+ type CellValue = number | string | null
27
+ type ColorBarOrientation = `vertical` | `horizontal`
28
+ type SelectionMode = `single` | `multi` | `range`
29
+ type AxisOrderKey = `label` | `key` | `sort_value`
30
+ type AxisOrder = AxisOrderKey | ((a: AxisItem, b: AxisItem) => number)
31
+ type CellPos = { x_idx: number; y_idx: number }
32
+
33
+ let {
34
+ // Data props
35
+ x_items,
36
+ y_items,
37
+ values = [],
38
+ color_scale = $bindable(`interpolateViridis`),
39
+ color_scale_range = [null, null],
40
+ color_overrides = {},
41
+ missing_color = `transparent`,
42
+ log = false,
43
+ value_transform,
44
+ normalize = `linear`,
45
+ domain_mode = `auto`,
46
+ quantile_clip = [0.02, 0.98],
47
+ show_legend = false,
48
+ legend_position = `bottom`,
49
+ legend_label = `Value`,
50
+ legend_ticks = 5,
51
+ legend_format = `.3~f`,
52
+ // Interaction props
53
+ active_cell = $bindable(null),
54
+ selected_cells = $bindable([]),
55
+ selection_mode = `single`,
56
+ pinned_cell = $bindable(null),
57
+ tooltip_mode = `hover`,
58
+ disabled = false,
59
+ onclick,
60
+ ondblclick,
61
+ onselect,
62
+ onpin,
63
+ oncontextmenu,
64
+ enable_brush = false,
65
+ onbrush,
66
+ // Display props
67
+ tile_size = `6px`,
68
+ gap = `0px`,
69
+ hide_empty = false,
70
+ show_x_labels = true,
71
+ show_y_labels = true,
72
+ stagger_axis_labels = `auto`,
73
+ symmetric: symmetric_prop = false,
74
+ symmetric_label_position = `diagonal`,
75
+ label_style = ``,
76
+ x_order,
77
+ y_order,
78
+ highlight_x_keys = [],
79
+ highlight_y_keys = [],
80
+ search_query = ``,
81
+ sticky_x_labels = false,
82
+ sticky_y_labels = false,
83
+ virtualize = false,
84
+ overscan = 3,
85
+ export_formats = [`csv`, `json`],
86
+ onexport,
87
+ show_gridlines = false,
88
+ gridline_color = `color-mix(in srgb, currentColor 18%, transparent)`,
89
+ gridline_width = `1px`,
90
+ animate_updates = false,
91
+ animation_duration = `120ms`,
92
+ show_row_summaries = false,
93
+ show_col_summaries = false,
94
+ summary_fn,
95
+ theme = `default`,
96
+ // Controls pane
97
+ show_controls = false,
98
+ controls_open = $bindable(false),
99
+ controls_props = {},
100
+ controls_children,
101
+ // Cell value display
102
+ show_values = false,
103
+ // Axis config (label used as axis title)
104
+ x_axis = {},
105
+ y_axis = {},
106
+ // Snippet props
107
+ tooltip = false,
108
+ cell,
109
+ x_label_cell,
110
+ y_label_cell,
111
+ children,
112
+ ...rest
113
+ }: Omit<HTMLAttributes<HTMLDivElement>, `onclick` | `ondblclick`> & {
114
+ x_items: AxisItem[]
115
+ y_items: AxisItem[]
116
+ values?:
117
+ | CellValue[][]
118
+ | Record<string, Record<string, CellValue>>
119
+ color_scale?: D3InterpolateName | ((val: number) => string)
120
+ color_scale_range?: [number | null, number | null]
121
+ color_overrides?: Record<string, string>
122
+ missing_color?: string
123
+ log?: boolean
124
+ value_transform?: (
125
+ value: number,
126
+ ctx: { x_item: AxisItem; y_item: AxisItem; x_idx: number; y_idx: number },
127
+ ) => number | null
128
+ normalize?: NormalizeMode
129
+ domain_mode?: DomainMode
130
+ quantile_clip?: [number, number]
131
+ show_legend?: boolean
132
+ legend_position?: LegendPosition
133
+ legend_label?: string
134
+ legend_ticks?: number
135
+ legend_format?: string
136
+ active_cell?: { x_idx: number; y_idx: number } | null
137
+ selected_cells?: CellPos[]
138
+ selection_mode?: SelectionMode
139
+ pinned_cell?: CellPos | null
140
+ tooltip_mode?: `hover` | `pinned` | `both`
141
+ disabled?: boolean
142
+ onclick?: (cell: CellContext) => void
143
+ ondblclick?: (cell: CellContext) => void
144
+ onselect?: (cells: CellPos[]) => void
145
+ onpin?: (cell: CellPos | null) => void
146
+ oncontextmenu?: (cell: CellContext, event: MouseEvent) => void
147
+ enable_brush?: boolean
148
+ onbrush?: (payload: {
149
+ x_range: [number, number]
150
+ y_range: [number, number]
151
+ cells: CellContext[]
152
+ }) => void
153
+ tile_size?: string
154
+ gap?: string
155
+ // false: show all rows/cols. 'compact': remove all-null rows/cols.
156
+ // 'gaps': keep grid positions but hide all-null rows/cols (preserves alignment).
157
+ hide_empty?: false | `compact` | `gaps`
158
+ show_x_labels?: boolean
159
+ show_y_labels?: boolean
160
+ stagger_axis_labels?: boolean | `auto`
161
+ symmetric?: SymmetricMode
162
+ symmetric_label_position?: `diagonal` | `edge`
163
+ label_style?: string
164
+ x_order?: AxisOrder
165
+ y_order?: AxisOrder
166
+ highlight_x_keys?: string[]
167
+ highlight_y_keys?: string[]
168
+ search_query?: string
169
+ sticky_x_labels?: boolean
170
+ sticky_y_labels?: boolean
171
+ virtualize?: boolean
172
+ overscan?: number
173
+ export_formats?: HeatmapExportFormat[]
174
+ onexport?: (format: HeatmapExportFormat, payload: unknown) => void
175
+ show_gridlines?: boolean
176
+ gridline_color?: string
177
+ gridline_width?: string
178
+ animate_updates?: boolean
179
+ animation_duration?: string
180
+ show_row_summaries?: boolean
181
+ show_col_summaries?: boolean
182
+ summary_fn?: (values: number[]) => number | null
183
+ theme?: `default` | `light` | `dark` | `publication`
184
+ // Controls pane (opt-in, renders HeatmapMatrixControls inside the shell)
185
+ show_controls?: boolean
186
+ controls_open?: boolean
187
+ controls_props?: Partial<ComponentProps<typeof HeatmapMatrixControls>>
188
+ controls_children?: Snippet<[{ controls_open: boolean }]>
189
+ // Cell value display (true uses '.3~g', string is a format_num spec; ignored when cell snippet is set)
190
+ show_values?: boolean | string
191
+ // Axis config (label used as axis title)
192
+ x_axis?: AxisConfig
193
+ y_axis?: AxisConfig
194
+ tooltip?: HeatmapTooltipProp
195
+ cell?: Snippet<[CellContext]>
196
+ x_label_cell?: Snippet<[{ item: AxisItem; idx: number }]>
197
+ y_label_cell?: Snippet<[{ item: AxisItem; idx: number }]>
198
+ children?: Snippet
199
+ } = $props()
200
+
201
+ // Normalize symmetric prop: true→'lower', otherwise pass through
202
+ const symmetric = $derived(
203
+ symmetric_prop === true ? `lower` : symmetric_prop,
204
+ )
205
+
206
+ // Check if a cell should be skipped in symmetric mode
207
+ function is_hidden_cell(x_idx: number, y_idx: number): boolean {
208
+ if (symmetric === `lower`) return x_idx > y_idx
209
+ if (symmetric === `upper`) return x_idx < y_idx
210
+ return false
211
+ }
212
+
213
+ // === Value resolution ===
214
+ let x_keys = $derived(x_items.map((item) => item.key ?? item.label))
215
+ let y_keys = $derived(y_items.map((item) => item.key ?? item.label))
216
+ let interaction_axis_signature = $derived(JSON.stringify([x_keys, y_keys]))
217
+ let highlight_x_key_set = $derived(new SvelteSet(highlight_x_keys))
218
+ let highlight_y_key_set = $derived(new SvelteSet(highlight_y_keys))
219
+ let search_query_norm = $derived(search_query.trim().toLowerCase())
220
+
221
+ let get_value = $derived.by(() => {
222
+ if (Array.isArray(values)) {
223
+ const matrix_values = values as CellValue[][]
224
+ return (x_idx: number, y_idx: number): CellValue =>
225
+ matrix_values[y_idx]?.[x_idx] ?? null
226
+ }
227
+ // Record<y_key, Record<x_key, value>>
228
+ const record = values as Record<string, Record<string, CellValue>>
229
+ return (x_idx: number, y_idx: number): CellValue => {
230
+ const y_key = y_keys[y_idx]
231
+ const x_key = x_keys[x_idx]
232
+ return record[y_key]?.[x_key] ?? null
233
+ }
234
+ })
235
+
236
+ // === Visibility filtering ===
237
+ // Single pass to find which columns and rows have at least one non-null value
238
+ function sort_indices(
239
+ indices: number[],
240
+ items: AxisItem[],
241
+ axis_order: AxisOrder | undefined,
242
+ ): number[] {
243
+ if (!axis_order) return indices
244
+ const sorted = [...indices]
245
+ if (typeof axis_order === `function`) {
246
+ sorted.sort((idx_a, idx_b) => axis_order(items[idx_a], items[idx_b]))
247
+ return sorted
248
+ }
249
+ sorted.sort((idx_a, idx_b) => {
250
+ const item_a = items[idx_a]
251
+ const item_b = items[idx_b]
252
+ if (axis_order === `sort_value`) {
253
+ const a_val = item_a.sort_value ?? Number.POSITIVE_INFINITY
254
+ const b_val = item_b.sort_value ?? Number.POSITIVE_INFINITY
255
+ return a_val - b_val
256
+ }
257
+ if (axis_order === `key`) {
258
+ return (item_a.key ?? item_a.label).localeCompare(item_b.key ?? item_b.label)
259
+ }
260
+ return item_a.label.localeCompare(item_b.label)
261
+ })
262
+ return sorted
263
+ }
264
+
265
+ let { vis_x, vis_y } = $derived.by(() => {
266
+ const all_x = Array.from({ length: x_items.length }, (_, idx) => idx)
267
+ const all_y = Array.from({ length: y_items.length }, (_, idx) => idx)
268
+ const filtered_x = search_query_norm
269
+ ? all_x.filter((idx) => {
270
+ const item = x_items[idx]
271
+ const key = item.key ?? item.label
272
+ return key.toLowerCase().includes(search_query_norm) ||
273
+ item.label.toLowerCase().includes(search_query_norm)
274
+ })
275
+ : all_x
276
+ const filtered_y = search_query_norm
277
+ ? all_y.filter((idx) => {
278
+ const item = y_items[idx]
279
+ const key = item.key ?? item.label
280
+ return key.toLowerCase().includes(search_query_norm) ||
281
+ item.label.toLowerCase().includes(search_query_norm)
282
+ })
283
+ : all_y
284
+ if (!hide_empty) {
285
+ return {
286
+ vis_x: sort_indices(filtered_x, x_items, x_order),
287
+ vis_y: sort_indices(filtered_y, y_items, y_order),
288
+ }
289
+ }
290
+
291
+ const col_has_data = Array(x_items.length).fill(false)
292
+ const row_has_data = Array(y_items.length).fill(false)
293
+ for (let y_idx = 0; y_idx < y_items.length; y_idx++) {
294
+ for (let x_idx = 0; x_idx < x_items.length; x_idx++) {
295
+ if (get_value(x_idx, y_idx) !== null) {
296
+ col_has_data[x_idx] = true
297
+ row_has_data[y_idx] = true
298
+ }
299
+ }
300
+ }
301
+ return {
302
+ vis_x: sort_indices(
303
+ filtered_x.filter((idx) => col_has_data[idx]),
304
+ x_items,
305
+ x_order,
306
+ ),
307
+ vis_y: sort_indices(
308
+ filtered_y.filter((idx) => row_has_data[idx]),
309
+ y_items,
310
+ y_order,
311
+ ),
312
+ }
313
+ })
314
+
315
+ // === Color computation ===
316
+ let color_scale_fn = $derived.by(() => {
317
+ if (typeof color_scale === `function`) return color_scale
318
+ const named_scale = d3_sc[color_scale]
319
+ return typeof named_scale === `function` ? named_scale : d3_sc.interpolateViridis
320
+ })
321
+
322
+ function get_transformed_value(x_idx: number, y_idx: number): number | null {
323
+ const raw_value = get_value(x_idx, y_idx)
324
+ if (typeof raw_value !== `number` || !Number.isFinite(raw_value)) return null
325
+ if (!value_transform) return raw_value
326
+ const transformed_value = value_transform(raw_value, {
327
+ x_item: x_items[x_idx],
328
+ y_item: y_items[y_idx],
329
+ x_idx,
330
+ y_idx,
331
+ })
332
+ if (transformed_value === null || !Number.isFinite(transformed_value)) return null
333
+ return transformed_value
334
+ }
335
+
336
+ function get_quantile(sorted_values: number[], quantile: number): number {
337
+ if (!sorted_values.length) return 0
338
+ const clipped_quantile = Math.max(0, Math.min(1, quantile))
339
+ const float_idx = (sorted_values.length - 1) * clipped_quantile
340
+ const low_idx = Math.floor(float_idx)
341
+ const high_idx = Math.ceil(float_idx)
342
+ if (low_idx === high_idx) return sorted_values[low_idx]
343
+ const low_weight = high_idx - float_idx
344
+ const high_weight = float_idx - low_idx
345
+ return sorted_values[low_idx] * low_weight + sorted_values[high_idx] * high_weight
346
+ }
347
+
348
+ let valid_numeric_values = $derived.by(() => {
349
+ const numeric_values: number[] = []
350
+ for (let y_idx = 0; y_idx < y_items.length; y_idx++) {
351
+ for (let x_idx = 0; x_idx < x_items.length; x_idx++) {
352
+ if (is_hidden_cell(x_idx, y_idx)) continue
353
+ const value = get_transformed_value(x_idx, y_idx)
354
+ if (value === null) continue
355
+ numeric_values.push(value)
356
+ }
357
+ }
358
+ return numeric_values
359
+ })
360
+
361
+ // Single-pass min/max to avoid spreading large arrays into Math.min/max
362
+ let [auto_min, auto_max] = $derived.by(() => {
363
+ let [min, max] = [Infinity, -Infinity]
364
+ for (const value of valid_numeric_values) {
365
+ if (value < min) min = value
366
+ if (value > max) max = value
367
+ }
368
+ return min <= max ? [min, max] as const : [0, 1] as const
369
+ })
370
+
371
+ let [robust_min, robust_max] = $derived.by(() => {
372
+ if (!valid_numeric_values.length) return [0, 1] as const
373
+ const sorted_values = valid_numeric_values.toSorted((value_a, value_b) =>
374
+ value_a - value_b
375
+ )
376
+ const [q_low, q_high] = quantile_clip
377
+ const clipped_min = get_quantile(sorted_values, q_low)
378
+ const clipped_max = get_quantile(sorted_values, q_high)
379
+ return clipped_min <= clipped_max
380
+ ? [clipped_min, clipped_max] as const
381
+ : [clipped_max, clipped_min] as const
382
+ })
383
+
384
+ let [domain_min, domain_max] = $derived.by(() => {
385
+ if (
386
+ domain_mode === `fixed` &&
387
+ color_scale_range[0] !== null &&
388
+ color_scale_range[1] !== null
389
+ ) {
390
+ return [color_scale_range[0], color_scale_range[1]] as const
391
+ }
392
+ if (domain_mode === `robust`) return [robust_min, robust_max] as const
393
+ return [auto_min, auto_max] as const
394
+ })
395
+
396
+ let cs_min = $derived(color_scale_range[0] ?? domain_min)
397
+ let cs_max = $derived(color_scale_range[1] ?? domain_max)
398
+ let use_log_norm = $derived(normalize === `log` || log)
399
+
400
+ // Map a single value to a background color
401
+ function value_to_color(val: CellValue): string | null {
402
+ if (val === null) return missing_color || null
403
+ if (typeof val === `string`) {
404
+ if (is_color(val)) return val
405
+ return missing_color || null
406
+ }
407
+ if (!Number.isFinite(val) || !color_scale_fn) return missing_color || null
408
+ if (use_log_norm && val <= 0) return missing_color || null
409
+
410
+ const span = cs_max - cs_min
411
+ if (!Number.isFinite(span) || span === 0) return color_scale_fn(0.5)
412
+
413
+ let normalized = typeof normalize === `function`
414
+ ? normalize(val, cs_min, cs_max)
415
+ : (val - cs_min) / span
416
+ if (use_log_norm) {
417
+ const is_descending_range = cs_min > cs_max
418
+ const lower_bound = Math.min(cs_min, cs_max)
419
+ const upper_bound = Math.max(cs_min, cs_max)
420
+ if (upper_bound <= 0) return missing_color || null
421
+ const safe_lower_bound = Math.max(lower_bound, Number.MIN_VALUE)
422
+ const safe_value = Math.max(val, safe_lower_bound)
423
+ const log_min = Math.log(safe_lower_bound)
424
+ const log_max = Math.log(upper_bound)
425
+ if (
426
+ !Number.isFinite(log_min) || !Number.isFinite(log_max) || log_max === log_min
427
+ ) {
428
+ return color_scale_fn(0.5)
429
+ }
430
+ const log_normalized = (Math.log(safe_value) - log_min) / (log_max - log_min)
431
+ normalized = is_descending_range ? 1 - log_normalized : log_normalized
432
+ }
433
+ if (!Number.isFinite(normalized)) return missing_color || null
434
+ return color_scale_fn(Math.max(0, Math.min(1, normalized)))
435
+ }
436
+
437
+ // Batch compute background colors as a flat array indexed by y_idx * n_x + x_idx.
438
+ // Text colors are only computed when a cell snippet is provided (otherwise cells have no text).
439
+ let n_x = $derived(x_items.length)
440
+ let bg_flat = $derived.by(() => {
441
+ const n_y = y_items.length
442
+ const colors: (string | null)[] = Array(n_x * n_y)
443
+ for (let y_idx = 0; y_idx < n_y; y_idx++) {
444
+ const row_offset = y_idx * n_x
445
+ for (let x_idx = 0; x_idx < n_x; x_idx++) {
446
+ if (is_hidden_cell(x_idx, y_idx)) {
447
+ colors[row_offset + x_idx] = null
448
+ continue
449
+ }
450
+ const override_key = make_color_override_key(x_keys[x_idx], y_keys[y_idx])
451
+ const raw_value = get_value(x_idx, y_idx)
452
+ const transformed_value = typeof raw_value === `number`
453
+ ? get_transformed_value(x_idx, y_idx)
454
+ : raw_value
455
+ colors[row_offset + x_idx] = override_key in color_overrides
456
+ ? color_overrides[override_key]
457
+ : value_to_color(transformed_value)
458
+ }
459
+ }
460
+ return colors
461
+ })
462
+
463
+ const to_contrast_colors = (bg_values: Array<string | null>): Array<string | null> =>
464
+ bg_values.map((bg_color) =>
465
+ bg_color ? pick_contrast_color({ bg_color }) : null
466
+ )
467
+
468
+ // Compute text colors when cells render content that needs contrast (cell snippet or show_values)
469
+ let text_flat = $derived.by(() => {
470
+ if (!cell && !show_values) return null
471
+ return to_contrast_colors(bg_flat)
472
+ })
473
+
474
+ // Keep selected outlines visible against each cell's background.
475
+ let selected_outline_flat = $derived.by(() => to_contrast_colors(bg_flat))
476
+
477
+ const get_flat_idx = (x_idx: number, y_idx: number): number => y_idx * n_x + x_idx
478
+
479
+ // Look up bg color by indices
480
+ const get_bg = (x_idx: number, y_idx: number): string | null =>
481
+ bg_flat[get_flat_idx(x_idx, y_idx)]
482
+
483
+ // === Cell context builder (only called for clicks, not per-hover) ===
484
+ function build_cell_context(x_idx: number, y_idx: number): CellContext {
485
+ return {
486
+ x_item: x_items[x_idx],
487
+ y_item: y_items[y_idx],
488
+ x_idx,
489
+ y_idx,
490
+ value: get_value(x_idx, y_idx),
491
+ bg_color: get_bg(x_idx, y_idx),
492
+ }
493
+ }
494
+
495
+ // === Fully imperative hover management ===
496
+ // ZERO $state writes during mouseover — all DOM updates are direct.
497
+ // This avoids Svelte's reactive flush which would re-evaluate effects.
498
+ const is_browser = typeof window !== `undefined`
499
+ let tooltip_div: HTMLDivElement | undefined = $state()
500
+ let active_cell_raf = 0 // rAF handle for deferred active_cell update
501
+ let click_timeout_id: ReturnType<typeof setTimeout> | null = null
502
+ const dblclick_delay_ms = 250
503
+ let last_hover_x = -1
504
+ let last_hover_y = -1
505
+ let matrix_el: HTMLDivElement | undefined = $state()
506
+ let scroll_left = $state(0)
507
+ let scroll_top = $state(0)
508
+ let viewport_width = $state(0)
509
+ let viewport_height = $state(0)
510
+ let grid_offset_left = $state(0)
511
+ let grid_offset_top = $state(0)
512
+ let brush_start: CellPos | null = $state(null)
513
+ let brush_end: CellPos | null = $state(null)
514
+ let last_selected_cell: CellPos | null = $state(null)
515
+
516
+ // In symmetric mode, labels can either stay on outer edges ('edge')
517
+ // or move toward the missing triangle and hug the diagonal ('diagonal').
518
+ let use_diagonal_symmetric_labels = $derived(
519
+ symmetric && symmetric_label_position === `diagonal`,
520
+ )
521
+ let use_staggered_x_labels = $derived(
522
+ stagger_axis_labels === true ||
523
+ (stagger_axis_labels === `auto` && vis_x.length >= 24),
524
+ )
525
+ let use_staggered_y_labels = $derived(
526
+ stagger_axis_labels === true ||
527
+ (stagger_axis_labels === `auto` && vis_y.length >= 24),
528
+ )
529
+ let use_side_split_x_labels = $derived(
530
+ use_staggered_x_labels && !use_diagonal_symmetric_labels,
531
+ )
532
+ // Don't split y-labels to both sides when symmetric -- one side has no cells
533
+ let use_side_split_y_labels = $derived(use_staggered_y_labels && !symmetric)
534
+ // For 'gaps' mode: explicit grid placement to preserve positional alignment
535
+ let gaps_mode = $derived(hide_empty === `gaps`)
536
+ let visible_col_count = $derived(gaps_mode ? x_items.length : vis_x.length)
537
+ let visible_row_count = $derived(gaps_mode ? y_items.length : vis_y.length)
538
+ let show_bottom_summary_row = $derived(show_col_summaries)
539
+ let show_right_summary_col = $derived(show_row_summaries)
540
+ let grid_col_count = $derived(visible_col_count + (show_right_summary_col ? 1 : 0))
541
+ let grid_row_count = $derived(visible_row_count + (show_bottom_summary_row ? 1 : 0))
542
+
543
+ const cell_pos_key = (x_idx: number, y_idx: number): string => `${x_idx}:${y_idx}`
544
+
545
+ let selected_cell_key_set = $derived(
546
+ new SvelteSet(
547
+ selected_cells.map((cell_pos) => cell_pos_key(cell_pos.x_idx, cell_pos.y_idx)),
548
+ ),
549
+ )
550
+
551
+ function parse_px_size(size: string): number {
552
+ const parsed = Number.parseFloat(size)
553
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 12
554
+ }
555
+
556
+ let tile_size_px = $derived(parse_px_size(tile_size))
557
+ let gap_px = $derived(parse_px_size(gap))
558
+ let tile_stride_px = $derived(tile_size_px + gap_px)
559
+ let render_vis_x = $derived.by(() => {
560
+ if (!virtualize) return vis_x
561
+ const raw_start_pos =
562
+ Math.floor((scroll_left - grid_offset_left) / tile_stride_px) - overscan
563
+ const start_pos = Math.max(0, raw_start_pos)
564
+ const raw_end_pos =
565
+ Math.ceil((scroll_left - grid_offset_left + viewport_width) / tile_stride_px) +
566
+ overscan
567
+ const end_pos = Math.min(vis_x.length, raw_end_pos)
568
+ return vis_x.slice(start_pos, end_pos)
569
+ })
570
+ let render_vis_y = $derived.by(() => {
571
+ if (!virtualize) return vis_y
572
+ const raw_start_pos =
573
+ Math.floor((scroll_top - grid_offset_top) / tile_stride_px) - overscan
574
+ const start_pos = Math.max(0, raw_start_pos)
575
+ const raw_end_pos =
576
+ Math.ceil((scroll_top - grid_offset_top + viewport_height) / tile_stride_px) +
577
+ overscan
578
+ const end_pos = Math.min(vis_y.length, raw_end_pos)
579
+ return vis_y.slice(start_pos, end_pos)
580
+ })
581
+
582
+ const is_selected_cell = (x_idx: number, y_idx: number): boolean =>
583
+ selected_cell_key_set.has(cell_pos_key(x_idx, y_idx))
584
+
585
+ let vis_x_pos_map = $derived.by(() => {
586
+ const position_map = new SvelteMap<number, number>()
587
+ for (const [vis_pos, item_idx] of vis_x.entries()) {
588
+ position_map.set(item_idx, vis_pos)
589
+ }
590
+ return position_map
591
+ })
592
+
593
+ let vis_y_pos_map = $derived.by(() => {
594
+ const position_map = new SvelteMap<number, number>()
595
+ for (const [vis_pos, item_idx] of vis_y.entries()) {
596
+ position_map.set(item_idx, vis_pos)
597
+ }
598
+ return position_map
599
+ })
600
+ let highlight_x_by_idx = $derived(
601
+ new SvelteSet(
602
+ vis_x.filter((idx) =>
603
+ highlight_x_key_set.has(x_items[idx].key ?? x_items[idx].label)
604
+ ),
605
+ ),
606
+ )
607
+ let highlight_y_by_idx = $derived(
608
+ new SvelteSet(
609
+ vis_y.filter((idx) =>
610
+ highlight_y_key_set.has(y_items[idx].key ?? y_items[idx].label)
611
+ ),
612
+ ),
613
+ )
614
+
615
+ function get_vis_col(item_idx: number): number | null {
616
+ if (gaps_mode) return item_idx
617
+ return vis_x_pos_map.get(item_idx) ?? null
618
+ }
619
+
620
+ function get_vis_row(item_idx: number): number | null {
621
+ if (gaps_mode) return item_idx
622
+ return vis_y_pos_map.get(item_idx) ?? null
623
+ }
624
+
625
+ function x_label_diag_grid_row(x_idx: number): number | undefined {
626
+ const vis_row = get_vis_row(x_idx)
627
+ if (vis_row === null) return undefined
628
+ if (symmetric === `upper`) {
629
+ // Upper triangle: place x label below diagonal (in empty lower-left area)
630
+ return Math.min(visible_row_count + 1, vis_row + 3)
631
+ }
632
+ // Lower/default: place x label above diagonal (in empty upper-right area)
633
+ return Math.max(1, vis_row + 1)
634
+ }
635
+
636
+ function x_label_diag_grid_col(x_idx: number): number | undefined {
637
+ const vis_col = get_vis_col(x_idx)
638
+ if (vis_col === null) return undefined
639
+ return vis_col + 2
640
+ }
641
+
642
+ function y_label_edge_grid_row(y_idx: number): number | undefined {
643
+ const vis_row = get_vis_row(y_idx)
644
+ if (vis_row === null) return undefined
645
+ return vis_row + 2
646
+ }
647
+
648
+ function x_label_grid_col(x_idx: number): number | undefined {
649
+ if (use_diagonal_symmetric_labels) return x_label_diag_grid_col(x_idx)
650
+ return cell_grid_col(x_idx)
651
+ }
652
+
653
+ function x_label_grid_row(x_idx: number): number | undefined {
654
+ if (use_diagonal_symmetric_labels) return x_label_diag_grid_row(x_idx)
655
+ if (use_side_split_x_labels && x_idx % 2 !== 0) {
656
+ return visible_row_count + 2 + (show_bottom_summary_row ? 1 : 0)
657
+ }
658
+ return 1
659
+ }
660
+
661
+ // Upper symmetric or staggered odd labels: place on right side
662
+ function y_label_grid_col(y_idx: number): number {
663
+ if (symmetric === `upper` || (use_side_split_y_labels && y_idx % 2 !== 0)) {
664
+ return visible_col_count + 2 + (show_right_summary_col ? 1 : 0)
665
+ }
666
+ return 1
667
+ }
668
+
669
+ function cell_grid_col(x_idx: number): number | undefined {
670
+ const vis_col = get_vis_col(x_idx)
671
+ if (vis_col === null) return undefined
672
+ return vis_col + 2
673
+ }
674
+
675
+ function cell_grid_row(y_idx: number): number | undefined {
676
+ const vis_row = get_vis_row(y_idx)
677
+ if (vis_row === null) return undefined
678
+ return vis_row + 2
679
+ }
680
+
681
+ function schedule_raf(callback: () => void): number {
682
+ if (!is_browser) {
683
+ callback()
684
+ return 0
685
+ }
686
+ return globalThis.requestAnimationFrame(callback)
687
+ }
688
+
689
+ function cancel_raf(raf_handle: number): void {
690
+ if (!is_browser || raf_handle === 0) return
691
+ globalThis.cancelAnimationFrame(raf_handle)
692
+ }
693
+
694
+ function clear_pending_click(): void {
695
+ if (click_timeout_id === null) return
696
+ clearTimeout(click_timeout_id)
697
+ click_timeout_id = null
698
+ }
699
+
700
+ function parse_cell_indices(
701
+ cell_el: HTMLElement,
702
+ ): { x_idx: number; y_idx: number } | null {
703
+ const x_value = Number(cell_el.dataset.x)
704
+ const y_value = Number(cell_el.dataset.y)
705
+ if (!Number.isInteger(x_value) || !Number.isInteger(y_value)) return null
706
+ return { x_idx: x_value, y_idx: y_value }
707
+ }
708
+
709
+ function get_cell_context_from_target(
710
+ event_target: EventTarget | null,
711
+ ): CellContext | null {
712
+ const cell_el = get_cell_el_from_target(event_target)
713
+ if (!cell_el) return null
714
+ const indices = parse_cell_indices(cell_el)
715
+ if (!indices) return null
716
+ return build_cell_context(indices.x_idx, indices.y_idx)
717
+ }
718
+
719
+ function trigger_click(cell_context: CellContext): void {
720
+ if (!onclick) return
721
+ if (!ondblclick) {
722
+ onclick(cell_context)
723
+ return
724
+ }
725
+ clear_pending_click()
726
+ click_timeout_id = setTimeout(() => {
727
+ onclick(cell_context)
728
+ click_timeout_id = null
729
+ }, dblclick_delay_ms)
730
+ }
731
+
732
+ function get_cell_el_from_target(
733
+ event_target: EventTarget | null,
734
+ ): HTMLElement | null {
735
+ const target_node = event_target
736
+ if (!(target_node instanceof Element)) return null
737
+ if (target_node instanceof HTMLElement && target_node.dataset.x !== undefined) {
738
+ return target_node
739
+ }
740
+ const closest_cell = target_node.closest(`[data-x][data-y]`)
741
+ return closest_cell instanceof HTMLElement ? closest_cell : null
742
+ }
743
+
744
+ function update_selected_cells(
745
+ event: MouseEvent,
746
+ clicked_cell: CellPos,
747
+ ): void {
748
+ if (selection_mode === `single`) {
749
+ selected_cells = [clicked_cell]
750
+ last_selected_cell = clicked_cell
751
+ onselect?.(selected_cells)
752
+ return
753
+ }
754
+ if (
755
+ selection_mode === `range` &&
756
+ event.shiftKey &&
757
+ last_selected_cell
758
+ ) {
759
+ const x_min = Math.min(last_selected_cell.x_idx, clicked_cell.x_idx)
760
+ const x_max = Math.max(last_selected_cell.x_idx, clicked_cell.x_idx)
761
+ const y_min = Math.min(last_selected_cell.y_idx, clicked_cell.y_idx)
762
+ const y_max = Math.max(last_selected_cell.y_idx, clicked_cell.y_idx)
763
+ const next_cells: CellPos[] = []
764
+ for (let y_idx = y_min; y_idx <= y_max; y_idx++) {
765
+ for (let x_idx = x_min; x_idx <= x_max; x_idx++) {
766
+ if (is_hidden_cell(x_idx, y_idx)) continue
767
+ next_cells.push({ x_idx, y_idx })
768
+ }
769
+ }
770
+ selected_cells = next_cells
771
+ onselect?.(selected_cells)
772
+ return
773
+ }
774
+ const clicked_key = cell_pos_key(clicked_cell.x_idx, clicked_cell.y_idx)
775
+ const next_cells = [...selected_cells]
776
+ const existing_idx = next_cells.findIndex((pos) =>
777
+ cell_pos_key(pos.x_idx, pos.y_idx) === clicked_key
778
+ )
779
+ const toggle_mode = selection_mode === `multi` && (event.metaKey || event.ctrlKey)
780
+ if (existing_idx >= 0 && toggle_mode) next_cells.splice(existing_idx, 1)
781
+ else if (selection_mode === `multi` && toggle_mode) next_cells.push(clicked_cell)
782
+ else next_cells.splice(0, next_cells.length, clicked_cell)
783
+ selected_cells = next_cells
784
+ last_selected_cell = clicked_cell
785
+ onselect?.(selected_cells)
786
+ }
787
+
788
+ function update_tooltip_position(client_x: number, client_y: number): void {
789
+ if (!tooltip_div) return
790
+ const tw = tooltip_div.offsetWidth
791
+ const th = tooltip_div.offsetHeight
792
+ // Flip to opposite side of cursor when near viewport edges
793
+ const left = client_x + 10 + tw > globalThis.innerWidth ? client_x - 10 - tw : client_x + 10
794
+ const top = client_y + 12 + th > globalThis.innerHeight ? client_y - 12 - th : client_y + 12
795
+ tooltip_div.style.left = `${Math.max(0, left)}px`
796
+ tooltip_div.style.top = `${Math.max(0, top)}px`
797
+ }
798
+
799
+ function set_pinned_cell(next_cell: CellPos | null): void {
800
+ pinned_cell = next_cell
801
+ onpin?.(next_cell)
802
+ }
803
+
804
+ // Write default tooltip content imperatively (no reactive state)
805
+ function update_tooltip_content(
806
+ td: HTMLElement,
807
+ x_idx: number,
808
+ y_idx: number,
809
+ ): void {
810
+ const x_label = x_items[x_idx]?.label ?? ``
811
+ const y_label = y_items[y_idx]?.label ?? ``
812
+ const val = get_value(x_idx, y_idx)
813
+ const value_str = val == null
814
+ ? ``
815
+ : typeof val === `number`
816
+ ? format_num(val)
817
+ : String(val)
818
+ td.textContent = value_str
819
+ ? `${x_label} - ${y_label}: ${value_str}`
820
+ : `${x_label} - ${y_label}`
821
+ }
822
+
823
+ function handle_mouseover(event: MouseEvent) {
824
+ if (disabled) return
825
+ const cell_el = get_cell_el_from_target(event.target)
826
+ if (!cell_el) return
827
+ const indices = parse_cell_indices(cell_el)
828
+ if (!indices) return
829
+ const { x_idx, y_idx } = indices
830
+
831
+ // Ignore redundant enters on the same cell (can happen with nested children)
832
+ if (last_hover_x === x_idx && last_hover_y === y_idx) {
833
+ return
834
+ }
835
+ last_hover_x = x_idx
836
+ last_hover_y = y_idx
837
+
838
+ // Defer bindable writes out of the hot mouseover path
839
+ cancel_raf(active_cell_raf)
840
+ active_cell_raf = schedule_raf(() => {
841
+ active_cell = { x_idx, y_idx }
842
+ })
843
+
844
+ if (enable_brush && brush_start) brush_end = { x_idx, y_idx }
845
+ if (tooltip === false || !tooltip_div || tooltip_mode === `pinned`) return
846
+
847
+ // Use viewport coordinates to avoid forced layout reads on large grids
848
+ update_tooltip_position(event.clientX, event.clientY)
849
+ tooltip_div.classList.add(`visible`)
850
+
851
+ if (typeof tooltip === `function`) {
852
+ tooltip_cell = build_cell_context(x_idx, y_idx)
853
+ } else {
854
+ update_tooltip_content(tooltip_div, x_idx, y_idx)
855
+ }
856
+ }
857
+
858
+ function handle_mouseout(event: MouseEvent) {
859
+ if (disabled) return
860
+ const related = event.relatedTarget as HTMLElement | null
861
+ if (related?.closest?.(`[data-x][data-y]`)) return
862
+ // Clear active state imperatively
863
+ last_hover_x = -1
864
+ last_hover_y = -1
865
+ const keep_tooltip_visible = tooltip_mode === `pinned` ||
866
+ (tooltip_mode === `both` && pinned_cell !== null)
867
+ if (!keep_tooltip_visible) {
868
+ tooltip_div?.classList.remove(`visible`)
869
+ }
870
+ // Defer reactive cleanup to rAF
871
+ cancel_raf(active_cell_raf)
872
+ active_cell_raf = schedule_raf(() => {
873
+ active_cell = null
874
+ if (!keep_tooltip_visible) tooltip_cell = null
875
+ })
876
+ }
877
+
878
+ function handle_click(event: MouseEvent) {
879
+ if (disabled) return
880
+ const cell_context = get_cell_context_from_target(event.target)
881
+ if (!cell_context) return
882
+ const { x_idx, y_idx } = cell_context
883
+ update_selected_cells(event, { x_idx, y_idx })
884
+ if (tooltip_mode === `both` || tooltip_mode === `pinned`) {
885
+ set_pinned_cell({ x_idx, y_idx })
886
+ if (tooltip !== false && tooltip_div) {
887
+ update_tooltip_position(event.clientX, event.clientY)
888
+ tooltip_div.classList.add(`visible`)
889
+ if (typeof tooltip === `function`) tooltip_cell = cell_context
890
+ else update_tooltip_content(tooltip_div, x_idx, y_idx)
891
+ }
892
+ }
893
+ if (!onclick) return
894
+ trigger_click(cell_context)
895
+ }
896
+
897
+ function handle_dblclick(event: MouseEvent) {
898
+ if (disabled || !ondblclick) return
899
+ const cell_context = get_cell_context_from_target(event.target)
900
+ if (!cell_context) return
901
+ clear_pending_click()
902
+ ondblclick(cell_context)
903
+ }
904
+
905
+ function handle_contextmenu(event: MouseEvent): void {
906
+ if (disabled || !oncontextmenu) return
907
+ const cell_context = get_cell_context_from_target(event.target)
908
+ if (!cell_context) return
909
+ event.preventDefault()
910
+ oncontextmenu(cell_context, event)
911
+ }
912
+
913
+ function handle_mousedown(event: MouseEvent): void {
914
+ if (disabled || !enable_brush) return
915
+ const cell_context = get_cell_context_from_target(event.target)
916
+ if (!cell_context) return
917
+ brush_start = { x_idx: cell_context.x_idx, y_idx: cell_context.y_idx }
918
+ brush_end = { x_idx: cell_context.x_idx, y_idx: cell_context.y_idx }
919
+ }
920
+
921
+ function handle_mouseup(): void {
922
+ if (!enable_brush || !brush_start || !brush_end || !onbrush) {
923
+ brush_start = null
924
+ brush_end = null
925
+ return
926
+ }
927
+ const x_min = Math.min(brush_start.x_idx, brush_end.x_idx)
928
+ const x_max = Math.max(brush_start.x_idx, brush_end.x_idx)
929
+ const y_min = Math.min(brush_start.y_idx, brush_end.y_idx)
930
+ const y_max = Math.max(brush_start.y_idx, brush_end.y_idx)
931
+ const cells: CellContext[] = []
932
+ for (let y_idx = y_min; y_idx <= y_max; y_idx++) {
933
+ for (let x_idx = x_min; x_idx <= x_max; x_idx++) {
934
+ if (is_hidden_cell(x_idx, y_idx)) continue
935
+ cells.push(build_cell_context(x_idx, y_idx))
936
+ }
937
+ }
938
+ onbrush({ x_range: [x_min, x_max], y_range: [y_min, y_max], cells })
939
+ brush_start = null
940
+ brush_end = null
941
+ }
942
+
943
+ function focus_cell(x_idx: number, y_idx: number): boolean {
944
+ const target = matrix_el?.querySelector(`[data-x="${x_idx}"][data-y="${y_idx}"]`)
945
+ if (!(target instanceof HTMLElement)) return false
946
+ target.focus()
947
+ active_cell = { x_idx, y_idx }
948
+ return true
949
+ }
950
+
951
+ function handle_keydown(event: KeyboardEvent): void {
952
+ const active_el = document.activeElement
953
+ if (!(active_el instanceof HTMLElement)) return
954
+ if (!(active_el.dataset.x && active_el.dataset.y)) return
955
+ const x_idx = Number(active_el.dataset.x)
956
+ const y_idx = Number(active_el.dataset.y)
957
+ if (!Number.isInteger(x_idx) || !Number.isInteger(y_idx)) return
958
+ let [x_step, y_step] = [0, 0]
959
+ if (event.key === `ArrowRight`) x_step = 1
960
+ else if (event.key === `ArrowLeft`) x_step = -1
961
+ else if (event.key === `ArrowDown`) y_step = 1
962
+ else if (event.key === `ArrowUp`) y_step = -1
963
+ else if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === `e`) {
964
+ const format = export_formats[0]
965
+ if (format && onexport) onexport(format, build_export_payload(format))
966
+ return
967
+ } else return
968
+ event.preventDefault()
969
+ let [next_x, next_y] = [x_idx, y_idx]
970
+ const max_steps = Math.max(x_items.length, y_items.length) + 1
971
+ for (let step_idx = 0; step_idx < max_steps; step_idx++) {
972
+ next_x += x_step
973
+ next_y += y_step
974
+ if (
975
+ next_x < 0 || next_y < 0 || next_x >= x_items.length ||
976
+ next_y >= y_items.length
977
+ ) {
978
+ return
979
+ }
980
+ if (is_hidden_cell(next_x, next_y)) continue
981
+ if (focus_cell(next_x, next_y)) return
982
+ }
983
+ }
984
+
985
+ function build_export_payload(format: HeatmapExportFormat): unknown {
986
+ const rows = matrix_to_rows(
987
+ vis_x.map((x_idx) => x_items[x_idx]),
988
+ vis_y.map((y_idx) => y_items[y_idx]),
989
+ vis_y.map((y_idx) => vis_x.map((x_idx) => get_value(x_idx, y_idx))),
990
+ )
991
+ if (format === `json`) return rows
992
+ return rows_to_csv(rows)
993
+ }
994
+
995
+ function update_viewport_state(): void {
996
+ if (!matrix_el) return
997
+ scroll_left = matrix_el.scrollLeft
998
+ scroll_top = matrix_el.scrollTop
999
+ viewport_width = matrix_el.clientWidth
1000
+ viewport_height = matrix_el.clientHeight
1001
+ const first_rendered_cell = matrix_el.querySelector(
1002
+ `.cell[data-x][data-y]`,
1003
+ ) as HTMLElement | null
1004
+ if (!first_rendered_cell) return
1005
+ const x_idx = Number(first_rendered_cell.dataset.x)
1006
+ const y_idx = Number(first_rendered_cell.dataset.y)
1007
+ if (!Number.isInteger(x_idx) || !Number.isInteger(y_idx)) return
1008
+ const vis_col = get_vis_col(x_idx) ?? 0
1009
+ const vis_row = get_vis_row(y_idx) ?? 0
1010
+ grid_offset_left = first_rendered_cell.offsetLeft - vis_col * tile_stride_px
1011
+ grid_offset_top = first_rendered_cell.offsetTop - vis_row * tile_stride_px
1012
+ }
1013
+
1014
+ function compute_summary(summary_values: number[]): number | null {
1015
+ if (!summary_values.length) return null
1016
+ if (summary_fn) return summary_fn(summary_values)
1017
+ const total = summary_values.reduce((sum, value) => sum + value, 0)
1018
+ return total / summary_values.length
1019
+ }
1020
+
1021
+ function summarize_axis_values(
1022
+ primary_indices: number[],
1023
+ secondary_indices: number[],
1024
+ get_x_idx: (primary_idx: number, secondary_idx: number) => number,
1025
+ get_y_idx: (primary_idx: number, secondary_idx: number) => number,
1026
+ ): SvelteMap<number, number | null> {
1027
+ const summary_map = new SvelteMap<number, number | null>()
1028
+ for (const primary_idx of primary_indices) {
1029
+ const values_for_summary: number[] = []
1030
+ for (const secondary_idx of secondary_indices) {
1031
+ const x_idx = get_x_idx(primary_idx, secondary_idx)
1032
+ const y_idx = get_y_idx(primary_idx, secondary_idx)
1033
+ if (is_hidden_cell(x_idx, y_idx)) continue
1034
+ const value = get_value(x_idx, y_idx)
1035
+ if (typeof value === `number` && Number.isFinite(value)) {
1036
+ values_for_summary.push(value)
1037
+ }
1038
+ }
1039
+ summary_map.set(primary_idx, compute_summary(values_for_summary))
1040
+ }
1041
+ return summary_map
1042
+ }
1043
+
1044
+ let row_summaries = $derived.by(() => {
1045
+ if (!show_row_summaries) return new SvelteMap<number, number | null>()
1046
+ return summarize_axis_values(
1047
+ vis_y,
1048
+ vis_x,
1049
+ (_y_idx, x_idx) => x_idx,
1050
+ (y_idx) => y_idx,
1051
+ )
1052
+ })
1053
+
1054
+ let col_summaries = $derived.by(() => {
1055
+ if (!show_col_summaries) return new SvelteMap<number, number | null>()
1056
+ return summarize_axis_values(
1057
+ vis_x,
1058
+ vis_y,
1059
+ (x_idx) => x_idx,
1060
+ (_x_idx, y_idx) => y_idx,
1061
+ )
1062
+ })
1063
+
1064
+ let legend_orientation = $derived<ColorBarOrientation>(
1065
+ legend_position === `right` ? `vertical` : `horizontal`,
1066
+ )
1067
+ let legend_wrapper_style = $derived.by(() =>
1068
+ legend_position === `right`
1069
+ ? `--cbar-height: 120px; --cbar-min-height: 120px; --cbar-max-height: 120px;`
1070
+ : `--cbar-width: 180px;`
1071
+ )
1072
+
1073
+ let has_interaction_handlers = $derived(
1074
+ !disabled &&
1075
+ (
1076
+ Boolean(onclick) ||
1077
+ Boolean(ondblclick) ||
1078
+ Boolean(oncontextmenu) ||
1079
+ selection_mode !== `single` ||
1080
+ tooltip_mode !== `hover`
1081
+ ),
1082
+ )
1083
+ let cell_tag_name = $derived(has_interaction_handlers ? `button` : `div`)
1084
+ let cell_class_name = $derived(
1085
+ has_interaction_handlers ? `cell interactive` : `cell`,
1086
+ )
1087
+
1088
+ // Tooltip state: only used for custom tooltip snippets (function tooltips)
1089
+ let tooltip_cell: CellContext | null = $state(null)
1090
+ const axis_changed = make_change_detector()
1091
+ $effect(() => {
1092
+ if (!axis_changed(interaction_axis_signature)) return
1093
+ cancel_raf(active_cell_raf)
1094
+ // Cancel delayed clicks before old cell coordinates can fire on new axes.
1095
+ clear_pending_click()
1096
+ active_cell = null
1097
+ pinned_cell = null
1098
+ selected_cells = []
1099
+ last_selected_cell = null
1100
+ brush_start = null
1101
+ brush_end = null
1102
+ last_hover_x = -1
1103
+ last_hover_y = -1
1104
+ tooltip_cell = null
1105
+ tooltip_div?.classList.remove(`visible`)
1106
+ })
1107
+
1108
+ onMount(() => {
1109
+ update_viewport_state()
1110
+ if (!is_browser) return
1111
+ globalThis.addEventListener(`mouseup`, handle_mouseup)
1112
+ return () => {
1113
+ globalThis.removeEventListener(`mouseup`, handle_mouseup)
1114
+ }
1115
+ })
1116
+
1117
+ onDestroy(() => {
1118
+ cancel_raf(active_cell_raf)
1119
+ clear_pending_click()
1120
+ })
1121
+ </script>
1122
+
1123
+ <div
1124
+ class="heatmap legend-{legend_position}"
1125
+ style:padding-left={y_axis.label ? `1.8em` : undefined}
1126
+ >
1127
+ {#if show_controls}
1128
+ <HeatmapMatrixControls
1129
+ bind:controls_open
1130
+ bind:normalize
1131
+ bind:domain_mode
1132
+ bind:show_legend
1133
+ bind:legend_position
1134
+ bind:search_query
1135
+ {export_formats}
1136
+ onexport={onexport
1137
+ ? (fmt: HeatmapExportFormat) => onexport(fmt, build_export_payload(fmt))
1138
+ : undefined}
1139
+ toggle_visible
1140
+ children={controls_children}
1141
+ {...controls_props}
1142
+ />
1143
+ {/if}
1144
+ <div
1145
+ {...rest}
1146
+ bind:this={matrix_el}
1147
+ class="grid theme-{theme} {rest.class ?? ``}"
1148
+ style:--n-cols={gaps_mode ? x_items.length : grid_col_count}
1149
+ style:--n-rows={gaps_mode ? y_items.length : grid_row_count}
1150
+ style:--extra-right-y={(use_side_split_y_labels || symmetric === `upper`) ? 1 : 0}
1151
+ style:--extra-bottom-x={use_side_split_x_labels ? 1 : 0}
1152
+ style:--right-y-track={(use_side_split_y_labels || symmetric === `upper`) ? `max-content` : `0`}
1153
+ style:--bottom-x-track={use_side_split_x_labels ? `max-content` : `0`}
1154
+ style:--tile-size={tile_size}
1155
+ style:--heatmap-gridline-color={gridline_color}
1156
+ style:--heatmap-gridline-width={gridline_width}
1157
+ style:--heatmap-anim-duration={animation_duration}
1158
+ style:gap
1159
+ onmouseover={handle_mouseover}
1160
+ onmouseout={handle_mouseout}
1161
+ onmousedown={handle_mousedown}
1162
+ onmouseup={handle_mouseup}
1163
+ onclick={handle_click}
1164
+ ondblclick={handle_dblclick}
1165
+ oncontextmenu={handle_contextmenu}
1166
+ onkeydown={handle_keydown}
1167
+ onscroll={update_viewport_state}
1168
+ >
1169
+ <!-- Top-left corner spacer (when both axes have labels) -->
1170
+ {#if show_x_labels && show_y_labels}
1171
+ <div class="corner"></div>
1172
+ {/if}
1173
+
1174
+ <!-- X-axis labels (top row) -->
1175
+ {#if show_x_labels}
1176
+ {#each vis_x as x_idx (x_items[x_idx].key ?? x_items[x_idx].label)}
1177
+ {@const item = x_items[x_idx]}
1178
+ <div
1179
+ class="x-label"
1180
+ class:x-edge-top={use_side_split_x_labels && x_idx % 2 === 0}
1181
+ class:x-edge-bottom={use_side_split_x_labels && x_idx % 2 !== 0}
1182
+ class:highlighted={highlight_x_by_idx.has(x_idx)}
1183
+ class:sticky={sticky_x_labels}
1184
+ style={label_style || undefined}
1185
+ style:grid-column={x_label_grid_col(x_idx)}
1186
+ style:grid-row={x_label_grid_row(x_idx)}
1187
+ title={x_label_cell ? undefined : item.label}
1188
+ >
1189
+ {#if x_label_cell}
1190
+ {@render x_label_cell({ item, idx: x_idx })}
1191
+ {:else}
1192
+ {item.label}
1193
+ {/if}
1194
+ </div>
1195
+ {/each}
1196
+ {/if}
1197
+
1198
+ <!-- Grid rows: y-label + cells -->
1199
+ {#each render_vis_y as y_idx (y_items[y_idx].key ?? y_items[y_idx].label)}
1200
+ {@const y_item = y_items[y_idx]}
1201
+ {#if show_y_labels}
1202
+ <div
1203
+ class="y-label"
1204
+ class:y-edge-left={use_side_split_y_labels && y_idx % 2 === 0}
1205
+ class:y-edge-right={use_side_split_y_labels && y_idx % 2 !== 0}
1206
+ class:highlighted={highlight_y_by_idx.has(y_idx)}
1207
+ class:sticky={sticky_y_labels}
1208
+ style={label_style || undefined}
1209
+ style:grid-row={y_label_edge_grid_row(y_idx)}
1210
+ style:grid-column={y_label_grid_col(y_idx)}
1211
+ title={y_label_cell ? undefined : y_item.label}
1212
+ >
1213
+ {#if y_label_cell}
1214
+ {@render y_label_cell({ item: y_item, idx: y_idx })}
1215
+ {:else}
1216
+ {y_item.label}
1217
+ {/if}
1218
+ </div>
1219
+ {/if}
1220
+
1221
+ <!-- Cells for this row -->
1222
+ {#each render_vis_x as x_idx (x_items[x_idx].key ?? x_items[x_idx].label)}
1223
+ {@const flat_idx = get_flat_idx(x_idx, y_idx)}
1224
+ {@const bg = bg_flat[flat_idx]}
1225
+ {@const should_render = !is_hidden_cell(x_idx, y_idx)}
1226
+ {#if should_render}
1227
+ <svelte:element
1228
+ this={cell_tag_name}
1229
+ class={cell_class_name}
1230
+ class:selected={is_selected_cell(x_idx, y_idx)}
1231
+ class:gridlines={show_gridlines}
1232
+ class:animated={animate_updates}
1233
+ data-x={x_idx}
1234
+ data-y={y_idx}
1235
+ style:background-color={bg}
1236
+ style:color={text_flat?.[flat_idx]}
1237
+ style:--heatmap-selected-outline-color={selected_outline_flat[flat_idx]}
1238
+ style:grid-column={cell_grid_col(x_idx)}
1239
+ style:grid-row={cell_grid_row(y_idx)}
1240
+ >
1241
+ {#if cell}
1242
+ {@render cell(build_cell_context(x_idx, y_idx))}
1243
+ {:else if show_values}
1244
+ {@const raw = get_value(x_idx, y_idx)}
1245
+ {#if raw !== null}
1246
+ <span class="cell-value">{
1247
+ typeof raw === `number`
1248
+ ? format_num(raw, show_values === true ? `.3~g` : show_values)
1249
+ : raw
1250
+ }</span>
1251
+ {/if}
1252
+ {/if}
1253
+ </svelte:element>
1254
+ {:else}
1255
+ <div
1256
+ class="cell empty"
1257
+ style:grid-column={cell_grid_col(x_idx)}
1258
+ style:grid-row={cell_grid_row(y_idx)}
1259
+ >
1260
+ </div>
1261
+ {/if}
1262
+ {/each}
1263
+ {/each}
1264
+
1265
+ {#if show_row_summaries}
1266
+ {#each vis_y as y_idx (y_items[y_idx].key ?? y_items[y_idx].label)}
1267
+ <div
1268
+ class="summary summary-row"
1269
+ style:grid-column={visible_col_count + 2}
1270
+ style:grid-row={cell_grid_row(y_idx)}
1271
+ >
1272
+ {#if row_summaries.get(y_idx) !== null}
1273
+ {format_num(row_summaries.get(y_idx) ?? 0)}
1274
+ {/if}
1275
+ </div>
1276
+ {/each}
1277
+ {/if}
1278
+
1279
+ {#if show_col_summaries}
1280
+ {#each vis_x as x_idx (x_items[x_idx].key ?? x_items[x_idx].label)}
1281
+ <div
1282
+ class="summary summary-col"
1283
+ style:grid-column={cell_grid_col(x_idx)}
1284
+ style:grid-row={visible_row_count + 2}
1285
+ >
1286
+ {#if col_summaries.get(x_idx) !== null}
1287
+ {format_num(col_summaries.get(x_idx) ?? 0)}
1288
+ {/if}
1289
+ </div>
1290
+ {/each}
1291
+ {/if}
1292
+
1293
+ <!-- Tooltip: always in DOM, visibility toggled imperatively via classList -->
1294
+ {#if tooltip !== false}
1295
+ <div class="tooltip" bind:this={tooltip_div}>
1296
+ {#if typeof tooltip === `function` && tooltip_cell}
1297
+ {@render tooltip(tooltip_cell)}
1298
+ {/if}
1299
+ </div>
1300
+ {/if}
1301
+
1302
+ {@render children?.()}
1303
+ </div>
1304
+
1305
+ {#if show_legend}
1306
+ <ColorBar
1307
+ class="legend legend-{legend_position}"
1308
+ title={legend_label}
1309
+ orientation={legend_orientation}
1310
+ tick_labels={legend_ticks}
1311
+ tick_format={legend_format}
1312
+ range={[cs_min, cs_max]}
1313
+ scale_type={use_log_norm ? `log` : `linear`}
1314
+ {color_scale}
1315
+ wrapper_style={legend_wrapper_style}
1316
+ />
1317
+ {/if}
1318
+ {#if x_axis.label}<div class="x-title">{x_axis.label}</div>{/if}
1319
+ {#if y_axis.label}<div class="y-title">{y_axis.label}</div>{/if}
1320
+ </div>
1321
+
1322
+ <style>
1323
+ .heatmap {
1324
+ position: relative;
1325
+ width: min(100%, var(--heatmap-max-width, 1200px));
1326
+ max-width: var(--heatmap-max-width, 1200px);
1327
+ box-sizing: border-box;
1328
+ container-type: inline-size;
1329
+ &.legend-bottom {
1330
+ padding-bottom: 44px;
1331
+ }
1332
+ :global(.legend) {
1333
+ position: absolute;
1334
+ background: color-mix(in srgb, var(--bg, #fff) 80%, transparent);
1335
+ padding: 0.3rem 0.4rem;
1336
+ border-radius: var(--border-radius, 3pt);
1337
+ }
1338
+ &.legend-right :global(.legend-right) {
1339
+ right: 8px;
1340
+ top: 8px;
1341
+ }
1342
+ &.legend-bottom :global(.legend-bottom) {
1343
+ left: 50%;
1344
+ bottom: 80px;
1345
+ transform: translateX(-50%);
1346
+ }
1347
+ .x-title {
1348
+ text-align: center;
1349
+ font-size: 0.9em;
1350
+ margin-top: 4px;
1351
+ }
1352
+ .y-title {
1353
+ position: absolute;
1354
+ left: 0;
1355
+ top: 50%;
1356
+ writing-mode: vertical-lr;
1357
+ transform: translateY(-50%) rotate(180deg);
1358
+ font-size: 0.9em;
1359
+ white-space: nowrap;
1360
+ }
1361
+ }
1362
+ .grid {
1363
+ display: grid;
1364
+ grid-template-columns:
1365
+ max-content repeat(
1366
+ var(--n-cols),
1367
+ minmax(var(--tile-size, 6px), 1fr)
1368
+ ) var(--right-y-track, 0);
1369
+ grid-template-rows:
1370
+ max-content repeat(
1371
+ var(--n-rows),
1372
+ minmax(var(--tile-size, 6px), 1fr)
1373
+ ) var(--bottom-x-track, 0);
1374
+ position: relative;
1375
+ width: min(100%, var(--heatmap-max-width, 1200px));
1376
+ max-width: var(--heatmap-max-width, 1200px);
1377
+ aspect-ratio: calc(
1378
+ (
1379
+ var(--n-cols) + 1 + var(--extra-right-y, 0)
1380
+ )
1381
+ / (
1382
+ var(--n-rows) + 1 + var(--extra-bottom-x, 0)
1383
+ )
1384
+ );
1385
+ overflow: auto;
1386
+ &.theme-publication {
1387
+ --tooltip-bg: rgba(255, 255, 255, 0.98);
1388
+ --tooltip-color: #111;
1389
+ }
1390
+ &.theme-dark {
1391
+ --tooltip-bg: rgba(0, 0, 0, 0.9);
1392
+ --tooltip-color: #eee;
1393
+ }
1394
+ }
1395
+ .corner {
1396
+ min-width: 0; /* spacer in top-left when both axes have labels */
1397
+ }
1398
+ .cell {
1399
+ width: 100%;
1400
+ height: 100%;
1401
+ min-width: 0;
1402
+ min-height: 0;
1403
+ border-radius: var(
1404
+ --heatmap-cell-border-radius,
1405
+ calc(var(--tile-size, 6px) * var(--heatmap-cell-radius-ratio, 0.12))
1406
+ );
1407
+ overflow: hidden;
1408
+ display: flex;
1409
+ align-items: center;
1410
+ justify-content: center;
1411
+ cursor: default;
1412
+ &.interactive {
1413
+ border: none;
1414
+ padding: 0;
1415
+ font: inherit;
1416
+ line-height: inherit;
1417
+ cursor: pointer;
1418
+ }
1419
+ &.selected {
1420
+ box-shadow: inset 0 0 0
1421
+ var(
1422
+ --heatmap-selected-outline-width,
1423
+ clamp(1px, calc(var(--tile-size, 6px) * 0.16), 3px)
1424
+ )
1425
+ color-mix(
1426
+ in srgb,
1427
+ var(--heatmap-selected-outline-color, currentColor) 75%,
1428
+ transparent
1429
+ );
1430
+ }
1431
+ &.gridlines {
1432
+ border: var(--heatmap-gridline-width) solid var(--heatmap-gridline-color);
1433
+ }
1434
+ &.animated {
1435
+ transition: background-color var(--heatmap-anim-duration) ease;
1436
+ }
1437
+ &.empty {
1438
+ pointer-events: none;
1439
+ }
1440
+ .cell-value {
1441
+ font-size: clamp(8px, calc(var(--tile-size, 6px) * 0.45), 14px);
1442
+ user-select: none;
1443
+ white-space: nowrap;
1444
+ overflow: hidden;
1445
+ text-overflow: ellipsis;
1446
+ }
1447
+ }
1448
+ :is(.x-label, .y-label) {
1449
+ font-size: clamp(10px, calc(var(--tile-size, 6px) * 0.75), 24px);
1450
+ overflow: hidden;
1451
+ text-overflow: ellipsis;
1452
+ white-space: nowrap;
1453
+ min-width: 0;
1454
+ display: flex;
1455
+ align-items: center;
1456
+ justify-content: center;
1457
+ text-align: center;
1458
+ &.sticky {
1459
+ position: sticky;
1460
+ z-index: 2;
1461
+ background: var(--bg, transparent);
1462
+ }
1463
+ &.highlighted {
1464
+ font-weight: 700;
1465
+ text-decoration: underline;
1466
+ }
1467
+ }
1468
+ .x-label {
1469
+ overflow: visible;
1470
+ text-overflow: clip;
1471
+ align-items: flex-end;
1472
+ padding: 2px;
1473
+ &.sticky {
1474
+ top: 0;
1475
+ }
1476
+ &.x-edge-top {
1477
+ min-height: 1.6em;
1478
+ align-items: flex-end;
1479
+ }
1480
+ &.x-edge-bottom {
1481
+ min-height: 1.6em;
1482
+ align-items: flex-start;
1483
+ }
1484
+ }
1485
+ .y-label {
1486
+ padding: 0 2px;
1487
+ &.sticky {
1488
+ left: 0;
1489
+ }
1490
+ &:is(.y-edge-left, .y-edge-right) {
1491
+ min-width: 1.6em;
1492
+ }
1493
+ &.y-edge-left {
1494
+ justify-content: flex-end;
1495
+ text-align: right;
1496
+ }
1497
+ &.y-edge-right {
1498
+ justify-content: flex-start;
1499
+ text-align: left;
1500
+ }
1501
+ }
1502
+ .summary {
1503
+ font-size: clamp(9px, calc(var(--tile-size, 6px) * 0.6), 14px);
1504
+ align-self: center;
1505
+ justify-self: center;
1506
+ color: var(--text-color-muted, currentColor);
1507
+ opacity: 0.9;
1508
+ }
1509
+ .tooltip {
1510
+ display: none;
1511
+ position: fixed;
1512
+ transform: none;
1513
+ background: var(
1514
+ --tooltip-bg,
1515
+ light-dark(rgba(255, 255, 255, 0.95), rgba(0, 0, 0, 0.85))
1516
+ );
1517
+ color: var(--tooltip-color, light-dark(#222, #eee));
1518
+ padding: var(--tooltip-padding, 4px 6px);
1519
+ border-radius: var(--tooltip-border-radius, var(--border-radius, 3pt));
1520
+ font-size: var(--tooltip-font-size, 12px);
1521
+ text-align: var(--tooltip-text-align, center);
1522
+ line-height: var(--tooltip-line-height, 1.2);
1523
+ z-index: var(--tooltip-z-index, 10);
1524
+ pointer-events: none;
1525
+ box-shadow: var(
1526
+ --tooltip-shadow,
1527
+ light-dark(0 2px 8px rgba(0, 0, 0, 0.15), 0 2px 8px rgba(0, 0, 0, 0.4))
1528
+ );
1529
+ white-space: nowrap;
1530
+ &.visible {
1531
+ display: block;
1532
+ }
1533
+ &::before {
1534
+ content: '';
1535
+ position: absolute;
1536
+ top: -6px;
1537
+ left: 50%;
1538
+ transform: translateX(-50%);
1539
+ border-left: 6px solid transparent;
1540
+ border-right: 6px solid transparent;
1541
+ border-bottom: 6px solid
1542
+ var(--tooltip-bg, light-dark(rgba(255, 255, 255, 0.95), rgba(0, 0, 0, 0.85)));
1543
+ }
1544
+ }
1545
+ </style>