matterviz 0.4.0 → 0.4.2

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 (527) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +12 -14
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/app.css +53 -0
  6. package/dist/brillouin/BrillouinZone.svelte +132 -219
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +9 -20
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +47 -96
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +15 -42
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  13. package/dist/brillouin/BrillouinZoneScene.svelte +63 -230
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
  15. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  16. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  17. package/dist/brillouin/compute.d.ts +2 -0
  18. package/dist/brillouin/compute.js +80 -77
  19. package/dist/brillouin/geometry.d.ts +8 -0
  20. package/dist/brillouin/geometry.js +57 -0
  21. package/dist/brillouin/index.d.ts +2 -0
  22. package/dist/brillouin/index.js +2 -0
  23. package/dist/brillouin/types.d.ts +2 -2
  24. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  25. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  26. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +143 -246
  27. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  28. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +652 -976
  29. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  30. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  31. package/dist/chempot-diagram/color.d.ts +3 -6
  32. package/dist/chempot-diagram/color.js +5 -5
  33. package/dist/chempot-diagram/compute.d.ts +3 -3
  34. package/dist/chempot-diagram/compute.js +3 -1
  35. package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
  36. package/dist/chempot-diagram/controls-state.svelte.js +42 -0
  37. package/dist/chempot-diagram/export.d.ts +47 -0
  38. package/dist/chempot-diagram/export.js +133 -0
  39. package/dist/chempot-diagram/index.d.ts +1 -0
  40. package/dist/chempot-diagram/index.js +1 -0
  41. package/dist/chempot-diagram/pointer.d.ts +0 -10
  42. package/dist/chempot-diagram/pointer.js +4 -4
  43. package/dist/chempot-diagram/types.d.ts +3 -3
  44. package/dist/colors/index.d.ts +0 -4
  45. package/dist/colors/index.js +21 -22
  46. package/dist/composition/BarChart.svelte +37 -31
  47. package/dist/composition/BubbleChart.svelte +17 -17
  48. package/dist/composition/Composition.svelte +7 -11
  49. package/dist/composition/Formula.svelte +18 -25
  50. package/dist/composition/FormulaFilter.svelte +96 -98
  51. package/dist/composition/PieChart.svelte +60 -46
  52. package/dist/composition/chem-sys.js +3 -2
  53. package/dist/composition/format.js +4 -3
  54. package/dist/composition/index.d.ts +2 -0
  55. package/dist/composition/index.js +14 -0
  56. package/dist/composition/parse.d.ts +2 -3
  57. package/dist/composition/parse.js +27 -28
  58. package/dist/constants.js +11 -9
  59. package/dist/controls.d.ts +1 -0
  60. package/dist/controls.js +0 -1
  61. package/dist/convex-hull/ConvexHull.svelte +20 -25
  62. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  63. package/dist/convex-hull/ConvexHull2D.svelte +176 -256
  64. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  65. package/dist/convex-hull/ConvexHull3D.svelte +269 -804
  66. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  67. package/dist/convex-hull/ConvexHull4D.svelte +236 -755
  68. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  69. package/dist/convex-hull/ConvexHullChrome.svelte +264 -0
  70. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  71. package/dist/convex-hull/ConvexHullControls.svelte +128 -49
  72. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  73. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  74. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  75. package/dist/convex-hull/ConvexHullStats.svelte +210 -351
  76. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  77. package/dist/convex-hull/ConvexHullTooltip.svelte +16 -14
  78. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  79. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  80. package/dist/convex-hull/StructurePopup.svelte +17 -21
  81. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  82. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  83. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  84. package/dist/convex-hull/barycentric-coords.js +6 -33
  85. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  86. package/dist/convex-hull/canvas-interactions.svelte.js +279 -0
  87. package/dist/convex-hull/helpers.d.ts +47 -17
  88. package/dist/convex-hull/helpers.js +186 -101
  89. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  90. package/dist/convex-hull/hull-state.svelte.js +124 -0
  91. package/dist/convex-hull/index.d.ts +9 -7
  92. package/dist/convex-hull/index.js +7 -2
  93. package/dist/convex-hull/thermodynamics.js +109 -937
  94. package/dist/convex-hull/types.d.ts +12 -4
  95. package/dist/convex-hull/types.js +12 -0
  96. package/dist/coordination/CoordinationBarPlot.svelte +41 -43
  97. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  98. package/dist/coordination/calc-coordination.d.ts +1 -1
  99. package/dist/coordination/calc-coordination.js +28 -25
  100. package/dist/element/BohrAtom.svelte +6 -8
  101. package/dist/element/ElementHeading.svelte +4 -1
  102. package/dist/element/ElementPhoto.svelte +11 -9
  103. package/dist/element/ElementStats.svelte +12 -10
  104. package/dist/element/ElementTile.svelte +24 -29
  105. package/dist/element/ElementTile.svelte.d.ts +1 -1
  106. package/dist/element/Nucleus.svelte +4 -2
  107. package/dist/element/data.d.ts +1 -2
  108. package/dist/element/helpers.d.ts +4 -0
  109. package/dist/element/helpers.js +18 -0
  110. package/dist/element/index.d.ts +1 -0
  111. package/dist/element/index.js +3 -0
  112. package/dist/feedback/DragOverlay.svelte +5 -3
  113. package/dist/feedback/DragOverlay.svelte.d.ts +2 -1
  114. package/dist/feedback/StatusMessage.svelte +20 -7
  115. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  116. package/dist/fermi-surface/FermiSurface.svelte +78 -165
  117. package/dist/fermi-surface/FermiSurface.svelte.d.ts +9 -20
  118. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  119. package/dist/fermi-surface/FermiSurfaceScene.svelte +93 -272
  120. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  121. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  122. package/dist/fermi-surface/compute.js +14 -13
  123. package/dist/fermi-surface/export.js +4 -15
  124. package/dist/fermi-surface/index.d.ts +0 -1
  125. package/dist/fermi-surface/index.js +0 -1
  126. package/dist/fermi-surface/parse.d.ts +1 -1
  127. package/dist/fermi-surface/parse.js +84 -97
  128. package/dist/fermi-surface/types.d.ts +2 -2
  129. package/dist/heatmap-matrix/HeatmapMatrix.svelte +161 -185
  130. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +6 -5
  131. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +12 -9
  132. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  133. package/dist/heatmap-matrix/index.d.ts +8 -2
  134. package/dist/icons.d.ts +4 -0
  135. package/dist/icons.js +4 -0
  136. package/dist/index.d.ts +1 -0
  137. package/dist/index.js +1 -0
  138. package/dist/io/ExportPane.svelte +170 -0
  139. package/dist/io/ExportPane.svelte.d.ts +17 -0
  140. package/dist/io/decompress.d.ts +2 -1
  141. package/dist/io/decompress.js +22 -36
  142. package/dist/io/export.d.ts +9 -1
  143. package/dist/io/export.js +37 -29
  144. package/dist/io/fetch.d.ts +2 -4
  145. package/dist/io/fetch.js +0 -11
  146. package/dist/io/file-drop.d.ts +7 -0
  147. package/dist/io/file-drop.js +13 -0
  148. package/dist/io/index.d.ts +1 -0
  149. package/dist/io/index.js +3 -0
  150. package/dist/io/is-binary.d.ts +9 -0
  151. package/dist/io/is-binary.js +45 -1
  152. package/dist/io/types.d.ts +13 -0
  153. package/dist/io/url-drop.js +13 -25
  154. package/dist/isosurface/Isosurface.svelte +17 -23
  155. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  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 +50 -48
  159. package/dist/labels.d.ts +6 -2
  160. package/dist/labels.js +44 -14
  161. package/dist/layout/FullscreenButton.svelte +34 -0
  162. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  163. package/dist/layout/FullscreenToggle.svelte +12 -12
  164. package/dist/layout/InfoCard.svelte +7 -18
  165. package/dist/layout/InfoTag.svelte +1 -3
  166. package/dist/layout/NumberRangeInput.svelte +46 -0
  167. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  168. package/dist/layout/PropertyFilter.svelte +2 -6
  169. package/dist/layout/SettingsSection.svelte +21 -17
  170. package/dist/layout/SubpageGrid.svelte +3 -1
  171. package/dist/layout/ViewerChrome.svelte +115 -0
  172. package/dist/layout/ViewerChrome.svelte.d.ts +18 -0
  173. package/dist/layout/fullscreen.d.ts +4 -0
  174. package/dist/layout/fullscreen.js +3 -5
  175. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  176. package/dist/layout/fullscreen.svelte.js +36 -0
  177. package/dist/layout/index.d.ts +4 -0
  178. package/dist/layout/index.js +4 -0
  179. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  180. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  181. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  182. package/dist/layout/json-tree/utils.js +14 -23
  183. package/dist/math.d.ts +9 -3
  184. package/dist/math.js +37 -21
  185. package/dist/overlays/ContextMenu.svelte +4 -2
  186. package/dist/overlays/CopyButton.svelte +11 -5
  187. package/dist/overlays/DragControlTab.svelte +6 -1
  188. package/dist/overlays/DraggablePane.svelte +81 -26
  189. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  190. package/dist/overlays/GlassChip.svelte +30 -0
  191. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  192. package/dist/overlays/InfoPaneCards.svelte +11 -23
  193. package/dist/overlays/index.d.ts +11 -0
  194. package/dist/overlays/index.js +26 -0
  195. package/dist/overlays/portal.d.ts +2 -0
  196. package/dist/overlays/portal.js +14 -0
  197. package/dist/periodic-table/PeriodicTable.svelte +115 -146
  198. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  199. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  200. package/dist/periodic-table/TableInset.svelte +9 -4
  201. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  202. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  203. package/dist/phase-diagram/PhaseDiagramControls.svelte +73 -96
  204. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  205. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
  206. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  207. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +49 -134
  208. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  209. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  210. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  211. package/dist/phase-diagram/build-diagram.js +3 -3
  212. package/dist/phase-diagram/colors.js +1 -1
  213. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  214. package/dist/phase-diagram/parse.d.ts +2 -1
  215. package/dist/phase-diagram/parse.js +15 -15
  216. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  217. package/dist/phase-diagram/utils.js +2 -3
  218. package/dist/plot/bar/BarPlot.svelte +494 -692
  219. package/dist/plot/bar/BarPlot.svelte.d.ts +9 -15
  220. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  221. package/dist/plot/bar/BarPlotControls.svelte.d.ts +5 -7
  222. package/dist/plot/bar/SpacegroupBarPlot.svelte +31 -37
  223. package/dist/plot/bar/data.d.ts +5 -4
  224. package/dist/plot/bar/data.js +2 -1
  225. package/dist/plot/box/BoxPlot.svelte +361 -439
  226. package/dist/plot/box/BoxPlot.svelte.d.ts +6 -3
  227. package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
  228. package/dist/plot/box/Violin.svelte.d.ts +2 -1
  229. package/dist/plot/box/box-plot.d.ts +3 -2
  230. package/dist/plot/box/box-plot.js +6 -3
  231. package/dist/plot/box/kde.d.ts +2 -1
  232. package/dist/plot/box/kde.js +4 -4
  233. package/dist/plot/core/auto-place.d.ts +1 -1
  234. package/dist/plot/core/auto-place.js +5 -2
  235. package/dist/plot/core/axis-utils.d.ts +12 -7
  236. package/dist/plot/core/axis-utils.js +48 -48
  237. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  238. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  239. package/dist/plot/core/components/ColorBar.svelte +106 -111
  240. package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
  241. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  242. package/dist/plot/core/components/FillArea.svelte +10 -17
  243. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  244. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  245. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  246. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  247. package/dist/plot/core/components/Line.svelte +21 -11
  248. package/dist/plot/core/components/Line.svelte.d.ts +5 -2
  249. package/dist/plot/core/components/PlotAxis.svelte +42 -18
  250. package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
  251. package/dist/plot/core/components/PlotControls.svelte +65 -41
  252. package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
  253. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  254. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  255. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  256. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  257. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  258. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  259. package/dist/plot/core/components/ReferenceLine3D.svelte +56 -59
  260. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
  261. package/dist/plot/core/components/ReferencePlane.svelte +9 -10
  262. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
  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 +29 -476
  271. package/dist/plot/core/data-transform.js +9 -5
  272. package/dist/plot/core/fill-utils.d.ts +7 -4
  273. package/dist/plot/core/fill-utils.js +34 -9
  274. package/dist/plot/core/index.d.ts +1 -0
  275. package/dist/plot/core/index.js +1 -0
  276. package/dist/plot/core/interactions.d.ts +5 -1
  277. package/dist/plot/core/interactions.js +14 -2
  278. package/dist/plot/core/layout.d.ts +3 -1
  279. package/dist/plot/core/layout.js +22 -13
  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 +35 -0
  283. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  284. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -0
  286. package/dist/plot/core/reference-line.d.ts +10 -10
  287. package/dist/plot/core/reference-line.js +7 -7
  288. package/dist/plot/core/scales.d.ts +40 -25
  289. package/dist/plot/core/scales.js +49 -21
  290. package/dist/plot/core/svg.d.ts +2 -1
  291. package/dist/plot/core/types/fills.d.ts +101 -0
  292. package/dist/plot/core/types/fills.js +15 -0
  293. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  294. package/dist/plot/core/types/plot-3d.js +4 -0
  295. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  296. package/dist/plot/core/types/reference-lines.js +9 -0
  297. package/dist/plot/core/types.d.ts +47 -331
  298. package/dist/plot/core/types.js +23 -20
  299. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  300. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  301. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  302. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  303. package/dist/plot/core/utils/label-placement.d.ts +1 -1
  304. package/dist/plot/core/utils/label-placement.js +5 -5
  305. package/dist/plot/core/utils.d.ts +2 -1
  306. package/dist/plot/histogram/Histogram.svelte +373 -631
  307. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  308. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  309. package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
  310. package/dist/plot/histogram/histogram.d.ts +31 -0
  311. package/dist/plot/histogram/histogram.js +70 -0
  312. package/dist/plot/histogram/index.d.ts +1 -0
  313. package/dist/plot/histogram/index.js +1 -0
  314. package/dist/plot/index.d.ts +1 -0
  315. package/dist/plot/index.js +1 -0
  316. package/dist/plot/sankey/Sankey.svelte +79 -73
  317. package/dist/plot/sankey/Sankey.svelte.d.ts +3 -3
  318. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  319. package/dist/plot/sankey/sankey.js +3 -1
  320. package/dist/plot/scatter/BinnedScatterPlot.svelte +264 -112
  321. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +11 -4
  322. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  323. package/dist/plot/scatter/ScatterPlot.svelte +623 -821
  324. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +9 -15
  325. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  326. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  327. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  328. package/dist/plot/scatter/binned-scatter-types.d.ts +6 -12
  329. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  330. package/dist/plot/scatter/index.d.ts +1 -1
  331. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  332. package/dist/plot/scatter/scatter-data.js +8 -7
  333. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +40 -60
  334. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
  335. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +17 -15
  336. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
  337. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +232 -234
  338. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
  339. package/dist/plot/scatter-3d/Surface3D.svelte +9 -17
  340. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
  341. package/dist/plot/sunburst/Sunburst.svelte +256 -338
  342. package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
  343. package/dist/plot/sunburst/index.d.ts +1 -1
  344. package/dist/plot/sunburst/index.js +2 -1
  345. package/dist/plot/sunburst/render.d.ts +2 -2
  346. package/dist/plot/sunburst/render.js +47 -22
  347. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  348. package/dist/plot/sunburst/sunburst.js +14 -4
  349. package/dist/plot/treemap/Treemap.svelte +907 -0
  350. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  351. package/dist/plot/treemap/index.d.ts +3 -0
  352. package/dist/plot/treemap/index.js +4 -0
  353. package/dist/plot/treemap/treemap.d.ts +26 -0
  354. package/dist/plot/treemap/treemap.js +99 -0
  355. package/dist/rdf/RdfPlot.svelte +22 -26
  356. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  357. package/dist/rdf/calc-rdf.js +4 -8
  358. package/dist/sanitize.js +14 -3
  359. package/dist/scene/SceneCamera.svelte +62 -0
  360. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  361. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  362. package/dist/scene/bind-renderer.svelte.js +22 -0
  363. package/dist/scene/index.d.ts +4 -0
  364. package/dist/scene/index.js +5 -0
  365. package/dist/scene/props.js +52 -0
  366. package/dist/scene/types.d.ts +26 -0
  367. package/dist/scene/types.js +1 -0
  368. package/dist/settings.d.ts +33 -11
  369. package/dist/settings.js +136 -51
  370. package/dist/spectral/Bands.svelte +231 -237
  371. package/dist/spectral/Bands.svelte.d.ts +3 -2
  372. package/dist/spectral/BandsAndDos.svelte +29 -29
  373. package/dist/spectral/BrillouinBandsDos.svelte +21 -29
  374. package/dist/spectral/Dos.svelte +75 -77
  375. package/dist/spectral/Dos.svelte.d.ts +2 -1
  376. package/dist/spectral/helpers.d.ts +9 -9
  377. package/dist/spectral/helpers.js +66 -70
  378. package/dist/state.svelte.d.ts +0 -7
  379. package/dist/state.svelte.js +5 -24
  380. package/dist/structure/Arrow.svelte +6 -21
  381. package/dist/structure/ArrowInstances.svelte +160 -0
  382. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  383. package/dist/structure/AtomLegend.svelte +115 -75
  384. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  385. package/dist/structure/Bond.svelte +31 -23
  386. package/dist/structure/CanvasTooltip.svelte +16 -3
  387. package/dist/structure/CellSelect.svelte +22 -29
  388. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  389. package/dist/structure/Cylinder.svelte +24 -40
  390. package/dist/structure/InstancedAtoms.svelte +114 -0
  391. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  392. package/dist/structure/Lattice.svelte +85 -149
  393. package/dist/structure/SiteLabels.svelte +122 -0
  394. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  395. package/dist/structure/Structure.svelte +725 -735
  396. package/dist/structure/Structure.svelte.d.ts +8 -16
  397. package/dist/structure/StructureCarousel.svelte +630 -0
  398. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  399. package/dist/structure/StructureControls.svelte +298 -325
  400. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  401. package/dist/structure/StructureExportPane.svelte +62 -168
  402. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  403. package/dist/structure/StructureInfoPane.svelte +77 -69
  404. package/dist/structure/StructureInfoPane.svelte.d.ts +6 -6
  405. package/dist/structure/StructureScene.svelte +758 -600
  406. package/dist/structure/StructureScene.svelte.d.ts +24 -20
  407. package/dist/structure/StructureViewport.svelte +386 -0
  408. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  409. package/dist/structure/atom-label-placement.d.ts +18 -0
  410. package/dist/structure/atom-label-placement.js +115 -0
  411. package/dist/structure/atom-properties.d.ts +3 -1
  412. package/dist/structure/atom-properties.js +115 -54
  413. package/dist/structure/bond-order-perception.js +2 -4
  414. package/dist/structure/bonding.d.ts +12 -2
  415. package/dist/structure/bonding.js +172 -73
  416. package/dist/structure/edit-history.d.ts +6 -0
  417. package/dist/structure/edit-history.js +27 -0
  418. package/dist/structure/export.d.ts +25 -4
  419. package/dist/structure/export.js +103 -153
  420. package/dist/structure/format-detect.d.ts +1 -0
  421. package/dist/structure/format-detect.js +22 -0
  422. package/dist/structure/geometry.d.ts +9 -0
  423. package/dist/structure/geometry.js +27 -0
  424. package/dist/structure/index.d.ts +18 -1
  425. package/dist/structure/index.js +15 -2
  426. package/dist/structure/measure.d.ts +1 -1
  427. package/dist/structure/measure.js +6 -12
  428. package/dist/structure/parse.d.ts +5 -3
  429. package/dist/structure/parse.js +551 -567
  430. package/dist/structure/partial-occupancy.d.ts +0 -1
  431. package/dist/structure/partial-occupancy.js +5 -3
  432. package/dist/structure/pbc.d.ts +1 -1
  433. package/dist/structure/pbc.js +204 -51
  434. package/dist/structure/polyhedra.d.ts +40 -0
  435. package/dist/structure/polyhedra.js +587 -0
  436. package/dist/structure/site.d.ts +4 -0
  437. package/dist/structure/site.js +1 -0
  438. package/dist/structure/supercell.d.ts +1 -2
  439. package/dist/structure/supercell.js +10 -15
  440. package/dist/structure/validation.js +5 -6
  441. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  442. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  443. package/dist/symmetry/SymmetryElements.svelte +350 -0
  444. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  445. package/dist/symmetry/SymmetryStats.svelte +142 -49
  446. package/dist/symmetry/WyckoffTable.svelte +58 -16
  447. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  448. package/dist/symmetry/cell-transform.js +8 -14
  449. package/dist/symmetry/index.d.ts +15 -4
  450. package/dist/symmetry/index.js +308 -81
  451. package/dist/symmetry/spacegroups.d.ts +5 -1
  452. package/dist/symmetry/spacegroups.js +18 -3
  453. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  454. package/dist/symmetry/symmetry-elements.js +521 -0
  455. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  456. package/dist/symmetry/wyckoff-db.js +87 -0
  457. package/dist/table/HeatmapTable.svelte +1104 -378
  458. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  459. package/dist/table/ToggleMenu.svelte +5 -12
  460. package/dist/table/index.d.ts +21 -6
  461. package/dist/table/index.js +34 -21
  462. package/dist/theme/ThemeControl.svelte +16 -8
  463. package/dist/theme/index.d.ts +1 -5
  464. package/dist/theme/index.js +4 -10
  465. package/dist/theme/themes.mjs +14 -7
  466. package/dist/tooltip/KCoords.svelte +4 -1
  467. package/dist/tooltip/TooltipContent.svelte +2 -5
  468. package/dist/trajectory/Trajectory.svelte +556 -352
  469. package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
  470. package/dist/trajectory/TrajectoryError.svelte +11 -8
  471. package/dist/trajectory/TrajectoryExportPane.svelte +28 -54
  472. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  473. package/dist/trajectory/TrajectoryInfoPane.svelte +88 -99
  474. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  475. package/dist/trajectory/constants.js +6 -2
  476. package/dist/trajectory/extract.js +73 -71
  477. package/dist/trajectory/format-detect.d.ts +0 -1
  478. package/dist/trajectory/format-detect.js +13 -17
  479. package/dist/trajectory/frame-reader.d.ts +2 -1
  480. package/dist/trajectory/frame-reader.js +74 -136
  481. package/dist/trajectory/helpers.d.ts +12 -2
  482. package/dist/trajectory/helpers.js +68 -37
  483. package/dist/trajectory/index.d.ts +1 -0
  484. package/dist/trajectory/index.js +3 -0
  485. package/dist/trajectory/parse/ase.d.ts +9 -1
  486. package/dist/trajectory/parse/ase.js +47 -32
  487. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  488. package/dist/trajectory/parse/diagnostics.js +14 -0
  489. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  490. package/dist/trajectory/parse/h5-utils.js +109 -0
  491. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  492. package/dist/trajectory/parse/hdf5.js +116 -106
  493. package/dist/trajectory/parse/index.d.ts +3 -4
  494. package/dist/trajectory/parse/index.js +68 -119
  495. package/dist/trajectory/parse/lammps.d.ts +0 -2
  496. package/dist/trajectory/parse/lammps.js +14 -16
  497. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  498. package/dist/trajectory/parse/pymatgen.js +74 -0
  499. package/dist/trajectory/parse/vasp.js +13 -9
  500. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  501. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  502. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  503. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  504. package/dist/trajectory/parse/xyz.d.ts +9 -21
  505. package/dist/trajectory/parse/xyz.js +38 -39
  506. package/dist/trajectory/plotting.d.ts +8 -10
  507. package/dist/trajectory/plotting.js +102 -127
  508. package/dist/utils.d.ts +4 -0
  509. package/dist/utils.js +8 -1
  510. package/dist/xrd/XrdPlot.svelte +56 -85
  511. package/dist/xrd/broadening.d.ts +2 -1
  512. package/dist/xrd/broadening.js +2 -1
  513. package/dist/xrd/calc-xrd.js +8 -15
  514. package/dist/xrd/index.d.ts +2 -2
  515. package/dist/xrd/parse.d.ts +0 -1
  516. package/dist/xrd/parse.js +56 -73
  517. package/package.json +77 -36
  518. package/dist/api/mp.d.ts +0 -6
  519. package/dist/api/mp.js +0 -22
  520. package/dist/element/data.json +0 -11864
  521. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  522. package/dist/fermi-surface/marching-cubes.js +0 -2
  523. package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
  524. package/dist/plot/core/hover-lock.svelte.js +0 -45
  525. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  526. package/dist/structure/label-placement.d.ts +0 -14
  527. package/dist/structure/label-placement.js +0 -72
