matterviz 0.3.6 → 0.4.0

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