matterviz 0.4.1 → 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 (395) 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 +75 -85
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  10. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  11. package/dist/brillouin/BrillouinZoneScene.svelte +26 -39
  12. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  13. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  14. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +62 -74
  15. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  16. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +511 -547
  17. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  18. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  19. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  20. package/dist/colors/index.d.ts +0 -4
  21. package/dist/colors/index.js +19 -20
  22. package/dist/composition/BarChart.svelte +37 -31
  23. package/dist/composition/BubbleChart.svelte +17 -17
  24. package/dist/composition/Composition.svelte +7 -11
  25. package/dist/composition/Formula.svelte +18 -25
  26. package/dist/composition/FormulaFilter.svelte +92 -95
  27. package/dist/composition/PieChart.svelte +55 -41
  28. package/dist/composition/format.js +1 -1
  29. package/dist/composition/index.d.ts +2 -0
  30. package/dist/composition/index.js +14 -0
  31. package/dist/composition/parse.d.ts +2 -2
  32. package/dist/composition/parse.js +11 -10
  33. package/dist/constants.js +11 -9
  34. package/dist/convex-hull/ConvexHull.svelte +12 -15
  35. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  36. package/dist/convex-hull/ConvexHull2D.svelte +93 -92
  37. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  38. package/dist/convex-hull/ConvexHull3D.svelte +109 -140
  39. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  40. package/dist/convex-hull/ConvexHull4D.svelte +75 -94
  41. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  42. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  43. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  44. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  45. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  46. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  47. package/dist/convex-hull/StructurePopup.svelte +17 -21
  48. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  49. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  50. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  51. package/dist/convex-hull/helpers.d.ts +8 -10
  52. package/dist/convex-hull/helpers.js +36 -36
  53. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  54. package/dist/convex-hull/thermodynamics.js +18 -17
  55. package/dist/coordination/CoordinationBarPlot.svelte +38 -33
  56. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  57. package/dist/coordination/calc-coordination.d.ts +1 -1
  58. package/dist/coordination/calc-coordination.js +28 -25
  59. package/dist/element/BohrAtom.svelte +5 -8
  60. package/dist/element/ElementHeading.svelte +4 -1
  61. package/dist/element/ElementPhoto.svelte +11 -9
  62. package/dist/element/ElementStats.svelte +12 -10
  63. package/dist/element/ElementTile.svelte +24 -29
  64. package/dist/element/Nucleus.svelte +4 -2
  65. package/dist/element/data.d.ts +1 -2
  66. package/dist/element/helpers.d.ts +4 -0
  67. package/dist/element/helpers.js +18 -0
  68. package/dist/element/index.d.ts +1 -4
  69. package/dist/element/index.js +3 -18
  70. package/dist/feedback/DragOverlay.svelte +5 -5
  71. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  72. package/dist/feedback/StatusMessage.svelte +7 -4
  73. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  74. package/dist/fermi-surface/FermiSurface.svelte +14 -22
  75. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -7
  76. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  77. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  78. package/dist/fermi-surface/FermiSurfaceScene.svelte +37 -64
  79. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  80. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  81. package/dist/fermi-surface/compute.js +3 -3
  82. package/dist/fermi-surface/parse.js +22 -24
  83. package/dist/heatmap-matrix/HeatmapMatrix.svelte +109 -148
  84. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  85. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  86. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  87. package/dist/heatmap-matrix/index.d.ts +5 -0
  88. package/dist/icons.d.ts +4 -0
  89. package/dist/icons.js +4 -0
  90. package/dist/io/ExportPane.svelte +10 -6
  91. package/dist/io/decompress.d.ts +2 -1
  92. package/dist/io/decompress.js +22 -35
  93. package/dist/io/export.d.ts +4 -0
  94. package/dist/io/export.js +5 -1
  95. package/dist/io/fetch.d.ts +0 -3
  96. package/dist/io/fetch.js +0 -11
  97. package/dist/io/index.d.ts +0 -1
  98. package/dist/io/index.js +2 -9
  99. package/dist/io/is-binary.d.ts +9 -0
  100. package/dist/io/is-binary.js +45 -1
  101. package/dist/io/url-drop.js +13 -25
  102. package/dist/isosurface/Isosurface.svelte +17 -23
  103. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  104. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  105. package/dist/isosurface/parse-vaspwave.js +138 -0
  106. package/dist/isosurface/parse.js +6 -6
  107. package/dist/labels.d.ts +6 -2
  108. package/dist/labels.js +43 -13
  109. package/dist/layout/FullscreenButton.svelte +2 -1
  110. package/dist/layout/FullscreenToggle.svelte +10 -4
  111. package/dist/layout/InfoCard.svelte +7 -18
  112. package/dist/layout/InfoTag.svelte +1 -3
  113. package/dist/layout/NumberRangeInput.svelte +46 -0
  114. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  115. package/dist/layout/PropertyFilter.svelte +2 -6
  116. package/dist/layout/SettingsSection.svelte +21 -17
  117. package/dist/layout/SubpageGrid.svelte +3 -1
  118. package/dist/layout/ViewerChrome.svelte +9 -10
  119. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  120. package/dist/layout/fullscreen.js +3 -5
  121. package/dist/layout/fullscreen.svelte.js +1 -2
  122. package/dist/layout/index.d.ts +1 -0
  123. package/dist/layout/index.js +1 -0
  124. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  125. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  126. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  127. package/dist/layout/json-tree/utils.js +14 -23
  128. package/dist/math.d.ts +2 -0
  129. package/dist/math.js +19 -0
  130. package/dist/overlays/ContextMenu.svelte +4 -2
  131. package/dist/overlays/CopyButton.svelte +11 -5
  132. package/dist/overlays/DragControlTab.svelte +6 -1
  133. package/dist/overlays/DraggablePane.svelte +81 -26
  134. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  135. package/dist/overlays/GlassChip.svelte +30 -0
  136. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  137. package/dist/overlays/InfoPaneCards.svelte +11 -23
  138. package/dist/overlays/index.d.ts +7 -0
  139. package/dist/overlays/index.js +26 -0
  140. package/dist/overlays/portal.d.ts +2 -0
  141. package/dist/overlays/portal.js +14 -0
  142. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  143. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  144. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  145. package/dist/periodic-table/TableInset.svelte +9 -4
  146. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  147. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  148. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  149. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  150. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  151. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  152. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  153. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  154. package/dist/phase-diagram/build-diagram.js +3 -3
  155. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  156. package/dist/phase-diagram/parse.js +15 -15
  157. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  158. package/dist/phase-diagram/utils.js +2 -3
  159. package/dist/plot/bar/BarPlot.svelte +430 -391
  160. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  161. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  162. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  163. package/dist/plot/bar/SpacegroupBarPlot.svelte +29 -36
  164. package/dist/plot/bar/data.d.ts +5 -4
  165. package/dist/plot/bar/data.js +2 -1
  166. package/dist/plot/box/BoxPlot.svelte +301 -209
  167. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  168. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  169. package/dist/plot/box/box-plot.js +1 -1
  170. package/dist/plot/core/auto-place.js +1 -1
  171. package/dist/plot/core/axis-utils.d.ts +12 -7
  172. package/dist/plot/core/axis-utils.js +48 -48
  173. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  174. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  175. package/dist/plot/core/components/ColorBar.svelte +101 -106
  176. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  177. package/dist/plot/core/components/FillArea.svelte +10 -17
  178. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  179. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  180. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  181. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  182. package/dist/plot/core/components/Line.svelte +18 -9
  183. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  184. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  185. package/dist/plot/core/components/PlotControls.svelte +65 -41
  186. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  187. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  188. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  189. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  190. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  191. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  192. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  193. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  194. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  195. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  196. package/dist/plot/core/components/index.d.ts +1 -0
  197. package/dist/plot/core/components/index.js +1 -0
  198. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  199. package/dist/plot/core/data-cleaning-signal.js +467 -0
  200. package/dist/plot/core/data-cleaning.d.ts +2 -42
  201. package/dist/plot/core/data-cleaning.js +27 -474
  202. package/dist/plot/core/data-transform.js +9 -5
  203. package/dist/plot/core/fill-utils.d.ts +3 -1
  204. package/dist/plot/core/fill-utils.js +28 -6
  205. package/dist/plot/core/index.d.ts +1 -0
  206. package/dist/plot/core/index.js +1 -0
  207. package/dist/plot/core/interactions.js +0 -2
  208. package/dist/plot/core/layout.d.ts +3 -1
  209. package/dist/plot/core/layout.js +22 -13
  210. package/dist/plot/core/marginals.d.ts +170 -0
  211. package/dist/plot/core/marginals.js +436 -0
  212. package/dist/plot/core/reference-line.js +1 -1
  213. package/dist/plot/core/scales.d.ts +23 -0
  214. package/dist/plot/core/scales.js +39 -13
  215. package/dist/plot/core/types/fills.d.ts +101 -0
  216. package/dist/plot/core/types/fills.js +15 -0
  217. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  218. package/dist/plot/core/types/plot-3d.js +4 -0
  219. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  220. package/dist/plot/core/types/reference-lines.js +9 -0
  221. package/dist/plot/core/types.d.ts +29 -324
  222. package/dist/plot/core/types.js +23 -20
  223. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  224. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  225. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  226. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  227. package/dist/plot/core/utils/label-placement.js +2 -2
  228. package/dist/plot/histogram/Histogram.svelte +304 -325
  229. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  230. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  231. package/dist/plot/histogram/histogram.d.ts +31 -0
  232. package/dist/plot/histogram/histogram.js +70 -0
  233. package/dist/plot/histogram/index.d.ts +1 -0
  234. package/dist/plot/histogram/index.js +1 -0
  235. package/dist/plot/index.d.ts +1 -0
  236. package/dist/plot/index.js +1 -0
  237. package/dist/plot/sankey/Sankey.svelte +78 -69
  238. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  239. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  240. package/dist/plot/scatter/BinnedScatterPlot.svelte +263 -109
  241. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  242. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  243. package/dist/plot/scatter/ScatterPlot.svelte +477 -385
  244. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  245. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  246. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  247. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  248. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  249. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  250. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  251. package/dist/plot/scatter/scatter-data.js +8 -7
  252. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  253. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  254. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  255. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  256. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  257. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  258. package/dist/plot/sunburst/Sunburst.svelte +251 -329
  259. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  260. package/dist/plot/sunburst/index.d.ts +1 -1
  261. package/dist/plot/sunburst/index.js +2 -1
  262. package/dist/plot/sunburst/render.d.ts +2 -2
  263. package/dist/plot/sunburst/render.js +47 -22
  264. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  265. package/dist/plot/sunburst/sunburst.js +10 -3
  266. package/dist/plot/treemap/Treemap.svelte +907 -0
  267. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  268. package/dist/plot/treemap/index.d.ts +3 -0
  269. package/dist/plot/treemap/index.js +4 -0
  270. package/dist/plot/treemap/treemap.d.ts +26 -0
  271. package/dist/plot/treemap/treemap.js +99 -0
  272. package/dist/rdf/RdfPlot.svelte +22 -26
  273. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  274. package/dist/rdf/calc-rdf.js +4 -8
  275. package/dist/sanitize.js +1 -1
  276. package/dist/scene/bind-renderer.svelte.js +14 -6
  277. package/dist/settings.d.ts +19 -9
  278. package/dist/settings.js +77 -50
  279. package/dist/spectral/Bands.svelte +223 -230
  280. package/dist/spectral/BandsAndDos.svelte +11 -9
  281. package/dist/spectral/BrillouinBandsDos.svelte +19 -27
  282. package/dist/spectral/Dos.svelte +70 -73
  283. package/dist/spectral/helpers.d.ts +3 -3
  284. package/dist/spectral/helpers.js +25 -35
  285. package/dist/state.svelte.js +5 -18
  286. package/dist/structure/Arrow.svelte +5 -18
  287. package/dist/structure/ArrowInstances.svelte +160 -0
  288. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  289. package/dist/structure/AtomLegend.svelte +115 -75
  290. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  291. package/dist/structure/Bond.svelte +31 -23
  292. package/dist/structure/CanvasTooltip.svelte +15 -3
  293. package/dist/structure/CellSelect.svelte +11 -26
  294. package/dist/structure/Cylinder.svelte +24 -40
  295. package/dist/structure/InstancedAtoms.svelte +114 -0
  296. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  297. package/dist/structure/Lattice.svelte +85 -149
  298. package/dist/structure/SiteLabels.svelte +122 -0
  299. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  300. package/dist/structure/Structure.svelte +473 -419
  301. package/dist/structure/Structure.svelte.d.ts +4 -2
  302. package/dist/structure/StructureCarousel.svelte +630 -0
  303. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  304. package/dist/structure/StructureControls.svelte +157 -399
  305. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  306. package/dist/structure/StructureExportPane.svelte +17 -21
  307. package/dist/structure/StructureInfoPane.svelte +72 -66
  308. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  309. package/dist/structure/StructureScene.svelte +467 -476
  310. package/dist/structure/StructureScene.svelte.d.ts +3 -1
  311. package/dist/structure/StructureViewport.svelte +386 -0
  312. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  313. package/dist/structure/atom-label-placement.d.ts +16 -12
  314. package/dist/structure/atom-label-placement.js +70 -37
  315. package/dist/structure/atom-properties.d.ts +2 -0
  316. package/dist/structure/atom-properties.js +104 -38
  317. package/dist/structure/bonding.d.ts +10 -3
  318. package/dist/structure/bonding.js +84 -28
  319. package/dist/structure/edit-history.d.ts +6 -0
  320. package/dist/structure/edit-history.js +27 -0
  321. package/dist/structure/export.d.ts +1 -0
  322. package/dist/structure/export.js +39 -31
  323. package/dist/structure/format-detect.d.ts +1 -0
  324. package/dist/structure/format-detect.js +22 -0
  325. package/dist/structure/geometry.d.ts +9 -0
  326. package/dist/structure/geometry.js +27 -0
  327. package/dist/structure/index.d.ts +16 -1
  328. package/dist/structure/index.js +13 -2
  329. package/dist/structure/measure.d.ts +1 -1
  330. package/dist/structure/measure.js +6 -12
  331. package/dist/structure/parse.d.ts +2 -1
  332. package/dist/structure/parse.js +243 -222
  333. package/dist/structure/partial-occupancy.js +4 -2
  334. package/dist/structure/pbc.js +78 -98
  335. package/dist/structure/polyhedra.d.ts +0 -1
  336. package/dist/structure/polyhedra.js +3 -18
  337. package/dist/structure/supercell.d.ts +1 -2
  338. package/dist/structure/supercell.js +7 -13
  339. package/dist/symmetry/SymmetryElements.svelte +11 -15
  340. package/dist/symmetry/SymmetryStats.svelte +56 -68
  341. package/dist/symmetry/WyckoffTable.svelte +5 -24
  342. package/dist/symmetry/cell-transform.js +1 -0
  343. package/dist/symmetry/index.d.ts +1 -0
  344. package/dist/symmetry/index.js +8 -2
  345. package/dist/symmetry/spacegroups.js +3 -2
  346. package/dist/table/HeatmapTable.svelte +1102 -365
  347. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  348. package/dist/table/ToggleMenu.svelte +5 -12
  349. package/dist/table/index.d.ts +21 -6
  350. package/dist/table/index.js +34 -21
  351. package/dist/theme/ThemeControl.svelte +16 -8
  352. package/dist/theme/index.d.ts +1 -5
  353. package/dist/theme/index.js +4 -10
  354. package/dist/theme/themes.mjs +14 -7
  355. package/dist/tooltip/KCoords.svelte +4 -1
  356. package/dist/tooltip/TooltipContent.svelte +2 -5
  357. package/dist/trajectory/Trajectory.svelte +515 -308
  358. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  359. package/dist/trajectory/TrajectoryError.svelte +11 -8
  360. package/dist/trajectory/TrajectoryExportPane.svelte +14 -31
  361. package/dist/trajectory/TrajectoryInfoPane.svelte +85 -97
  362. package/dist/trajectory/extract.js +56 -34
  363. package/dist/trajectory/format-detect.js +11 -9
  364. package/dist/trajectory/frame-reader.d.ts +2 -0
  365. package/dist/trajectory/frame-reader.js +33 -29
  366. package/dist/trajectory/helpers.d.ts +2 -0
  367. package/dist/trajectory/helpers.js +18 -7
  368. package/dist/trajectory/index.d.ts +1 -0
  369. package/dist/trajectory/index.js +3 -0
  370. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  371. package/dist/trajectory/parse/h5-utils.js +109 -0
  372. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  373. package/dist/trajectory/parse/hdf5.js +116 -106
  374. package/dist/trajectory/parse/index.d.ts +2 -3
  375. package/dist/trajectory/parse/index.js +17 -20
  376. package/dist/trajectory/parse/lammps.js +8 -12
  377. package/dist/trajectory/parse/vasp.js +10 -7
  378. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  379. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  380. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  381. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  382. package/dist/trajectory/parse/xyz.js +11 -7
  383. package/dist/trajectory/plotting.d.ts +8 -9
  384. package/dist/trajectory/plotting.js +99 -27
  385. package/dist/utils.d.ts +3 -0
  386. package/dist/utils.js +7 -0
  387. package/dist/xrd/XrdPlot.svelte +47 -61
  388. package/dist/xrd/broadening.js +2 -1
  389. package/dist/xrd/calc-xrd.js +2 -4
  390. package/dist/xrd/parse.d.ts +0 -1
  391. package/dist/xrd/parse.js +56 -73
  392. package/package.json +61 -33
  393. package/dist/api/mp.d.ts +0 -6
  394. package/dist/api/mp.js +0 -22
  395. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
