matterviz 0.3.7 → 0.4.1

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 (486) hide show
  1. package/dist/Icon.svelte +7 -4
  2. package/dist/MillerIndexInput.svelte +1 -1
  3. package/dist/api/optimade.js +32 -26
  4. package/dist/app.css +0 -3
  5. package/dist/brillouin/BrillouinZone.svelte +76 -148
  6. package/dist/brillouin/BrillouinZone.svelte.d.ts +6 -14
  7. package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
  8. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
  10. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  11. package/dist/brillouin/BrillouinZoneScene.svelte +97 -205
  12. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +4 -23
  13. package/dist/brillouin/BrillouinZoneTooltip.svelte +16 -25
  14. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  15. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  16. package/dist/brillouin/compute.d.ts +2 -0
  17. package/dist/brillouin/compute.js +89 -90
  18. package/dist/brillouin/geometry.d.ts +8 -0
  19. package/dist/brillouin/geometry.js +57 -0
  20. package/dist/brillouin/index.d.ts +2 -0
  21. package/dist/brillouin/index.js +2 -0
  22. package/dist/brillouin/types.d.ts +2 -2
  23. package/dist/chempot-diagram/ChemPotDiagram.svelte +14 -13
  24. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  25. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +109 -203
  26. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  27. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +180 -470
  28. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  29. package/dist/chempot-diagram/async-compute.svelte.js +3 -1
  30. package/dist/chempot-diagram/chempot-worker.js +2 -1
  31. package/dist/chempot-diagram/color.d.ts +3 -6
  32. package/dist/chempot-diagram/color.js +5 -5
  33. package/dist/chempot-diagram/compute.d.ts +4 -4
  34. package/dist/chempot-diagram/compute.js +20 -20
  35. package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
  36. package/dist/chempot-diagram/controls-state.svelte.js +42 -0
  37. package/dist/chempot-diagram/export.d.ts +47 -0
  38. package/dist/chempot-diagram/export.js +133 -0
  39. package/dist/chempot-diagram/index.d.ts +1 -0
  40. package/dist/chempot-diagram/index.js +1 -0
  41. package/dist/chempot-diagram/pointer.d.ts +0 -10
  42. package/dist/chempot-diagram/pointer.js +4 -4
  43. package/dist/chempot-diagram/types.d.ts +3 -3
  44. package/dist/colors/index.js +8 -7
  45. package/dist/composition/FormulaFilter.svelte +18 -11
  46. package/dist/composition/PieChart.svelte +11 -10
  47. package/dist/composition/chem-sys.d.ts +8 -0
  48. package/dist/composition/chem-sys.js +86 -0
  49. package/dist/composition/format.js +7 -4
  50. package/dist/composition/index.d.ts +1 -0
  51. package/dist/composition/index.js +1 -0
  52. package/dist/composition/parse.d.ts +0 -1
  53. package/dist/composition/parse.js +41 -31
  54. package/dist/controls.d.ts +1 -0
  55. package/dist/controls.js +0 -1
  56. package/dist/convex-hull/ConvexHull.svelte +8 -10
  57. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  58. package/dist/convex-hull/ConvexHull2D.svelte +106 -185
  59. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  60. package/dist/convex-hull/ConvexHull3D.svelte +179 -683
  61. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  62. package/dist/convex-hull/ConvexHull4D.svelte +183 -687
  63. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  64. package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
  65. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  66. package/dist/convex-hull/ConvexHullControls.svelte +88 -7
  67. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  68. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  69. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  70. package/dist/convex-hull/ConvexHullStats.svelte +36 -175
  71. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  72. package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
  73. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  74. package/dist/convex-hull/GasPressureControls.svelte +4 -4
  75. package/dist/convex-hull/TemperatureSlider.svelte +2 -2
  76. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  77. package/dist/convex-hull/barycentric-coords.js +6 -33
  78. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  79. package/dist/convex-hull/canvas-interactions.svelte.js +278 -0
  80. package/dist/convex-hull/demo-temperature.d.ts +1 -1
  81. package/dist/convex-hull/demo-temperature.js +20 -22
  82. package/dist/convex-hull/gas-thermodynamics.d.ts +2 -2
  83. package/dist/convex-hull/gas-thermodynamics.js +22 -30
  84. package/dist/convex-hull/helpers.d.ts +42 -7
  85. package/dist/convex-hull/helpers.js +171 -78
  86. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  87. package/dist/convex-hull/hull-state.svelte.js +124 -0
  88. package/dist/convex-hull/index.d.ts +10 -8
  89. package/dist/convex-hull/index.js +7 -2
  90. package/dist/convex-hull/thermodynamics.js +136 -960
  91. package/dist/convex-hull/types.d.ts +13 -5
  92. package/dist/convex-hull/types.js +12 -0
  93. package/dist/coordination/CoordinationBarPlot.svelte +27 -34
  94. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  95. package/dist/element/BohrAtom.svelte +2 -1
  96. package/dist/element/index.d.ts +4 -0
  97. package/dist/element/index.js +18 -0
  98. package/dist/feedback/DragOverlay.svelte +3 -1
  99. package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
  100. package/dist/feedback/StatusMessage.svelte +13 -3
  101. package/dist/fermi-surface/FermiSlice.svelte +13 -5
  102. package/dist/fermi-surface/FermiSurface.svelte +78 -151
  103. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
  104. package/dist/fermi-surface/FermiSurfaceControls.svelte +1 -1
  105. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  106. package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -221
  107. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  108. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +8 -34
  109. package/dist/fermi-surface/compute.js +67 -66
  110. package/dist/fermi-surface/export.js +6 -16
  111. package/dist/fermi-surface/index.d.ts +0 -1
  112. package/dist/fermi-surface/index.js +0 -1
  113. package/dist/fermi-surface/parse.d.ts +1 -1
  114. package/dist/fermi-surface/parse.js +71 -79
  115. package/dist/fermi-surface/types.d.ts +3 -2
  116. package/dist/heatmap-matrix/HeatmapMatrix.svelte +69 -52
  117. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
  118. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
  119. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  120. package/dist/heatmap-matrix/index.d.ts +3 -2
  121. package/dist/heatmap-matrix/index.js +1 -1
  122. package/dist/index.d.ts +1 -0
  123. package/dist/index.js +1 -0
  124. package/dist/io/ExportPane.svelte +166 -0
  125. package/dist/io/ExportPane.svelte.d.ts +17 -0
  126. package/dist/io/decompress.js +5 -4
  127. package/dist/io/export.d.ts +9 -5
  128. package/dist/io/export.js +77 -51
  129. package/dist/io/fetch.d.ts +2 -1
  130. package/dist/io/fetch.js +5 -1
  131. package/dist/io/file-drop.d.ts +8 -1
  132. package/dist/io/file-drop.js +48 -36
  133. package/dist/io/index.d.ts +2 -0
  134. package/dist/io/index.js +10 -0
  135. package/dist/io/types.d.ts +13 -0
  136. package/dist/io/url-drop.js +64 -33
  137. package/dist/isosurface/parse.js +52 -51
  138. package/dist/isosurface/slice.js +5 -4
  139. package/dist/isosurface/types.js +1 -1
  140. package/dist/keyboard.d.ts +3 -0
  141. package/dist/keyboard.js +23 -0
  142. package/dist/labels.d.ts +1 -1
  143. package/dist/labels.js +9 -8
  144. package/dist/layout/FullscreenButton.svelte +33 -0
  145. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  146. package/dist/layout/FullscreenToggle.svelte +8 -14
  147. package/dist/layout/PropertyFilter.svelte +3 -2
  148. package/dist/layout/SettingsSection.svelte +1 -1
  149. package/dist/layout/ViewerChrome.svelte +116 -0
  150. package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
  151. package/dist/layout/fullscreen.d.ts +4 -0
  152. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  153. package/dist/layout/fullscreen.svelte.js +37 -0
  154. package/dist/layout/index.d.ts +3 -0
  155. package/dist/layout/index.js +3 -0
  156. package/dist/layout/json-tree/JsonNode.svelte +1 -1
  157. package/dist/layout/json-tree/JsonTree.svelte +2 -2
  158. package/dist/layout/json-tree/utils.js +5 -4
  159. package/dist/marching-cubes.js +8 -13
  160. package/dist/math.d.ts +12 -4
  161. package/dist/math.js +42 -30
  162. package/dist/overlays/DraggablePane.svelte +4 -4
  163. package/dist/overlays/index.d.ts +4 -0
  164. package/dist/periodic-table/PeriodicTable.svelte +27 -15
  165. package/dist/periodic-table/PropertySelect.svelte +1 -0
  166. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +9 -3
  167. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  168. package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
  169. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  170. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
  171. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  172. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
  173. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  174. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +1 -1
  175. package/dist/phase-diagram/build-diagram.js +2 -2
  176. package/dist/phase-diagram/colors.js +1 -1
  177. package/dist/phase-diagram/parse.d.ts +2 -1
  178. package/dist/phase-diagram/parse.js +6 -5
  179. package/dist/phase-diagram/types.d.ts +1 -1
  180. package/dist/phase-diagram/utils.d.ts +3 -3
  181. package/dist/phase-diagram/utils.js +8 -12
  182. package/dist/plot/{BarPlot.svelte → bar/BarPlot.svelte} +246 -841
  183. package/dist/plot/{BarPlot.svelte.d.ts → bar/BarPlot.svelte.d.ts} +8 -16
  184. package/dist/plot/{BarPlotControls.svelte → bar/BarPlotControls.svelte} +6 -5
  185. package/dist/plot/{BarPlotControls.svelte.d.ts → bar/BarPlotControls.svelte.d.ts} +3 -3
  186. package/dist/plot/{SpacegroupBarPlot.svelte → bar/SpacegroupBarPlot.svelte} +8 -7
  187. package/dist/plot/{SpacegroupBarPlot.svelte.d.ts → bar/SpacegroupBarPlot.svelte.d.ts} +1 -1
  188. package/dist/plot/bar/data.d.ts +40 -0
  189. package/dist/plot/bar/data.js +154 -0
  190. package/dist/plot/bar/geometry.d.ts +39 -0
  191. package/dist/plot/bar/geometry.js +60 -0
  192. package/dist/plot/bar/index.d.ts +3 -0
  193. package/dist/plot/bar/index.js +3 -0
  194. package/dist/plot/box/BoxPlot.svelte +1292 -0
  195. package/dist/plot/box/BoxPlot.svelte.d.ts +95 -0
  196. package/dist/plot/box/BoxPlotControls.svelte +109 -0
  197. package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
  198. package/dist/plot/box/Violin.svelte +14 -0
  199. package/dist/plot/box/Violin.svelte.d.ts +70 -0
  200. package/dist/plot/box/box-plot.d.ts +56 -0
  201. package/dist/plot/box/box-plot.js +129 -0
  202. package/dist/plot/box/index.d.ts +5 -0
  203. package/dist/plot/box/index.js +5 -0
  204. package/dist/plot/box/kde.d.ts +17 -0
  205. package/dist/plot/box/kde.js +160 -0
  206. package/dist/plot/box/quantile.d.ts +3 -0
  207. package/dist/plot/box/quantile.js +53 -0
  208. package/dist/plot/{auto-place.d.ts → core/auto-place.d.ts} +1 -1
  209. package/dist/plot/{auto-place.js → core/auto-place.js} +6 -3
  210. package/dist/plot/core/axis-utils.d.ts +46 -0
  211. package/dist/plot/core/axis-utils.js +110 -0
  212. package/dist/plot/{AxisLabel.svelte → core/components/AxisLabel.svelte} +2 -2
  213. package/dist/plot/{AxisLabel.svelte.d.ts → core/components/AxisLabel.svelte.d.ts} +1 -1
  214. package/dist/plot/{ColorBar.svelte → core/components/ColorBar.svelte} +41 -38
  215. package/dist/plot/{ColorBar.svelte.d.ts → core/components/ColorBar.svelte.d.ts} +7 -6
  216. package/dist/plot/{ColorScaleSelect.svelte → core/components/ColorScaleSelect.svelte} +4 -3
  217. package/dist/plot/{ColorScaleSelect.svelte.d.ts → core/components/ColorScaleSelect.svelte.d.ts} +2 -2
  218. package/dist/plot/core/components/ControlPane.svelte +46 -0
  219. package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
  220. package/dist/plot/{FillArea.svelte → core/components/FillArea.svelte} +17 -6
  221. package/dist/plot/{FillArea.svelte.d.ts → core/components/FillArea.svelte.d.ts} +1 -1
  222. package/dist/plot/{InteractiveAxisLabel.svelte → core/components/InteractiveAxisLabel.svelte} +3 -3
  223. package/dist/plot/{InteractiveAxisLabel.svelte.d.ts → core/components/InteractiveAxisLabel.svelte.d.ts} +2 -2
  224. package/dist/plot/{Line.svelte → core/components/Line.svelte} +33 -15
  225. package/dist/plot/{Line.svelte.d.ts → core/components/Line.svelte.d.ts} +3 -2
  226. package/dist/plot/{PlotAxis.svelte → core/components/PlotAxis.svelte} +9 -6
  227. package/dist/plot/{PlotAxis.svelte.d.ts → core/components/PlotAxis.svelte.d.ts} +5 -3
  228. package/dist/plot/{PlotControls.svelte → core/components/PlotControls.svelte} +17 -29
  229. package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
  230. package/dist/plot/{PlotLegend.svelte → core/components/PlotLegend.svelte} +21 -10
  231. package/dist/plot/{PlotLegend.svelte.d.ts → core/components/PlotLegend.svelte.d.ts} +3 -2
  232. package/dist/plot/{PlotTooltip.svelte → core/components/PlotTooltip.svelte} +17 -1
  233. package/dist/plot/{PlotTooltip.svelte.d.ts → core/components/PlotTooltip.svelte.d.ts} +8 -0
  234. package/dist/plot/{PortalSelect.svelte → core/components/PortalSelect.svelte} +11 -7
  235. package/dist/plot/{ReferenceLine.svelte → core/components/ReferenceLine.svelte} +3 -3
  236. package/dist/plot/{ReferenceLine.svelte.d.ts → core/components/ReferenceLine.svelte.d.ts} +1 -1
  237. package/dist/plot/{ReferenceLine3D.svelte → core/components/ReferenceLine3D.svelte} +5 -5
  238. package/dist/plot/{ReferenceLine3D.svelte.d.ts → core/components/ReferenceLine3D.svelte.d.ts} +5 -5
  239. package/dist/plot/{ReferencePlane.svelte → core/components/ReferencePlane.svelte} +8 -8
  240. package/dist/plot/{ReferencePlane.svelte.d.ts → core/components/ReferencePlane.svelte.d.ts} +5 -5
  241. package/dist/plot/{ZeroLines.svelte → core/components/ZeroLines.svelte} +3 -3
  242. package/dist/plot/{ZeroLines.svelte.d.ts → core/components/ZeroLines.svelte.d.ts} +3 -3
  243. package/dist/plot/{ZoomRect.svelte → core/components/ZoomRect.svelte} +1 -1
  244. package/dist/plot/{ZoomRect.svelte.d.ts → core/components/ZoomRect.svelte.d.ts} +1 -1
  245. package/dist/plot/core/components/index.d.ts +17 -0
  246. package/dist/plot/core/components/index.js +17 -0
  247. package/dist/plot/{data-cleaning.d.ts → core/data-cleaning.d.ts} +71 -1
  248. package/dist/plot/{data-cleaning.js → core/data-cleaning.js} +21 -23
  249. package/dist/plot/{data-transform.d.ts → core/data-transform.d.ts} +2 -2
  250. package/dist/plot/{data-transform.js → core/data-transform.js} +3 -3
  251. package/dist/plot/core/fill-utils.d.ts +34 -0
  252. package/dist/plot/core/fill-utils.js +391 -0
  253. package/dist/plot/core/index.d.ts +10 -0
  254. package/dist/plot/core/index.js +11 -0
  255. package/dist/plot/core/interactions.d.ts +39 -0
  256. package/dist/plot/core/interactions.js +209 -0
  257. package/dist/plot/{layout.d.ts → core/layout.d.ts} +1 -0
  258. package/dist/plot/{layout.js → core/layout.js} +16 -8
  259. package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
  260. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  261. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  262. package/dist/plot/core/placed-tween.svelte.js +68 -0
  263. package/dist/plot/{reference-line.d.ts → core/reference-line.d.ts} +11 -11
  264. package/dist/plot/{reference-line.js → core/reference-line.js} +29 -42
  265. package/dist/plot/core/scales.d.ts +40 -0
  266. package/dist/plot/{scales.js → core/scales.js} +94 -93
  267. package/dist/plot/core/svg.d.ts +3 -0
  268. package/dist/plot/core/svg.js +41 -0
  269. package/dist/plot/{types.d.ts → core/types.d.ts} +36 -85
  270. package/dist/plot/{types.js → core/types.js} +1 -1
  271. package/dist/plot/{utils → core/utils}/label-placement.d.ts +3 -3
  272. package/dist/plot/{utils → core/utils}/label-placement.js +3 -3
  273. package/dist/plot/core/utils/series-visibility.d.ts +26 -0
  274. package/dist/plot/{utils → core/utils}/series-visibility.js +29 -2
  275. package/dist/plot/core/utils.d.ts +12 -0
  276. package/dist/plot/core/utils.js +27 -0
  277. package/dist/plot/{Histogram.svelte → histogram/Histogram.svelte} +174 -551
  278. package/dist/plot/{Histogram.svelte.d.ts → histogram/Histogram.svelte.d.ts} +2 -2
  279. package/dist/plot/{HistogramControls.svelte → histogram/HistogramControls.svelte} +6 -6
  280. package/dist/plot/{HistogramControls.svelte.d.ts → histogram/HistogramControls.svelte.d.ts} +4 -4
  281. package/dist/plot/histogram/index.d.ts +2 -0
  282. package/dist/plot/histogram/index.js +2 -0
  283. package/dist/plot/index.d.ts +8 -41
  284. package/dist/plot/index.js +10 -39
  285. package/dist/plot/sankey/Sankey.svelte +697 -0
  286. package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
  287. package/dist/plot/sankey/SankeyControls.svelte +98 -0
  288. package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
  289. package/dist/plot/sankey/index.d.ts +4 -0
  290. package/dist/plot/sankey/index.js +3 -0
  291. package/dist/plot/sankey/sankey-types.d.ts +42 -0
  292. package/dist/plot/sankey/sankey-types.js +4 -0
  293. package/dist/plot/sankey/sankey.d.ts +52 -0
  294. package/dist/plot/sankey/sankey.js +189 -0
  295. package/dist/plot/{BinnedScatterPlot.svelte → scatter/BinnedScatterPlot.svelte} +64 -64
  296. package/dist/plot/{BinnedScatterPlot.svelte.d.ts → scatter/BinnedScatterPlot.svelte.d.ts} +6 -6
  297. package/dist/plot/{ElementScatter.svelte → scatter/ElementScatter.svelte} +6 -6
  298. package/dist/plot/{ElementScatter.svelte.d.ts → scatter/ElementScatter.svelte.d.ts} +2 -2
  299. package/dist/plot/{ScatterPlot.svelte → scatter/ScatterPlot.svelte} +297 -1008
  300. package/dist/plot/{ScatterPlot.svelte.d.ts → scatter/ScatterPlot.svelte.d.ts} +10 -18
  301. package/dist/plot/{ScatterPlotControls.svelte → scatter/ScatterPlotControls.svelte} +6 -5
  302. package/dist/plot/{ScatterPlotControls.svelte.d.ts → scatter/ScatterPlotControls.svelte.d.ts} +2 -2
  303. package/dist/plot/{ScatterPoint.svelte → scatter/ScatterPoint.svelte} +7 -7
  304. package/dist/plot/{ScatterPoint.svelte.d.ts → scatter/ScatterPoint.svelte.d.ts} +3 -3
  305. package/dist/plot/{adaptive-density.d.ts → scatter/adaptive-density.d.ts} +14 -4
  306. package/dist/plot/{adaptive-density.js → scatter/adaptive-density.js} +46 -20
  307. package/dist/plot/{binned-scatter-types.d.ts → scatter/binned-scatter-types.d.ts} +5 -12
  308. package/dist/plot/scatter/index.d.ts +7 -0
  309. package/dist/plot/scatter/index.js +5 -0
  310. package/dist/plot/scatter/scatter-data.d.ts +19 -0
  311. package/dist/plot/scatter/scatter-data.js +212 -0
  312. package/dist/plot/{ScatterPlot3D.svelte → scatter-3d/ScatterPlot3D.svelte} +25 -34
  313. package/dist/plot/{ScatterPlot3D.svelte.d.ts → scatter-3d/ScatterPlot3D.svelte.d.ts} +9 -17
  314. package/dist/plot/{ScatterPlot3DControls.svelte → scatter-3d/ScatterPlot3DControls.svelte} +14 -14
  315. package/dist/plot/{ScatterPlot3DControls.svelte.d.ts → scatter-3d/ScatterPlot3DControls.svelte.d.ts} +6 -6
  316. package/dist/plot/{ScatterPlot3DScene.svelte → scatter-3d/ScatterPlot3DScene.svelte} +129 -128
  317. package/dist/plot/{ScatterPlot3DScene.svelte.d.ts → scatter-3d/ScatterPlot3DScene.svelte.d.ts} +6 -15
  318. package/dist/plot/{Surface3D.svelte → scatter-3d/Surface3D.svelte} +7 -6
  319. package/dist/plot/{Surface3D.svelte.d.ts → scatter-3d/Surface3D.svelte.d.ts} +5 -4
  320. package/dist/plot/scatter-3d/index.d.ts +4 -0
  321. package/dist/plot/scatter-3d/index.js +4 -0
  322. package/dist/plot/sunburst/Sunburst.svelte +1041 -0
  323. package/dist/plot/sunburst/Sunburst.svelte.d.ts +97 -0
  324. package/dist/plot/sunburst/SunburstControls.svelte +200 -0
  325. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
  326. package/dist/plot/sunburst/index.d.ts +4 -0
  327. package/dist/plot/sunburst/index.js +4 -0
  328. package/dist/plot/sunburst/render.d.ts +34 -0
  329. package/dist/plot/sunburst/render.js +122 -0
  330. package/dist/plot/sunburst/sunburst.d.ts +62 -0
  331. package/dist/plot/sunburst/sunburst.js +269 -0
  332. package/dist/rdf/RdfPlot.svelte +2 -1
  333. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  334. package/dist/rdf/calc-rdf.js +11 -24
  335. package/dist/sanitize.js +14 -3
  336. package/dist/scene/SceneCamera.svelte +62 -0
  337. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  338. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  339. package/dist/scene/bind-renderer.svelte.js +14 -0
  340. package/dist/scene/index.d.ts +4 -0
  341. package/dist/scene/index.js +5 -0
  342. package/dist/scene/props.js +52 -0
  343. package/dist/scene/types.d.ts +26 -0
  344. package/dist/scene/types.js +1 -0
  345. package/dist/settings.d.ts +79 -3
  346. package/dist/settings.js +321 -1
  347. package/dist/spectral/Bands.svelte +47 -36
  348. package/dist/spectral/Bands.svelte.d.ts +6 -6
  349. package/dist/spectral/BandsAndDos.svelte +23 -25
  350. package/dist/spectral/BrillouinBandsDos.svelte +42 -30
  351. package/dist/spectral/Dos.svelte +15 -23
  352. package/dist/spectral/Dos.svelte.d.ts +4 -3
  353. package/dist/spectral/helpers.d.ts +8 -6
  354. package/dist/spectral/helpers.js +137 -65
  355. package/dist/state.svelte.d.ts +0 -7
  356. package/dist/state.svelte.js +0 -6
  357. package/dist/structure/Arrow.svelte +2 -4
  358. package/dist/structure/AtomLegend.svelte +8 -9
  359. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  360. package/dist/structure/CanvasTooltip.svelte +1 -0
  361. package/dist/structure/CellSelect.svelte +12 -5
  362. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  363. package/dist/structure/Cylinder.svelte +12 -8
  364. package/dist/structure/Cylinder.svelte.d.ts +4 -1
  365. package/dist/structure/Lattice.svelte +2 -2
  366. package/dist/structure/Structure.svelte +365 -423
  367. package/dist/structure/Structure.svelte.d.ts +5 -15
  368. package/dist/structure/StructureControls.svelte +217 -2
  369. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  370. package/dist/structure/StructureExportPane.svelte +54 -156
  371. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  372. package/dist/structure/StructureInfoPane.svelte +10 -9
  373. package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
  374. package/dist/structure/StructureScene.svelte +376 -208
  375. package/dist/structure/StructureScene.svelte.d.ts +22 -20
  376. package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
  377. package/dist/structure/{label-placement.js → atom-label-placement.js} +15 -5
  378. package/dist/structure/atom-properties.d.ts +1 -1
  379. package/dist/structure/atom-properties.js +17 -22
  380. package/dist/structure/bond-order-perception.js +3 -5
  381. package/dist/structure/bonding.d.ts +4 -0
  382. package/dist/structure/bonding.js +134 -63
  383. package/dist/structure/export.d.ts +24 -4
  384. package/dist/structure/export.js +89 -143
  385. package/dist/structure/index.d.ts +4 -4
  386. package/dist/structure/index.js +3 -3
  387. package/dist/structure/measure.d.ts +3 -2
  388. package/dist/structure/measure.js +6 -5
  389. package/dist/structure/parse.d.ts +3 -2
  390. package/dist/structure/parse.js +419 -438
  391. package/dist/structure/partial-occupancy.d.ts +0 -1
  392. package/dist/structure/partial-occupancy.js +1 -1
  393. package/dist/structure/pbc.d.ts +1 -1
  394. package/dist/structure/pbc.js +190 -13
  395. package/dist/structure/polyhedra.d.ts +41 -0
  396. package/dist/structure/polyhedra.js +602 -0
  397. package/dist/structure/site.d.ts +4 -0
  398. package/dist/structure/site.js +1 -0
  399. package/dist/structure/supercell.js +3 -2
  400. package/dist/structure/validation.js +5 -6
  401. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  402. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  403. package/dist/symmetry/SymmetryElements.svelte +354 -0
  404. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  405. package/dist/symmetry/SymmetryStats.svelte +113 -8
  406. package/dist/symmetry/WyckoffTable.svelte +68 -7
  407. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  408. package/dist/symmetry/cell-transform.js +7 -14
  409. package/dist/symmetry/index.d.ts +14 -4
  410. package/dist/symmetry/index.js +291 -72
  411. package/dist/symmetry/spacegroups.d.ts +12 -1
  412. package/dist/symmetry/spacegroups.js +63 -14
  413. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  414. package/dist/symmetry/symmetry-elements.js +521 -0
  415. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  416. package/dist/symmetry/wyckoff-db.js +87 -0
  417. package/dist/table/HeatmapTable.svelte +66 -25
  418. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  419. package/dist/table/index.d.ts +1 -3
  420. package/dist/table/index.js +1 -1
  421. package/dist/theme/index.js +8 -8
  422. package/dist/tooltip/KCoords.svelte +45 -0
  423. package/dist/tooltip/KCoords.svelte.d.ts +8 -0
  424. package/dist/tooltip/index.d.ts +1 -0
  425. package/dist/tooltip/index.js +1 -0
  426. package/dist/trajectory/Trajectory.svelte +123 -100
  427. package/dist/trajectory/Trajectory.svelte.d.ts +11 -22
  428. package/dist/trajectory/TrajectoryExportPane.svelte +17 -25
  429. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  430. package/dist/trajectory/TrajectoryInfoPane.svelte +5 -3
  431. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  432. package/dist/trajectory/constants.js +6 -2
  433. package/dist/trajectory/extract.js +17 -37
  434. package/dist/trajectory/format-detect.d.ts +1 -1
  435. package/dist/trajectory/format-detect.js +27 -19
  436. package/dist/trajectory/frame-reader.d.ts +0 -1
  437. package/dist/trajectory/frame-reader.js +63 -162
  438. package/dist/trajectory/helpers.d.ts +10 -2
  439. package/dist/trajectory/helpers.js +56 -36
  440. package/dist/trajectory/index.js +1 -1
  441. package/dist/trajectory/parse/ase.d.ts +9 -1
  442. package/dist/trajectory/parse/ase.js +47 -32
  443. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  444. package/dist/trajectory/parse/diagnostics.js +14 -0
  445. package/dist/trajectory/parse/hdf5.js +1 -1
  446. package/dist/trajectory/parse/index.d.ts +1 -1
  447. package/dist/trajectory/parse/index.js +65 -105
  448. package/dist/trajectory/parse/lammps.d.ts +0 -2
  449. package/dist/trajectory/parse/lammps.js +8 -6
  450. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  451. package/dist/trajectory/parse/pymatgen.js +74 -0
  452. package/dist/trajectory/parse/vasp.js +38 -18
  453. package/dist/trajectory/parse/xyz.d.ts +13 -1
  454. package/dist/trajectory/parse/xyz.js +102 -94
  455. package/dist/trajectory/plotting.d.ts +1 -2
  456. package/dist/trajectory/plotting.js +16 -113
  457. package/dist/utils.d.ts +2 -0
  458. package/dist/utils.js +7 -5
  459. package/dist/xrd/XrdPlot.svelte +16 -30
  460. package/dist/xrd/broadening.d.ts +2 -1
  461. package/dist/xrd/calc-xrd.js +18 -20
  462. package/dist/xrd/index.d.ts +2 -2
  463. package/dist/xrd/parse.js +2 -2
  464. package/package.json +43 -26
  465. package/dist/element/data.json +0 -11864
  466. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  467. package/dist/fermi-surface/marching-cubes.js +0 -2
  468. package/dist/plot/PlotControls.svelte.d.ts +0 -4
  469. package/dist/plot/axis-utils.d.ts +0 -19
  470. package/dist/plot/axis-utils.js +0 -78
  471. package/dist/plot/defaults.d.ts +0 -19
  472. package/dist/plot/defaults.js +0 -9
  473. package/dist/plot/fill-utils.d.ts +0 -46
  474. package/dist/plot/fill-utils.js +0 -322
  475. package/dist/plot/hover-lock.svelte.d.ts +0 -14
  476. package/dist/plot/hover-lock.svelte.js +0 -46
  477. package/dist/plot/interactions.d.ts +0 -12
  478. package/dist/plot/interactions.js +0 -101
  479. package/dist/plot/scales.d.ts +0 -48
  480. package/dist/plot/svg.d.ts +0 -1
  481. package/dist/plot/svg.js +0 -11
  482. package/dist/plot/utils/series-visibility.d.ts +0 -15
  483. package/dist/plot/utils.d.ts +0 -1
  484. package/dist/plot/utils.js +0 -14
  485. /package/dist/plot/{PortalSelect.svelte.d.ts → core/components/PortalSelect.svelte.d.ts} +0 -0
  486. /package/dist/plot/{binned-scatter-types.js → scatter/binned-scatter-types.js} +0 -0
