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
@@ -0,0 +1,109 @@
1
+ // Shared h5wasm plumbing for HDF5 trajectory parsers: type guards plus the
2
+ // write-to-in-memory-FS/open/cleanup lifecycle both torch-sim and vaspout
3
+ // parsing need (the FS write is the expensive part, so parsers share one open
4
+ // file handle instead of re-opening per format probe).
5
+ import { is_elem_symbol } from '../../element/helpers';
6
+ import * as h5wasm from 'h5wasm';
7
+ export const is_hdf5_dataset = (entity) => entity !== null && `to_array` in entity && entity instanceof h5wasm.Dataset;
8
+ export const is_hdf5_group = (entity) => entity !== null && `keys` in entity && entity instanceof h5wasm.Group;
9
+ // Datasets in interrupted files can be torn mid-chunk, making to_array throw —
10
+ // treat unreadable datasets like missing ones so callers keep what parsed so far.
11
+ export const read_dataset = (h5_file, path) => {
12
+ try {
13
+ const entity = h5_file.get(path);
14
+ return is_hdf5_dataset(entity) ? entity.to_array() : null;
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ };
20
+ // h5wasm returns JS strings for variable-length UTF-8 but may hand back byte
21
+ // arrays for fixed-length string datasets (like VASP's |S2 ion_types).
22
+ export const to_string_array = (data) => {
23
+ if (!Array.isArray(data))
24
+ return null;
25
+ const decoder = new TextDecoder();
26
+ const strings = [];
27
+ for (const item of data) {
28
+ if (typeof item === `string`)
29
+ strings.push(item.trim());
30
+ else if (item instanceof Uint8Array)
31
+ strings.push(decoder.decode(item).trim());
32
+ else
33
+ return null;
34
+ }
35
+ return strings;
36
+ };
37
+ // Integer datasets (like int64 number_ion_types) can surface as BigInt
38
+ // values or typed arrays depending on dtype; normalize to plain numbers.
39
+ export const to_number_array = (data) => {
40
+ const values = Array.isArray(data)
41
+ ? data
42
+ : ArrayBuffer.isView(data)
43
+ ? Array.from(data)
44
+ : null;
45
+ if (!values)
46
+ return null;
47
+ const numbers = values.map((item) => (typeof item === `bigint` ? Number(item) : item));
48
+ return numbers.every((item) => typeof item === `number` && Number.isFinite(item))
49
+ ? numbers
50
+ : null;
51
+ };
52
+ // Scalar datasets surface as plain numbers, 1-element arrays, or BigInt
53
+ // depending on dtype; normalize to a finite number or null.
54
+ export const to_scalar_number = (data) => {
55
+ const value = Array.isArray(data) ? data[0] : data;
56
+ if (typeof value === `bigint`)
57
+ return Number(value);
58
+ return typeof value === `number` && Number.isFinite(value) ? value : null;
59
+ };
60
+ // Apply VASP's POSCAR-style universal scaling factor to lattice vectors
61
+ export const scale_matrix = (matrix, scale) => scale === 1 ? matrix : matrix.map((row) => row.map((val) => val * scale));
62
+ // Expand VASP's (ion_types, number_ion_types) pair into per-atom symbols,
63
+ // e.g. ([Ga, Sb], [1, 1]) -> [Ga, Sb]. Throws on unknown symbols and
64
+ // malformed counts so torn/corrupt HDF5 input fails loudly, not by dropping atoms.
65
+ export const expand_ion_types = (ion_types, ion_counts) => {
66
+ if (ion_types.length !== ion_counts.length) {
67
+ throw new Error(`ion_types (${ion_types.length}) and ion_counts (${ion_counts.length}) length mismatch`);
68
+ }
69
+ const elements = [];
70
+ for (const [type_idx, symbol] of ion_types.entries()) {
71
+ if (!is_elem_symbol(symbol)) {
72
+ throw new Error(`Unknown element symbol in ion_types: ${symbol}`);
73
+ }
74
+ const ion_count = ion_counts[type_idx];
75
+ if (!Number.isFinite(ion_count) || !Number.isInteger(ion_count) || ion_count < 0) {
76
+ throw new Error(`Invalid ion count for ${symbol}: ${ion_count}`);
77
+ }
78
+ for (let count = 0; count < ion_count; count++)
79
+ elements.push(symbol);
80
+ }
81
+ return elements;
82
+ };
83
+ // Writes the buffer to h5wasm's in-memory FS under a unique temp name, opens
84
+ // it, runs the callback (awaiting async ones so cleanup can't race reads),
85
+ // and always closes + unlinks afterwards.
86
+ export async function with_h5_file(buffer, filename, callback) {
87
+ const { FS } = await h5wasm.ready;
88
+ const file_basename = filename
89
+ ?.split(`/`)
90
+ .at(-1)
91
+ ?.replaceAll(/[^\w.-]/g, `_`) ?? `temp`;
92
+ const unique_suffix = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
93
+ const temp_filename = `${file_basename}-${unique_suffix}.h5`;
94
+ FS.writeFile(temp_filename, new Uint8Array(buffer));
95
+ let h5_file = null;
96
+ try {
97
+ h5_file = new h5wasm.File(temp_filename, `r`);
98
+ return await callback(h5_file);
99
+ }
100
+ finally {
101
+ h5_file?.close();
102
+ try {
103
+ FS.unlink(temp_filename);
104
+ }
105
+ catch {
106
+ /* temp file cleanup is best-effort */
107
+ }
108
+ }
109
+ }
@@ -1,2 +1,2 @@
1
1
  import type { TrajectoryType } from '../index';
2
- export declare function parse_torch_sim_hdf5(buffer: ArrayBuffer, filename?: string): Promise<TrajectoryType>;
2
+ export declare function parse_hdf5_trajectory(buffer: ArrayBuffer, filename?: string): Promise<TrajectoryType>;
@@ -1,78 +1,96 @@
1
- // HDF5 trajectory parsing (torch-sim / generic format)
1
+ // HDF5 trajectory parsing: dispatches between VASP vaspout.h5 and the
2
+ // torch-sim / generic dataset-alias layout after a single file open.
2
3
  import { calc_lattice_params, transpose_3x3_matrix } from '../../math';
3
- import * as h5wasm from 'h5wasm';
4
- import { convert_atomic_numbers, create_trajectory_frame, validate_3x3_matrix, } from '../helpers';
5
- const is_hdf5_dataset = (entity) => entity !== null && `to_array` in entity && entity instanceof h5wasm.Dataset;
6
- const is_hdf5_group = (entity) => entity !== null && `keys` in entity && entity instanceof h5wasm.Group;
7
- export async function parse_torch_sim_hdf5(buffer, filename) {
8
- const { FS } = await h5wasm.ready;
9
- const file_basename = filename
10
- ?.split(`/`)
11
- .at(-1)
12
- ?.replaceAll(/[^\w.-]/g, `_`) ?? `temp`;
13
- const unique_suffix = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
14
- const temp_filename = `${file_basename}-${unique_suffix}.h5`;
15
- FS.writeFile(temp_filename, new Uint8Array(buffer));
16
- let h5_file = null;
17
- try {
18
- h5_file = new h5wasm.File(temp_filename, `r`);
19
- const found_paths = {};
20
- let total_groups_found = 0;
21
- const find_dataset = (names) => {
22
- const discover = (parent, path = ``) => {
23
- total_groups_found++;
24
- for (const name of parent.keys()) {
25
- const item = parent.get(name);
26
- const full_path = path ? `${path}/${name}` : `/${name}`;
27
- if (names.includes(name) && is_hdf5_dataset(item)) {
28
- const found_name = names.find((dataset_name) => dataset_name === name);
29
- if (found_name)
30
- found_paths[found_name] = full_path;
31
- return item;
32
- }
33
- if (is_hdf5_group(item)) {
34
- const result = discover(item, full_path);
35
- if (result)
36
- return result;
37
- }
4
+ import { convert_atomic_numbers, count_elements, create_trajectory_frame, validate_3x3_matrix, } from '../helpers';
5
+ import { is_hdf5_dataset, is_hdf5_group, read_dataset, with_h5_file } from './h5-utils';
6
+ import { is_vaspout_h5_file, parse_vaspout_h5_file } from './vaspout-h5';
7
+ // Routes an opened HDF5 file to the right parser: vaspout.h5 has the VASP 6.x
8
+ // root-group layout, everything else falls through to the torch-sim recursive
9
+ // dataset-name search. One FS write + open, no parse-and-fallback.
10
+ export async function parse_hdf5_trajectory(buffer, filename) {
11
+ return with_h5_file(buffer, filename, (h5_file) => is_vaspout_h5_file(h5_file)
12
+ ? parse_vaspout_h5_file(h5_file)
13
+ : parse_torch_sim_h5_file(h5_file));
14
+ }
15
+ // Dataset-name aliases searched (in order) across the whole group tree
16
+ const POSITION_ALIASES = [`positions`, `coords`, `coordinates`];
17
+ const ATOMIC_NUMBER_ALIASES = [`atomic_numbers`, `numbers`, `Z`, `species`];
18
+ const CELL_ALIASES = [`cell`, `cells`, `lattice`];
19
+ const ENERGY_ALIASES = [`potential_energy`, `energy`];
20
+ function parse_torch_sim_h5_file(h5_file) {
21
+ const alias_groups = [POSITION_ALIASES, ATOMIC_NUMBER_ALIASES, CELL_ALIASES, ENERGY_ALIASES];
22
+ const all_aliases = new Set(alias_groups.flat());
23
+ const found_paths = {};
24
+ const found_alias_groups = new Set();
25
+ let total_groups_found = 0;
26
+ const discover = (parent, path = ``) => {
27
+ total_groups_found++;
28
+ for (const name of parent.keys()) {
29
+ const item = parent.get(name);
30
+ const full_path = path ? `${path}/${name}` : `/${name}`;
31
+ if (is_hdf5_dataset(item) && all_aliases.has(name)) {
32
+ found_paths[name] ??= full_path;
33
+ for (const [group_idx, aliases] of alias_groups.entries()) {
34
+ if (aliases.includes(name))
35
+ found_alias_groups.add(group_idx);
38
36
  }
39
- return null;
40
- };
41
- return discover(h5_file);
42
- };
43
- const positions_data = find_dataset([`positions`, `coords`, `coordinates`])?.to_array();
44
- const atomic_numbers_data = find_dataset([
45
- `atomic_numbers`,
46
- `numbers`,
47
- `Z`,
48
- `species`,
49
- ])?.to_array();
50
- const cells_data = find_dataset([`cell`, `cells`, `lattice`])?.to_array();
51
- const energies_data = find_dataset([`potential_energy`, `energy`])?.to_array();
52
- if (!positions_data || !atomic_numbers_data) {
53
- const missing_datasets = [];
54
- if (!positions_data) {
55
- missing_datasets.push(`positions (tried: positions, coords, coordinates)`);
37
+ if (found_alias_groups.size === alias_groups.length)
38
+ return;
56
39
  }
57
- if (!atomic_numbers_data) {
58
- missing_datasets.push(`atomic numbers (tried: atomic_numbers, numbers, Z, species)`);
40
+ else if (is_hdf5_group(item)) {
41
+ discover(item, full_path);
42
+ if (found_alias_groups.size === alias_groups.length)
43
+ return;
59
44
  }
60
- const missing_str = missing_datasets.join(`, `);
61
- const available_str = Array.from(h5_file.keys()).join(`, `);
62
- throw new Error(`Missing required dataset(s) in HDF5 file: ${missing_str}. Available datasets: ${available_str}`);
63
45
  }
64
- const positions_are_frames = positions_data.length > 0 &&
65
- positions_data.every((entry) => Array.isArray(entry) && entry.every((coord) => Array.isArray(coord)));
66
- const positions = positions_are_frames ? positions_data : [positions_data];
67
- const atomic_numbers_are_frames = atomic_numbers_data.length > 0 &&
68
- atomic_numbers_data.every((entry) => Array.isArray(entry));
69
- const atomic_numbers = atomic_numbers_are_frames
70
- ? atomic_numbers_data
71
- : [atomic_numbers_data];
72
- const frames = positions.map((frame_pos, idx) => {
46
+ };
47
+ discover(h5_file);
48
+ const first_path = (names) => names.map((name) => found_paths[name]).find(Boolean);
49
+ const find_dataset = (names) => {
50
+ const path = first_path(names);
51
+ return path ? read_dataset(h5_file, path) : null;
52
+ };
53
+ const positions_data = find_dataset(POSITION_ALIASES);
54
+ const atomic_numbers_data = find_dataset(ATOMIC_NUMBER_ALIASES);
55
+ const cells_data = find_dataset(CELL_ALIASES);
56
+ const energies_data = find_dataset(ENERGY_ALIASES);
57
+ if (!positions_data || !atomic_numbers_data) {
58
+ const missing_datasets = [];
59
+ if (!positions_data) {
60
+ missing_datasets.push(`positions (tried: ${POSITION_ALIASES.join(`, `)})`);
61
+ }
62
+ if (!atomic_numbers_data) {
63
+ missing_datasets.push(`atomic numbers (tried: ${ATOMIC_NUMBER_ALIASES.join(`, `)})`);
64
+ }
65
+ const missing_str = missing_datasets.join(`, `);
66
+ const available_str = [...h5_file.keys()].join(`, `);
67
+ throw new Error(`Missing required dataset(s) in HDF5 file: ${missing_str}. Available datasets: ${available_str}`);
68
+ }
69
+ const positions_are_frames = positions_data.length > 0 &&
70
+ positions_data.every((entry) => Array.isArray(entry) && entry.every((coord) => Array.isArray(coord)));
71
+ const positions = positions_are_frames ? positions_data : [positions_data];
72
+ const atomic_numbers_are_frames = atomic_numbers_data.length > 0 &&
73
+ atomic_numbers_data.every((entry) => Array.isArray(entry));
74
+ const atomic_numbers = atomic_numbers_are_frames
75
+ ? atomic_numbers_data
76
+ : [atomic_numbers_data];
77
+ // A constant cell may be stored as a single 3x3 matrix; normalize to a
78
+ // per-frame array so cells[idx] always yields a full lattice (indexing a bare
79
+ // 3x3 with a frame index would hand a single row to validate_3x3_matrix)
80
+ const cells_are_frames = cells_data?.every((entry) => Array.isArray(entry) && entry.every((row) => Array.isArray(row)));
81
+ const cells = cells_data
82
+ ? cells_are_frames
83
+ ? cells_data
84
+ : [cells_data]
85
+ : null;
86
+ const frames = [];
87
+ let dropped_steps = 0;
88
+ for (const [idx, frame_pos] of positions.entries()) {
89
+ try {
73
90
  const frame_atomic_numbers = atomic_numbers[idx] || atomic_numbers[0];
74
91
  const frame_elements = convert_atomic_numbers(frame_atomic_numbers);
75
- const cell = cells_data?.[idx];
92
+ // constant-cell files reuse the single normalized cell for every frame
93
+ const cell = cells_are_frames ? cells?.[idx] : cells?.[0];
76
94
  const lattice_mat = cell ? transpose_3x3_matrix(validate_3x3_matrix(cell)) : undefined;
77
95
  const energy_entry = energies_data?.[idx];
78
96
  const energy = Array.isArray(energy_entry) ? energy_entry[0] : energy_entry;
@@ -83,45 +101,37 @@ export async function parse_torch_sim_hdf5(buffer, filename) {
83
101
  metadata.volume = calc_lattice_params(lattice_mat).volume;
84
102
  }
85
103
  const pbc = lattice_mat ? [true, true, true] : [false, false, false];
86
- return create_trajectory_frame(frame_pos, frame_elements, lattice_mat, pbc, idx, metadata);
87
- });
88
- const first_frame_elements = frames[0]?.structure.sites.map((site) => site.species[0].element) ?? [];
89
- return {
90
- frames,
91
- metadata: {
92
- source_format: `hdf5_trajectory`,
93
- frame_count: frames.length,
94
- num_atoms: first_frame_elements.length,
95
- periodic_boundary_conditions: cells_data ? [true, true, true] : [false, false, false],
96
- element_counts: first_frame_elements.reduce((counts, element) => {
97
- counts[element] = (counts[element] || 0) + 1;
98
- return counts;
99
- }, {}),
100
- discovered_datasets: {
101
- positions: found_paths.positions ||
102
- found_paths.coords ||
103
- found_paths.coordinates ||
104
- `unknown`,
105
- atomic_numbers: found_paths.atomic_numbers ||
106
- found_paths.numbers ||
107
- found_paths.Z ||
108
- found_paths.species ||
109
- `unknown`,
110
- cells: found_paths.cell || found_paths.cells || found_paths.lattice,
111
- energies: found_paths.potential_energy || found_paths.energy,
112
- },
113
- total_groups_found,
114
- has_cell_info: Boolean(cells_data),
115
- },
116
- };
117
- }
118
- finally {
119
- h5_file?.close();
120
- try {
121
- FS.unlink(temp_filename);
104
+ frames.push(create_trajectory_frame(frame_pos, frame_elements, lattice_mat, pbc, idx, metadata));
122
105
  }
123
- catch {
124
- /* temp file cleanup is best-effort */
106
+ catch (err) {
107
+ // Same torn-tail resiliency as the vaspout parser: interrupted writers
108
+ // zero-fill trailing chunks (atomic number 0, degenerate cells), which
109
+ // fails validation — keep the frames parsed so far and report the rest
110
+ // as dropped. A file whose very first frame is unparsable still throws.
111
+ if (frames.length === 0)
112
+ throw err;
113
+ dropped_steps = positions.length - idx;
114
+ break;
125
115
  }
126
116
  }
117
+ const first_frame_elements = frames[0]?.structure.sites.map((site) => site.species[0].element) ?? [];
118
+ return {
119
+ frames,
120
+ metadata: {
121
+ source_format: `hdf5_trajectory`,
122
+ frame_count: frames.length,
123
+ num_atoms: first_frame_elements.length,
124
+ periodic_boundary_conditions: cells_data ? [true, true, true] : [false, false, false],
125
+ element_counts: count_elements(first_frame_elements),
126
+ discovered_datasets: {
127
+ positions: first_path(POSITION_ALIASES) ?? `unknown`,
128
+ atomic_numbers: first_path(ATOMIC_NUMBER_ALIASES) ?? `unknown`,
129
+ cells: first_path(CELL_ALIASES),
130
+ energies: first_path(ENERGY_ALIASES),
131
+ },
132
+ total_groups_found,
133
+ has_cell_info: Boolean(cells_data),
134
+ ...(dropped_steps > 0 ? { dropped_steps } : {}),
135
+ },
136
+ };
127
137
  }
@@ -1,12 +1,12 @@
1
- import { is_trajectory_file } from '../format-detect';
2
- import { TrajFrameReader } from '../frame-reader';
3
- import type { FrameLoader, ParseProgress, TrajectoryType } from '../index';
1
+ import type { ParseProgress, TrajectoryType } from '../index';
4
2
  import type { AtomTypeMapping, LoadingOptions } from '../types';
5
- export { LARGE_FILE_THRESHOLD, MAX_BIN_FILE_SIZE, MAX_TEXT_FILE_SIZE, } from '../constants';
3
+ export declare const LARGE_FILE_THRESHOLD: number;
4
+ export declare const MAX_BIN_FILE_SIZE: number;
5
+ export declare const MAX_TEXT_FILE_SIZE: number;
6
6
  export type { AtomTypeMapping, LoadingOptions } from '../types';
7
- export { is_trajectory_file, TrajFrameReader };
7
+ export { is_trajectory_file } from '../format-detect';
8
+ export { TrajFrameReader } from '../frame-reader';
8
9
  export declare function parse_trajectory_data(data: unknown, filename?: string, atom_type_mapping?: AtomTypeMapping): Promise<TrajectoryType>;
9
10
  export declare function get_unsupported_format_message(filename: string, content: string): string | null;
10
11
  export declare function parse_trajectory_async(data: ArrayBuffer | string, filename: string, on_progress?: (progress: ParseProgress) => void, options?: LoadingOptions): Promise<TrajectoryType>;
11
- export declare function create_frame_loader(filename: string): FrameLoader;
12
12
  export declare function load_binary_traj(resp: Response, type: string, fallback?: boolean): Promise<ArrayBuffer | string>;
@@ -1,15 +1,14 @@
1
1
  // Parsing functions for trajectory data from various formats
2
2
  import { is_binary } from '../../io/is-binary';
3
3
  import { is_plain_object } from '../../utils';
4
+ import { DEFAULTS } from '../../settings';
4
5
  import { is_parsed_structure, parse_xyz } from '../../structure/parse';
5
- import { INDEX_SAMPLE_RATE, LARGE_FILE_THRESHOLD } from '../constants';
6
- import { strip_compression_extensions } from '../../io';
7
- import { ext_hint, FORMAT_PATTERNS, is_trajectory_file } from '../format-detect';
6
+ import { ext_hint, FORMAT_PATTERNS, indexed_trajectory_format, is_indexable_trajectory_filename, } from '../format-detect';
8
7
  import { TrajFrameReader } from '../frame-reader';
9
8
  import { count_xyz_frames } from '../helpers';
10
9
  import { parse_ase_trajectory } from './ase';
11
10
  import { get_traj_parse_warnings, reset_traj_parse_warnings, traj_warn } from './diagnostics';
12
- import { parse_torch_sim_hdf5 } from './hdf5';
11
+ import { parse_hdf5_trajectory } from './hdf5';
13
12
  import { parse_lammps_trajectory } from './lammps';
14
13
  import { parse_pymatgen_trajectory } from './pymatgen';
15
14
  import { parse_vasp_xdatcar } from './vasp';
@@ -21,16 +20,23 @@ const assert_frame_structure = (structure, label) => {
21
20
  throw new Error(`Invalid structure in ${context}: expected non-empty 'sites' array with species and coordinates`);
22
21
  }
23
22
  };
24
- // Re-export constants and types for consumers
25
- export { LARGE_FILE_THRESHOLD, MAX_BIN_FILE_SIZE, MAX_TEXT_FILE_SIZE, } from '../constants';
26
- export { is_trajectory_file, TrajFrameReader };
23
+ // Constants for trajectory parsing and large file handling
24
+ export const LARGE_FILE_THRESHOLD = 400 * 1024 * 1024; // 400MB
25
+ const INDEX_SAMPLE_RATE = 100; // Default sample rate for frame indexing
26
+ // Fallback thresholds for component usage without loading_options, derived from the
27
+ // settings schema so settings-driven contexts (e.g. the VSCode extension) and direct
28
+ // component use agree on when large-file/indexed loading kicks in.
29
+ export const MAX_BIN_FILE_SIZE = DEFAULTS.trajectory.bin_file_threshold; // 50MB
30
+ export const MAX_TEXT_FILE_SIZE = DEFAULTS.trajectory.text_file_threshold; // 25MB
31
+ export { is_trajectory_file } from '../format-detect';
32
+ export { TrajFrameReader } from '../frame-reader';
27
33
  export async function parse_trajectory_data(data, filename, atom_type_mapping) {
28
34
  reset_traj_parse_warnings();
29
35
  if (data instanceof ArrayBuffer) {
30
36
  if (FORMAT_PATTERNS.ase(data, filename))
31
37
  return parse_ase_trajectory(data, filename);
32
38
  if (FORMAT_PATTERNS.hdf5(data, filename))
33
- return parse_torch_sim_hdf5(data, filename);
39
+ return parse_hdf5_trajectory(data, filename);
34
40
  throw new Error(`Unsupported binary format${filename ? `: ${filename}` : ``}`);
35
41
  }
36
42
  if (typeof data === `string`) {
@@ -45,19 +51,15 @@ export async function parse_trajectory_data(data, filename, atom_type_mapping) {
45
51
  }
46
52
  // Single XYZ fallback (content-sniffed when the filename gives no format hint,
47
53
  // e.g. blob: object URLs whose basenames are UUIDs)
48
- const xyz_hint = ext_hint(filename, /\.(xyz|extxyz)$/);
54
+ const xyz_hint = ext_hint(filename, /\.(?:xyz|extxyz)$/);
49
55
  if (xyz_hint || (xyz_hint === null && count_xyz_frames(content) === 1)) {
50
- try {
51
- const structure = parse_xyz(content);
52
- if (structure) {
53
- return {
54
- frames: [{ structure, step: 0, metadata: {} }],
55
- metadata: { source_format: `single_xyz`, frame_count: 1 },
56
- };
57
- }
58
- }
59
- catch {
60
- // Single-frame XYZ parsing failed, continue to JSON parsing.
56
+ // parse_xyz never throws (it returns null); fall through to JSON parsing.
57
+ const structure = parse_xyz(content);
58
+ if (structure) {
59
+ return {
60
+ frames: [{ structure, step: 0, metadata: {} }],
61
+ metadata: { source_format: `single_xyz`, frame_count: 1 },
62
+ };
61
63
  }
62
64
  }
63
65
  try {
@@ -157,10 +159,9 @@ export async function parse_trajectory_async(data, filename, on_progress, option
157
159
  // Use indexed loading for supported large files (including compressed names).
158
160
  // When the filename gives no format hint (e.g. blob: URLs), sniff a content
159
161
  // prefix for XYZ frames so large extensionless files still get indexed.
160
- const base_filename = strip_compression_extensions(filename);
161
- const can_index = /\.(xyz|extxyz|traj)$/.test(base_filename) ||
162
+ const can_index = is_indexable_trajectory_filename(filename) ||
162
163
  (typeof data === `string` &&
163
- ext_hint(filename, /\.(xyz|extxyz)$/) === null &&
164
+ ext_hint(filename, /\.(?:xyz|extxyz)$/) === null &&
164
165
  count_xyz_frames(data.slice(0, 2 ** 20)) >= 1);
165
166
  if (should_use_indexing && can_index) {
166
167
  return attach_parse_warnings(await parse_with_unified_loader(data, filename, { index_sample_rate, extract_plot_metadata }, on_progress));
@@ -216,9 +217,7 @@ async function parse_with_unified_loader(data, filename, options, on_progress) {
216
217
  }
217
218
  const stage = `Ready: ${total_frames} frames indexed`;
218
219
  on_progress?.({ current: 100, total: 100, stage });
219
- const source_format = filename.toLowerCase().endsWith(`.traj`)
220
- ? `ase_trajectory`
221
- : `xyz_trajectory`;
220
+ const source_format = `${indexed_trajectory_format(filename)}_trajectory`;
222
221
  return {
223
222
  frames,
224
223
  metadata: { source_format, frame_count: total_frames },
@@ -229,13 +228,6 @@ async function parse_with_unified_loader(data, filename, options, on_progress) {
229
228
  frame_loader: loader,
230
229
  };
231
230
  }
232
- // Factory function for frame loader (simplified)
233
- export function create_frame_loader(filename) {
234
- if (!/\.(xyz|extxyz|traj)$/.exec(filename.toLowerCase())) {
235
- throw new Error(`Unsupported format for frame loading: ${filename}`);
236
- }
237
- return new TrajFrameReader(filename);
238
- }
239
231
  export async function load_binary_traj(resp, type, fallback = false) {
240
232
  try {
241
233
  // Read binary from a clone so the original can be used for text fallback
@@ -1,7 +1,7 @@
1
1
  import { ELEM_SYMBOLS } from '../../labels';
2
2
  import * as math from '../../math';
3
- import { coerce_elem_symbol } from '../../element';
4
- import { create_trajectory_frame } from '../helpers';
3
+ import { coerce_elem_symbol } from '../../element/helpers';
4
+ import { count_elements, create_trajectory_frame } from '../helpers';
5
5
  import { traj_warn } from './diagnostics';
6
6
  const is_periodic = (token) => token.toLowerCase().startsWith(`p`);
7
7
  // Parse LAMMPS box bounds → lattice matrix. Handles orthogonal and triclinic boxes.
@@ -60,11 +60,11 @@ export function parse_lammps_trajectory(content, filename, atom_type_mapping) {
60
60
  if (!skip_to(`ITEM: TIMESTEP`))
61
61
  break;
62
62
  idx++;
63
- const timestep = parseInt(read_line(), 10) || 0;
63
+ const timestep = Math.trunc(Number(read_line())) || 0;
64
64
  if (!skip_to(`ITEM: NUMBER OF ATOMS`))
65
65
  break;
66
66
  idx++;
67
- const num_atoms = parseInt(read_line(), 10);
67
+ const num_atoms = Math.trunc(Number(read_line()));
68
68
  if (!num_atoms || num_atoms <= 0)
69
69
  continue;
70
70
  // BOX BOUNDS: orthogonal="pp pp pp", triclinic="xy xz yz pp pp pp"
@@ -111,7 +111,7 @@ export function parse_lammps_trajectory(content, filename, atom_type_mapping) {
111
111
  const frac_to_cart = use_scaled ? math.create_frac_to_cart(lattice_matrix) : null;
112
112
  for (let atom = 0; atom < num_atoms && idx < lines.length; atom++) {
113
113
  const parts = read_line().split(/\s+/);
114
- const coords = pos_cols.map((col_idx) => parseFloat(parts[col_idx]));
114
+ const coords = pos_cols.map((col_idx) => Number(parts[col_idx]));
115
115
  if (coords.some(isNaN) || parts.length <= max_col_idx)
116
116
  continue;
117
117
  // Convert scaled coordinates to Cartesian if needed
@@ -119,7 +119,7 @@ export function parse_lammps_trajectory(content, filename, atom_type_mapping) {
119
119
  let element_symbol;
120
120
  if (type_col !== undefined) {
121
121
  // Map atom type to element using custom mapping or default (type 1 -> H, etc.)
122
- const atom_type = parseInt(parts[type_col], 10) || 1;
122
+ const atom_type = Math.trunc(Number(parts[type_col])) || 1;
123
123
  atom_types_found.add(atom_type);
124
124
  element_symbol = get_element(atom_type);
125
125
  }
@@ -134,7 +134,7 @@ export function parse_lammps_trajectory(content, filename, atom_type_mapping) {
134
134
  }
135
135
  }
136
136
  else if (id_col !== undefined) {
137
- const atom_id = parseInt(parts[id_col], 10) || 1;
137
+ const atom_id = Math.trunc(Number(parts[id_col])) || 1;
138
138
  atom_types_found.add(atom_id);
139
139
  if (!id_fallback_warning_emitted) {
140
140
  traj_warn(`LAMMPS parser fallback: mapping atom IDs to elements from ID column; this may be incorrect for large or sequential IDs. Prefer a TYPE column when available.`);
@@ -159,11 +159,7 @@ export function parse_lammps_trajectory(content, filename, atom_type_mapping) {
159
159
  throw new Error(`No valid frames found in LAMMPS trajectory`);
160
160
  }
161
161
  const first_frame = frames[0];
162
- const element_counts = first_frame.structure.sites.reduce((counts, site) => {
163
- const elem = site.species[0].element;
164
- counts[elem] = (counts[elem] || 0) + 1;
165
- return counts;
166
- }, {});
162
+ const element_counts = count_elements(first_frame.structure.sites.map((site) => site.species[0].element));
167
163
  return {
168
164
  frames,
169
165
  metadata: {
@@ -1,14 +1,15 @@
1
1
  import * as math from '../../math';
2
- import { is_elem_symbol } from '../../element';
2
+ import { is_elem_symbol } from '../../element/helpers';
3
3
  import { create_trajectory_frame, validate_3x3_matrix } from '../helpers';
4
+ import { parse_leading_num } from '../../utils';
4
5
  // Parse the 7-line XDATCAR header at lines[start]: title, scale factor, 3 lattice rows
5
6
  // (multiplied by scale), element names, element counts
6
7
  function parse_xdatcar_header(lines, start) {
7
- const scale = parseFloat(lines[start + 1]);
8
+ const scale = parse_leading_num(lines[start + 1]);
8
9
  const rows = lines.slice(start + 2, start + 5).map((line) => line
9
10
  .trim()
10
11
  .split(/\s+/)
11
- .map((val) => parseFloat(val) * scale));
12
+ .map((val) => Number(val) * scale));
12
13
  const names = lines[start + 5].trim().split(/\s+/);
13
14
  const counts = lines[start + 6].trim().split(/\s+/).map(Number);
14
15
  return { scale, rows, names, counts };
@@ -31,7 +32,9 @@ export function parse_vasp_xdatcar(content, filename) {
31
32
  const bad_element = element_names.find((name) => !is_elem_symbol(name));
32
33
  if (bad_element)
33
34
  throw new Error(`Invalid element symbol in XDATCAR: ${bad_element}`);
34
- let elements = element_names.flatMap((name, idx) => Array(element_counts[idx]).fill(name));
35
+ // "Na Cl" + [2, 2] -> [Na, Na, Cl, Cl]
36
+ const expand_element_counts = (names, counts) => names.flatMap((name, idx) => Array(counts[idx]).fill(name));
37
+ let elements = expand_element_counts(element_names, element_counts);
35
38
  const frames = [];
36
39
  let line_idx = 7;
37
40
  let frac_to_cart = math.create_frac_to_cart(lattice_matrix);
@@ -49,14 +52,14 @@ export function parse_vasp_xdatcar(content, filename) {
49
52
  if (hdr.names.length === hdr.counts.length &&
50
53
  hdr.names.every(is_elem_symbol) &&
51
54
  hdr.counts.every((count) => Number.isInteger(count) && count > 0)) {
52
- elements = hdr.names.flatMap((name, idx) => Array(hdr.counts[idx]).fill(name));
55
+ elements = expand_element_counts(hdr.names, hdr.counts);
53
56
  }
54
57
  }
55
58
  }
56
59
  const config_line = lines[config_idx];
57
60
  line_idx = config_idx + 1;
58
- const step_match = /configuration=\s*(\d+)/.exec(config_line);
59
- const step = step_match ? parseInt(step_match[1], 10) : frames.length + 1;
61
+ const step_match = /configuration=\s*(?<step>\d+)/.exec(config_line);
62
+ const step = step_match ? Math.trunc(Number(step_match[1])) : frames.length + 1;
60
63
  const positions = [];
61
64
  for (let idx = 0; idx < elements.length && line_idx < lines.length; idx++) {
62
65
  const coords = lines[line_idx].trim().split(/\s+/).slice(0, 3).map(Number);
@@ -0,0 +1,13 @@
1
+ import type { ElectronicBandStructure, ElectronicDos } from '../../spectral';
2
+ import type * as h5wasm from 'h5wasm';
3
+ export interface VaspoutElectronicData {
4
+ dos: ElectronicDos | null;
5
+ bands: ElectronicBandStructure | null;
6
+ }
7
+ export declare const read_vaspout_dos: (h5_file: h5wasm.File) => ElectronicDos | null;
8
+ export declare const line_mode_labels: (labels: string[] | null, per_segment_dataset: number | null, n_kpoints: number) => {
9
+ labels: (string | null)[];
10
+ per_segment: number;
11
+ } | null;
12
+ export declare const read_vaspout_bands: (h5_file: h5wasm.File, dos?: ElectronicDos | null) => ElectronicBandStructure | null;
13
+ export declare const read_vaspout_electronic: (h5_file: h5wasm.File) => VaspoutElectronicData | null;