@@ -61,6 +61,6 @@ type $$ComponentProps = EventHandlers & HTMLAttributes<HTMLDivElement> & {
61
61
  wrapper?: HTMLDivElement;
62
62
  fullscreen?: boolean;
63
63
  };
64
- declare const Trajectory: import("svelte").Component<$$ComponentProps, {}, "trajectory" | "fullscreen" | "wrapper" | "hovered" | "controls_open" | "fps" | "info_pane_open" | "display_mode" | "current_step_idx" | "visible_properties">;
64
+ declare const Trajectory: import("svelte").Component<$$ComponentProps, {}, "fullscreen" | "wrapper" | "hovered" | "controls_open" | "trajectory" | "fps" | "info_pane_open" | "display_mode" | "current_step_idx" | "visible_properties">;
65
65
  type Trajectory = ReturnType<typeof Trajectory>;
66
66
  export default Trajectory;
@@ -3,14 +3,17 @@
3
3
  import type { Snippet } from 'svelte'
4
4
  import type { HTMLAttributes } from 'svelte/elements'
5
5
 
6
- let { error_msg, on_dismiss, error_snippet, ...rest }:
7
- & HTMLAttributes<HTMLDivElement>
8
- & {
9
- error_msg: string
10
- on_dismiss: () => void
11
- // Custom error snippet for advanced error handling
12
- error_snippet?: Snippet<[{ error_msg: string; on_dismiss: () => void }]>
13
- } = $props()
6
+ let {
7
+ error_msg,
8
+ on_dismiss,
9
+ error_snippet,
10
+ ...rest
11
+ }: HTMLAttributes<HTMLDivElement> & {
12
+ error_msg: string
13
+ on_dismiss: () => void
14
+ // Custom error snippet for advanced error handling
15
+ error_snippet?: Snippet<[{ error_msg: string; on_dismiss: () => void }]>
16
+ } = $props()
14
17
  </script>