@@ -0,0 +1,74 @@
1
+ import * as math from '../../math';
2
+ import { calc_force_stats, create_trajectory_frame, validate_3x3_matrix, } from '../helpers';
3
+ import { is_plain_object } from '../../utils';
4
+ import { traj_warn } from './diagnostics';
5
+ // Non-empty array of pymatgen Species-like objects with non-empty string element
6
+ // symbols (predicate so callers get narrowing; rejects e.g. { element: null })
7
+ const is_species_array = (val) => Array.isArray(val) &&
8
+ val.length > 0 &&
9
+ val.every((sp) => sp != null &&
10
+ typeof sp === `object` &&
11
+ `element` in sp &&
12
+ typeof sp.element === `string` &&
13
+ sp.element.trim().length > 0);
14
+ // Parse an already-JSON-parsed pymatgen Trajectory object (detected via @class === 'Trajectory' with species/coords/lattice present)
15
+ export function parse_pymatgen_trajectory(obj, filename) {
16
+ // Validate shape upfront so malformed input fails with a clear message
17
+ // (callers gate only on truthiness, not structure) rather than a cryptic `.map` error
18
+ if (!is_species_array(obj.species)) {
19
+ throw new TypeError(`Invalid pymatgen Trajectory: 'species' must be a non-empty array of { element } objects`);
20
+ }
21
+ if (!Array.isArray(obj.coords)) {
22
+ throw new TypeError(`Invalid pymatgen Trajectory: 'coords' must be an array of frames`);
23
+ }
24
+ const frame_elements = obj.species.map((specie) => specie.element);
25
+ const coords = obj.coords;
26
+ const matrix = validate_3x3_matrix(obj.lattice);
27
+ const frame_properties = obj.frame_properties || [];
28
+ const frac_to_cart = math.create_frac_to_cart(matrix);
29
+ const frames = coords.map((frame_coords, idx) => {
30
+ const positions = frame_coords.map((abc) => frac_to_cart(abc));
31
+ // Process frame properties to extract numpy arrays
32
+ const raw_properties = frame_properties[idx] || {};
33
+ const processed_properties = {};
34
+ Object.entries(raw_properties).forEach(([key, value]) => {
35
+ if (is_plain_object(value) && value[`@class`] === `array`) {
36
+ processed_properties[key] = value.data;
37
+ if (key === `forces` && Array.isArray(value.data)) {
38
+ // Object.assign ignores the null calc_force_stats returns for empty forces
39
+ Object.assign(processed_properties, calc_force_stats(value.data));
40
+ }
41
+ if (key === `stress` && Array.isArray(value.data)) {
42
+ const stress_tensor = value.data;
43
+ if (!math.is_square_matrix(stress_tensor, 3)) {
44
+ traj_warn(`Invalid stress tensor structure in frame ${idx}`);
45
+ }
46
+ else {
47
+ // Calculate stress components (diagonal elements represent normal stresses)
48
+ const normal_stresses = [
49
+ stress_tensor[0][0],
50
+ stress_tensor[1][1],
51
+ stress_tensor[2][2],
52
+ ];
53
+ processed_properties.stress_max = Math.max(...normal_stresses.map(Math.abs));
54
+ // Calculate hydrostatic pressure (negative of mean normal stress)
55
+ processed_properties.pressure =
56
+ -(normal_stresses[0] + normal_stresses[1] + normal_stresses[2]) / 3;
57
+ }
58
+ }
59
+ }
60
+ else {
61
+ processed_properties[key] = value;
62
+ }
63
+ });
64
+ return create_trajectory_frame(positions, frame_elements, matrix, [true, true, true], idx, processed_properties);
65
+ });
66
+ const metadata = {
67
+ filename,
68
+ source_format: `pymatgen_trajectory`,
69
+ frame_count: frames.length,
70
+ species_list: [...new Set(frame_elements)],
71
+ periodic_boundary_conditions: [true, true, true],
72
+ };
73
+ return { frames, metadata };
74
+ }
@@ -1,42 +1,62 @@
1
1
  import * as math from '../../math';
