matterviz 0.4.1 → 0.4.3

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 (499) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +48 -60
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/api/optimade.js +10 -7
  6. package/dist/app.css +68 -0
  7. package/dist/brillouin/BrillouinZone.svelte +90 -91
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  9. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  12. package/dist/brillouin/BrillouinZoneScene.svelte +46 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  14. package/dist/brillouin/compute.js +10 -16
  15. package/dist/brillouin/geometry.js +2 -2
  16. package/dist/chempot-diagram/ChemPotDiagram.svelte +48 -50
  17. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +61 -169
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +559 -755
  20. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  21. package/dist/chempot-diagram/async-compute.svelte.js +13 -14
  22. package/dist/chempot-diagram/color.d.ts +21 -1
  23. package/dist/chempot-diagram/color.js +70 -1
  24. package/dist/chempot-diagram/compute.d.ts +7 -0
  25. package/dist/chempot-diagram/compute.js +85 -26
  26. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  27. package/dist/chempot-diagram/export.js +1 -6
  28. package/dist/chempot-diagram/temperature.js +9 -10
  29. package/dist/colors/index.d.ts +0 -4
  30. package/dist/colors/index.js +19 -20
  31. package/dist/composition/BarChart.svelte +30 -26
  32. package/dist/composition/BubbleChart.svelte +17 -17
  33. package/dist/composition/Composition.svelte +10 -19
  34. package/dist/composition/Formula.svelte +20 -27
  35. package/dist/composition/FormulaFilter.svelte +115 -184
  36. package/dist/composition/PieChart.svelte +55 -41
  37. package/dist/composition/format.js +7 -9
  38. package/dist/composition/index.d.ts +2 -0
  39. package/dist/composition/index.js +14 -0
  40. package/dist/composition/parse.d.ts +2 -2
  41. package/dist/composition/parse.js +61 -115
  42. package/dist/constants.d.ts +0 -1
  43. package/dist/constants.js +17 -26
  44. package/dist/convex-hull/ConvexHull.svelte +12 -15
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +93 -94
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +127 -186
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +131 -180
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  53. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  54. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  55. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  56. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  57. package/dist/convex-hull/StructurePopup.svelte +18 -22
  58. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  59. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  60. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  61. package/dist/convex-hull/gas-thermodynamics.js +21 -53
  62. package/dist/convex-hull/helpers.d.ts +8 -10
  63. package/dist/convex-hull/helpers.js +37 -43
  64. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  65. package/dist/convex-hull/thermodynamics.js +37 -44
  66. package/dist/coordination/CoordinationBarPlot.svelte +49 -53
  67. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  68. package/dist/coordination/calc-coordination.d.ts +1 -1
  69. package/dist/coordination/calc-coordination.js +28 -25
  70. package/dist/element/BohrAtom.svelte +5 -9
  71. package/dist/element/ElementHeading.svelte +4 -1
  72. package/dist/element/ElementPhoto.svelte +11 -9
  73. package/dist/element/ElementStats.svelte +12 -10
  74. package/dist/element/ElementTile.svelte +44 -67
  75. package/dist/element/Nucleus.svelte +4 -2
  76. package/dist/element/data.d.ts +3 -2
  77. package/dist/element/data.js +5 -1
  78. package/dist/element/helpers.d.ts +4 -0
  79. package/dist/element/helpers.js +18 -0
  80. package/dist/element/index.d.ts +2 -5
  81. package/dist/element/index.js +4 -19
  82. package/dist/feedback/DragOverlay.svelte +5 -5
  83. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  84. package/dist/feedback/StatusMessage.svelte +7 -4
  85. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  86. package/dist/fermi-surface/FermiSurface.svelte +35 -44
  87. package/dist/fermi-surface/FermiSurface.svelte.d.ts +7 -13
  88. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  89. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  90. package/dist/fermi-surface/FermiSurfaceScene.svelte +64 -136
  91. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  92. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  93. package/dist/fermi-surface/compute.js +25 -58
  94. package/dist/fermi-surface/parse.js +54 -88
  95. package/dist/file-viewer/JsonBrowser.svelte +1043 -0
  96. package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
  97. package/dist/file-viewer/PlotPanel.svelte +350 -0
  98. package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
  99. package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
  100. package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
  101. package/dist/file-viewer/detect.d.ts +11 -0
  102. package/dist/file-viewer/detect.js +381 -0
  103. package/dist/file-viewer/eligibility.d.ts +4 -0
  104. package/dist/file-viewer/eligibility.js +53 -0
  105. package/dist/file-viewer/host-protocol.d.ts +50 -0
  106. package/dist/file-viewer/host-transfer.d.ts +25 -0
  107. package/dist/file-viewer/host-transfer.js +42 -0
  108. package/dist/file-viewer/index.d.ts +5 -0
  109. package/dist/file-viewer/index.js +5 -0
  110. package/dist/file-viewer/main.d.ts +44 -0
  111. package/dist/file-viewer/main.js +535 -0
  112. package/dist/file-viewer/parse.d.ts +9 -0
  113. package/dist/file-viewer/parse.js +170 -0
  114. package/dist/file-viewer/plot-utils.d.ts +24 -0
  115. package/dist/file-viewer/plot-utils.js +191 -0
  116. package/dist/file-viewer/types.d.ts +4 -0
  117. package/dist/file-viewer/types.js +5 -0
  118. package/dist/heatmap-matrix/HeatmapMatrix.svelte +153 -219
  119. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  120. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  121. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  122. package/dist/heatmap-matrix/index.d.ts +5 -0
  123. package/dist/icons.d.ts +4 -0
  124. package/dist/icons.js +4 -0
  125. package/dist/index.d.ts +2 -2
  126. package/dist/index.js +1 -1
  127. package/dist/io/ExportPane.svelte +11 -7
  128. package/dist/io/decompress.d.ts +4 -1
  129. package/dist/io/decompress.js +24 -36
  130. package/dist/io/export.d.ts +11 -4
  131. package/dist/io/export.js +75 -19
  132. package/dist/io/fetch.d.ts +0 -3
  133. package/dist/io/fetch.js +0 -11
  134. package/dist/io/file-drop.js +60 -35
  135. package/dist/io/index.d.ts +0 -1
  136. package/dist/io/index.js +2 -9
  137. package/dist/io/is-binary.d.ts +9 -0
  138. package/dist/io/is-binary.js +45 -1
  139. package/dist/io/url-drop.d.ts +2 -0
  140. package/dist/io/url-drop.js +40 -40
  141. package/dist/isosurface/Isosurface.svelte +700 -215
  142. package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
  143. package/dist/isosurface/IsosurfaceControls.svelte +590 -116
  144. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
  145. package/dist/isosurface/VolumeSlice.svelte +224 -0
  146. package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
  147. package/dist/isosurface/coloring.d.ts +20 -0
  148. package/dist/isosurface/coloring.js +118 -0
  149. package/dist/isosurface/geometry-worker-types.d.ts +38 -0
  150. package/dist/isosurface/geometry.worker.d.ts +1 -0
  151. package/dist/isosurface/geometry.worker.js +59 -0
  152. package/dist/isosurface/grid.d.ts +10 -0
  153. package/dist/isosurface/grid.js +31 -0
  154. package/dist/isosurface/index.d.ts +4 -0
  155. package/dist/isosurface/index.js +4 -0
  156. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  157. package/dist/isosurface/parse-vaspwave.js +138 -0
  158. package/dist/isosurface/parse.js +6 -6
  159. package/dist/isosurface/profile.d.ts +12 -0
  160. package/dist/isosurface/profile.js +19 -0
  161. package/dist/isosurface/sampling.d.ts +34 -0
  162. package/dist/isosurface/sampling.js +408 -0
  163. package/dist/isosurface/slice-rendering.d.ts +13 -0
  164. package/dist/isosurface/slice-rendering.js +79 -0
  165. package/dist/isosurface/slice.d.ts +22 -2
  166. package/dist/isosurface/slice.js +200 -116
  167. package/dist/isosurface/types.d.ts +24 -1
  168. package/dist/isosurface/types.js +120 -8
  169. package/dist/json-path.d.ts +4 -0
  170. package/dist/json-path.js +89 -0
  171. package/dist/labels.d.ts +6 -2
  172. package/dist/labels.js +44 -14
  173. package/dist/layout/FullscreenButton.svelte +2 -1
  174. package/dist/layout/FullscreenToggle.svelte +10 -4
  175. package/dist/layout/InfoCard.svelte +8 -21
  176. package/dist/layout/InfoTag.svelte +1 -3
  177. package/dist/layout/NumberRangeInput.svelte +46 -0
  178. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  179. package/dist/layout/PropertyFilter.svelte +2 -6
  180. package/dist/layout/SettingsSection.svelte +57 -62
  181. package/dist/layout/SettingsSection.svelte.d.ts +6 -7
  182. package/dist/layout/SubpageGrid.svelte +3 -1
  183. package/dist/layout/ViewerChrome.svelte +16 -11
  184. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  185. package/dist/layout/fullscreen.js +3 -5
  186. package/dist/layout/fullscreen.svelte.js +1 -2
  187. package/dist/layout/index.d.ts +1 -0
  188. package/dist/layout/index.js +1 -0
  189. package/dist/layout/json-tree/JsonNode.svelte +22 -59
  190. package/dist/layout/json-tree/JsonTree.svelte +101 -172
  191. package/dist/layout/json-tree/JsonValue.svelte +9 -32
  192. package/dist/layout/json-tree/utils.d.ts +0 -3
  193. package/dist/layout/json-tree/utils.js +50 -188
  194. package/dist/marching-cubes.d.ts +8 -1
  195. package/dist/marching-cubes.js +115 -48
  196. package/dist/math.d.ts +5 -2
  197. package/dist/math.js +48 -38
  198. package/dist/overlays/ContextMenu.svelte +19 -34
  199. package/dist/overlays/CopyButton.svelte +11 -5
  200. package/dist/overlays/DragControlTab.svelte +6 -1
  201. package/dist/overlays/DraggablePane.svelte +110 -74
  202. package/dist/overlays/DraggablePane.svelte.d.ts +2 -1
  203. package/dist/overlays/GlassChip.svelte +32 -0
  204. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  205. package/dist/overlays/InfoPaneCards.svelte +11 -23
  206. package/dist/overlays/index.d.ts +7 -0
  207. package/dist/overlays/index.js +26 -0
  208. package/dist/overlays/portal.d.ts +2 -0
  209. package/dist/overlays/portal.js +14 -0
  210. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  211. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  212. package/dist/periodic-table/PeriodicTableControls.svelte +37 -115
  213. package/dist/periodic-table/TableInset.svelte +9 -4
  214. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +68 -105
  215. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  216. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  217. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  218. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  219. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  220. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  221. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  222. package/dist/phase-diagram/build-diagram.js +4 -9
  223. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  224. package/dist/phase-diagram/parse.js +15 -15
  225. package/dist/phase-diagram/svg-to-diagram.js +28 -27
  226. package/dist/phase-diagram/utils.js +2 -3
  227. package/dist/plot/bar/BarPlot.svelte +461 -426
  228. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  229. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  230. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  231. package/dist/plot/bar/SpacegroupBarPlot.svelte +46 -77
  232. package/dist/plot/bar/data.d.ts +5 -4
  233. package/dist/plot/bar/data.js +2 -1
  234. package/dist/plot/box/BoxPlot.svelte +322 -226
  235. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  236. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  237. package/dist/plot/box/box-plot.js +1 -1
  238. package/dist/plot/core/auto-place.d.ts +1 -1
  239. package/dist/plot/core/auto-place.js +2 -2
  240. package/dist/plot/core/axis-utils.d.ts +12 -7
  241. package/dist/plot/core/axis-utils.js +48 -48
  242. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  243. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  244. package/dist/plot/core/components/ColorBar.svelte +101 -106
  245. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  246. package/dist/plot/core/components/FillArea.svelte +10 -17
  247. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  248. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  249. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  250. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  251. package/dist/plot/core/components/Line.svelte +18 -9
  252. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  253. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  254. package/dist/plot/core/components/PlotControls.svelte +65 -41
  255. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  256. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  257. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  258. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  259. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  260. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  261. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  262. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  263. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  264. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  265. package/dist/plot/core/components/index.d.ts +1 -0
  266. package/dist/plot/core/components/index.js +1 -0
  267. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  268. package/dist/plot/core/data-cleaning-signal.js +467 -0
  269. package/dist/plot/core/data-cleaning.d.ts +2 -42
  270. package/dist/plot/core/data-cleaning.js +27 -474
  271. package/dist/plot/core/data-transform.d.ts +1 -2
  272. package/dist/plot/core/data-transform.js +9 -15
  273. package/dist/plot/core/fill-utils.d.ts +3 -1
  274. package/dist/plot/core/fill-utils.js +28 -6
  275. package/dist/plot/core/index.d.ts +1 -0
  276. package/dist/plot/core/index.js +1 -0
  277. package/dist/plot/core/interactions.js +0 -2
  278. package/dist/plot/core/layout.d.ts +15 -6
  279. package/dist/plot/core/layout.js +57 -38
  280. package/dist/plot/core/marginals.d.ts +170 -0
  281. package/dist/plot/core/marginals.js +436 -0
  282. package/dist/plot/core/pan-zoom.svelte.d.ts +2 -4
  283. package/dist/plot/core/pan-zoom.svelte.js +34 -17
  284. package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -21
  286. package/dist/plot/core/reference-line.js +1 -1
  287. package/dist/plot/core/scales.d.ts +23 -0
  288. package/dist/plot/core/scales.js +39 -13
  289. package/dist/plot/core/svg.js +0 -1
  290. package/dist/plot/core/types/fills.d.ts +101 -0
  291. package/dist/plot/core/types/fills.js +15 -0
  292. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  293. package/dist/plot/core/types/plot-3d.js +4 -0
  294. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  295. package/dist/plot/core/types/reference-lines.js +9 -0
  296. package/dist/plot/core/types.d.ts +29 -324
  297. package/dist/plot/core/types.js +23 -20
  298. package/dist/plot/core/utils/hierarchy-chart.d.ts +52 -0
  299. package/dist/plot/core/utils/hierarchy-chart.js +191 -0
  300. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  301. package/dist/plot/core/utils/hierarchy-labels.js +100 -0
  302. package/dist/plot/core/utils/label-placement.js +2 -2
  303. package/dist/plot/histogram/Histogram.svelte +314 -340
  304. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  305. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  306. package/dist/plot/histogram/histogram.d.ts +31 -0
  307. package/dist/plot/histogram/histogram.js +70 -0
  308. package/dist/plot/histogram/index.d.ts +1 -0
  309. package/dist/plot/histogram/index.js +1 -0
  310. package/dist/plot/index.d.ts +1 -0
  311. package/dist/plot/index.js +1 -0
  312. package/dist/plot/sankey/Sankey.svelte +78 -69
  313. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  314. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  315. package/dist/plot/sankey/sankey.js +13 -9
  316. package/dist/plot/scatter/BinnedScatterPlot.svelte +311 -141
  317. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  318. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  319. package/dist/plot/scatter/ScatterPlot.svelte +517 -410
  320. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  321. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  322. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  323. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  324. package/dist/plot/scatter/adaptive-density.d.ts +1 -1
  325. package/dist/plot/scatter/adaptive-density.js +36 -20
  326. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  327. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  328. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  329. package/dist/plot/scatter/scatter-data.js +8 -7
  330. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  331. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  332. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  333. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  334. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  335. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  336. package/dist/plot/sunburst/Sunburst.svelte +269 -347
  337. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  338. package/dist/plot/sunburst/index.d.ts +1 -1
  339. package/dist/plot/sunburst/index.js +2 -1
  340. package/dist/plot/sunburst/render.d.ts +2 -2
  341. package/dist/plot/sunburst/render.js +47 -22
  342. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  343. package/dist/plot/sunburst/sunburst.js +10 -3
  344. package/dist/plot/treemap/Treemap.svelte +1022 -0
  345. package/dist/plot/treemap/Treemap.svelte.d.ts +90 -0
  346. package/dist/plot/treemap/index.d.ts +4 -0
  347. package/dist/plot/treemap/index.js +4 -0
  348. package/dist/plot/treemap/labels.d.ts +38 -0
  349. package/dist/plot/treemap/labels.js +80 -0
  350. package/dist/plot/treemap/treemap.d.ts +28 -0
  351. package/dist/plot/treemap/treemap.js +102 -0
  352. package/dist/rdf/RdfPlot.svelte +37 -59
  353. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  354. package/dist/rdf/calc-rdf.js +63 -52
  355. package/dist/rdf/index.d.ts +0 -1
  356. package/dist/sanitize.js +85 -27
  357. package/dist/scene/SceneCamera.svelte +1 -1
  358. package/dist/scene/SceneCamera.svelte.d.ts +1 -1
  359. package/dist/scene/bind-renderer.svelte.js +14 -6
  360. package/dist/scene/index.d.ts +1 -2
  361. package/dist/scene/index.js +1 -1
  362. package/dist/scene/{props.js → props.svelte.js} +15 -1
  363. package/dist/settings.d.ts +19 -9
  364. package/dist/settings.js +229 -525
  365. package/dist/spectral/Bands.svelte +207 -221
  366. package/dist/spectral/BandsAndDos.svelte +11 -9
  367. package/dist/spectral/BrillouinBandsDos.svelte +19 -42
  368. package/dist/spectral/Dos.svelte +92 -93
  369. package/dist/spectral/helpers.d.ts +3 -3
  370. package/dist/spectral/helpers.js +65 -140
  371. package/dist/state.svelte.js +5 -18
  372. package/dist/structure/Arrow.svelte +5 -18
  373. package/dist/structure/ArrowInstances.svelte +160 -0
  374. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  375. package/dist/structure/AtomLegend.svelte +120 -85
  376. package/dist/structure/AtomLegend.svelte.d.ts +2 -3
  377. package/dist/structure/Bond.svelte +31 -23
  378. package/dist/structure/CanvasTooltip.svelte +15 -3
  379. package/dist/structure/CellSelect.svelte +45 -35
  380. package/dist/structure/Cylinder.svelte +24 -40
  381. package/dist/structure/InstancedAtoms.svelte +114 -0
  382. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  383. package/dist/structure/Lattice.svelte +85 -149
  384. package/dist/structure/SiteLabels.svelte +122 -0
  385. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  386. package/dist/structure/Structure.svelte +636 -504
  387. package/dist/structure/Structure.svelte.d.ts +4 -2
  388. package/dist/structure/StructureCarousel.svelte +637 -0
  389. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  390. package/dist/structure/StructureControls.svelte +165 -425
  391. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  392. package/dist/structure/StructureExportPane.svelte +17 -21
  393. package/dist/structure/StructureInfoPane.svelte +128 -133
  394. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  395. package/dist/structure/StructureScene.svelte +535 -578
  396. package/dist/structure/StructureScene.svelte.d.ts +6 -2
  397. package/dist/structure/StructureViewport.svelte +451 -0
  398. package/dist/structure/StructureViewport.svelte.d.ts +65 -0
  399. package/dist/structure/atom-label-placement.d.ts +16 -12
  400. package/dist/structure/atom-label-placement.js +70 -37
  401. package/dist/structure/atom-properties.d.ts +2 -0
  402. package/dist/structure/atom-properties.js +105 -38
  403. package/dist/structure/bond-order-perception.js +3 -8
  404. package/dist/structure/bonding.d.ts +9 -3
  405. package/dist/structure/bonding.js +95 -46
  406. package/dist/structure/edit-history.d.ts +6 -0
  407. package/dist/structure/edit-history.js +27 -0
  408. package/dist/structure/export.d.ts +1 -0
  409. package/dist/structure/export.js +89 -105
  410. package/dist/structure/format-detect.d.ts +1 -0
  411. package/dist/structure/format-detect.js +20 -0
  412. package/dist/structure/geometry.d.ts +9 -0
  413. package/dist/structure/geometry.js +27 -0
  414. package/dist/structure/index.d.ts +16 -1
  415. package/dist/structure/index.js +15 -10
  416. package/dist/structure/measure.d.ts +1 -1
  417. package/dist/structure/measure.js +6 -12
  418. package/dist/structure/parse.d.ts +2 -1
  419. package/dist/structure/parse.js +272 -313
  420. package/dist/structure/partial-occupancy.js +10 -5
  421. package/dist/structure/pbc.js +85 -107
  422. package/dist/structure/polyhedra.d.ts +0 -1
  423. package/dist/structure/polyhedra.js +7 -21
  424. package/dist/structure/prop-groups.d.ts +85 -0
  425. package/dist/structure/prop-groups.js +18 -0
  426. package/dist/structure/supercell.d.ts +1 -2
  427. package/dist/structure/supercell.js +7 -13
  428. package/dist/symmetry/SymmetryElements.svelte +11 -15
  429. package/dist/symmetry/SymmetryStats.svelte +55 -71
  430. package/dist/symmetry/WyckoffTable.svelte +10 -28
  431. package/dist/symmetry/cell-transform.js +6 -14
  432. package/dist/symmetry/index.d.ts +1 -0
  433. package/dist/symmetry/index.js +13 -10
  434. package/dist/symmetry/spacegroups.js +3 -2
  435. package/dist/table/HeatmapTable.svelte +1142 -447
  436. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  437. package/dist/table/ToggleMenu.svelte +168 -53
  438. package/dist/table/ToggleMenu.svelte.d.ts +1 -1
  439. package/dist/table/index.d.ts +21 -6
  440. package/dist/table/index.js +34 -21
  441. package/dist/theme/ThemeControl.svelte +16 -8
  442. package/dist/theme/embedded.d.ts +18 -0
  443. package/dist/theme/embedded.js +206 -0
  444. package/dist/theme/index.d.ts +5 -5
  445. package/dist/theme/index.js +5 -12
  446. package/dist/theme/themes.mjs +44 -66
  447. package/dist/tooltip/KCoords.svelte +4 -1
  448. package/dist/tooltip/TooltipContent.svelte +3 -6
  449. package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
  450. package/dist/tooltip/index.d.ts +8 -1
  451. package/dist/trajectory/Trajectory.svelte +613 -386
  452. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  453. package/dist/trajectory/TrajectoryError.svelte +12 -74
  454. package/dist/trajectory/TrajectoryExportPane.svelte +14 -32
  455. package/dist/trajectory/TrajectoryInfoPane.svelte +127 -164
  456. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
  457. package/dist/trajectory/extract.js +61 -49
  458. package/dist/trajectory/format-detect.d.ts +2 -0
  459. package/dist/trajectory/format-detect.js +17 -13
  460. package/dist/trajectory/frame-reader.d.ts +2 -0
  461. package/dist/trajectory/frame-reader.js +35 -32
  462. package/dist/trajectory/helpers.d.ts +2 -0
  463. package/dist/trajectory/helpers.js +34 -56
  464. package/dist/trajectory/index.d.ts +1 -0
  465. package/dist/trajectory/index.js +5 -8
  466. package/dist/trajectory/parse/ase.js +1 -1
  467. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  468. package/dist/trajectory/parse/h5-utils.js +109 -0
  469. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  470. package/dist/trajectory/parse/hdf5.js +116 -106
  471. package/dist/trajectory/parse/index.d.ts +6 -6
  472. package/dist/trajectory/parse/index.js +25 -33
  473. package/dist/trajectory/parse/lammps.js +8 -12
  474. package/dist/trajectory/parse/vasp.js +10 -7
  475. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  476. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  477. package/dist/trajectory/parse/vaspout-h5.d.ts +4 -0
  478. package/dist/trajectory/parse/vaspout-h5.js +281 -0
  479. package/dist/trajectory/parse/xyz.js +59 -9
  480. package/dist/trajectory/plotting.d.ts +8 -9
  481. package/dist/trajectory/plotting.js +113 -64
  482. package/dist/utils.d.ts +3 -0
  483. package/dist/utils.js +7 -0
  484. package/dist/xrd/XrdPlot.svelte +79 -118
  485. package/dist/xrd/broadening.js +2 -1
  486. package/dist/xrd/calc-xrd.js +24 -62
  487. package/dist/xrd/parse.d.ts +0 -1
  488. package/dist/xrd/parse.js +69 -95
  489. package/package.json +94 -34
  490. package/readme.md +6 -5
  491. package/dist/api/mp.d.ts +0 -6
  492. package/dist/api/mp.js +0 -22
  493. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  494. package/dist/scene/types.d.ts +0 -26
  495. package/dist/tooltip/types.d.ts +0 -8
  496. package/dist/trajectory/constants.d.ts +0 -6
  497. package/dist/trajectory/constants.js +0 -11
  498. /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
  499. /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