15
18
 
16
19
  <div {...rest}>
@@ -62,7 +62,7 @@
62
62
  if (!canvas) return 0
63
63
  const pixels = canvas.width * canvas.height * resolution_multiplier ** 2
64
64
  const bitrate = estimate_video_bitrate(pixels, video_fps)
65
- return (bitrate * export_frame_count / video_fps) / 8 / 1024 / 1024
65
+ return (bitrate * export_frame_count) / video_fps / 8 / 1024 / 1024
66
66
  })
67
67
 
68
68
  // Initialize end_frame when trajectory changes
@@ -84,9 +84,7 @@
84
84
  }
85
85
  })
86
86
 
87
- let export_frame_count = $derived(
88
- end_frame >= start_frame ? end_frame - start_frame + 1 : 0,
89
- )
87
+ let export_frame_count = $derived(end_frame >= start_frame ? end_frame - start_frame + 1 : 0)
90
88
 
91
89
  async function handle_video_export(format: `webm` | `mp4` = `webm`) {
92
90
  export_error = null
@@ -96,8 +94,8 @@
96
94
  export_error = !trajectory
97
95
  ? `No trajectory`
98
96
  : !canvas
99
- ? `Canvas not ready`
100
- : `Invalid frame range`
97
+ ? `Canvas not ready`
98
+ : `Invalid frame range`
101
99
  return
102
100
  }