2
- import { create_trajectory_frame, is_valid_element_symbol, validate_3x3_matrix, } from '../helpers';
2
+ import { is_elem_symbol } from '../../element';
3
+ import { create_trajectory_frame, validate_3x3_matrix } from '../helpers';
4
+ // Parse the 7-line XDATCAR header at lines[start]: title, scale factor, 3 lattice rows
5
+ // (multiplied by scale), element names, element counts
6
+ function parse_xdatcar_header(lines, start) {
7
+ const scale = parseFloat(lines[start + 1]);
8
+ const rows = lines.slice(start + 2, start + 5).map((line) => line
9
+ .trim()
10
+ .split(/\s+/)
11
+ .map((val) => parseFloat(val) * scale));
12
+ const names = lines[start + 5].trim().split(/\s+/);
13
+ const counts = lines[start + 6].trim().split(/\s+/).map(Number);
14
+ return { scale, rows, names, counts };
15
+ }
3
16
  export function parse_vasp_xdatcar(content, filename) {
4
17
  const lines = content.trim().split(/\r?\n/);
5
18
  if (lines.length < 10)
6
19
  throw new Error(`XDATCAR file too short`);
7
- const scale = parseFloat(lines[1]);
8
- if (isNaN(scale))
20
+ const header = parse_xdatcar_header(lines, 0);
21
+ const { names: element_names, counts: element_counts } = header;
22
+ if (isNaN(header.scale))
9
23
  throw new Error(`Invalid scale factor`);
10
- const lattice_matrix = validate_3x3_matrix(lines.slice(2, 5).map((line) => line
11
- .trim()
12
- .split(/\s+/)
13
- .map((component) => parseFloat(component) * scale)));
14
- const element_names = lines[5].trim().split(/\s+/);
15
- const element_counts = lines[6].trim().split(/\s+/).map(Number);
24
+ let lattice_matrix = validate_3x3_matrix(header.rows);
16
25
  if (element_names.length !== element_counts.length) {
17
26
  throw new Error(`XDATCAR element names/counts mismatch: names=${element_names.length}, counts=${element_counts.length}`);
18
27
  }
19
28
  if (element_counts.some((count) => !Number.isFinite(count) || !Number.isInteger(count) || count <= 0)) {
20
29
  throw new Error(`XDATCAR contains invalid element counts: expected finite positive integers`);
21
30
  }
22
- const validated_element_names = element_names.map((name) => {
23
- if (!is_valid_element_symbol(name)) {
24
- throw new Error(`Invalid element symbol in XDATCAR: ${name}`);
25
- }
26
- return name;
27
- });
28
- const elements = validated_element_names.flatMap((name, idx) => Array(element_counts[idx]).fill(name));
31
+ const bad_element = element_names.find((name) => !is_elem_symbol(name));
32
+ if (bad_element)
33
+ throw new Error(`Invalid element symbol in XDATCAR: ${bad_element}`);
34
+ let elements = element_names.flatMap((name, idx) => Array(element_counts[idx]).fill(name));
29
35
  const frames = [];
30
36
  let line_idx = 7;
31
- const frac_to_cart = math.create_frac_to_cart(lattice_matrix);
37
+ let frac_to_cart = math.create_frac_to_cart(lattice_matrix);
32
38
  while (line_idx < lines.length) {
33
39
  const config_idx = lines.findIndex((line, idx) => idx >= line_idx && line.includes(`Direct configuration=`));
34
40
  if (config_idx === -1)
35
41
  break;
42
+ // Variable-cell runs (NPT/ISIF=3) repeat the full 7-line header before each configuration
43
+ if (config_idx - line_idx >= 7) {
44
+ const hdr = parse_xdatcar_header(lines, config_idx - 7);
45
+ if (Number.isFinite(hdr.scale) &&
46
+ hdr.rows.every((row) => row.length === 3 && row.every(Number.isFinite))) {
47
+ lattice_matrix = validate_3x3_matrix(hdr.rows);
48
+ frac_to_cart = math.create_frac_to_cart(lattice_matrix);
49
+ if (hdr.names.length === hdr.counts.length &&
50
+ hdr.names.every(is_elem_symbol) &&
51
+ hdr.counts.every((count) => Number.isInteger(count) && count > 0)) {
52
+ elements = hdr.names.flatMap((name, idx) => Array(hdr.counts[idx]).fill(name));
53
+ }
54
+ }
55
+ }
36
56
  const config_line = lines[config_idx];
37
57
  line_idx = config_idx + 1;
38
58
  const step_match = /configuration=\s*(\d+)/.exec(config_line);
39
- const step = step_match ? parseInt(step_match[1]) : frames.length + 1;
59
+ const step = step_match ? parseInt(step_match[1], 10) : frames.length + 1;
40
60
  const positions = [];
41
61
  for (let idx = 0; idx < elements.length && line_idx < lines.length; idx++) {
42
62
  const coords = lines[line_idx].trim().split(/\s+/).slice(0, 3).map(Number);
@@ -1,2 +1,14 @@
1
- import type { TrajectoryType } from '../index';
1
+ import type { TrajectoryFrame, TrajectoryType } from '../index';
2
+ export declare function parse_xyz_comment_metadata(comment: string): {
3
+ step?: number;
4
+ properties: Record<string, number>;
5
+ };
6
+ export declare function build_xyz_frame(lines: string[], frame: {
7
+ start: number;
8
+ num_atoms: number;
9
+ comment: string;
10
+ }, opts: {
11
+ frame_label: string;
12
+ default_step: number;
13
+ }): TrajectoryFrame;
2
14
  export declare function parse_xyz_trajectory(content: string): TrajectoryType;
@@ -1,103 +1,111 @@
1
1
  import * as math from '../../math';
2
- import { coerce_element_symbol, create_trajectory_frame } from '../helpers';
3
- export function parse_xyz_trajectory(content) {
4
- const lines = content.trim().split(/\r?\n/);
5
- const frames = [];
6
- let line_idx = 0;
7
- while (line_idx < lines.length) {
8
- if (!lines[line_idx]?.trim()) {
9
- line_idx++;
10
- continue;
2
+ import { coerce_elem_symbol } from '../../element';
3
+ import { calc_force_stats, create_trajectory_frame, iter_xyz_frames, } from '../helpers';
4
+ import { traj_warn } from './diagnostics';
5
+ // Resolve species/pos/forces column offsets from an extxyz Properties string of
6
+ // name:type:ncols triples (e.g. "species:S:1:pos:R:3:forces:R:3"), falling back
7
+ // to the conventional "symbol x y z" layout when absent or malformed
8
+ function parse_extxyz_columns(comment) {
9
+ const fields = /Properties\s*=\s*"?([^"\s]+)"?/i.exec(comment)?.[1].split(`:`) ?? [];
10
+ // Well-formed Properties is name:type:ncols triples; a non-multiple of 3 is malformed,
11
+ // so bail to the conventional default rather than trusting a partial layout
12
+ let layout = fields.length % 3 === 0 ? {} : null;
13
+ for (let idx = 0, offset = 0; layout && idx + 3 <= fields.length; idx += 3) {
14
+ const ncols = parseInt(fields[idx + 2], 10);
15
+ if (Number.isInteger(ncols) && ncols > 0) {
16
+ layout[fields[idx].toLowerCase()] = { offset, ncols };
17
+ offset += ncols;
11
18
  }
12
- const num_atoms = parseInt(lines[line_idx].trim(), 10);
13
- if (isNaN(num_atoms) || num_atoms <= 0 || line_idx + num_atoms + 1 >= lines.length) {
14
- line_idx++;
19
+ else
20
+ layout = null;
21
+ }
22
+ const species_col = layout?.species?.offset ?? 0;
23
+ const pos_col = layout?.pos?.offset ?? 1;
24
+ const forces_col = layout?.forces && layout.forces.ncols >= 3 ? layout.forces.offset : -1;
25
+ return { species_col, pos_col, forces_col, min_cols: Math.max(pos_col + 3, species_col + 1) };
26
+ }
27
+ // Parse Lattice="ax ay az bx by bz cx cy cz" from an extxyz comment line
28
+ function parse_extxyz_lattice(comment) {
29
+ const vals = /Lattice\s*=\s*"([^"]+)"/i.exec(comment)?.[1].trim().split(/\s+/).map(Number);
30
+ if (vals?.length !== 9 || !vals.every(Number.isFinite))
31
+ return undefined;
32
+ return [vals.slice(0, 3), vals.slice(3, 6), vals.slice(6, 9)];
33
+ }
34
+ // Keys anchored at ^|\s and followed by [=:] so single-letter keys (E/V/P/T) don't match mid-word
35
+ const make_pattern = (keys) => new RegExp(`(?:^|\\s)(?:${keys})\\s*[=:]\\s*([-+]?\\d*\\.?\\d+(?:[eE][-+]?\\d+)?)`, `i`);
36
+ const METADATA_PATTERNS = {
37
+ energy: make_pattern(`energy|E|etot|total_energy`),
38
+ volume: make_pattern(`volume|vol|V`),
39
+ pressure: make_pattern(`pressure|press|P`),
40
+ temperature: make_pattern(`temperature|temp|T`),
41
+ force_max: make_pattern(`max_force|force_max|fmax`),
42
+ bandgap: make_pattern(`bandgap|E_gap|gap`),
43
+ };
44
+ // Extract step number and scalar properties from an (ext)XYZ comment line
45
+ export function parse_xyz_comment_metadata(comment) {
46
+ const properties = {};
47
+ for (const [key, pattern] of Object.entries(METADATA_PATTERNS)) {
48
+ const match = pattern.exec(comment);
49
+ if (match)
50
+ properties[key] = parseFloat(match[1]);
51
+ }
52
+ const step = /(?:^|\s)(?:step|frame|ionic_step)\s*[=:]?\s*(\d+)/i.exec(comment)?.[1];
53
+ return { step: step ? parseInt(step, 10) : undefined, properties };
54
+ }
55
+ // Parse num_atoms atom lines starting at lines[start], reading species/pos/forces from
56
+ // their Properties-declared column offsets; invalid atoms are skipped with a warning.
57
+ // force_stats holds raw forces plus max and RMS force magnitudes when forces are present.
58
+ function parse_xyz_atom_lines(lines, start, num_atoms, comment, frame_label) {
59
+ const { species_col, pos_col, forces_col, min_cols } = parse_extxyz_columns(comment);
60
+ const elements = [];
61
+ const positions = [];
62
+ const forces = [];
63
+ for (let idx = 0; idx < num_atoms; idx++) {
64
+ const parts = lines[start + idx]?.trim().split(/\s+/) ?? [];
65
+ if (parts.length < min_cols)
66
+ continue;
67
+ const pos = parts.slice(pos_col, pos_col + 3).map(parseFloat);
68
+ if (!pos.every(Number.isFinite)) {
69
+ traj_warn(`Skipping XYZ atom with invalid coordinates in ${frame_label} at line ${start + idx + 1}`);
15
70
  continue;
16
71
  }
17
- const comment = lines[++line_idx] || ``;
18
- const metadata = {};
19
- // Extract properties efficiently
20
- const extractors = {
21
- step: /(?:step|frame|ionic_step)\s*[=:]?\s*(\d+)/i,
22
- energy: /(?:energy|E|etot|total_energy)\s*[=:]?\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/i,
23
- volume: /(?:volume|vol|V)\s*[=:]?\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/i,
24
- pressure: /(?:pressure|press|P)\s*[=:]?\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/i,
25
- temperature: /(?:temperature|temp|T)\s*[=:]?\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/i,
26
- force_max: /(?:max_force|force_max|fmax)\s*[=:]?\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/i,
27
- bandgap: /(?:bandgap|E_gap|gap)\s*[=:]?\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/i,
28
- };
29
- const step_match = extractors.step.exec(comment);
30
- const step = step_match?.[1] ? parseInt(step_match[1]) : frames.length;
31
- Object.entries(extractors).forEach(([key, pattern]) => {
32
- if (key === `step`)
33
- return;
34
- const match = pattern.exec(comment);
35
- if (match)
36
- metadata[key] = parseFloat(match[1]);
37
- });
38
- // Extract lattice matrix
39
- const lattice_match = /Lattice\s*=\s*"([^"]+)"/i.exec(comment);
40
- let lattice_matrix;
41
- if (lattice_match) {
42
- const values = lattice_match[1].split(/\s+/).map(Number);
43
- if (values.length === 9 && values.every((value) => Number.isFinite(value))) {
44
- lattice_matrix = [
45
- [values[0], values[1], values[2]],
46
- [values[3], values[4], values[5]],
47
- [values[6], values[7], values[8]],
48
- ];
49
- metadata.volume = math.calc_lattice_params(lattice_matrix).volume;
50
- }
51
- }
52
- // Parse atoms
53
- const positions = [];
54
- const elements = [];
55
- const forces = [];
56
- const has_forces = comment.includes(`forces:R:3`);
57
- for (let idx = 0; idx < num_atoms; idx++) {
58
- line_idx++;
59
- if (line_idx >= lines.length)
60
- break;
61
- const parts = lines[line_idx].trim().split(/\s+/);
62
- if (parts.length >= 4) {
63
- const x_coord = parseFloat(parts[1]);
64
- const y_coord = parseFloat(parts[2]);
65
- const z_coord = parseFloat(parts[3]);
66
- if (!Number.isFinite(x_coord) ||
67
- !Number.isFinite(y_coord) ||
68
- !Number.isFinite(z_coord)) {
69
- console.warn(`Skipping XYZ atom with invalid coordinates in frame ${frames.length} at line ${line_idx + 1}`);
70
- continue;
71
- }
72
- const raw_symbol = parts[0];
73
- const element_symbol = coerce_element_symbol(raw_symbol);
74
- if (!element_symbol) {
75
- console.warn(`Skipping XYZ atom with unknown element symbol "${raw_symbol}" in frame ${frames.length}`);
76
- continue;
77
- }
78
- elements.push(element_symbol);
79
- positions.push([x_coord, y_coord, z_coord]);
80
- if (has_forces && parts.length >= 7) {
81
- const force_x = parseFloat(parts[4]);
82
- const force_y = parseFloat(parts[5]);
83
- const force_z = parseFloat(parts[6]);
84
- if (Number.isFinite(force_x) &&
85
- Number.isFinite(force_y) &&
86
- Number.isFinite(force_z)) {
87
- forces.push([force_x, force_y, force_z]);
88
- }
89
- }
90
- }
72
+ const symbol = parts[species_col];
73
+ const element_symbol = coerce_elem_symbol(symbol);
74
+ if (!element_symbol) {
75
+ traj_warn(`Skipping XYZ atom with unknown element symbol "${symbol}" in ${frame_label}`);
76
+ continue;
91
77
  }
92
- if (forces.length > 0) {
93
- metadata.forces = forces;
94
- const magnitudes = forces.map((force) => Math.hypot(...force));
95
- metadata.force_max = Math.max(...magnitudes);
96
- // Calculate RMS (root mean square) of force magnitudes
97
- metadata.force_norm = Math.sqrt(magnitudes.reduce((sum, mag) => sum + mag ** 2, 0) / magnitudes.length);
78
+ elements.push(element_symbol);
79
+ positions.push(pos);
80
+ if (forces_col >= 0 && parts.length >= forces_col + 3) {
81
+ const force_vec = parts.slice(forces_col, forces_col + 3).map(parseFloat);
82
+ if (force_vec.every(Number.isFinite))
83
+ forces.push(force_vec);
98
84
  }
99
- frames.push(create_trajectory_frame(positions, elements, lattice_matrix, lattice_matrix ? [true, true, true] : undefined, step, metadata));
100
- line_idx++;
85
+ }
86
+ const stats = calc_force_stats(forces);
87
+ return { elements, positions, force_stats: stats && { forces, ...stats } };
88
+ }
89
+ // Assemble a TrajectoryFrame from the XYZ frame starting at lines[start] (count line,
90
+ // comment line, atom lines). Shared by the eager parser and the indexed frame reader.
91
+ export function build_xyz_frame(lines, frame, opts) {
92
+ const { start, num_atoms, comment } = frame;
93
+ const { step, properties } = parse_xyz_comment_metadata(comment);
94
+ const lattice_matrix = parse_extxyz_lattice(comment);
95
+ const { elements, positions, force_stats } = parse_xyz_atom_lines(lines, start + 2, num_atoms, comment, opts.frame_label);
96
+ const metadata = { ...properties, ...force_stats };
97
+ if (lattice_matrix)
98
+ metadata.volume = math.calc_lattice_params(lattice_matrix).volume;
99
+ return create_trajectory_frame(positions, elements, lattice_matrix, lattice_matrix ? [true, true, true] : undefined, step ?? opts.default_step, metadata);
100
+ }
101
+ export function parse_xyz_trajectory(content) {
102
+ const lines = content.trim().split(/\r?\n/);
103
+ const frames = [];
104
+ for (const frame of iter_xyz_frames(lines)) {
105
+ frames.push(build_xyz_frame(lines, frame, {
106
+ frame_label: `frame ${frames.length}`,
107
+ default_step: frames.length,
108
+ }));
101
109
  }
102
110
  return {
103
111
  frames,
@@ -1,4 +1,4 @@
1
- import type { DataSeries } from '../plot/types';
1
+ import type { DataSeries } from '../plot/core/types';
2
2
  import type { TrajectoryDataExtractor, TrajectoryMetadata, TrajectoryType } from './index';
3
3
  export interface PlotSeriesOptions {
4
4
  property_config?: Record<string, {
@@ -9,7 +9,6 @@ export interface PlotSeriesOptions {
9
9
  default_visible_properties?: Set<string>;
10
10
  }
11
11
  export declare function generate_plot_series(trajectory: TrajectoryType, data_extractor: TrajectoryDataExtractor, options?: PlotSeriesOptions): DataSeries[];
12
- export declare function toggle_series_visibility(series: DataSeries[], target_series_idx: number): DataSeries[];
13
12
  export declare function should_hide_plot(trajectory: TrajectoryType | undefined, plot_series: DataSeries[], tolerance?: number): boolean;
14
13
  export declare function generate_axis_labels(plot_series: DataSeries[]): {
15
14
  y1: string;
@@ -32,18 +32,9 @@ function extract_property_statistics(trajectory, data_extractor) {
32
32
  if (typeof value !== `number` || key === `Step` || key.startsWith(`constant_`)) {
33
33
  return;
34
34
  }
35
- if (!property_stats.has(key)) {
36
- const stats = { values: [], sum: 0, sum_squares: 0, min: value, max: value };
37
- property_stats.set(key, stats);
38
- }
39
- const stat = property_stats.get(key);
40
- if (stat) {
41
- stat.values.push(value);
42
- stat.sum += value;
43
- stat.sum_squares += value * value;
44
- stat.min = Math.min(stat.min, value);
45
- stat.max = Math.max(stat.max, value);
46
- }
35
+ const stat = property_stats.get(key) ?? { values: [] };
36
+ property_stats.set(key, stat);
37
+ stat.values.push(value);
47
38
  });
48
39
  });
49
40
  // Convert to final format with variation detection
@@ -101,7 +92,7 @@ function group_and_assign_series(series, default_visible_properties) {
101
92
  // Group by unit
102
93
  const unit_map = new Map();
103
94
  for (const srs of series) {
104
- const unit = srs.unit || `dimensionless`;
95
+ const unit = srs.unit ?? `dimensionless`;
105
96
  const group = unit_map.get(unit) ?? [];
106
97
  group.push(srs);
107
98
  unit_map.set(unit, group);
@@ -112,7 +103,7 @@ function group_and_assign_series(series, default_visible_properties) {
112
103
  const priority = calculate_priority(unit, group_series);
113
104
  const has_default_visible = group_series.some((srs) => {
114
105
  const metadata = Array.isArray(srs.metadata) ? srs.metadata[0] : srs.metadata;
115
- const property_key = metadata?.property_key || srs.label || ``;
106
+ const property_key = (metadata?.property_key || srs.label) ?? ``;
116
107
  return is_default_visible(property_key, default_visible_properties);
117
108
  });
118
109
  return { unit, series: group_series, priority, is_visible: has_default_visible };
@@ -158,7 +149,7 @@ function extract_label_and_unit(key, property_config) {
158
149
  if (config)
159
150
  return { clean_label: config.label, unit: config.unit };
160
151
  return {
161
- clean_label: key.charAt(0).toUpperCase() + key.slice(1).replace(/_/g, ` `),
152
+ clean_label: key.charAt(0).toUpperCase() + key.slice(1).replaceAll('_', ` `),
162
153
  unit: ``,
163
154
  };
164
155
  }
@@ -169,14 +160,14 @@ function calculate_priority(unit, group_series) {
169
160
  return unit_priority;
170
161
  // Energy properties get high priority
171
162
  const has_energy = group_series.some((srs) => {
172
- const label = srs.label?.toLowerCase() || ``;
163
+ const label = srs.label?.toLowerCase() ?? ``;
173
164
  return ENERGY_PROPERTIES.some((prop) => label.includes(prop));
174
165
  });
175
166
  if (has_energy)
176
167
  return 10;
177
168
  // Force properties get medium priority
178
169
  const has_force = group_series.some((srs) => {
179
- const label = srs.label?.toLowerCase() || ``;
170
+ const label = srs.label?.toLowerCase() ?? ``;
180
171
  return FORCE_PROPERTIES.some((prop) => label.includes(prop));
181
172
  });
182
173
  if (has_force)
@@ -187,8 +178,8 @@ function calculate_priority(unit, group_series) {
187
178
  const normalize_property_key = (key) => {
188
179
  const normalized = key
189
180
  .toLowerCase()
190
- .replace(/<[^>]*>/g, ``)
191
- .replace(/_/g, ` `)
181
+ .replaceAll(/<[^>]*>/g, ``)
182
+ .replaceAll('_', ` `)
192
183
  .trim();
193
184
  // Map common force property aliases to canonical form
194
185
  return [`fmax`, `f`, `force maximum`].includes(normalized) ? `force max` : normalized;
@@ -201,94 +192,6 @@ const is_default_visible = (property_key, default_properties) => {
201
192
  }
202
193
  return false;
203
194
  };
204
- // Optimized series visibility toggling
205
- export function toggle_series_visibility(series, target_series_idx) {
206
- if (target_series_idx < 0 || target_series_idx >= series.length)
207
- return series;
208
- const target_series = series[target_series_idx];
209
- const new_visibility = !target_series.visible;
210
- // Create unit groups from current state
211
- const unit_groups = create_unit_groups_from_series(series);
212
- const target_group = unit_groups.find((group) => group.series.includes(target_series));
213
- if (!target_group)
214
- return series;
215
- // Start with updating the target series visibility
216
- const updated_series = series.map((srs) => srs === target_series ? { ...srs, visible: new_visibility } : { ...srs });
217
- // Handle smart group replacement for new groups
218
- if (new_visibility && !target_group.is_visible) {
219
- const visible_groups = unit_groups.filter((group) => group.is_visible);
220
- if (visible_groups.length >= 2) {
221
- // Hide lowest priority group (highest priority number)
222
- const lowest_priority_group = visible_groups
223
- .sort((g1, g2) => g1.priority - g2.priority)
224
- .pop(); // Get the last (lowest priority) group
225
- if (lowest_priority_group) {
226
- lowest_priority_group.is_visible = false;
227
- // Also hide the actual series in this group
228
- lowest_priority_group.series.forEach((srs1) => {
229
- const series_idx = updated_series.findIndex((srs2) => srs2.label === srs1.label && srs2.unit === srs1.unit);
230
- if (series_idx !== -1) {
231
- updated_series[series_idx] = { ...updated_series[series_idx], visible: false };
232
- }
233
- });
234
- }
235
- }
236
- target_group.is_visible = true;
237
- }
238
- // Recalculate group visibility and reassign axes
239
- update_group_visibility_and_axes(updated_series, unit_groups);
240
- return updated_series;
241
- }
242
- function create_unit_groups_from_series(series) {
243
- const unit_map = new Map();
244
- for (const srs of series) {
245
- const unit = srs.unit || `dimensionless`;
246
- const group = unit_map.get(unit) ?? [];
247
- group.push(srs);
248
- unit_map.set(unit, group);
249
- }
250
- return Array.from(unit_map.entries())
251
- .map(([unit, group_series]) => ({
252
- unit,
253
- series: group_series,
254
- priority: calculate_priority(unit, group_series),
255
- is_visible: group_series.some((srs) => srs.visible),
256
- }))
257
- .sort((a, b) => a.priority - b.priority);
258
- }
259
- function update_group_visibility_and_axes(series, unit_groups) {
260
- // Update group visibility based on series
261
- for (const group of unit_groups) {
262
- group.is_visible = group.series.some((srs1) => series.find((srs2) => srs2.label === srs1.label && srs2.unit === srs1.unit)?.visible);
263
- }
264
- // Apply 2-group limit
265
- if (unit_groups.filter((unit_group) => unit_group.is_visible).length > 2) {
266
- for (const group of unit_groups.filter((unit_group) => unit_group.is_visible).slice(2)) {
267
- group.is_visible = false;
268
- for (const srs1 of group.series) {
269
- const idx = series.findIndex((srs2) => srs2.label === srs1.label && srs2.unit === srs1.unit);
270
- if (idx !== -1)
271
- series[idx] = { ...series[idx], visible: false };
272
- }
273
- }
274
- }
275
- // Assign axes
276
- const final_visible = unit_groups
277
- .filter((group) => group.is_visible)
278
- .sort((g1, g2) => g1.priority - g2.priority);
279
- const axis_map = new Map();
280
- if (final_visible.length >= 1)
281
- axis_map.set(final_visible[0], `y1`);
282
- if (final_visible.length === 2)
283
- axis_map.set(final_visible[1], `y2`);
284
- // Apply to series
285
- for (const [idx, srs] of series.entries()) {
286
- const group = unit_groups.find((unit_group) => unit_group.series.some((member) => member.label === srs.label && member.unit === srs.unit));
287
- if (group && axis_map.has(group)) {
288
- series[idx] = { ...srs, y_axis: axis_map.get(group) };
289
- }
290
- }
291
- }
292
195
  // Utility functions
293
196
  export function should_hide_plot(trajectory, plot_series, tolerance = 1e-10) {
294
197
  if (!trajectory || trajectory.frames.length <= 1 || plot_series.length === 0) {
@@ -313,12 +216,12 @@ export function should_hide_plot(trajectory, plot_series, tolerance = 1e-10) {
313
216
  }
314
217
  function get_axis_label(axis_series) {
315
218
  const visible_series = axis_series.filter((srs) => srs.visible);
316
- if (!visible_series.length)
219
+ if (visible_series.length === 0)
317
220
  return `Value`;
318
221
  const unit_groups = new Map();
319
222
  visible_series.forEach((srs) => {
320
- const unit = srs.unit || ``;
321
- const label = srs.label || `Value`;
223
+ const unit = srs.unit ?? ``;
224
+ const label = srs.label ?? `Value`;
322
225
  if (!unit_groups.has(unit))
323
226
  unit_groups.set(unit, []);
324
227
  const group = unit_groups.get(unit);
@@ -326,14 +229,14 @@ function get_axis_label(axis_series) {
326
229
  group.push(label);
327
230
  });
328
231
  const unit_entries = Array.from(unit_groups.entries());
329
- if (!unit_entries.length)
232
+ if (unit_entries.length === 0)
330
233
  return `Value`;
331
234
  const [unit, labels] = unit_entries[0];
332
235
  const unique_labels = [...new Set(labels)].sort().join(` / `);
333
236
  return unit ? `${unique_labels} (${unit})` : unique_labels;
334
237
  }
335
238
  export function generate_axis_labels(plot_series) {
336
- if (!plot_series.length)
239
+ if (plot_series.length === 0)
337
240
  return { y1: `Value`, y2: `Value` };
338
241
  return {
339
242
  y1: get_axis_label(plot_series.filter((srs) => (srs.y_axis ?? `y1`) === `y1`)),
@@ -341,7 +244,7 @@ export function generate_axis_labels(plot_series) {
341
244
  };
342
245
  }
343
246
  export function generate_streaming_plot_series(metadata_list, options = {}) {
344
- if (!metadata_list.length)
247
+ if (metadata_list.length === 0)
345
248
  return [];
346
249
  const { property_config = trajectory_property_config, colors = PLOT_COLORS, default_visible_properties = DEFAULT_VISIBLE, max_points = 10_000, // 10,000 plot points provides good visual fidelity while maintaining browser performance
347
250
  } = options;
package/dist/utils.d.ts CHANGED
@@ -1,6 +1,8 @@
1
+ export declare const is_plain_object: (val: unknown) => val is Record<string, unknown>;
1
2
  export declare function merge_nested<T extends Record<string, unknown>>(obj1: T, obj2?: Partial<T>): T;
2
3
  export declare const escape_html: (unsafe_string: string) => string;
3
4
  export declare const normalize_unicode_minus: (value: string) => string;
4
5
  export declare const normalize_scientific_notation: (value: string) => string;
6
+ export declare const to_error: (value: unknown) => Error;
5
7
  export declare function make_change_detector(): (value: unknown) => boolean;
6
8
  export declare function decode_url_safe_base64(encoded: string): string | undefined;
package/dist/utils.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Check if value is a plain object (not array, null, or other types)
2
- const is_plain_object = (val) => typeof val === `object` && val !== null && !Array.isArray(val);
2
+ export const is_plain_object = (val) => typeof val === `object` && val !== null && !Array.isArray(val);
3
3
  // Merge nested objects (1 level deep).
4
4
  export function merge_nested(obj1, obj2) {
5
5
  const result = { ...obj1, ...obj2 };
@@ -18,11 +18,13 @@ export const escape_html = (unsafe_string) => unsafe_string
18
18
  .replaceAll(`"`, `&quot;`)
19
19
  .replaceAll(`'`, `&#39;`);
20
20
  // Normalize unicode minus (U+2212) to ASCII hyphen-minus.
21
- export const normalize_unicode_minus = (value) => value.replace(/−/g, `-`);
21
+ export const normalize_unicode_minus = (value) => value.replaceAll('−', `-`);
22
22
  // Normalize scientific notation variants (d/D exponent, Mathematica *^).
23
- export const normalize_scientific_notation = (value) => normalize_unicode_minus(value).toLowerCase().replace(/d/g, `e`).replace(/\*\^/g, `e`);
23
+ export const normalize_scientific_notation = (value) => normalize_unicode_minus(value).toLowerCase().replaceAll('d', `e`).replaceAll('*^', `e`);
24
+ // Coerce an unknown thrown value into an Error (for typed Promise rejections / error callbacks).
25
+ export const to_error = (value) => value instanceof Error ? value : new Error(String(value));
24
26
  export function make_change_detector() {
25
- const unset = Symbol();
27
+ const unset = Symbol(`unset`);
26
28
  let prev = unset;
27
29
  return (value) => {
28
30
  const changed = prev !== unset && value !== prev;
@@ -34,7 +36,7 @@ export function make_change_detector() {
34
36
  // Converts `-` → `+`, `_` → `/`, restores padding, then decodes.
35
37
  // Returns undefined if decoding fails.
36
38
  export function decode_url_safe_base64(encoded) {
37
- const std_b64 = encoded.replace(/-/g, `+`).replace(/_/g, `/`);
39
+ const std_b64 = encoded.replaceAll('-', `+`).replaceAll('_', `/`);
38
40
  const padded = std_b64 + `=`.repeat((4 - (std_b64.length % 4)) % 4);
39
41
  try {
40
42
  return atob(padded);