@@ -75,7 +75,7 @@ export function pad_periodic_grid(grid, dims, pad_fraction) {
75
75
  }
76
76
  // Max total grid points before downsampling is applied for isosurface extraction.
77
77
  // 500K balances visual quality with interactive performance (<200ms marching cubes).
78
- const MAX_GRID_POINTS = 500_000;
78
+ export const MAX_GRID_POINTS = 500_000;
79
79
  // Downsample a 3D volumetric grid to keep total point count under a budget.
80
80
  // Uses block averaging to preserve data fidelity while reducing grid dimensions.
81
81
  // Returns original grid/dims if already within budget.
@@ -147,16 +147,17 @@ export const DEFAULT_ISOSURFACE_SETTINGS = {
147
147
  wireframe: false,
148
148
  halo: 0,
149
149
  };
150
+ const field_has_significant_negatives = ({ min, abs_max }) => min < -abs_max * 0.01;
151
+ const default_isovalue = ({ abs_max }) => abs_max > 0 ? abs_max * 0.2 : DEFAULT_ISOSURFACE_SETTINGS.isovalue;
150
152
  // Compute reasonable isosurface settings from a volume's data range.
151
153
  // Sets isovalue to 20% of abs_max and enables negative lobe when data has
152
154
  // significant negative values (>1% of max).