103
101
 
@@ -172,13 +170,7 @@
172
170
  <label>
173
171
  Frame Rate (FPS)
174
172
  <input type="number" min={10} max={60} bind:value={video_fps} />
175
- <input
176
- type="range"
177
- min={10}
178
- max={60}
179
- bind:value={video_fps}
180
- style="accent-color: var(--accent-color)"
181
- />
173
+ <input type="range" min={10} max={60} bind:value={video_fps} />
182
174
  </label>
183
175
 
184
176
  <span class="field-label">
@@ -192,7 +184,9 @@
192
184
  class:active={resolution_multiplier === multiplier}
193
185
  onclick={() => (resolution_multiplier = multiplier)}
194
186
  {@attach tooltip({
195
- content: canvas ? `${multiplier}x (${width_px}×${height_px})` : `${multiplier}x`,
187
+ content: canvas
188
+ ? `${multiplier}x (${width_px}×${height_px})`
189
+ : `${multiplier}x`,
196
190
  })}
197
191
  >
198
192
  {multiplier}x
@@ -214,7 +208,6 @@
214
208
  min={0}
215
209
  max={Math.max(0, total_frames_available - 1)}
216
210
  bind:value={start_frame}
217
- style="accent-color: var(--accent-color)"
218
211
  />
219
212
  </label>
220
213
 
@@ -231,7 +224,6 @@
231
224
  min={start_frame}
232
225
  max={Math.max(0, total_frames_available - 1)}
233
226
  bind:value={end_frame}
234
- style="accent-color: var(--accent-color)"
235
227
  />
236
228
  </label>
237
229
  </SettingsSection>
@@ -243,13 +235,7 @@
243
235
  {/if}
244
236
 
245
237
  <div class="export-buttons">
