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
@@ -12,9 +12,29 @@ export declare function structure_to_xyz_str(structure?: AnyStructure): string;
12
12
  export declare function structure_to_cif_str(structure?: AnyStructure): string;
13
13
  export declare function structure_to_poscar_str(structure?: AnyStructure): string;
14
14
  export declare function structure_to_json_str(structure?: AnyStructure): string;
15
- export declare function export_structure_as_cif(structure?: AnyStructure): void;
16
- export declare function export_structure_as_poscar(structure?: AnyStructure): void;
17
- export declare function export_structure_as_xyz(structure?: AnyStructure): void;
18
- export declare function export_structure_as_json(structure?: AnyStructure): void;
15
+ export declare const STRUCT_TEXT_FORMATS: {
16
+ readonly json: {
17
+ readonly to_str: typeof structure_to_json_str;
18
+ readonly ext: "json";
19
+ readonly mime: "application/json";
20
+ };
21
+ readonly xyz: {
22
+ readonly to_str: typeof structure_to_xyz_str;
23
+ readonly ext: "xyz";
24
+ readonly mime: "text/plain";
25
+ };
26
+ readonly cif: {
27
+ readonly to_str: typeof structure_to_cif_str;
28
+ readonly ext: "cif";
29
+ readonly mime: "chemical/x-cif";
30
+ };
31
+ readonly poscar: {
32
+ readonly to_str: typeof structure_to_poscar_str;
33
+ readonly ext: "poscar";
34
+ readonly mime: "text/plain";
35
+ };
36
+ };
37
+ export type StructTextFormat = keyof typeof STRUCT_TEXT_FORMATS;
38
+ export declare function export_structure_as(fmt: StructTextFormat, structure?: AnyStructure): void;
19
39
  export declare function export_structure_as_glb(scene: Scene | null, structure: AnyStructure | undefined): void;
20
40
  export declare function export_structure_as_obj(scene: Scene | null, structure: AnyStructure | undefined): void;
@@ -1,11 +1,13 @@
1
1
  import { get_electro_neg_formula } from '../composition';
2
2
  import { download } from '../io/fetch';
3
3
  import * as math from '../math';
4
+ import { is_plain_object } from '../utils';
4
5
  import { Color, Group, Matrix4, Mesh, MeshStandardMaterial, ShaderMaterial } from 'three';
5
6
  import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';
6
7
  import { OBJExporter } from 'three/examples/jsm/exporters/OBJExporter.js';