@@ -2,6 +2,19 @@
2
2
  import { decompress_file } from './decompress';
3
3
  import { handle_url_drop } from './url-drop';
4
4
  import { to_error } from '../utils';
5
+ // Drag-over visual-state handlers for file-drop zones; spread onto the drop target
6
+ // alongside `ondrop` from create_file_drop_handler
7
+ export const drag_over_handlers = (opts) => ({
8
+ // preventDefault on dragover marks the element as a valid drop target; dragleave
9
+ // has no default action to cancel, so it only clears the visual state
10
+ ondragover: (event) => {
11
+ event.preventDefault();
12
+ if (opts.allow && !opts.allow())
13
+ return;
14
+ opts.set_dragover(true);
15
+ },
16
+ ondragleave: () => opts.set_dragover(false),
17
+ });
5
18
  // Handles URL drops (from FilePicker), direct file drops with decompression,
6
19
  // loading state, and error reporting.
7
20
  export const create_file_drop_handler = (opts) => async (event) => {
@@ -1,3 +1,4 @@
1
+ export { default as ExportPane } from './ExportPane.svelte';
1
2
  export * from './decompress';
2
3
  export * from './export';
3
4
  export * from './fetch';
package/dist/io/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ export { default as ExportPane } from './ExportPane.svelte';
2
+ // strip_compression_extensions lives in ./decompress (Svelte-free) so parser
3
+ // modules can import it inside Web Workers; re-exported here.
1
4
  export * from './decompress';
2
5
  export * from './export';
3
6
  export * from './fetch';
@@ -1 +1,10 @@
1
1
  export declare const is_binary: (content: string) => boolean;
2
+ export declare const has_gzip_magic: (bytes: Uint8Array) => boolean;
3
+ export declare const has_hdf5_magic: (bytes: Uint8Array) => boolean;
4
+ export declare const has_binary_magic: (bytes: Uint8Array) => boolean;
5
+ export declare const ext_of: (name: string) => string;
6
+ export declare const BINARY_EXTENSIONS: Set<string>;
7
+ export declare const is_known_text_file: (basename: string) => boolean;
8
+ export declare const strip_gz_ext: (filename: string) => string;
9
+ export declare const has_binary_inner_ext: (filename: string) => boolean;
10
+ export declare const is_binary_payload: (filename: string, buffer: ArrayBuffer) => boolean;
@@ -1,4 +1,8 @@
1
- // Simplified binary detection
1
+ // Single source of truth for binary-vs-text detection in the io layer (used by
2
+ // decompress.ts and url-drop.ts): (1) is_binary string heuristic, (2) has_*_magic byte
3
+ // signatures, (3) extension/filename classification.
4
+ // === (1) string-content heuristic ===
5
+ // Detect binary from decoded text: a NUL byte or a high ratio of non-printable chars.
2
6
  export const is_binary = (content) => {
3
7
  if (!content)
4
8
  return false;
@@ -18,3 +22,43 @@ export const is_binary = (content) => {
18
22
  }
19
23
  return (binary_char_count / content.length > 0.1 || printable_ascii_count / content.length < 0.7);
20
24
  };
25
+ // === (2) magic-byte signatures ===
26
+ const starts_with = (bytes, sig) => bytes.length >= sig.length && sig.every((byte, idx) => bytes[idx] === byte);
27
+ // gzip member header
28
+ export const has_gzip_magic = (bytes) => starts_with(bytes, [0x1f, 0x8b]);
29
+ // Full 8-byte HDF5 superblock signature "\x89HDF\r\n\x1a\n" — used to validate that a file
30
+ // claiming a .h5/.hdf5 extension really is HDF5 (stricter than the binary sniff below).
31
+ export const has_hdf5_magic = (bytes) => starts_with(bytes, [0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a]);
32
+ // Leading bytes that mark a payload as binary so a lossy UTF-8 decode would corrupt it.
33
+ // HDF5 is matched by its 4-byte "\x89HDF" prefix (the non-ASCII 0x89 already rules out text
34
+ // starting with "HDF"); the full 4-byte ZIP signatures rule out text merely starting "PK".
35
+ export const has_binary_magic = (bytes) => has_gzip_magic(bytes) ||
36
+ starts_with(bytes, [0x89, 0x48, 0x44, 0x46]) || // HDF5 "\x89HDF"
37
+ starts_with(bytes, [0x50, 0x4b, 0x03, 0x04]) || // ZIP local file
38
+ starts_with(bytes, [0x50, 0x4b, 0x05, 0x06]) || // ZIP empty archive (EOCD)
39
+ starts_with(bytes, [0x50, 0x4b, 0x07, 0x08]) || // ZIP spanned
40
+ starts_with(bytes, [0x2d, 0x20, 0x6f, 0x66, 0x20, 0x55, 0x6c, 0x6d]); // ASE .traj "- of Ulm"
41
+ // === (3) extension / filename classification ===
42
+ export const ext_of = (name) => name.split(`.`).pop()?.toLowerCase() ?? ``;
43
+ // Binary data formats whose lossy UTF-8 decode would corrupt bytes (post-decompression)
44
+ const BINARY_DATA_EXTENSIONS = new Set(`h5 hdf5 traj npz pkl dat brml raw`.split(` `));
45
+ // All extensions treated as binary: data formats + compressed wrappers that must be
46
+ // downloaded/kept as raw bytes (used for binary-fetch mode and .gz inner-format checks)
47
+ export const BINARY_EXTENSIONS = new Set([
48
+ ...BINARY_DATA_EXTENSIONS,
49
+ ...`gz gzip zip bz2 xz`.split(` `),
50
+ ]);
51
+ // Known text formats (plus extensionless VASP files) — safe to fetch/sniff as text
52
+ const TEXT_EXTENSIONS = new Set(`xyz extxyz json cif poscar yaml yml txt md py js ts css html xml`.split(` `));
53
+ const VASP_BASENAME_RE = /^(?:poscar|xdatcar|contcar)$/i;
54
+ export const is_known_text_file = (basename) => TEXT_EXTENSIONS.has(ext_of(basename)) || VASP_BASENAME_RE.test(basename);
55
+ const GZ_EXT_RE = /\.(?:gz|gzip)$/i;
56
+ // Strip a trailing .gz/.gzip wrapper extension, leaving any inner extension intact
57
+ export const strip_gz_ext = (filename) => filename.replace(GZ_EXT_RE, ``);
58
+ // Whether the file inside a .gz/.gzip wrapper is a known binary format that a lossy text
59
+ // decode would corrupt (bytes >= 0x80 -> U+FFFD)
60
+ export const has_binary_inner_ext = (filename) => BINARY_EXTENSIONS.has(ext_of(strip_gz_ext(filename)));
61
+ // Binary if the (post-decompression) extension is a known binary data format or the leading
62
+ // bytes match a magic signature
63
+ export const is_binary_payload = (filename, buffer) => BINARY_DATA_EXTENSIONS.has(ext_of(filename)) ||
64
+ has_binary_magic(new Uint8Array(buffer.slice(0, 8)));
@@ -6,3 +6,16 @@ export interface FileInfo {
6
6
  category?: string;
7
7
  category_icon?: string;
8
8
  }
9
+ export interface ExportItem {
10
+ label: string;
11
+ hint?: string;
12
+ disabled?: boolean;
13
+ on_download?: () => void;
14
+ copy_text?: () => string | null;
15
+ show_dpi?: boolean;
16
+ }
17
+ export interface ExportSection {
18
+ title?: string;
19
+ tooltip?: string;
20
+ items: ExportItem[];
21
+ }
@@ -1,9 +1,6 @@
1
1
  import { load_binary_traj } from '../trajectory/parse';
2
2
  import { decompress_data_binary } from './decompress';
3
- const BINARY_EXTENSIONS = new Set(`h5 hdf5 traj npz pkl dat gz gzip zip bz2 xz brml raw`.split(` `));
4
- const TEXT_EXTENSIONS = new Set(`xyz extxyz json cif poscar yaml yml txt md py js ts css html xml`.split(` `));
5
- const VASP_BASENAME_RE = /^(poscar|xdatcar|contcar)$/i;
6
- const GZ_EXT_RE = /\.(gz|gzip)$/i;
3
+ import { BINARY_EXTENSIONS, ext_of, has_binary_inner_ext, has_binary_magic, has_gzip_magic, has_hdf5_magic, is_known_text_file, strip_gz_ext, } from './is-binary';
7
4
  // Extract filename from Content-Disposition header, falling back to url_basename.
8
5
  function extract_filename(headers, fallback) {
9
6
  if (!headers)
@@ -11,11 +8,11 @@ function extract_filename(headers, fallback) {
11
8
  const content_disposition_str = headers.get(`content-disposition`);
12
9
  if (!content_disposition_str)
13
10
  return fallback;
14
- const star_match = /filename\*=([^;]+)/i.exec(content_disposition_str);
11
+ const star_match = /filename\*=(?<value>[^;]+)/i.exec(content_disposition_str);
15
12
  if (star_match?.[1]) {
16
13
  let raw = star_match[1].trim().replaceAll(/^"|"$/g, ``);
17
14
  // Strip any RFC 5987 charset'language' prefix; bare values pass through unchanged
18
- const ext_value_match = /^[\w!#$%&+^`{}~-]+'[\w-]*'(.*)$/.exec(raw);
15
+ const ext_value_match = /^[\w!#$%&+^`{}~-]+'[\w-]*'(?<value>.*)$/.exec(raw);
19
16
  if (ext_value_match)
20
17
  raw = ext_value_match[1];
21
18
  try {
@@ -25,17 +22,13 @@ function extract_filename(headers, fallback) {
25
22
  return raw;
26
23
  }
27
24
  }
28
- const plain_match = /filename\s*=\s*"?([^";]+)"?/i.exec(content_disposition_str);
25
+ const plain_match = /filename\s*=\s*"?(?<value>[^";]+)"?/i.exec(content_disposition_str);
29
26
  // truthiness check (not ??) so whitespace-only `filename=` values fall back too
30
27
  const name = plain_match?.[1]?.trim();
31
28
  if (!name)
32
29
  return fallback;
33
30
  return name;
34
31
  }
35
- const ext_of = (name) => name.split(`.`).pop()?.toLowerCase() ?? ``;
36
- // Whether the file inside a .gz/.gzip wrapper is a known binary format that a
37
- // lossy text decode would corrupt (bytes >= 0x80 → U+FFFD)
38
- const has_binary_inner_ext = (filename) => BINARY_EXTENSIONS.has(ext_of(filename.replace(GZ_EXT_RE, ``)));
39
32
  // Gunzip a fetched payload → [content, filename] with .gz/.gzip stripped; content
40
33
  // stays an ArrayBuffer for binary inner formats, decoded string otherwise
41
34
  async function decompress_gz_payload(buffer, filename) {
@@ -43,7 +36,7 @@ async function decompress_gz_payload(buffer, filename) {
43
36
  const content = has_binary_inner_ext(filename)
44
37
  ? decompressed
45
38
  : new TextDecoder().decode(decompressed);
46
- return [content, filename.replace(GZ_EXT_RE, ``)];
39
+ return [content, strip_gz_ext(filename)];
47
40
  }
48
41
  // Handle URL-based file drop data by fetching content lazily
49
42
  export async function handle_url_drop(drag_event, callback) {
@@ -87,12 +80,10 @@ export async function load_from_url(url, callback) {
87
80
  if (ext === `h5` || ext === `hdf5`) {
88
81
  const result = await load_binary_traj(resp, `H5`, true);
89
82
  // Log warning if signature doesn't match (only for ArrayBuffer results)
90
- if (result instanceof ArrayBuffer && result.byteLength >= 8) {
91
- const view = new Uint8Array(result.slice(0, 8));
92
- const hdf5_signature = [0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a];
93
- if (!hdf5_signature.every((byte, idx) => view[idx] === byte)) {
94
- console.warn(`File has .h5/.hdf5 extension but missing HDF5 signature`);
95
- }
83
+ if (result instanceof ArrayBuffer &&
84
+ result.byteLength >= 8 &&
85
+ !has_hdf5_magic(new Uint8Array(result.slice(0, 8)))) {
86
+ console.warn(`File has .h5/.hdf5 extension but missing HDF5 signature`);
96
87
  }
97
88
  return callback(result, filename);
98
89
  }
@@ -108,7 +99,7 @@ export async function load_from_url(url, callback) {
108
99
  }
109
100
  // Skip Range requests for known text formats to avoid production server issues
110
101
  // Include VASP files that don't have extensions (POSCAR, XDATCAR, CONTCAR)
111
- const is_known_text = TEXT_EXTENSIONS.has(ext) || VASP_BASENAME_RE.test(url_basename);
102
+ const is_known_text = is_known_text_file(url_basename);
112
103
  let sniffed_callback_args;
113
104
  if (!is_known_text) {
114
105
  // Only the Range sniff is guarded (failure → plain text fetch). Once magic bytes
@@ -121,13 +112,10 @@ export async function load_from_url(url, callback) {
121
112
  const head = await fetch(url, { headers: { Range: `bytes=0-15` } });
122
113
  if (head.ok) {
123
114
  const buf = new Uint8Array(await head.arrayBuffer());
124
- const is_gzip = buf[0] === 0x1f && buf[1] === 0x8b;
125
- const is_hdf5 = buf[0] === 0x89 && buf[1] === 0x48 && buf[2] === 0x44 && buf[3] === 0x46;
126
- // ASE .traj files start with the Ulm signature "- of Ulm"
127
- const is_ase_traj = [0x2d, 0x20, 0x6f, 0x66, 0x20, 0x55, 0x6c, 0x6d].every((byte, idx) => buf[idx] === byte);
128
- if (is_gzip)
115
+ // gzip is gunzipped downstream; other binary magic (HDF5, ZIP, ASE Ulm) stays raw
116
+ if (has_gzip_magic(buf))
129
117
  sniffed = `gzip`;
130
- else if (is_hdf5 || is_ase_traj)
118
+ else if (has_binary_magic(buf))
131
119
  sniffed = `binary`;
132
120
  }
133
121
  }
@@ -14,13 +14,12 @@
14
14
  Uint32BufferAttribute,
15
15
  } from 'three'
16
16
  import type { IsosurfaceLayer, IsosurfaceSettings, VolumetricData } from './types'
17
- import {
18
- DEFAULT_ISOSURFACE_SETTINGS,
19
- downsample_grid,
20
- pad_periodic_grid,
21
- } from './types'
17
+ import { DEFAULT_ISOSURFACE_SETTINGS, downsample_grid, pad_periodic_grid } from './types'
22
18
 
23
- let { volume, settings = DEFAULT_ISOSURFACE_SETTINGS }: {
19
+ let {
20
+ volume,
21
+ settings = DEFAULT_ISOSURFACE_SETTINGS,
22
+ }: {
24
23
  volume: VolumetricData
25
24
  settings?: IsosurfaceSettings
26
25
  } = $props()
@@ -28,23 +27,22 @@
28
27
  // Resolve layers: use explicit layers array if provided, else build from single-isovalue settings
29
28
  let resolved_layers = $derived.by((): IsosurfaceLayer[] => {
30
29
  if (settings.layers?.length) return settings.layers
31
- return [{
32
- isovalue: settings.isovalue,
33
- color: settings.positive_color,
34
- opacity: settings.opacity,
35
- visible: true,
36
- show_negative: settings.show_negative,
37
- negative_color: settings.negative_color,
38
- }]
30
+ return [
31
+ {
32
+ isovalue: settings.isovalue,
33
+ color: settings.positive_color,
34
+ opacity: settings.opacity,
35
+ visible: true,
36
+ show_negative: settings.show_negative,
37
+ negative_color: settings.negative_color,
38
+ },
39
+ ]
39
40
  })
40
41
 
41
42
  // Build indexed BufferGeometry from marching cubes output.
42
43
  // Uses Three.js index buffer to avoid tripling vertex data, and
43
44
  // computeVertexNormals() for fast GPU-friendly normals.
44
- function build_geometry(
45
- vertices: Vec3[],
46
- faces: number[][],
47
- ): BufferGeometry | null {
45
+ function build_geometry(vertices: Vec3[], faces: number[][]): BufferGeometry | null {
48
46
  if (vertices.length === 0 || faces.length === 0) return null
49
47
 
50
48
  // Flatten vertices: Vec3[] → Float32Array
@@ -242,11 +240,7 @@
242
240
  </T.Mesh>
243
241
  {:else if entry.opacity < 1}
244
242
  <!-- Two-pass rendering for correct transparency -->
245
- <T.Mesh
246
- geometry={entry.geometry}
247
- renderOrder={entry.render_order}
248
- frustumCulled={false}
249
- >
243
+ <T.Mesh geometry={entry.geometry} renderOrder={entry.render_order} frustumCulled={false}>
250
244
  <T.MeshStandardMaterial
251
245
  color={entry.color}
252
246
  transparent
@@ -45,7 +45,7 @@
45
45
  function update_layer(idx: number, updates: Partial<IsosurfaceLayer>) {
46
46
  if (!settings.layers) return
47
47
  settings.layers = settings.layers.map((layer, layer_idx) =>
48
- layer_idx === idx ? { ...layer, ...updates } : layer
48
+ layer_idx === idx ? { ...layer, ...updates } : layer,
49
49
  )
50
50
  }
51
51
  </script>
@@ -68,7 +68,9 @@
68
68
  <div class="pane-row compact-row">
69
69
  {#if volumes.length > 1}
70
70
  <label
71
- {@attach tooltip({ content: `Select which volume to display (e.g. charge vs magnetization)` })}
71
+ {@attach tooltip({
72
+ content: `Select which volume to display (e.g. charge vs magnetization)`,
73
+ })}
72
74
  >
73
75
  <span>Volume:</span>
74
76
  <select bind:value={active_volume_idx}>
@@ -79,13 +81,14 @@
79
81
  </label>
80
82
  {/if}
81
83
  <label
82
- {@attach tooltip({ content: `Number of isosurface shells at different density thresholds` })}
84
+ {@attach tooltip({
85
+ content: `Number of isosurface shells at different density thresholds`,
86
+ })}
83
87
  >
84
88
  <span>Layers:</span>
85
89
  <select
86
90
  value={n_layers}
87
- onchange={(event) =>
88
- set_layer_count(Number(event.currentTarget.value))}
91
+ onchange={(event) => set_layer_count(Number(event.currentTarget.value))}
89
92
  >
90
93
  {#each [1, 2, 3, 4, 5] as count (count)}
91
94
  <option value={count}>{count}</option>
@@ -95,14 +98,16 @@
95
98
  <!-- Sync both settings.show_negative (single-layer fallback) and all layer entries
96
99
  so the toggle works consistently regardless of which mode is active -->
97
100
  <label
98
- {@attach tooltip({ content: `Show negative lobe at −isovalue (for orbitals, ESP, magnetization)` })}
101
+ {@attach tooltip({
102
+ content: `Show negative lobe at −isovalue (for orbitals, ESP, magnetization)`,
103
+ })}
99
104
  >
100
105
  <span>Neg. lobe</span>
101
106
  <input
102
107
  type="checkbox"
103
108
  checked={is_multi_layer
104
- ? settings.layers?.some((layer) => layer.show_negative) ?? false
105
- : settings.show_negative}
109
+ ? (settings.layers?.some((layer) => layer.show_negative) ?? false)
110
+ : settings.show_negative}
106
111
  onchange={(event) => {
107
112
  const checked = event.currentTarget.checked
108
113
  settings.show_negative = checked
@@ -115,9 +120,7 @@
115
120
  }}
116
121
  />
117
122
  </label>
118
- <label
119
- {@attach tooltip({ content: `Render as wireframe mesh instead of solid surface` })}
120
- >
123
+ <label {@attach tooltip({ content: `Render as wireframe mesh instead of solid surface` })}>
121
124
  <span>Wireframe</span>
122
125
  <input type="checkbox" bind:checked={settings.wireframe} />
123
126
  </label>
@@ -135,8 +138,7 @@
135
138
  <input
136
139
  type="color"
137
140
  value={layer.color}
138
- onchange={(event) =>
139
- update_layer(idx, { color: event.currentTarget.value })}
141
+ onchange={(event) => update_layer(idx, { color: event.currentTarget.value })}
140
142
  />
141
143
  <input
142
144
  type="range"
@@ -145,9 +147,9 @@
145
147
  {step}
146
148
  value={layer.isovalue}
147
149
  oninput={(event) =>
148
- update_layer(idx, {
149
- isovalue: Number(event.currentTarget.value),
150
- })}
150
+ update_layer(idx, {
151
+ isovalue: Number(event.currentTarget.value),
152
+ })}
151
153
  style="flex: 1; min-width: 60px"
152
154
  />
153
155
  <span class="layer-value">{format_num(layer.isovalue, `.3~g`)}</span>
@@ -158,9 +160,9 @@
158
160
  step={0.05}
159
161
  value={layer.opacity}
160
162
  oninput={(event) =>
161
- update_layer(idx, {
162
- opacity: Number(event.currentTarget.value),
163
- })}
163
+ update_layer(idx, {
164
+ opacity: Number(event.currentTarget.value),
165
+ })}
164
166
  style="width: 50px"
165
167
  title="Opacity: {format_num(layer.opacity, `.2f`)}"
166
168
  />
@@ -169,23 +171,21 @@
169
171
  {:else}
170
172
  <!-- Single-layer: isovalue slider full width -->
171
173
  <label
172
- {@attach tooltip({ content: `Density threshold — surface is drawn where grid values equal this` })}
174
+ {@attach tooltip({
175
+ content: `Density threshold — surface is drawn where grid values equal this`,
176
+ })}
173
177
  >
174
178
  <span>Isovalue:</span>
175
- <input
176
- type="range"
177
- min={step}
178
- max={slider_max}
179
- {step}
180
- bind:value={settings.isovalue}
181
- />
179
+ <input type="range" min={step} max={slider_max} {step} bind:value={settings.isovalue} />
182
180
  <span class="value">{format_num(settings.isovalue, `.4~g`)}</span>
183
181
  </label>
184
182
 
185
183
  <!-- Opacity + colors on one row -->
186
184
  <div class="pane-row compact-row">
187
185
  <label
188
- {@attach tooltip({ content: `Surface transparency — lower values reveal inner structure` })}
186
+ {@attach tooltip({
187
+ content: `Surface transparency — lower values reveal inner structure`,
188
+ })}
189
189
  >
190
190
  <span>Opacity:</span>
191
191
  <input
@@ -203,9 +203,7 @@
203
203
  <input type="color" bind:value={settings.positive_color} />
204
204
  </label>
205
205
  {#if settings.show_negative}
206
- <label
207
- {@attach tooltip({ content: `Color for the negative (−isovalue) surface` })}
208
- >
206
+ <label {@attach tooltip({ content: `Color for the negative (−isovalue) surface` })}>
209
207
  <span>&minus; Color</span>
210
208
  <input type="color" bind:value={settings.negative_color} />
211
209
  </label>
@@ -215,24 +213,21 @@
215
213
 
216
214
  {#if volumes?.[active_volume_idx]?.periodic}
217
215
  <label
218
- {@attach tooltip({ content: `Extend isosurface beyond cell boundaries to close partial spheres (fraction of cell)` })}
216
+ {@attach tooltip({
217
+ content: `Extend isosurface beyond cell boundaries to close partial spheres (fraction of cell)`,
218
+ })}
219
219
  >
220
220
  Halo: {format_num(settings.halo, `.2f`)}
221
- <input
222
- type="range"
223
- min={0}
224
- max={0.5}
225
- step={0.01}
226
- bind:value={settings.halo}
227
- />
221
+ <input type="range" min={0} max={0.5} step={0.01} bind:value={settings.halo} />
228
222
  </label>
229
223
  {/if}
230
224
 
231
225
  {#if volumes[active_volume_idx]}
232
226
  <div class="grid-info">
233
- {volumes[active_volume_idx].grid_dims.join(` × `)} grid &nbsp;|&nbsp; [{
234
- format_num(data_range.min, `.3~g`)
235
- }, {format_num(data_range.max, `.3~g`)}]
227
+ {volumes[active_volume_idx].grid_dims.join(` × `)} grid &nbsp;|&nbsp; [{format_num(
228
+ data_range.min,
229
+ `.3~g`,
230
+ )}, {format_num(data_range.max, `.3~g`)}]
236
231
  </div>
237
232
  {/if}
238
233
  </SettingsSection>
@@ -0,0 +1,3 @@
1
+ import type { VolumetricFileData } from './types';
2
+ export declare const is_vaspwave_filename: (filename: string) => boolean;
3
+ export declare function parse_vaspwave_charge(buffer: ArrayBuffer, filename?: string): Promise<VolumetricFileData>;
@@ -0,0 +1,138 @@
1
+ // Parser for VASP vaspwave.h5 charge density: charge/charge on charge/grid
2
+ // plus the embedded structure under structure/positions (dataset paths follow
3
+ // ferrox's VASPWAVE_* constants / py4vasp's VASP 6.x schema). Full files are
4
+ // hundreds of MB, so embedding hosts are expected to prune them server-side
5
+ // first; this parser sees only charge/{charge,grid} + structure/positions.
6
+ //
7
+ // Prototype scope: charge (+ magnetization) isosurfaces only — wavefunctions
8
+ // are out of scope. The "charge density RMS per SCF step" convergence signal
9
+ // is already covered by OSZICAR's rms(c) column in the vaspout.h5 parser
10
+ // (scf_charge_rms frame metadata); diffing charge grids between live reloads
11
+ // is explicitly out of scope here.
12
+ import { calc_lattice_params, create_frac_to_cart } from '../math';
13
+ import { wrap_to_unit_cell } from '../structure/pbc';
14
+ import { make_site } from '../structure/site';
15
+ import { validate_3x3_matrix } from '../trajectory/helpers';
16
+ import { expand_ion_types, is_hdf5_dataset, read_dataset, scale_matrix, to_number_array, to_scalar_number, to_string_array, with_h5_file, } from '../trajectory/parse/h5-utils';
17
+ import { grid_data_range } from './types';
18
+ const CHARGE_PATH = `charge/charge`;
19
+ const CHARGE_GRID_PATH = `charge/grid`;
20
+ const STRUCTURE_PREFIX = `structure/positions`;
21
+ // vaspwave carries charge density/wavefunctions, never a trajectory — used by
22
+ // file-open routing to divert from the HDF5 trajectory dispatcher.
23
+ export const is_vaspwave_filename = (filename) => {
24
+ const basename = filename.split(`/`).pop() ?? filename;
25
+ return /vaspwave.*\.(?:h5|hdf5)$/i.test(basename);
26
+ };
27
+ const dataset_shape = (h5_file, path) => {
28
+ const entity = h5_file.get(path);
29
+ return is_hdf5_dataset(entity) ? (entity.shape ?? null) : null;
30
+ };
31
+ const read_embedded_structure = (h5_file) => {
32
+ const lattice_data = read_dataset(h5_file, `${STRUCTURE_PREFIX}/lattice_vectors`);
33
+ if (!lattice_data) {
34
+ throw new Error(`vaspwave.h5 has no embedded structure (${STRUCTURE_PREFIX}/lattice_vectors) — ` +
35
+ `cannot place the charge grid in a lattice`);
36
+ }
37
+ const scale = to_scalar_number(read_dataset(h5_file, `${STRUCTURE_PREFIX}/scale`)) ?? 1;
38
+ const lattice = scale_matrix(validate_3x3_matrix(lattice_data), scale);
39
+ // Sites are optional for rendering (the isosurface needs only the lattice),
40
+ // so a pruned/torn file missing ion data still opens with an empty cell.
41
+ const sites = [];
42
+ const ion_types = to_string_array(read_dataset(h5_file, `${STRUCTURE_PREFIX}/ion_types`));
43
+ const ion_counts = to_number_array(read_dataset(h5_file, `${STRUCTURE_PREFIX}/number_ion_types`));
44
+ const frac_positions = read_dataset(h5_file, `${STRUCTURE_PREFIX}/position_ions`);
45
+ if (ion_types && ion_counts && frac_positions && ion_types.length === ion_counts.length) {
46
+ const elements = expand_ion_types(ion_types, ion_counts);
47
+ const frac_to_cart = create_frac_to_cart(lattice);
48
+ for (const [site_idx, element] of elements.entries()) {
49
+ const frac = frac_positions[site_idx];
50
+ if (!Array.isArray(frac) || frac.length < 3)
51
+ break; // torn positions: keep what parsed
52
+ const abc = wrap_to_unit_cell(frac.slice(0, 3));
53
+ sites.push(make_site(element, abc, frac_to_cart(abc), `${element}${site_idx + 1}`));
54
+ }
55
+ }
56
+ return {
57
+ sites,
58
+ lattice: { matrix: lattice, pbc: [true, true, true], ...calc_lattice_params(lattice) },
59
+ };
60
+ };
61
+ // VASP writes volumetric data C-order [components, nz, ny, nx]; the grid
62
+ // dataset [nx, ny, nz] disambiguates (same logic as ferrox's
63
+ // volumetric_grid_shape_and_order — when nx == nz both layouts match, so
64
+ // default to the canonical zyx order).
65
+ const charge_axis_order = (spatial_shape, grid_dims) => {
66
+ const [nx, ny, nz] = grid_dims;
67
+ const matches = (dims) => dims.every((dim, idx) => dim === spatial_shape[idx]);
68
+ if (matches([nz, ny, nx]))
69
+ return `zyx`;
70
+ if (matches([nx, ny, nz]))
71
+ return `xyz`;
72
+ throw new Error(`vaspwave.h5 ${CHARGE_GRID_PATH} [${grid_dims}] is incompatible with ` +
73
+ `${CHARGE_PATH} spatial shape [${spatial_shape}]`);
74
+ };
75
+ function parse_vaspwave_charge_file(h5_file) {
76
+ const shape = dataset_shape(h5_file, CHARGE_PATH);
77
+ if (!shape) {
78
+ throw new Error(`vaspwave.h5 file has no charge density (missing ${CHARGE_PATH})`);
79
+ }
80
+ // Only the dimension count is checked here — the spatial axis order (zyx vs
81
+ // xyz) is disambiguated later by charge_axis_order against CHARGE_GRID_PATH.
82
+ if (shape.length !== 4) {
83
+ throw new Error(`${CHARGE_PATH} must have 4 dimensions, got [${shape}]`);
84
+ }
85
+ const n_components = shape[0];
86
+ if (n_components < 1 || n_components > 2) {
87
+ throw new Error(`${CHARGE_PATH} has unsupported component count ${n_components}; expected 1 ` +
88
+ `(non-spin-polarized) or 2 (total + magnetization)`);
89
+ }
90
+ const grid_dims = to_number_array(read_dataset(h5_file, CHARGE_GRID_PATH));
91
+ if (grid_dims?.length !== 3) {
92
+ throw new Error(`vaspwave.h5 is missing ${CHARGE_GRID_PATH}; cannot determine the axis order of ${CHARGE_PATH}`);
93
+ }
94
+ const axis_order = charge_axis_order(shape.slice(1), grid_dims);
95
+ const [nx, ny, nz] = grid_dims;
96
+ const structure = read_embedded_structure(h5_file);
97
+ const lattice = structure.lattice.matrix;
98
+ const charge_data = read_dataset(h5_file, CHARGE_PATH);
99
+ if (!charge_data)
100
+ throw new Error(`Failed to read ${CHARGE_PATH} data`);
101
+ // Metadata shape and decoded data can disagree in torn/corrupt files — fail
102
+ // loudly instead of silently rendering fewer components than the file claims
103
+ if (charge_data.length !== n_components) {
104
+ throw new Error(`${CHARGE_PATH} decoded ${charge_data.length} components but its shape claims ${n_components}`);
105
+ }
106
+ const component_labels = [`charge density`, `magnetization density`];
107
+ const volumes = charge_data.map((component, component_idx) => {
108
+ const grid = Array(nx);
109
+ for (let x_idx = 0; x_idx < nx; x_idx++) {
110
+ const plane = Array(ny);
111
+ for (let y_idx = 0; y_idx < ny; y_idx++) {
112
+ const row = Array(nz);
113
+ for (let z_idx = 0; z_idx < nz; z_idx++) {
114
+ row[z_idx] =
115
+ axis_order === `zyx`
116
+ ? component[z_idx][y_idx][x_idx]
117
+ : component[x_idx][y_idx][z_idx];
118
+ }
119
+ plane[y_idx] = row;
120
+ }
121
+ grid[x_idx] = plane;
122
+ }
123
+ return {
124
+ grid,
125
+ grid_dims: [nx, ny, nz],
126
+ lattice,
127
+ origin: [0, 0, 0],
128
+ data_range: grid_data_range(grid),
129
+ data_order: `x_fastest`,
130
+ periodic: true,
131
+ label: component_labels[component_idx],
132
+ };
133
+ });
134
+ return { structure, volumes };
135
+ }
136
+ export async function parse_vaspwave_charge(buffer, filename) {
137
+ return with_h5_file(buffer, filename, parse_vaspwave_charge_file);
138
+ }