246
- {#each [
247
- { label: `WebM`, format: `webm`, hint: `Export as WebM video` },
248
- { label: `MP4`, format: `mp4`, hint: `WebM + ffmpeg command` },
249
- ] as const as
250
- { label, format, hint }
251
- (format)
252
- }
238
+ {#each [{ label: `WebM`, format: `webm`, hint: `Export as WebM video` }, { label: `MP4`, format: `mp4`, hint: `WebM + ffmpeg command` }] as const as { label, format, hint } (format)}
253
239
  <div style="display: flex; align-items: center; gap: 4pt">
254
240
  {label}
255
241
  <button
@@ -267,15 +253,11 @@
267
253
  </div>
268
254
 
269
255
  <div class="export-info">
270
- {(export_frame_count / video_fps).toFixed(1)}s ({export_frame_count} frames: {
271
- start_frame
272
- }–{end_frame})
256
+ {(export_frame_count / video_fps).toFixed(1)}s ({export_frame_count} frames: {start_frame}–{end_frame})
273
257
  {#if file_size_mb > 0}
274
- • ~{
275
- file_size_mb < 1
258
+ • ~{file_size_mb < 1
276
259
  ? `${(file_size_mb * 1024).toFixed(0)} KB`
277
- : `${file_size_mb.toFixed(1)} MB`
278
- }
260
+ : `${file_size_mb.toFixed(1)} MB`}
279
261
  {/if}
280
262
  </div>
281
263
 
@@ -292,7 +274,8 @@
292
274
  gap: 6pt;
293
275
  white-space: nowrap;
294
276
  }
295
- .warning, .error-message {
277
+ .warning,
278
+ .error-message {
296
279
  padding: 1ex;
297
280
  border-radius: var(--traj-border-radius, var(--border-radius, 3pt));
298
281
  font-size: 0.9em;
@@ -2,7 +2,7 @@
2
2
  import type { PaneProps, PaneToggleProps } from '../overlays'
3
3
  import type { InfoItem } from '../layout'
4
4
  import InfoPaneCards from '../overlays/InfoPaneCards.svelte'
5
- import { format_num } from '../labels'
5
+ import { format_bytes, format_num } from '../labels'
6
6
  import DraggablePane from '../overlays/DraggablePane.svelte'
7
7
  import { get_electro_neg_formula } from '../composition'
8
8
  import { SETTINGS_CONFIG } from '../settings'
@@ -34,11 +34,6 @@
34
34
  } = $props()
35
35
 
36
36
  // Helper functions
37
- const format_size = (bytes: number) =>
38
- bytes > 1024 * 1024
39
- ? `${format_num(bytes / (1024 * 1024), `.2~f`)} MB`
40
- : `${format_num(bytes / 1024, `.2~f`)} KB`
41
-
42
37
  const is_valid_number = (val: unknown): val is number =>
43
38
  typeof val === `number` && isFinite(val)
44
39
 
@@ -51,8 +46,7 @@
51
46
  return `${format_num(values[0], decimals)} ${unit}`.trim()
52
47
  }
53
48
  const [min, max] = [Math.min(...values), Math.max(...values)]
54
- return `${format_num(min, decimals)} - ${format_num(max, decimals)} ${unit}`
55
- .trim()
49
+ return `${format_num(min, decimals)} - ${format_num(max, decimals)} ${unit}`.trim()
56
50
  }
57
51
 
58
52
  const safe_item = (
@@ -60,7 +54,7 @@
60
54
  value: string | null,
61
55
  key?: string,
62
56
  tooltip?: string,
63
- ): InfoItem | null => value ? { label, value, key, tooltip } : null
57
+ ): InfoItem | null => (value ? { label, value, key, tooltip } : null)
64
58
 
65
59
  // oxlint-disable-next-line eslint-plugin-unicorn/prefer-native-coercion-functions -- type predicate needed for narrowing
66
60
  const is_info_item = (item: unknown): item is InfoItem => Boolean(item)
@@ -79,7 +73,8 @@
79
73
  (!trajectory?.frames?.length && !trajectory?.total_frames) ||
80
74
  current_step_idx < 0 ||
81
75
  current_step_idx >= (trajectory.total_frames ?? trajectory.frames?.length ?? 0)
82
- ) return []
76
+ )
77
+ return []
83
78
 
84
79
  // For indexed trajectories, we might not have the current frame loaded
85
80
  const current_frame = trajectory.frames?.[current_step_idx]
@@ -90,22 +85,18 @@
90
85
  // File info section
91
86
  const file_items = [
92
87
  current_filename &&
93
- safe_item(
94
- `Name`,
95
- current_filename,
96
- `file-name`,
97
- current_file_path || undefined,
98
- ),
99
- file_size && file_size > 0 &&
100
- safe_item(`File Size`, format_size(file_size), `file-size`),
88
+ safe_item(`Name`, current_filename, `file-name`, current_file_path || undefined),
89
+ file_size &&
90
+ file_size > 0 &&
91
+ safe_item(`File Size`, format_bytes(file_size), `file-size`),
101
92
  file_object?.lastModified &&
102
- safe_item(
103
- `Modified`,
104
- new Date(file_object.lastModified).toLocaleString(),
105
- `file-modified`,
106
- ),
93
+ safe_item(
94
+ `Modified`,
95
+ new Date(file_object.lastModified).toLocaleString(),
96
+ `file-modified`,
97
+ ),
107
98
  trajectory.metadata?.source_format &&
108
- safe_item(`Format`, String(trajectory.metadata.source_format), `file-format`),
99
+ safe_item(`Format`, String(trajectory.metadata.source_format), `file-format`),
109
100
  ].filter(is_info_item)
110
101
 