153
155
  export function auto_isosurface_settings(data_range) {
154
- const has_negatives = data_range.min < -data_range.abs_max * 0.01;
155
156
  return {
156
157
  ...DEFAULT_ISOSURFACE_SETTINGS,
157
158
  // Fall back to default isovalue for all-zero grids to keep controls usable
158
- isovalue: data_range.abs_max > 0 ? data_range.abs_max * 0.2 : DEFAULT_ISOSURFACE_SETTINGS.isovalue,
159
- show_negative: has_negatives,
159
+ isovalue: default_isovalue(data_range),
160
+ show_negative: field_has_significant_negatives(data_range),
160
161
  };
161
162
  }
162
163
  // Generate N evenly-spaced isosurface layers across a data range.
@@ -165,7 +166,7 @@ export function auto_isosurface_settings(data_range) {
165
166
  export function generate_layers(data_range, n_layers) {
166
167
  if (n_layers <= 0 || data_range.abs_max <= 0)
167
168
  return [];
168
- const has_negatives = data_range.min < -data_range.abs_max * 0.01;
169
+ const show_negative = field_has_significant_negatives(data_range);
169
170
  // Space isovalues from high (inner) to low (outer)
170
171
  return Array.from({ length: n_layers }, (_, idx) => {
171
172
  // Fraction from 0.8 (inner) to 0.1 (outer)
@@ -175,18 +176,129 @@ export function generate_layers(data_range, n_layers) {
175
176
  color: LAYER_COLORS[idx % LAYER_COLORS.length],
176
177
  opacity: n_layers === 1 ? 0.6 : 0.8 - idx * (0.5 / Math.max(n_layers - 1, 1)),
177
178
  visible: true,
178
- show_negative: has_negatives,
179
+ show_negative,
179
180
  negative_color: LAYER_COLORS[(idx + 1) % LAYER_COLORS.length],
180
181
  };
181
182
  });
182
183
  }
183
- // Tile (repeat) volumetric data to fill a supercell.
184
+ // Build a default isosurface layer for a newly added volume: isovalue at 20% of
185
+ // abs_max, next unused palette color, and negative lobe when the data is signed.
186
+ export function auto_volume_layer(volume, volume_idx, color_offset = 0) {
187
+ return {
188
+ isovalue: default_isovalue(volume.data_range),
189
+ color: LAYER_COLORS[color_offset % LAYER_COLORS.length],
190
+ opacity: 0.6,
191
+ visible: true,
192
+ show_negative: field_has_significant_negatives(volume.data_range),
193
+ negative_color: LAYER_COLORS[(color_offset + 1) % LAYER_COLORS.length],
194
+ volume_idx,
195
+ };
196
+ }
197
+ // Convert single-isovalue settings into an explicit layers array (no-op when
198
+ // layers already exist — an explicit empty array means zero surfaces and is
199
+ // preserved). Used when entering multi-volume mode so the implicit
200
+ // active-volume surface survives as an editable layer.
201
+ export function materialize_layers(settings, active_volume_idx) {
202
+ if (settings.layers) {
203
+ // Pin any layers still relying on the implicit active volume
204
+ return settings.layers.map((layer) => ({
205
+ ...layer,
206
+ volume_idx: layer.volume_idx ?? active_volume_idx,
207
+ }));
208
+ }
209
+ return [
210
+ {
211
+ isovalue: settings.isovalue,
212
+ color: settings.positive_color,
213
+ opacity: settings.opacity,
214
+ visible: true,
215
+ show_negative: settings.show_negative,
216
+ negative_color: settings.negative_color,
217
+ volume_idx: active_volume_idx,
218
+ },
219
+ ];
220
+ }
221
+ // Remove a volume from the registry: drops layers whose geometry references it,
222
+ // unsets color sources pointing at it, and shifts higher indices down by one.
223
+ // Layers without an explicit volume_idx implicitly reference `active_volume_idx`.
224
+ export function remove_volume(volumes, layers, removed_idx, active_volume_idx = 0) {
225
+ const remap = (idx) => {
226
+ if (idx === undefined || idx === removed_idx)
227
+ return undefined;
228
+ return idx > removed_idx ? idx - 1 : idx;
229
+ };
230
+ return {
231
+ volumes: volumes.filter((_vol, idx) => idx !== removed_idx),
232
+ layers: layers
233
+ .filter((layer) => (layer.volume_idx ?? active_volume_idx) !== removed_idx)
234
+ .map((layer) => ({
235
+ ...layer,
236
+ volume_idx: remap(layer.volume_idx ?? active_volume_idx) ?? 0,
237
+ color_volume_idx: remap(layer.color_volume_idx),
238
+ })),
239
+ };
240
+ }
241
+ // Label volumes parsed from a file with a stable `source` id (compression-
242
+ // stripped filename) and a display label (multi-block files like spin-polarized
243
+ // CHGCAR get "<file>: <block label>" labels).
244
+ export function label_file_volumes(volumes, filename) {
245
+ const source = filename.replace(/\.(?:gz|gzip|bz2|xz|zst)$/i, ``);
246
+ return volumes.map((vol, idx) => ({
247
+ ...vol,
248
+ source,
249
+ label: volumes.length > 1 ? `${source}: ${vol.label ?? idx + 1}` : source,
250
+ }));
251
+ }
252
+ // Two lattices describe the same cell when all matrix entries agree within
253
+ // tolerance — the signal that an imported file is another scalar field of the
254
+ // already-loaded system and should be appended rather than replace the scene.
255
+ export const lattices_match = (lattice_a, lattice_b, tolerance = 0.05) => Boolean(lattice_a && lattice_b) &&
256
+ lattice_a.every((row, row_idx) => row.every((val, col_idx) => Math.abs(val - lattice_b[row_idx][col_idx]) < tolerance));
257
+ // Merge volumes from a newly imported file (pre-labeled via label_file_volumes)
258
+ // into an existing registry. Reimporting a source with the same block count
259
+ // replaces its volumes in place, preserving user-tuned layers; a changed block
260
+ // count drops the stale group (remapping layer indices) before appending fresh
261
+ // volumes. New volumes each get an auto-generated layer.
262
+ // Layers without an explicit volume_idx implicitly reference `active_volume_idx`
263
+ // and are pinned to it up front so index remapping treats them correctly.
264
+ export function merge_imported_volumes(existing, existing_layers, incoming, active_volume_idx = 0) {
265
+ const source = incoming[0]?.source;
266
+ let volumes = [...existing];
267
+ let layers = existing_layers.map((layer) => ({
268
+ ...layer,
269
+ volume_idx: layer.volume_idx ?? active_volume_idx,
270
+ }));
271
+ const group_indices = volumes
272
+ .map((vol, idx) => (source !== undefined && vol.source === source ? idx : -1))
273
+ .filter((idx) => idx >= 0);
274
+ if (group_indices.length === incoming.length && incoming.length > 0) {
275
+ // Same source, same block count: replace in place, keep layer settings
276
+ for (const [incoming_idx, vol_idx] of group_indices.entries()) {
277
+ volumes[vol_idx] = incoming[incoming_idx];
278
+ }
279
+ return { volumes, layers, first_touched_idx: group_indices[0], n_added: 0 };
280
+ }
281
+ // Drop any stale volumes from the same source (block count changed)
282
+ for (let removed = group_indices.length - 1; removed >= 0; removed--) {
283
+ ;
284
+ ({ volumes, layers } = remove_volume(volumes, layers, group_indices[removed]));
285
+ }
286
+ const first_touched_idx = volumes.length;
287
+ for (const vol of incoming) {
288
+ layers.push(auto_volume_layer(vol, volumes.length, layers.length));
289
+ volumes.push(vol);
290
+ }
291
+ return { volumes, layers, first_touched_idx, n_added: incoming.length };
292
+ }
293
+ // Tile (repeat) periodic volumetric data to fill a supercell. Finite volumes
294
+ // remain unchanged: structure supercells must not implicitly repeat molecular
295
+ // or other bounded scalar fields.
184
296
  // Pre-downsamples the source grid when the tiled result would exceed MAX_GRID_POINTS
185
297
  // to avoid large temporary allocations. Returns the original volume unchanged for
186
298
  // [1,1,1] scaling.
187
299
  export function tile_volumetric_data(volume, scaling) {
188
300
  const [sx, sy, sz] = scaling;
189
- if (sx === 1 && sy === 1 && sz === 1)
301
+ if (!volume.periodic || (sx === 1 && sy === 1 && sz === 1))
190
302
  return volume;
191
303
  const total_cells = sx * sy * sz;
192
304
  let src_grid = volume.grid;
@@ -0,0 +1,4 @@
1
+ export declare const format_path: (segments: (string | number)[]) => string;
2
+ export declare const build_path: (parent_path: string, key: string | number) => string;
3
+ export declare function parse_path(path: string): (string | number)[];
4
+ export declare function resolve_path(root: unknown, path: string): unknown;
@@ -0,0 +1,89 @@
1
+ // Dot/bracket path codec for arbitrary JavaScript object keys.
2
+ // Special keys use JSON.stringify so quotes/backslashes/brackets round-trip.
3
+ const PATH_IDENTIFIER_RE = /^[A-Za-z_$][\w$]*$/u;
4
+ function format_path_segment(segment, is_first = false) {
5
+ if (typeof segment === `number`)
6
+ return `[${segment}]`;
7
+ if (PATH_IDENTIFIER_RE.test(segment))
8
+ return is_first ? segment : `.${segment}`;
9
+ return `[${JSON.stringify(segment)}]`;
10
+ }
11
+ export const format_path = (segments) => segments.map((segment, idx) => format_path_segment(segment, idx === 0)).join(``);
12
+ export const build_path = (parent_path, key) => parent_path ? parent_path + format_path_segment(key) : format_path_segment(key, true);
13
+ export function parse_path(path) {
14
+ if (!path)
15
+ return [];
16
+ const segments = [];
17
+ let pos = 0;
18
+ while (pos < path.length) {
19
+ const char = path[pos];
20
+ if (char === `.`) {
21
+ pos++;
22
+ continue;
23
+ }
24
+ if (char !== `[`) {
25
+ const start = pos;
26
+ while (pos < path.length && path[pos] !== `.` && path[pos] !== `[`)
27
+ pos++;
28
+ if (pos > start)
29
+ segments.push(path.slice(start, pos));
30
+ continue;
31
+ }
32
+ pos++; // skip `[`
33
+ if (path[pos] === `]`) {
34
+ pos++;
35
+ continue;
36
+ }
37
+ if (path[pos] === `"`) {
38
+ const json_start = pos;
39
+ let escaped = false;
40
+ pos++;
41
+ while (pos < path.length) {
42
+ const quote_char = path[pos];
43
+ if (escaped)
44
+ escaped = false;
45
+ else if (quote_char === `\\`)
46
+ escaped = true;
47
+ else if (quote_char === `"`)
48
+ break;
49
+ pos++;
50
+ }
51
+ if (pos >= path.length) {
52
+ segments.push(path.slice(json_start + 1));
53
+ break;
54
+ }
55
+ try {
56
+ segments.push(JSON.parse(path.slice(json_start, pos + 1)));
57
+ }
58
+ catch {
59
+ segments.push(path.slice(json_start + 1, pos));
60
+ }
61
+ pos++;
62
+ if (path[pos] === `]`)
63
+ pos++;
64
+ continue;
65
+ }
66
+ const start = pos;
67
+ while (pos < path.length && path[pos] !== `]`)
68
+ pos++;
69
+ const token = path.slice(start, pos);
70
+ if (token) {
71
+ const num = Number(token);
72
+ segments.push(Number.isNaN(num) ? token : num);
73
+ }
74
+ if (path[pos] === `]`)
75
+ pos++;
76
+ }
77
+ return segments;
78
+ }
79
+ export function resolve_path(root, path) {
80
+ if (!path)
81
+ return root;
82
+ let current = root;
83
+ for (const key of parse_path(path)) {
84
+ if (current == null || typeof current !== `object`)
85
+ return undefined;
86
+ current = current[key];
87
+ }
88
+ return current;
89
+ }
package/dist/labels.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare const ELEM_HEATMAP_KEYS: (keyof ChemicalElement)[];
12
12
  export declare const ELEM_HEATMAP_LABELS: Partial<Record<string, keyof ChemicalElement>>;
13
13
  export declare const DEFAULT_FMT: [string, string];
14
14
  export declare const FRACTION_GLYPHS: readonly (readonly [number, string])[];
15
+ export declare const format_value_or_num: (value: number, fmt?: string) => string;
15
16
  export declare const format_num: (num: number, fmt?: string | number) => string;
16
17
  export declare const format_vec3: (vec: Readonly<Vec3>, fmt_spec?: string) => string;
17
18
  export declare const format_bytes: (bytes?: number) => string;
@@ -47,7 +48,10 @@ export declare const SUBSCRIPT_MAP: {
47
48
  readonly '9': "₉";
48
49
  };
49
50
  export declare const superscript_digits: (input: string) => string;
50
- export declare const trajectory_property_config: Record<string, {
51
+ export declare const SCF_AXIS_GROUP = "eV (SCF)";
52
+ export interface TrajPropertyConfig {
51
53
  label: string;
52
54
  unit: string;
53
- }>;
55
+ axis_group?: string;
56
+ }
57
+ export declare const trajectory_property_config: Record<string, TrajPropertyConfig>;
package/dist/labels.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { normalize_unicode_minus } from './utils';
1
2
  import { format } from 'd3-format';
2
3
  import * as d3_symbols from 'd3-shape';
3
4
  import { timeFormat } from 'd3-time-format';
@@ -33,12 +34,11 @@ export function format_value(value, formatter) {
33
34
  return `Infinity`;
34
35
  if (Number.isNaN(value))
35
36
  return `NaN`;
36
- // Format and normalize unicode minus
37
- const formatted = format(formatter)(value).replaceAll('−', `-`);
37
+ const formatted = normalize_unicode_minus(format(formatter)(value));
38
38
  // Handle percentage formatting - remove trailing zeros
39
39
  if (formatter.includes(`%`)) {
40
40
  return formatted.includes(`.`)
41
- ? formatted.replace(/(\.\d*?)0+%$/, `$1%`).replace(/\.%$/, `%`)
41
+ ? formatted.replace(/(?<decimals>\.\d*?)0+%$/, `$1%`).replace(/\.%$/, `%`)
42
42
  : formatted;
43
43
  }
44
44
  // Handle currency formatting - preserve precision if specified
@@ -47,26 +47,44 @@ export function format_value(value, formatter) {
47
47
  }
48
48
  // Remove trailing zeros after decimal point
49
49
  const out = formatted.includes(`.`)
50
- ? formatted.replace(/(\.\d*?)0+$/, `$1`).replace(/\.$/, ``)
50
+ ? formatted.replace(/(?<decimals>\.\d*?)0+$/, `$1`).replace(/\.$/, ``)
51
51
  : formatted;
52
52
  return out === `-0` ? `0` : out;
53
53
  }
54
- // TODO add labels and units for all elemental properties
54
+ // Human-readable label + unit (null when dimensionless) for displayable element
55
+ // properties. Omitted: Record-valued (ionic_radii, shannon_radii), assets
56
+ // (cpk-hex, spectral_img), heading/summary fields (name, symbol, category,
57
+ // discoverer, year, summary) and electronegativity_pauling (identical to
58
+ // electronegativity).
55
59
  export const ELEM_PROPERTY_LABELS = {
60
+ appearance: [`Appearance`, null],
56
61
  atomic_mass: [`Atomic Mass`, `u`],
57
62
  atomic_radius: [`Atomic Radius`, `Å`],
58
63
  boiling_point: [`Boiling Point`, `K`],
64
+ column: [`Group`, null],
65
+ common_oxidation_states: [`Common Oxidation States`, null],
59
66
  covalent_radius: [`Covalent Radius`, `Å`],
60
67
  density: [`Density`, `g/cm³`],
61
- electron_affinity: [`Electron Affinity`, null],
68
+ electron_affinity: [`Electron Affinity`, `kJ/mol`],
69
+ electron_configuration: [`Electron Configuration`, null],
70
+ electron_configuration_semantic: [`Electron Configuration (semantic)`, null],
62
71
  electronegativity: [`Electronegativity`, null],
72
+ electrons: [`Electrons`, null],
63
73
  first_ionization: [`First Ionization Energy`, `eV`],
74
+ icsd_oxidation_states: [`ICSD Oxidation States`, null],
75
+ ionization_energies: [`Ionization Energies`, `kJ/mol`],
64
76
  melting_point: [`Melting Point`, `K`],
65
77
  mendeleev_number: [`Mendeleev Number`, null],
66
- // molar_heat: [`Molar Heat`, `J/(mol·K)`],
78
+ molar_heat: [`Molar Heat`, `J/(mol·K)`],
67
79
  n_shells: [`Number of Shells`, null],
68
80
  n_valence: [`Electron Valency`, null],
81
+ neutrons: [`Neutrons`, null],
69
82
  number: [`Atomic Number`, null],
83
+ number_of_isotopes: [`Number of Isotopes`, null],
84
+ oxidation_states: [`Oxidation States`, null],
85
+ period: [`Period`, null],
86
+ phase: [`Phase`, null],
87
+ protons: [`Protons`, null],
70
88
  shells: [`Electron Shell Occupations`, null],
71
89
  specific_heat: [`Specific Heat`, `J/(g K)`],
72
90
  };
@@ -108,6 +126,10 @@ export const FRACTION_GLYPHS = [
108
126
  [7 / 8, `⁷⁄₈`],
109
127
  [11 / 12, `¹¹⁄₁₂`],
110
128
  ];
129
+ // format_value when an explicit format is given, else format_num's adaptive
130
+ // default: SI prefixes for |value| >= 1 (4500 -> 4.5k) but plain decimals
131
+ // below 1 (0.2 stays 0.2, never the SI milli form "200m")
132
+ export const format_value_or_num = (value, fmt) => fmt ? format_value(value, fmt) : format_num(value);
111
133
  // fmt as number only allowed to support [].map(format_num) without type error
112
134
  export const format_num = (num, fmt) => {
113
135
  if (num === null)
@@ -119,7 +141,7 @@ export const format_num = (num, fmt) => {
119
141
  return format(fmt)(num);
120
142
  };
121
143
  // Format a 3D vector as "(x, y, z)" with configurable precision
122
- export const format_vec3 = (vec, fmt_spec = `.4~`) => `(${format_num(vec[0], fmt_spec)}, ${format_num(vec[1], fmt_spec)}, ${format_num(vec[2], fmt_spec)})`;
144
+ export const format_vec3 = (vec, fmt_spec = `.3~`) => `(${format_num(vec[0], fmt_spec)}, ${format_num(vec[1], fmt_spec)}, ${format_num(vec[2], fmt_spec)})`;
123
145
  const BYTE_UNITS = [`B`, `KiB`, `MiB`, `GiB`, `TiB`, `PiB`];
124
146
  // Format file sizes using IEC binary units (1024 factor).
125
147
  export const format_bytes = (bytes) => {
@@ -157,10 +179,10 @@ export function parse_si_float(value) {
157
179
  if (typeof value !== `string`)
158
180
  return value;
159
181
  // Remove whitespace and commas
160
- const cleaned = value.trim().replaceAll(/(\d),(\d)/g, `$1$2`);
182
+ const cleaned = value.trim().replaceAll(/(?<before>\d),(?<after>\d)/g, `$1$2`);
161
183
  // SI-formatted number (e.g. "1.23k", "789µ"). Suffixes are case-sensitive (m=milli vs
162
184
  // M=mega), so no `i` flag: mismatched-case suffixes return the string as-is.
163
- const match = /^([-+]?\d*\.?\d+)\s*([yzafpnµmkMGTPEZY])?$/.exec(cleaned);
185
+ const match = /^(?<num_part>[-+]?\d*\.?\d+)\s*(?<suffix>[yzafpnµmkMGTPEZY])?$/.exec(cleaned);
164
186
  if (match) {
165
187
  const [, num_part, suffix] = match;
166
188
  let multiplier = 1;
@@ -171,11 +193,12 @@ export function parse_si_float(value) {
171
193
  multiplier = 1000 ** (index - 8);
172
194
  }
173
195
  }
174
- return parseFloat(num_part) * multiplier;
196
+ return Number(num_part) * multiplier;
175
197
  }
176
- // If it's a number without SI suffix, try parsing it
198
+ // If it's a number without SI suffix, try parsing it (dropping stray commas
199
+ // not already stripped above, e.g. trailing ones)
177
200
  if (/^[-+]?[\d,]+\.?\d*$/.test(cleaned))
178
- return parseFloat(cleaned);
201
+ return Number(cleaned.replaceAll(`,`, ``));
179
202
  // If the value is not a formatted number, return as is
180
203
  return value;
181
204
  }
@@ -234,7 +257,9 @@ export const SUBSCRIPT_MAP = {
234
257
  };
235
258
  // replaces all signs and digits with their unicode superscript equivalent
236
259
  export const superscript_digits = (input) => input.replaceAll(/[\d+-]/g, (match) => is_superscript_key(match) ? SUPERSCRIPT_MAP[match] : match);
237
- // Trajectory property configuration: clean labels and units as structured data
260
+ // Axis-group key for SCF convergence series: shared between the property config
261
+ // below and the log-scale detection in trajectory/plotting.ts so the two can't drift
262
+ export const SCF_AXIS_GROUP = `eV (SCF)`;
238
263
  export const trajectory_property_config = {
239
264
  // Energy properties
240
265
  energy: { label: `Energy`, unit: `eV` },
@@ -275,4 +300,9 @@ export const trajectory_property_config = {
275
300
  Pressure: { label: `Pressure`, unit: `GPa` },
276
301
  stress_max: { label: `σ<sub>max</sub>`, unit: `GPa` },
277
302
  stress_frobenius: { label: `σ<sub>F</sub>`, unit: `GPa` },
303
+ // SCF/electronic convergence properties (e.g. from VASP vaspout.h5 OSZICAR data)
304
+ n_scf_steps: { label: `SCF steps`, unit: `steps` },
305
+ scf_energy_delta: { label: `|ΔE<sub>SCF</sub>|`, unit: `eV`, axis_group: SCF_AXIS_GROUP },
306
+ scf_rms: { label: `ρ residual (rms)`, unit: `a.u.` },
307
+ scf_charge_rms: { label: `ρ<sub>c</sub> residual (rms(c))`, unit: `a.u.` },
278
308
  };
@@ -21,9 +21,10 @@
21
21
  type="button"
22
22
  onclick={() => toggle_fullscreen(wrapper)}
23
23
  title="{fullscreen ? `Exit` : `Enter`} fullscreen"
24
+ aria-label="{fullscreen ? `Exit` : `Enter`} fullscreen"
24
25
  aria-pressed={fullscreen}
25
26
  {...rest}
26
- class="fullscreen-btn {rest.class ?? ``}"
27
+ class={[`fullscreen-btn`, rest.class]}
27
28
  >
28
29
  {#if typeof toggle === `function`}
29
30
  {@render toggle({ fullscreen })}
@@ -4,14 +4,17 @@
4
4
  import Icon from '../Icon.svelte'
5
5
  import type { HTMLButtonAttributes } from 'svelte/elements'
6
6
 
7
- let { fullscreen = $bindable(false), ...rest }: HTMLButtonAttributes & {
7
+ let {
8
+ fullscreen = $bindable(false),
9
+ ...rest
10
+ }: HTMLButtonAttributes & {
8
11
  fullscreen?: boolean
9
12
  } = $props()
10
13
  </script>
11
14
 
12
15
  <button
13
16
  {...rest}
14
- class="fullscreen-toggle {rest.class ?? ``}"
17
+ class={[`fullscreen-toggle`, rest.class]}
15
18
  onclick={() => (fullscreen = !fullscreen)}
16
19
  aria-label={fullscreen ? `Exit fullscreen` : `Enter fullscreen`}
17
20
  type="button"
@@ -33,9 +36,12 @@
33
36
  background-color: transparent;
34
37
  cursor: pointer;
35
38
  opacity: 0;
36
- transition: opacity 0.2s, background-color 0.2s;
39
+ transition:
40
+ opacity 0.2s,
41
+ background-color 0.2s;
37
42
  }
38
- .fullscreen-toggle:hover, .fullscreen-toggle:focus {
43
+ .fullscreen-toggle:hover,
44
+ .fullscreen-toggle:focus {
39
45
  background-color: color-mix(in srgb, currentColor 8%, transparent);
40
46
  opacity: var(--fullscreen-btn-hover-opacity, 1);
41
47
  }
@@ -4,8 +4,9 @@
4
4
  import type { Snippet } from 'svelte'
5
5
  import type { HTMLAttributes } from 'svelte/elements'
6
6
 
7
- interface Props<T extends keyof HTMLElementTagNameMap = `section`>
8
- extends HTMLAttributes<HTMLElementTagNameMap[T]> {
7
+ interface Props<T extends keyof HTMLElementTagNameMap = `section`> extends HTMLAttributes<
8
+ HTMLElementTagNameMap[T]
9
+ > {
9
10
  data?: {
10
11
  title: string
11
12
  value?: string | number | number[] | null
@@ -25,17 +26,15 @@
25
26
  data = [],
26
27
  title = ``,
27
28
  fallback = ``,
28
- fmt = `.2f`,
29
+ fmt: default_fmt = `.2f`,
29
30
  as = `section`,
30
31
  title_snippet,
31
32
  fallback_snippet,
32
33
  ...rest
33
34
  }: Props = $props()
34
-
35
- let default_fmt = $derived(fmt) // rename fmt to default_fmt for internal use
36
35
  </script>
37
36
 
38
- <svelte:element this={as} {...rest} class="info-card {rest.class ?? ``}">
37
+ <svelte:element this={as} {...rest} class={[`info-card`, rest.class]}>
39
38
  {#if title || title_snippet}
40
39
  <h2>
41
40
  {#if title_snippet}{@render title_snippet()}{:else}
@@ -43,13 +42,7 @@
43
42
  {/if}
44
43
  </h2>
45
44
  {/if}
46
- {#each data.filter((itm) =>
47
- (!(`condition` in itm) || itm?.condition) && itm.value !== undefined &&
48
- itm.value !== null
49
- ) as
50
- { title, value, unit, fmt = default_fmt, tooltip }
51
- (title + value + unit + fmt)
52
- }
45
+ {#each data.filter((itm) => (!(`condition` in itm) || itm?.condition) && itm.value !== undefined && itm.value !== null) as { title, value, unit, fmt = default_fmt, tooltip } (title + value + unit + fmt)}
53
46
  <div>
54
47
  <span class="title" {title}>
55
48
  {@html sanitize_html(title)}
@@ -77,10 +70,7 @@
77
70
  padding: var(--ic-padding, 10pt 12pt);
78
71
  margin: var(--ic-margin, 1em 0);
79
72
  gap: var(--ic-gap, 10pt 5%);
80
- background-color: var(
81
- --ic-bg,
82
- light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.1))
83
- );
73
+ background-color: var(--ic-bg, light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.1)));
84
74
  font-size: var(--ic-font-size);
85
75
  width: var(--ic-width);
86
76
  }
@@ -88,10 +78,7 @@
88
78
  grid-column: 1 / -1;
89
79
  margin: 0;
90
80
  border-bottom: 1px solid
91
- var(
92
- --ic-title-border-color,
93
- light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.3))
94
- );
81
+ var(--ic-title-border-color, light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.3)));
95
82
  }
