matterviz 0.3.4 → 0.3.6

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