111
102
  if (file_items.length > 0) {
@@ -116,32 +107,33 @@
116
107
  const traj_items = [
117
108
  safe_item(
118
109
  `Total Frames`,
119
- `${format_num(total_frames, `.3~s`)} (current: ${
120
- format_num(current_step_idx + 1, `.3~s`)
121
- })`,
110
+ `${format_num(total_frames, `.3~s`)} (current: ${format_num(
111
+ current_step_idx + 1,
112
+ `.3~s`,
113
+ )})`,
122
114
  `total-frames`,
123
115
  ),
124
116
  trajectory.is_indexed &&
125
- safe_item(
126
- `Indexed`,
127
- `Yes`,
128
- `indexed-mode`,
129
- SETTINGS_CONFIG.trajectory.use_indexing.description,
130
- ),
117
+ safe_item(
118
+ `Indexed`,
119
+ `Yes`,
120
+ `indexed-mode`,
121
+ SETTINGS_CONFIG.trajectory.use_indexing.description,
122
+ ),
131
123
  trajectory.indexed_frames &&
132
- safe_item(
133
- `Index Points`,
134
- `${trajectory.indexed_frames.length}`,
135
- `index-points`,
136
- `Number of frames indexed for fast seeking`,
137
- ),
124
+ safe_item(
125
+ `Index Points`,
126
+ `${trajectory.indexed_frames.length}`,
127
+ `index-points`,
128
+ `Number of frames indexed for fast seeking`,
129
+ ),
138
130
  trajectory.plot_metadata &&
139
- safe_item(
140
- `Plot Metadata`,
141
- `${trajectory.plot_metadata.length} frames`,
142
- `plot-metadata`,
143
- `Pre-extracted metadata for plotting`,
144
- ),
131
+ safe_item(
132
+ `Plot Metadata`,
133
+ `${trajectory.plot_metadata.length} frames`,
134
+ `plot-metadata`,
135
+ `Pre-extracted metadata for plotting`,
136
+ ),
145
137
  ].filter(is_info_item)
146
138
 
147
139
  if (traj_items.length > 0) {
@@ -158,30 +150,35 @@
158
150
  const structure_items = [
159
151
  safe_item(`Atoms`, `${structure.sites.length}`, `atoms`),
160
152
  formula && safe_item(`Formula`, String(formula), `formula`),
161
- is_valid_number(volume) && volume > 0 &&
162
- safe_item(`Volume`, `${format_num(volume, `.3~s`)} ų`, `volume`),
163
- is_valid_number(volume) && volume > 0 && structure.sites.length > 0 &&
164
- safe_item(
165
- `Density`,
166
- `${format_num(structure.sites.length / volume, `.4~s`)} atoms/ų`,
167
- `density`,
168
- ),
153
+ is_valid_number(volume) &&
154
+ volume > 0 &&
155
+ safe_item(`Volume`, `${format_num(volume, `.3~s`)} ų`, `volume`),
156
+ is_valid_number(volume) &&
157
+ volume > 0 &&
158
+ structure.sites.length > 0 &&
159
+ safe_item(
160
+ `Density`,
161
+ `${format_num(structure.sites.length / volume, `.4~s`)} atoms/ų`,
162
+ `density`,
163
+ ),
169
164
  [a, b, c].every(is_valid_number) &&
170
- safe_item(
171
- `Cell Lengths`,
172
- `${format_num(a as number, `.3~f`)}, ${format_num(b as number, `.3~f`)}, ${
173
- format_num(c as number, `.3~f`)
174
- } Å`,
175
- `cell-lengths`,
176
- ),
165
+ safe_item(
166
+ `Cell Lengths`,
167
+ `${format_num(a as number, `.3~f`)}, ${format_num(b as number, `.3~f`)}, ${format_num(
168
+ c as number,
169
+ `.3~f`,
170
+ )} Å`,
171
+ `cell-lengths`,
172
+ ),
177
173
  [alpha, beta, gamma].every(is_valid_number) &&
178
- safe_item(
179
- `Cell Angles`,
180
- `${format_num(alpha as number, `.2~f`)}°, ${
181
- format_num(beta as number, `.2~f`)
182
- }°, ${format_num(gamma as number, `.2~f`)}°`,
183
- `cell-angles`,
184
- ),
174
+ safe_item(
175
+ `Cell Angles`,
176
+ `${format_num(alpha as number, `.2~f`)}°, ${format_num(
177
+ beta as number,
178
+ `.2~f`,
179
+ )}°, ${format_num(gamma as number, `.2~f`)}°`,
180
+ `cell-angles`,
181
+ ),
185
182
  ].filter(is_info_item)
186
183
 
187
184
  if (structure_items.length > 0) {
@@ -212,11 +209,11 @@
212
209
 
213
210
  const energy_items = [
214
211
  is_valid_number(current_energy) &&
215
- safe_item(
216
- `Current Energy`,
217
- `${format_num(current_energy, `.3~s`)} eV`,
218
- `energy-current`,
219
- ),
212
+ safe_item(
213
+ `Current Energy`,
214
+ `${format_num(current_energy, `.3~s`)} eV`,
215
+ `energy-current`,
216
+ ),
220
217
  energy_range && safe_item(`Energy Range`, energy_range, `energy-range`),
221
218
  ].filter(is_info_item)
222
219
 
@@ -235,11 +232,11 @@
235
232
 
236
233
  const force_items = [
237
234
  is_valid_number(current_force) &&
238
- safe_item(
239
- `Max Force`,
240
- `${format_num(current_force, `.3~s`)} eV/Å`,
241
- `force-current`,
242
- ),
235
+ safe_item(
236
+ `Max Force`,
237
+ `${format_num(current_force, `.3~s`)} eV/Å`,
238
+ `force-current`,
239
+ ),
243
240
  force_range && safe_item(`Force Range`, force_range, `force-range`),
244
241
  ].filter(is_info_item)
245
242
 
@@ -250,29 +247,22 @@
250
247
  }
251
248
 
252
249
  // Volume change section (only for regular trajectories)
253
- if (
254
- !trajectory.is_indexed && current_frame?.structure &&
255
- trajectory.frames.length > 1
256
- ) {
257
- const lattice = `lattice` in current_frame.structure
258
- ? current_frame.structure.lattice
259
- : null
250
+ if (!trajectory.is_indexed && current_frame?.structure && trajectory.frames.length > 1) {
251
+ const lattice =
252
+ `lattice` in current_frame.structure ? current_frame.structure.lattice : null
260
253
  if (lattice) {
261
- const volumes = trajectory.frames.map((
262
- { structure },
263
- ) => (`lattice` in structure && structure.lattice?.volume))
254
+ const volumes = trajectory.frames
255
+ .map(({ structure }) => `lattice` in structure && structure.lattice?.volume)
264
256
  .filter(is_valid_number)
265
257
  .filter((volume) => volume > 0)
266
258
 
267
259
  if (volumes.length > 1) {
268
- const vol_change = (Math.max(...volumes) - Math.min(...volumes)) /
269
- Math.min(...volumes)
260
+ const vol_change =
261
+ (Math.max(...volumes) - Math.min(...volumes)) / Math.min(...volumes)
270
262
  if (Math.abs(vol_change) > 0.1 && is_valid_number(vol_change)) {
271
- const vol_items = [safe_item(
272
- `Volume Change`,
273
- `${format_num(vol_change, `.2~%`)}`,
274
- `vol-change`,
275
- )].filter(is_info_item)
263
+ const vol_items = [
264
+ safe_item(`Volume Change`, `${format_num(vol_change, `.2~%`)}`, `vol-change`),
265
+ ].filter(is_info_item)
276
266
 
277
267
  if (vol_items.length > 0) {
278
268
  sections.push({ title: `Volume`, items: vol_items })
@@ -284,9 +274,7 @@
284
274
  return sections
285
275
  })
286
276
 
287
- let info_cards = $derived(
288
- info_pane_data.map(({ title, items }) => ({ title, rows: items })),
289
- )
277
+ let info_cards = $derived(info_pane_data.map(({ title, items }) => ({ title, rows: items })))
290
278
  let n_info_items = $derived(
291
279
  info_pane_data.reduce((count, { items }) => count + items.length, 0),
292
280
  )
@@ -52,6 +52,23 @@ export const force_stress_data_extractor = (frame) => {
52
52
  }
53
53
  return data;
54
54
  };
55
+ // Data extractor for SCF/electronic-convergence properties. Parsers emit these
56
+ // per frame (per ionic step, or per SCF step for static single-point runs) —
57
+ // e.g. the vaspout.h5 parser fills them from VASP's OSZICAR data.
58
+ const scf_data_extractor = (frame) => {
59
+ const data = {
60
+ Step: frame.step,
61
+ };
62
+ if (frame.metadata) {
63
+ copy_numeric_fields(data, frame.metadata, [
64
+ `n_scf_steps`,
65
+ `scf_energy_delta`,
66
+ `scf_rms`,
67
+ `scf_charge_rms`,
68
+ ]);
69
+ }
70
+ return data;
71
+ };
55
72
  // Data extractor for structural properties
56
73
  export const structural_data_extractor = (frame) => {
57
74
  const data = {
@@ -93,50 +110,55 @@ export const structural_data_extractor = (frame) => {
93
110
  }
94
111
  return data;
95
112
  };
96
- // Helper function to check if a property varies across trajectory frames
97
- function property_varies(trajectory, property_key, tolerance = 1e-10) {
98
- if (trajectory.frames.length <= 1)
99
- return false;
100
- const values = [];
113
+ const LATTICE_PARAMS = [`a`, `b`, `c`, `alpha`, `beta`, `gamma`];
114
+ // Cache per trajectory: full_data_extractor runs once per frame, so without this it
115
+ // rescans all frames on every call (O(n²)). WeakMap → GC'd with the trajectory.
116
+ const constant_params_cache = new WeakMap();
117
+ // Lattice params constant across the trajectory, in a single pass (prefer lattice value,
118
+ // else metadata; tol 1e-10). A param must be observed in ≥1 frame to count as constant;
119
+ // params absent from every frame are excluded (not silently treated as "constant").
120
+ function get_constant_lattice_params(trajectory) {
121
+ const cached = constant_params_cache.get(trajectory);
122
+ if (cached)
123
+ return cached;
124
+ const tolerance = 1e-10;
125
+ const first_values = new Map();
126
+ const varies = new Set();
101
127
  for (const frame of trajectory.frames) {
102
- // Check both direct structure properties and metadata
103
- let value;
104
- if (`lattice` in frame.structure) {
105
- const lattice_value = frame.structure.lattice[property_key];
106
- if (typeof lattice_value === `number`)
107
- value = lattice_value;
108
- }
109
- if (value === undefined && frame.metadata && property_key in frame.metadata) {
110
- const metadata_value = frame.metadata[property_key];
111
- if (typeof metadata_value === `number`) {
112
- value = metadata_value;
113
- }
114
- }
115
- if (value !== undefined) {
116
- values.push(value);
128
+ const lattice = `lattice` in frame.structure
129
+ ? frame.structure.lattice
130
+ : null;
131
+ for (const param of LATTICE_PARAMS) {
132
+ if (varies.has(param))
133
+ continue; // already known to vary, skip
134
+ const lattice_value = lattice?.[param];
135
+ const value = typeof lattice_value === `number` ? lattice_value : frame.metadata?.[param];
136
+ // Number.isFinite: NaN is typeof `number` but Math.abs(next-NaN)=NaN → false constant
137
+ if (typeof value !== `number` || !Number.isFinite(value))
138
+ continue;
139
+ const first = first_values.get(param);
140
+ if (first === undefined)
141
+ first_values.set(param, value);
142
+ else if (Math.abs(value - first) > tolerance)
143
+ varies.add(param);
117
144
  }
118
145
  }
119
- if (values.length <= 1)
120
- return false;
121
- const first_value = values[0];
122
- return values.some((value) => Math.abs(value - first_value) > tolerance);
146
+ // only params observed in ≥1 frame; a never-present param is not "constant"
147
+ const constant = new Set([...first_values.keys()].filter((param) => !varies.has(param)));
148
+ constant_params_cache.set(trajectory, constant);
149
+ return constant;
123
150
  }
124
151
  // Combined data extractor that extracts all common properties
125
152
  export const full_data_extractor = (frame, trajectory) => {
126
- const base_data = {
153
+ const result = {
127
154
  ...energy_data_extractor(frame, trajectory),
128
155
  ...force_stress_data_extractor(frame, trajectory),
156
+ ...scf_data_extractor(frame, trajectory),
129
157
  ...structural_data_extractor(frame, trajectory),
130
158
  };
131
- // Check which lattice parameters vary
132
- const lattice_params = [`a`, `b`, `c`, `alpha`, `beta`, `gamma`];
133
- const result = { ...base_data };
134
- // Add metadata to specify which properties don't vary
135
- for (const param of lattice_params) {
136
- if (!property_varies(trajectory, param)) {
137
- // Mark individual lattice parameters as constant
138
- result[`constant_${param}`] = 1;
139
- }
159
+ // Mark individual lattice parameters that don't vary across the trajectory
160
+ for (const param of get_constant_lattice_params(trajectory)) {
161
+ result[`constant_${param}`] = 1;
140
162
  }
141
163
  return result;
142
164
  };
@@ -1,10 +1,11 @@
1
1
  // Format detection for trajectory files
2
2
  import { CONFIG_DIRS_REGEX, MD_SIM_EXCLUDE_REGEX, TRAJ_EXTENSIONS_REGEX, TRAJ_FALLBACK_EXTENSIONS_REGEX, TRAJ_KEYWORDS_SIMPLE_REGEX, XDATCAR_REGEX, } from '../constants';
3
- import { strip_compression_extensions } from '../io';
3
+ import { strip_compression_extensions } from '../io/decompress';
4
+ import { parse_leading_num } from '../utils';
4
5
  import { count_xyz_frames } from './helpers';
5
6
  // Extensions that explicitly identify a format — when present, format detection trusts
6
7
  // the extension instead of sniffing content
7
- const KNOWN_FORMAT_EXT_REGEX = /\.(xyz|extxyz|traj|h5|hdf5|lammpstrj|json|cif|poscar|vasp|yaml|yml|xml|csv)$/;
8
+ const KNOWN_FORMAT_EXT_REGEX = /\.(?:xyz|extxyz|traj|h5|hdf5|lammpstrj|json|cif|poscar|vasp|yaml|yml|xml|csv)$/;
8
9
  // Classify the filename hint for a format whose extensions match ext_regex:
9
10
  // true = filename matches, false = filename names a different known format,
10
11
  // null = no usable hint (missing filename or unrecognized extension, e.g. the UUID
@@ -29,7 +30,7 @@ export const FORMAT_PATTERNS = {
29
30
  return [0x2d, 0x20, 0x6f, 0x66, 0x20, 0x55, 0x6c, 0x6d].every((byte, idx) => view[idx] === byte);
30
31
  },
31
32
  hdf5: (data, filename) => {
32
- if (ext_hint(filename, /\.(h5|hdf5)$/) === false)
33
+ if (ext_hint(filename, /\.(?:h5|hdf5)$/) === false)
33
34
  return false;
34
35
  if (!(data instanceof ArrayBuffer) || data.byteLength < 8)
35
36
  return false;
@@ -43,11 +44,11 @@ export const FORMAT_PATTERNS = {
43
44
  const lines = data.trim().split(/\r?\n/);
44
45
  return (lines.length >= 10 &&
45
46
  lines.some((line) => line.includes(`Direct configuration=`)) &&
46
- !isNaN(parseFloat(lines[1])) &&
47
+ !isNaN(parse_leading_num(lines[1])) &&
47
48
  lines.slice(2, 5).every((line) => line.trim().split(/\s+/).length === 3));
48
49
  },
49
50
  xyz_multi: (data, filename) => {
50
- if (ext_hint(filename, /\.(xyz|extxyz)$/) === false)
51
+ if (ext_hint(filename, /\.(?:xyz|extxyz)$/) === false)
51
52
  return false;
52
53
  return count_xyz_frames(data) >= 2;
53
54
  },
@@ -63,7 +64,7 @@ export function is_trajectory_file(filename, content) {
63
64
  return false;
64
65
  const base_name = strip_compression_extensions(filename);
65
66
  // For xyz/extxyz files, use content-based detection if available
66
- if (/\.(xyz|extxyz)$/i.test(base_name)) {
67
+ if (/\.(?:xyz|extxyz)$/i.test(base_name)) {
67
68
  if (content)
68
69
  return count_xyz_frames(content) >= 2;
69
70
  return TRAJ_KEYWORDS_SIMPLE_REGEX.test(base_name);
@@ -74,9 +75,10 @@ export function is_trajectory_file(filename, content) {
74
75
  // Special exclusion for generic md_simulation pattern with certain extensions
75
76
  if (MD_SIM_EXCLUDE_REGEX.test(base_name))
76
77
  return false;
77
- // For .h5/.hdf5 files, require trajectory keywords
78
- if (/\.(h5|hdf5)$/i.test(base_name)) {
79
- return TRAJ_KEYWORDS_SIMPLE_REGEX.test(base_name);
78
+ // For .h5/.hdf5 files, require trajectory keywords. vaspout.h5 (VASP's
79
+ // HDF5 output) is always trajectory-shaped regardless of keywords.
80
+ if (/\.(?:h5|hdf5)$/i.test(base_name)) {
81
+ return /vaspout/i.test(base_name) || TRAJ_KEYWORDS_SIMPLE_REGEX.test(base_name);
80
82
  }
81
83
  // For other extensions, require both keywords and specific extensions
82
84
  return (TRAJ_KEYWORDS_SIMPLE_REGEX.test(base_name) &&
@@ -2,6 +2,7 @@ import type { FrameIndex, FrameLoader, ParseProgress, TrajectoryFrame, Trajector
2
2
  export declare class TrajFrameReader implements FrameLoader {
3
3
  private readonly format;
4
4
  private global_numbers?;
5
+ private xyz_cache?;
5
6
  constructor(filename: string);
6
7
  get_total_frames(data: string | ArrayBuffer): Promise<number>;
7
8
  build_frame_index(data: string | ArrayBuffer, sample_rate: number, on_progress?: (progress: ParseProgress) => void): Promise<FrameIndex[]>;
@@ -10,6 +11,7 @@ export declare class TrajFrameReader implements FrameLoader {
10
11
  sample_rate?: number;
11
12
  properties?: string[];
12
13
  }, on_progress?: (progress: ParseProgress) => void): Promise<TrajectoryMetadata[]>;
14
+ private get_xyz_cache;
13
15
  private load_xyz_frame;
14
16
  private load_ase_frame;
15
17
  private parse_ase_metadata;