96
83
  div {
97
84
  display: flex;
@@ -49,9 +49,7 @@
49
49
  else void copy_to_clipboard()
50
50
  }
51
51
 
52
- function handle_keydown(
53
- event: KeyboardEvent & { currentTarget: HTMLElement },
54
- ): void {
52
+ function handle_keydown(event: KeyboardEvent & { currentTarget: HTMLElement }): void {
55
53
  if (disabled || (event.key !== `Enter` && event.key !== ` `)) return
56
54
  event.preventDefault()
57
55
  event.currentTarget.click()
@@ -0,0 +1,46 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte'
3
+ import type { HTMLAttributes } from 'svelte/elements'
4
+ import { tooltip } from 'svelte-multiselect/attachments'
5
+
6
+ // Paired number + range input bound to the same value, wrapped in a flex <label>.
7
+ // The label text/markup is passed as children (supports inline units like <small>Å</small>).
8
+ // Pass a `title` (via rest) to show a tooltip; wrapping <label> only names the number input
9
+ // so range slider reuses that `title` as its accessible name.
10
+ let {
11
+ value = $bindable(),
12
+ min,
13
+ max,
14
+ step,
15
+ children,
16
+ ...rest
17
+ }: {
18
+ value: number | undefined
19
+ min: number | string
20
+ max: number | string
21
+ step: number | string
22
+ children?: Snippet
23
+ } & HTMLAttributes<HTMLLabelElement> = $props()
24
+ </script>
25
+
26
+ <label {@attach tooltip()} {...rest}>
27
+ {@render children?.()}
28
+ <input type="number" {min} {max} {step} bind:value />
29
+ <input type="range" {min} {max} {step} bind:value aria-label={rest.title} />
30
+ </label>
31
+
32
+ <style>
33
+ label {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 10pt;
37
+ }
38
+ input {
39
+ font-size: inherit;
40
+ font-family: inherit;
41
+ }
42
+ input[type='range'] {
43
+ flex: 1;
44
+ min-width: 40px;
45
+ }
46
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type $$ComponentProps = {
4
+ value: number | undefined;
5
+ min: number | string;
6
+ max: number | string;
7
+ step: number | string;
8
+ children?: Snippet;
9
+ } & HTMLAttributes<HTMLLabelElement>;
10
+ declare const NumberRangeInput: import("svelte").Component<$$ComponentProps, {}, "value">;
11
+ type NumberRangeInput = ReturnType<typeof NumberRangeInput>;
12
+ export default NumberRangeInput;
@@ -40,9 +40,7 @@
40
40
  onclear?: () => void // Callback when clear button is clicked (fires before onchange)
41
41
  } & HTMLAttributes<HTMLDivElement> = $props()
42
42
 
43
- let show_histogram = $derived(
44
- histogram_position !== `none` && histogram_data?.length,
45
- )
43
+ let show_histogram = $derived(histogram_position !== `none` && histogram_data?.length)
46
44
 
47
45
  // Active when either bound is set (undefined = unbounded)
48
46
  let active = $derived(min_value !== undefined || max_value !== undefined)
@@ -56,9 +54,7 @@
56
54
  return histogram_data.filter((val) => val >= min && val <= max)
57
55
  })
58
56
 
59
- function onkeydown(
60
- event: KeyboardEvent & { currentTarget: HTMLInputElement },
61
- ): void {
57
+ function onkeydown(event: KeyboardEvent & { currentTarget: HTMLInputElement }): void {
62
58
  if (event.key === `Enter`) {
63
59
  event.preventDefault()
64
60
  event.currentTarget.blur()