7
- // Type guard to check if a material has a color property (duck typing for bundler compatibility)
8
- // Uses duck typing to work across different Three.js instances (Threlte vs vanilla Three.js)
8
+ // @internal exported only for tests - not part of the public API.
9
+ // Type guard to check if a material has a color property (duck typing for bundler
10
+ // compatibility across different Three.js instances - Threlte vs vanilla Three.js).
9
11
  export function has_color_property(mat) {
10
12
  if (!(`color` in mat))
11
13
  return false;
@@ -47,8 +49,9 @@ function convert_shader_to_standard(shader_mat) {
47
49
  standard_mat.name = shader_mat.name || `converted_shader_material`;
48
50
  return standard_mat;
49
51
  }
50
- // Extract bond gradient colors from geometry attributes for a specific instance
51
- // Returns midpoint color between start and end colors for the bond
52
+ // @internal exported only for tests - not part of the public API.
53
+ // Extract bond gradient colors from geometry attributes for a specific instance.
54
+ // Returns midpoint color between start and end colors for the bond.
52
55
  export function extract_bond_color_for_instance(geometry, instance_idx) {
53
56
  const color_start_attr = geometry.getAttribute(`instanceColorStart`);
54
57
  const color_end_attr = geometry.getAttribute(`instanceColorEnd`);
@@ -70,8 +73,10 @@ export function extract_bond_color_for_instance(geometry, instance_idx) {
70
73
  const [mid_r, mid_g, mid_b] = math.scale(math.add(start_rgb, end_rgb), 0.5);
71
74
  return new Color(mid_r, mid_g, mid_b);
72
75
  }
73
- // Remove custom/non-standard attributes from geometry that cause export issues
74
- // Standard GLTF attributes: position, normal, tangent, texcoord_N, color_N, joints_N, weights_N
76
+ // @internal exported only for tests - not part of the public API.
77
+ // Remove custom/non-standard attributes from geometry that cause export issues.
78
+ // Standard GLTF attributes: position, normal, tangent, texcoord_N, color_N, joints_N,
79
+ // weights_N.
75
80
  export function clean_geometry_for_export(geometry) {
76
81
  const standard_attrs = new Set([
77
82
  `position`,
@@ -98,7 +103,8 @@ export function clean_geometry_for_export(geometry) {
98
103
  geometry.deleteAttribute(attr_name);
99
104
  }
100
105
  }
101
- // Generate MTL (Wavefront Material) content from scene materials
106
+ // @internal exported only for tests - not part of the public API.
107
+ // Generate MTL (Wavefront Material) content from scene materials.
102
108
  export function generate_mtl_content(scene) {
103
109
  const lines = [`# MTL file generated by MatterViz`, ``];
104
110
  const processed_materials = new Set();
@@ -108,6 +114,7 @@ export function generate_mtl_content(scene) {
108
114
  const materials = Array.isArray(object.material) ? object.material : [object.material];
109
115
  for (const mat of materials) {
110
116
  // Skip if already processed or no name
117
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty name should use default
111
118
  const mat_name = mat.name || `default_material`;
112
119
  if (processed_materials.has(mat_name))
113
120
  continue;
@@ -294,10 +301,10 @@ function convert_instanced_meshes_to_regular(scene) {
294
301
  // Generate a filename for structure exports based on structure metadata
295
302
  // Sanitize string for use in filenames by removing problematic characters.
296
303
  const sanitize_filename_part = (text) => text
297
- .replace(/<\/?[^>]+>/g, ``) // strip HTML tags
298
- .replace(/[/\\:*?"<>|]/g, `_`) // replace filesystem-invalid chars
299
- .replace(/_+/g, `_`) // condense consecutive underscores
300
- .replace(/^_|_$/g, ``); // remove leading/trailing underscores
304
+ .replaceAll(/<\/?[^>]+>/g, ``) // strip HTML tags
305
+ .replaceAll(/[/\\:*?"<>|]/g, `_`) // replace filesystem-invalid chars
306
+ .replaceAll(/_+/g, `_`) // condense consecutive underscores
307
+ .replaceAll(/^_|_$/g, ``); // remove leading/trailing underscores
301
308
  export function create_structure_filename(structure, extension) {
302
309
  if (!structure)
303
310
  return `structure.${extension}`;
@@ -340,6 +347,17 @@ export function create_structure_filename(structure, extension) {
340
347
  const base_name = parts.length > 0 ? parts.join(`-`) : `structure`;
341
348
  return `${base_name}.${extension}`;
342
349
  }
350
+ // First species' element of a site, or `X` when the site has no species
351
+ const site_element = (site) => site.species?.[0]?.element || `X`;
352
+ // Fractional coordinates from abc, falling back to converting xyz; throws when neither
353
+ // is available. idx (when given) is included in the error message.
354
+ function get_frac_coords(site, cart_to_frac, idx) {
355
+ if (Array.isArray(site.abc) && site.abc.length >= 3)
356
+ return site.abc.slice(0, 3);
357
+ if (site.xyz?.length >= 3 && cart_to_frac)
358
+ return cart_to_frac(site.xyz.slice(0, 3));
359
+ throw new Error(`No valid coordinates found for site${idx === undefined ? `` : ` ${idx}`}`);
360
+ }
343
361
  // Generate XYZ content string without saving
344
362
  export function structure_to_xyz_str(structure) {
345
363
  if (!structure?.sites)
@@ -357,8 +375,7 @@ export function structure_to_xyz_str(structure) {
357
375
  // Include extended XYZ lattice information when available so round-trips preserve lattice
358
376
  if (`lattice` in structure && structure.lattice?.matrix?.length === 3) {
359
377
  const lattice_values = structure.lattice.matrix
360
- .flat()
361
- .map((value) => (Number.isFinite(value) ? value : 0).toFixed(8))
378
+ .flatMap((row) => row.map((value) => (Number.isFinite(value) ? value : 0).toFixed(8)))
362
379
  .join(` `);
363
380
  comment_parts.push(`Lattice="${lattice_values}"`);
364
381
  }
@@ -370,14 +387,7 @@ export function structure_to_xyz_str(structure) {
370
387
  : null;
371
388
  // Atom lines: element symbol followed by x, y, z coordinates
372
389
  for (const site of structure.sites) {
373
- // Extract element symbol from species
374
- let element_symbol = `X`; // default fallback
375
- if (site.species && Array.isArray(site.species) && site.species.length > 0) {
376
- // species is an array of Species objects with element property
377
- const first_species = site.species[0];
378
- if (first_species && `element` in first_species && first_species.element)
379
- element_symbol = first_species.element;
380
- }
390
+ const element_symbol = site_element(site);
381
391
  // Get coordinates - prefer xyz; fallback to abc (converted to cartesian if lattice available)
382
392
  let coords;
383
393
  if (site.xyz && Array.isArray(site.xyz) && site.xyz.length >= 3) {
@@ -432,7 +442,7 @@ function get_cif_block_name(structure) {
432
442
  if (structure.id) {
433
443
  // Remove invalid CIF characters (keep alphanumerics and underscores)
434
444
  // and condense consecutive underscores for cleaner block names
435
- return structure.id.replace(/[^a-zA-Z0-9_]/g, `_`).replace(/_+/g, `_`);
445
+ return structure.id.replaceAll(/[^a-zA-Z0-9_]/g, `_`).replaceAll(/_+/g, `_`);
436
446
  }
437
447
  return `structure`;
438
448
  }
@@ -463,13 +473,11 @@ export function structure_to_cif_str(structure) {
463
473
  lines.push(`_cell_angle_gamma ${lattice.gamma.toFixed(6)}`);
464
474
  }
465
475
  // Space group information
466
- if (`symmetry` in structure &&
467
- structure.symmetry &&
468
- typeof structure.symmetry === `object`) {
469
- const symmetry = structure.symmetry;
470
- const { space_group_number, space_group_symbol } = symmetry;
476
+ if (`symmetry` in structure && is_plain_object(structure.symmetry)) {
477
+ const { space_group_number, space_group_symbol } = structure.symmetry;
471
478
  if (typeof space_group_symbol === `string` && space_group_symbol) {
472
- lines.push(`_space_group_name_H-M_alt ${space_group_symbol}`);
479
+ // Quote H-M symbols: their spaces (e.g. 'F m -3 m') would break CIF tokenization
480
+ lines.push(`_space_group_name_H-M_alt '${space_group_symbol}'`);
473
481
  }
474
482
  if ((typeof space_group_number === `number` || typeof space_group_number === `string`) &&
475
483
  space_group_number) {
@@ -477,6 +485,9 @@ export function structure_to_cif_str(structure) {
477
485
  }
478
486
  }
479
487
  lines.push(``);
488
+ // Explicit identity-only symmetry-ops loop (like pymatgen's CifWriter): sites are the
489
+ // full P1 list, so without it parsers would re-apply the H-M ops and multiply sites
490
+ lines.push(`loop_`, `_symmetry_equiv_pos_as_xyz`, ` 'x, y, z'`, ``);
480
491
  // Atom site loop header
481
492
  lines.push(`loop_`);
482
493
  lines.push(`_atom_site_label`);
@@ -487,34 +498,24 @@ export function structure_to_cif_str(structure) {
487
498
  lines.push(`_atom_site_occupancy`);
488
499
  // Cache inverse transpose for Cartesian→fractional conversion (avoids recomputing per site)
489
500
  const cart_to_frac = lattice.matrix?.length === 3 ? math.create_cart_to_frac(lattice.matrix) : null;
490
- // Atom sites
501
+ // Atom sites: one row per species entry so disordered (multi-species) sites
502
+ // keep every component with its own occupancy instead of only species[0]
491
503
  for (let idx = 0; idx < structure.sites.length; idx++) {
492
504
  const site = structure.sites[idx];
493
505
  if (!site)
494
506
  continue; // Skip if site is undefined
495
- // Extract element symbol from species
496
- let element_symbol = `X`; // default fallback
497
- let occupancy = 1;
498
- if (site.species && Array.isArray(site.species) && site.species.length > 0) {
499
- const first_species = site.species[0];
500
- if (first_species && `element` in first_species && first_species.element) {
501
- element_symbol = first_species.element;
502
- occupancy = first_species?.occu ?? 1;
503
- }
507
+ const frac_coords = get_frac_coords(site, cart_to_frac, idx);
508
+ const coords_str = frac_coords.map((coord) => coord.toFixed(8)).join(` `);
509
+ const species_list = site.species?.length ? site.species : [{ element: `X`, occu: 1 }];
510
+ for (const [spec_idx, species] of species_list.entries()) {
511
+ const elem = species?.element || `X`;
512
+ // Row format: label element x y z occupancy. Labels must be unique per row,
513
+ // so disordered sites get a per-species suffix.
514
+ const label = species_list.length > 1
515
+ ? `${elem}${idx + 1}_${spec_idx}`
516
+ : site.label || `${elem}${idx + 1}`;
517
+ lines.push(`${label} ${elem} ${coords_str} ${(species?.occu ?? 1).toFixed(8)}`);
504
518
  }
505
- // Get fractional coordinates
506
- let frac_coords;
507
- if (site.abc && Array.isArray(site.abc) && site.abc.length >= 3) {
508
- frac_coords = site.abc.slice(0, 3);
509
- }
510
- else if (site.xyz?.length >= 3 && cart_to_frac) {
511
- frac_coords = cart_to_frac(site.xyz);
512
- }
513
- else
514
- throw new Error(`No valid coordinates found for site ${idx}`);
515
- // Format: label element_symbol x y z
516
- const label = site.label || `${element_symbol}${idx + 1}`;
517
- lines.push(`${label} ${element_symbol} ${frac_coords[0].toFixed(8)} ${frac_coords[1].toFixed(8)} ${frac_coords[2].toFixed(8)} ${occupancy.toFixed(8)}`);
518
519
  }
519
520
  return lines.join(`\n`);
520
521
  }
@@ -528,8 +529,8 @@ export function structure_to_poscar_str(structure) {
528
529
  const lines = [];
529
530
  // Use plain text formula for POSCAR title to avoid HTML tags
530
531
  const formula = get_electro_neg_formula(structure, true);
531
- const title = structure.id ||
532
- (formula && formula !== `Unknown` ? formula : null) ||
532
+ const title = structure.id || // oxlint-disable-line @typescript-eslint/prefer-nullish-coalescing -- first non-empty string
533
+ (formula && formula !== `Unknown` ? formula : null) || // oxlint-disable-line @typescript-eslint/prefer-nullish-coalescing -- first non-empty string
533
534
  `Generated from structure`;
534
535
  lines.push(title);
535
536
  lines.push(`1.0`); // Scale factor (1.0 for direct coordinates)
@@ -544,27 +545,20 @@ export function structure_to_poscar_str(structure) {
544
545
  else {
545
546
  throw new Error(`No valid lattice matrix for POSCAR export`);
546
547
  }
547
- // Count atoms by element
548
- const element_counts = new Map();
549
- const element_symbols = [];
548
+ // Group sites by element in one pass, preserving first-appearance element order
549
+ const sites_by_element = new Map();
550
550
  for (const site of structure.sites) {
551
- let element_symbol = `X`; // default fallback
552
- if (site.species && Array.isArray(site.species) && site.species.length > 0) {
553
- const first_species = site.species[0];
554
- if (first_species && `element` in first_species && first_species.element) {
555
- element_symbol = first_species.element;
556
- }
557
- }
558
- if (!element_counts.has(element_symbol)) {
559
- element_counts.set(element_symbol, 0);
560
- element_symbols.push(element_symbol);
561
- }
562
- element_counts.set(element_symbol, Number(element_counts.get(element_symbol)) + 1);
551
+ const element_symbol = site_element(site);
552
+ const group = sites_by_element.get(element_symbol);
553
+ if (group)
554
+ group.push(site);
555
+ else
556
+ sites_by_element.set(element_symbol, [site]);
563
557
  }
564
558
  // Element symbols line
565
- lines.push(element_symbols.join(` `));
559
+ lines.push([...sites_by_element.keys()].join(` `));
566
560
  // Atom counts line
567
- lines.push(element_symbols.map((el) => element_counts.get(el)).join(` `));
561
+ lines.push([...sites_by_element.values()].map((group) => group.length).join(` `));
568
562
  // Check if any site has selective dynamics
569
563
  const has_selective_dynamics = structure.sites.some((site) => site.properties?.selective_dynamics);
570
564
  if (has_selective_dynamics) {
@@ -575,38 +569,19 @@ export function structure_to_poscar_str(structure) {
575
569
  // Cache inverse transpose for Cartesian→fractional conversion (avoids recomputing per site)
576
570
  const cart_to_frac = lattice.matrix?.length === 3 ? math.create_cart_to_frac(lattice.matrix) : null;
577
571
  // Atom coordinates grouped by element
578
- for (const element_symbol of element_symbols) {
579
- for (const site of structure.sites) {
580
- let site_element = `X`;
581
- if (site.species && Array.isArray(site.species) && site.species.length > 0) {
582
- const first_species = site.species[0];
583
- if (first_species && `element` in first_species && first_species.element) {
584
- site_element = first_species.element;
585
- }
586
- }
587
- if (site_element === element_symbol) {
588
- // Get fractional coordinates
589
- let frac_coords;
590
- if (site.abc && Array.isArray(site.abc) && site.abc.length >= 3) {
591
- frac_coords = site.abc.slice(0, 3);
592
- }
593
- else if (site.xyz?.length >= 3 && cart_to_frac) {
594
- frac_coords = cart_to_frac(site.xyz.slice(0, 3));
595
- }
596
- else {
597
- throw new Error(`No valid coordinates found for site`);
598
- }
599
- let selective_dynamics_str = ``;
600
- if (has_selective_dynamics) {
601
- const sel_dyn = (site.properties?.selective_dynamics ?? [
602
- true,
603
- true,
604
- true,
605
- ]);
606
- selective_dynamics_str = ` ${sel_dyn[0] ? `T` : `F`} ${sel_dyn[1] ? `T` : `F`} ${sel_dyn[2] ? `T` : `F`}`;
607
- }
608
- lines.push(`${frac_coords[0].toFixed(8)} ${frac_coords[1].toFixed(8)} ${frac_coords[2].toFixed(8)}${selective_dynamics_str}`);
572
+ for (const group of sites_by_element.values()) {
573
+ for (const site of group) {
574
+ const frac_coords = get_frac_coords(site, cart_to_frac);
575
+ let selective_dynamics_str = ``;
576
+ if (has_selective_dynamics) {
577
+ const sel_dyn = (site.properties?.selective_dynamics ?? [
578
+ true,
579
+ true,
580
+ true,
581
+ ]);
582
+ selective_dynamics_str = ` ${sel_dyn[0] ? `T` : `F`} ${sel_dyn[1] ? `T` : `F`} ${sel_dyn[2] ? `T` : `F`}`;
609
583
  }
584
+ lines.push(`${frac_coords[0].toFixed(8)} ${frac_coords[1].toFixed(8)} ${frac_coords[2].toFixed(8)}${selective_dynamics_str}`);
610
585
  }
611
586
  }
612
587
  return lines.join(`\n`);
@@ -617,51 +592,22 @@ export function structure_to_json_str(structure) {
617
592
  throw new Error(`No structure to export`);
618
593
  return JSON.stringify(structure, null, 2);
619
594
  }
620
- // Export structure as CIF format
621
- export function export_structure_as_cif(structure) {
622
- try {
623
- const content = structure_to_cif_str(structure);
624
- const filename = create_structure_filename(structure, `cif`);
625
- download(content, filename, `chemical/x-cif`);
626
- }
627
- catch (error) {
628
- console.error(`Failed to export CIF:`, error);
629
- }
630
- }
631
- // Export structure as VASP POSCAR format
632
- export function export_structure_as_poscar(structure) {
633
- try {
634
- const content = structure_to_poscar_str(structure);
635
- const filename = create_structure_filename(structure, `poscar`);
636
- download(content, filename, `text/plain`);
637
- }
638
- catch (error) {
639
- console.error(`Failed to export POSCAR:`, error);
640
- }
641
- }
642
- // Export structure as XYZ format. Format specification:
643
- // - Line 1: Number of atoms
644
- // - Line 2: Comment line (structure ID, formula, etc.)
645
- // - Remaining lines: Element symbol followed by x, y, z coordinates (in Angstrom)
646
- export function export_structure_as_xyz(structure) {
647
- try {
648
- const xyz_content = structure_to_xyz_str(structure);
649
- const filename = create_structure_filename(structure, `xyz`);
650
- download(xyz_content, filename, `text/plain`);
651
- }
652
- catch (error) {
653
- console.error(`Error exporting XYZ:`, error);
654
- }
655
- }
656
- // Export structure in pymatgen JSON format
657
- export function export_structure_as_json(structure) {
595
+ // Text export formats: serializer + file extension + MIME type per format
596
+ export const STRUCT_TEXT_FORMATS = {
597
+ json: { to_str: structure_to_json_str, ext: `json`, mime: `application/json` },
598
+ xyz: { to_str: structure_to_xyz_str, ext: `xyz`, mime: `text/plain` },
599
+ cif: { to_str: structure_to_cif_str, ext: `cif`, mime: `chemical/x-cif` },
600
+ poscar: { to_str: structure_to_poscar_str, ext: `poscar`, mime: `text/plain` },
601
+ };
602
+ // Serialize structure in the given text format and trigger a browser download
603
+ export function export_structure_as(fmt, structure) {
604
+ const { to_str, ext, mime } = STRUCT_TEXT_FORMATS[fmt];
658
605
  try {
659
- const data = structure_to_json_str(structure);
660
- const filename = create_structure_filename(structure, `json`);
661
- download(data, filename, `application/json`);
606
+ const content = to_str(structure);
607
+ download(content, create_structure_filename(structure, ext), mime);
662
608
  }
663
609
  catch (error) {
664
- console.error(`Error exporting JSON:`, error);
610
+ console.error(`Failed to export ${fmt.toUpperCase()}:`, error);
665
611
  }
666
612
  }
667
613
  // Export Three.js scene as GLB (binary GLTF) file
@@ -15,6 +15,8 @@ export { default as CanvasTooltip } from './CanvasTooltip.svelte';
15
15
  export { default as Cylinder } from './Cylinder.svelte';
16
16
  export { default as Lattice } from './Lattice.svelte';
17
17
  export * from './pbc';
18
+ export * from './polyhedra';
19
+ export * from './site';
18
20
  export { default as Structure } from './Structure.svelte';
19
21
  export { default as StructureControls } from './StructureControls.svelte';
20
22
  export { default as StructureExportPane } from './StructureExportPane.svelte';
@@ -36,9 +38,7 @@ export type Site = {
36
38
  properties: Record<string, unknown>;
37
39
  };
38
40
  export declare const LATTICE_PARAM_KEYS: readonly ["a", "b", "c", "alpha", "beta", "gamma"];
39
- export type LatticeParams = {
40
- [key in (typeof LATTICE_PARAM_KEYS)[number]]: number;
41
- };
41
+ export type LatticeParams = Record<(typeof LATTICE_PARAM_KEYS)[number], number>;
42
42
  export type LatticeType = {
43
43
  matrix: math.Matrix3x3;
44
44
  pbc: Pbc;
@@ -84,7 +84,7 @@ export declare const atomic_radii: CompositionType;
84
84
  export declare function get_density(structure: Crystal): number;
85
85
  export declare function get_center_of_mass(structure: AnyStructure): Vec3;
86
86
  export declare const VECTOR_KEY_PREFIXES: readonly ["force", "forces", "magmom", "magmoms", "spin", "spins"];
87
- export declare function is_vector_key(key: string): boolean;
87
+ export declare const is_vector_key: (key: string) => boolean;
88
88
  export declare const VECTOR_PALETTE: readonly ["#e74c3c", "#3498db", "#2ecc71", "#f39c12", "#9b59b6", "#1abc9c"];
89
89
  export declare const default_vector_configs: (keys: string[]) => {
90
90
  [k: string]: {
@@ -10,6 +10,8 @@ export { default as CanvasTooltip } from './CanvasTooltip.svelte';
10
10
  export { default as Cylinder } from './Cylinder.svelte';
11
11
  export { default as Lattice } from './Lattice.svelte';
12
12
  export * from './pbc';
13
+ export * from './polyhedra';
14
+ export * from './site';
13
15
  export { default as Structure } from './Structure.svelte';
14
16
  export { default as StructureControls } from './StructureControls.svelte';
15
17
  export { default as StructureExportPane } from './StructureExportPane.svelte';
@@ -94,9 +96,7 @@ export const VECTOR_KEY_PREFIXES = [
94
96
  `spin`,
95
97
  `spins`,
96
98
  ];
97
- export function is_vector_key(key) {
98
- return VECTOR_KEY_PREFIXES.some((prefix) => key === prefix || key.startsWith(`${prefix}_`));
99
- }
99
+ export const is_vector_key = (key) => VECTOR_KEY_PREFIXES.some((prefix) => key === prefix || key.startsWith(`${prefix}_`));
100
100
  // Default color palette for distinguishing multiple vector layers
101
101
  export const VECTOR_PALETTE = [
102
102
  `#e74c3c`,
@@ -1,6 +1,7 @@
1
1
  import type { LatticeConverters, Matrix3x3, Vec3 } from '../math';
2
+ import type { Pbc } from './pbc';
2
3
  export type AngleMode = `degrees` | `radians`;
3
4
  export declare const MAX_SELECTED_SITES = 8;
4
- export declare function displacement_pbc(from: Vec3, to: Vec3, lattice_matrix: Matrix3x3 | null | undefined, converters?: LatticeConverters): Vec3;
5
- export declare function distance_pbc(a: Vec3, b: Vec3, lattice_matrix: Matrix3x3): number;
5
+ export declare function displacement_pbc(from: Vec3, to: Vec3, lattice_matrix: Matrix3x3 | null | undefined, converters?: LatticeConverters, pbc?: Pbc): Vec3;
6
+ export declare function distance_pbc(a: Vec3, b: Vec3, lattice_matrix: Matrix3x3, converters?: LatticeConverters, pbc?: Pbc): number;
6
7
  export declare function angle_between_vectors(v1: Vec3, v2: Vec3, mode?: AngleMode): number;
@@ -2,14 +2,15 @@
2
2
  import { min_image_displacement, subtract } from '../math';
3
3
  export const MAX_SELECTED_SITES = 8;
4
4
  // Calculate minimum image displacement between two points under PBC
5
- // If lattice_matrix is null/undefined, returns Euclidean displacement
6
- export function displacement_pbc(from, to, lattice_matrix, converters) {
5
+ // If lattice_matrix is null/undefined, returns Euclidean displacement.
6
+ // pbc flags disable wrapping along non-periodic axes (e.g. slab vacuum directions).
7
+ export function displacement_pbc(from, to, lattice_matrix, converters, pbc) {
7
8
  if (!lattice_matrix)
8
9
  return subtract(to, from);
9
- return min_image_displacement(from, to, lattice_matrix, converters);
10
+ return min_image_displacement(from, to, lattice_matrix, converters, pbc);
10
11
  }
11
- export function distance_pbc(a, b, lattice_matrix) {
12
- const [dx, dy, dz] = displacement_pbc(a, b, lattice_matrix);
12
+ export function distance_pbc(a, b, lattice_matrix, converters, pbc) {
13
+ const [dx, dy, dz] = displacement_pbc(a, b, lattice_matrix, converters, pbc);
13
14
  return Math.hypot(dx, dy, dz);
14
15
  }
15
16
  export function angle_between_vectors(v1, v2, mode = `degrees`) {
@@ -54,9 +54,10 @@ export declare function parse_xyz(content: string): ParsedStructure | null;
54
54
  export declare function parse_cif(content: string, wrap_fractional_coords?: boolean, strict?: boolean): ParsedStructure | null;
55
55
  export type CellType = `primitive_cell` | `unit_cell` | `supercell` | `phonon_primitive_cell` | `phonon_supercell` | `auto`;
56
56
  export declare function parse_phonopy_yaml(content: string, cell_type?: CellType): ParsedStructure | null;
57
+ export declare function is_parsed_structure(obj: unknown): obj is ParsedStructure;
57
58
  export declare function normalize_fractional_coords(structure: ParsedStructure): ParsedStructure;
58
- export declare function parse_structure_file(content: string, filename?: string): ParsedStructure | null;
59
- export declare function parse_any_structure(content: string, filename: string): AnyStructure | null;
59
+ export declare function parse_structure_file(content: string, filename?: string): ParsedStructure;
60
+ export declare function parse_any_structure(content: string, filename: string): AnyStructure;
60
61
  export declare function parse_optimade_json(content: string): ParsedStructure | null;
61
62
  export declare function parse_optimade_from_raw(raw: unknown): ParsedStructure | null;
62
63
  export declare function is_optimade_json(content: string): boolean;