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,269 @@
1
+ // Layout helpers for Sunburst charts, wrapping d3-hierarchy's partition.
2
+ // Single source of truth for the hierarchy/angle math so the component stays
3
+ // declarative and the layout is independently unit-testable. The partition is
4
+ // computed in normalized coordinates (angle as fraction of full circle in [0, 1],
5
+ // radius in integer ring units where y0 === depth) independent of pixel size and
6
+ // zoom — the component maps these to screen space per frame (zoomable-sunburst trick).
7
+ import { hsl } from 'd3-color';
8
+ import { hierarchy, partition } from 'd3-hierarchy';
9
+ import { DEFAULT_SERIES_COLORS } from '../core/types';
10
+ import { DEFAULTS } from '../../settings';
11
+ // Compute normalized arc extents, resolved colors and breadcrumbs for a node tree.
12
+ // Never mutates user data: d3-hierarchy wraps inputs in HierarchyNodes and all derived
13
+ // fields (value overrides, ids, colors) are written onto the returned arcs only.
14
+ export function compute_sunburst_layout(data, opts = {}) {
15
+ const {
16
+ // value_mode/min_fraction fallbacks derive from DEFAULTS.sunburst to prevent drift
17
+ value_mode = DEFAULTS.sunburst.value_mode, sort = `none`, level_lighten = 0, min_fraction = DEFAULTS.sunburst.min_fraction, other_label = `Other`, } = opts;
18
+ // Fresh object each call (not a shared constant) so callers can't corrupt each other
19
+ if (Array.isArray(data) ? data.length === 0 : !data) {
20
+ return { arcs: [], root: null, max_depth: 0 };
21
+ }
22
+ // Single root node is used directly; arrays get a synthetic invisible root
23
+ const root_data = Array.isArray(data) ? { children: data } : data;
24
+ const root = hierarchy(root_data, (node) => node.children);
25
+ // 'remainder': d3's .sum() adds the node's own value on top of its children's sum,
26
+ // which is exactly plotly's branchvalues='remainder'. 'leaf-sum' ignores parent values.
27
+ // 'total': every explicitly set value is authoritative (plotly branchvalues='total');
28
+ // nodes without one get their children's sum. Children summing to less than their
29
+ // parent leave a trailing angular gap; more than the parent overflows (plotly errors
30
+ // here; we warn and the component clamps angles).
31
+ if (value_mode === `remainder`)
32
+ root.sum((node) => node.value ?? 0);
33
+ else if (value_mode === `total`) {
34
+ root.eachAfter((node) => {
35
+ const child_sum = node.children?.reduce((sum, child) => sum + (child.value ?? 0), 0) ?? 0;
36
+ node.value = node.data.value ?? child_sum;
37
+ if (node.children && node.data.value != null && child_sum > node.data.value + 1e-9) {
38
+ console.warn(`Sunburst: children of "${node.data.label ?? node.data.id ?? `root`}" sum to ${child_sum}, exceeding its value of ${node.data.value} (value_mode='total')`);
39
+ }
40
+ });
41
+ }
42
+ else
43
+ root.sum((node) => (node.children?.length ? 0 : (node.value ?? 0)));
44
+ if (sort !== `none`) {
45
+ const sign = sort === `descending` ? -1 : 1;
46
+ root.sort((node_a, node_b) => sign * ((node_a.value ?? 0) - (node_b.value ?? 0)));
47
+ }
48
+ // 'Other' bucketing: move sub-threshold children to the end of each sibling list
49
+ // (after sorting, before partition) so the smalls occupy one contiguous angular run
50
+ // that flatten() below can merge into a single synthetic arc.
51
+ const bucket_threshold = min_fraction > 0 ? min_fraction * (root.value ?? 0) : 0;
52
+ if (bucket_threshold > 0) {
53
+ root.each((node) => {
54
+ if (!node.children)
55
+ return;
56
+ const small = node.children.filter((child) => (child.value ?? 0) < bucket_threshold);
57
+ if (small.length >= 2) {
58
+ const kept = node.children.filter((child) => (child.value ?? 0) >= bucket_threshold);
59
+ node.children = [...kept, ...small];
60
+ }
61
+ });
62
+ }
63
+ // x in [0, 1] (angle fraction), y in ring units (y0 === depth, y1 === depth + 1)
64
+ const part_root = partition().size([1, root.height + 1])(root);
65
+ const arcs = [];
66
+ const seen_ids = new Set();
67
+ const root_value = root.value ?? 0;
68
+ const palette_len = DEFAULT_SERIES_COLORS.length;
69
+ let depth1_count = 0; // running index among depth-1 nodes, for palette cycling
70
+ // Resolved fill for a node: explicit > depth-1 palette > inherited, optionally
71
+ // lightened by depth. base = unlightened color descendants inherit.
72
+ const resolve_color = (depth, explicit, parent_base) => {
73
+ const base = explicit ??
74
+ (depth === 1
75
+ ? DEFAULT_SERIES_COLORS[depth1_count++ % palette_len]
76
+ : (parent_base ?? `transparent`));
77
+ let color = base;
78
+ if (!explicit && depth > 1 && level_lighten > 0) {
79
+ color = hsl(base)
80
+ .brighter(level_lighten * (depth - 1))
81
+ .formatHex();
82
+ }
83
+ return { base, color };
84
+ };
85
+ // Construct + append an arc, deriving indices, breadcrumbs and fractions from the
86
+ // parent (shared by regular nodes and synthetic 'Other' arcs)
87
+ const push_arc = (parent, fields) => {
88
+ if (seen_ids.has(fields.id)) {
89
+ console.warn(`Sunburst: duplicate node id "${fields.id}" — set unique \`id\`s or labels.`);
90
+ }
91
+ seen_ids.add(fields.id);
92
+ const arc = {
93
+ node_idx: arcs.length,
94
+ subtree_end: arcs.length, // leaves keep this; branches update after recursion
95
+ parent_idx: parent?.node_idx ?? null,
96
+ path: parent ? [...parent.path, fields.id] : [],
97
+ label_path: parent ? [...parent.label_path, fields.label ?? `${fields.id}`] : [],
98
+ fraction: root_value > 0 ? fields.value / root_value : 0,
99
+ parent_fraction: parent ? (parent.value > 0 ? fields.value / parent.value : 0) : 1,
100
+ ...fields,
101
+ };
102
+ arcs.push(arc);
103
+ return arc;
104
+ };
105
+ // Pre-order DFS so each subtree occupies a contiguous node_idx range
106
+ const flatten = (node, parent, parent_base, // unlightened color descendants inherit
107
+ child_idx) => {
108
+ const { depth } = node;
109
+ const explicit = node.data.color;
110
+ const { base, color } = resolve_color(depth, explicit, parent_base);
111
+ // Stable id: explicit, else slash-joined label path (e.g. "cubic/Fm-3m")
112
+ const parent_prefix = parent && parent.id !== `` ? `${parent.id}/` : ``;
113
+ const segment = node.data.label ?? `${child_idx}`;
114
+ const id = node.data.id ?? (depth === 0 ? (node.data.label ?? ``) : `${parent_prefix}${segment}`);
115
+ const { x0, x1, y0, y1 } = node;
116
+ const arc = push_arc(parent, {
117
+ id,
118
+ label: node.data.label,
119
+ value: node.value ?? 0,
120
+ color,
121
+ depth,
122
+ is_leaf: !node.children?.length,
123
+ x0,
124
+ x1,
125
+ y0,
126
+ y1,
127
+ metadata: node.data.metadata,
128
+ });
129
+ // Children below the bucket threshold form a contiguous trailing run (reordered
130
+ // above); merge runs of >= 2 into one synthetic 'Other' leaf instead of recursing
131
+ const kids = node.children ?? [];
132
+ let cut = kids.length;
133
+ if (bucket_threshold > 0) {
134
+ const first_small = kids.findLastIndex((kid) => (kid.value ?? 0) >= bucket_threshold) + 1;
135
+ if (kids.length - first_small >= 2)
136
+ cut = first_small;
137
+ }
138
+ kids.forEach((child, idx) => {
139
+ if (idx < cut)
140
+ flatten(child, arc, explicit ?? base, idx);
141
+ });
142
+ if (cut < kids.length) {
143
+ const smalls = kids.slice(cut);
144
+ push_arc(arc, {
145
+ id: `${arc.id !== `` ? `${arc.id}/` : ``}${other_label}`,
146
+ label: other_label,
147
+ value: smalls.reduce((sum, child) => sum + (child.value ?? 0), 0),
148
+ color: resolve_color(depth + 1, undefined, explicit ?? base).color,
149
+ depth: depth + 1,
150
+ is_leaf: true,
151
+ is_other: true,
152
+ x0: smalls[0].x0,
153
+ x1: smalls[smalls.length - 1].x1,
154
+ y0: depth + 1,
155
+ y1: depth + 2,
156
+ });
157
+ }
158
+ arc.subtree_end = arcs.length - 1;
159
+ };
160
+ flatten(part_root, null, null, 0);
161
+ return { arcs, root: arcs[0], max_depth: root.height };
162
+ }
163
+ // Build a nested node tree from flat path rows (plotly-express style), e.g.
164
+ // { path: ['cubic', 'Fm-3m'], value: 12 }. Rows sharing a full path accumulate their
165
+ // values; rows whose path is a proper prefix of others set that interior node's own
166
+ // value (meaningful with value_mode 'total'/'remainder').
167
+ export function sunburst_from_paths(rows) {
168
+ const roots = new Map();
169
+ rows.forEach((row, row_idx) => {
170
+ if (!row.path || row.path.length === 0) {
171
+ throw new Error(`sunburst_from_paths: row ${row_idx} has an empty path`);
172
+ }
173
+ let level = roots;
174
+ let trie;
175
+ let id = ``;
176
+ for (const segment of row.path) {
177
+ id = id ? `${id}/${segment}` : `${segment}`;
178
+ trie = level.get(segment);
179
+ if (!trie) {
180
+ trie = { node: { id, label: `${segment}` }, children: new Map() };
181
+ level.set(segment, trie);
182
+ }
183
+ level = trie.children;
184
+ }
185
+ const node = trie.node;
186
+ node.value = (node.value ?? 0) + row.value;
187
+ if (row.color != null)
188
+ node.color = row.color;
189
+ if (row.metadata != null)
190
+ node.metadata = row.metadata;
191
+ });
192
+ const to_nodes = (level) => [...level.values()].map(({ node, children }) => children.size ? { ...node, children: to_nodes(children) } : node);
193
+ return to_nodes(roots);
194
+ }
195
+ // Build a nested node tree from plotly trace arrays (labels/parents/values [+ ids]),
196
+ // the format pymatviz/matbench-discovery sunburst exports use (with branchvalues
197
+ // 'total' -> pair with value_mode 'total'). parents entries of ''/null/undefined mark
198
+ // root-level nodes; parents reference ids when given, else labels.
199
+ export function sunburst_from_labels_parents(labels, parents, values, opts = {}) {
200
+ const { ids, colors, metadata } = opts;
201
+ for (const [name, arr] of [
202
+ [`parents`, parents],
203
+ [`values`, values],
204
+ [`ids`, ids],
205
+ [`colors`, colors],
206
+ [`metadata`, metadata],
207
+ ]) {
208
+ if (arr && arr.length !== labels.length) {
209
+ throw new Error(`sunburst_from_labels_parents: labels (${labels.length}) and ${name} (${arr.length}) must have equal length`);
210
+ }
211
+ }
212
+ const key_to_idx = new Map();
213
+ const nodes = labels.map((label, idx) => {
214
+ const key = ids?.[idx] ?? label;
215
+ if (key_to_idx.has(key)) {
216
+ throw new Error(`sunburst_from_labels_parents: duplicate node ${ids ? `id` : `label`} "${key}"${ids ? `` : ` — pass opts.ids to disambiguate`}`);
217
+ }
218
+ key_to_idx.set(key, idx);
219
+ const node = { id: key, label };
220
+ if (values?.[idx] != null)
221
+ node.value = values[idx];
222
+ if (colors?.[idx] != null)
223
+ node.color = colors[idx];
224
+ if (metadata?.[idx] != null)
225
+ node.metadata = metadata[idx];
226
+ return node;
227
+ });
228
+ // Resolve all parent references up front (one map lookup per node)
229
+ const parent_idxs = labels.map((_, idx) => {
230
+ const ref = parents[idx];
231
+ if (ref == null || ref === ``)
232
+ return null;
233
+ const found = key_to_idx.get(ref);
234
+ if (found === undefined) {
235
+ throw new Error(`sunburst_from_labels_parents: node "${ids?.[idx] ?? labels[idx]}" references unknown parent "${ref}"`);
236
+ }
237
+ return found;
238
+ });
239
+ // O(n) cycle detection: walk each unvisited parent chain once, marking nodes
240
+ // 'in-progress' on the way up. Hitting an in-progress node = cycle; hitting a
241
+ // 'done' node = chain already verified acyclic.
242
+ const state = new Uint8Array(nodes.length); // 0 = unvisited, 1 = in progress, 2 = done
243
+ for (let idx = 0; idx < nodes.length; idx++) {
244
+ if (state[idx] !== 0)
245
+ continue;
246
+ let cur = idx;
247
+ while (cur != null && state[cur] === 0) {
248
+ state[cur] = 1;
249
+ cur = parent_idxs[cur];
250
+ }
251
+ if (cur != null && state[cur] === 1) {
252
+ throw new Error(`sunburst_from_labels_parents: cycle detected involving node "${ids?.[cur] ?? labels[cur]}"`);
253
+ }
254
+ // Mark the walked chain as verified
255
+ for (let mark = idx; mark != null && state[mark] === 1;) {
256
+ state[mark] = 2;
257
+ mark = parent_idxs[mark];
258
+ }
259
+ }
260
+ const roots = [];
261
+ nodes.forEach((node, idx) => {
262
+ const parent = parent_idxs[idx];
263
+ if (parent == null)
264
+ roots.push(node);
265
+ else
266
+ (nodes[parent].children ??= []).push(node);
267
+ });
268
+ return roots;
269
+ }
@@ -10,6 +10,7 @@
10
10
  import { is_crystal } from '../structure/validation'
11
11
  import type { ComponentProps, Snippet } from 'svelte'
12
12
  import { calculate_all_pair_rdfs, calculate_rdf, type RdfEntry } from './index'
13
+ import { to_error } from '../utils'
13
14
 
14
15
  let {
15
16
  patterns,
@@ -66,7 +67,7 @@
66
67
  }
67
68
  } catch (exc) {
68
69
  error_msg = `Failed to process structure: ${
69
- exc instanceof Error ? exc.message : String(exc)
70
+ to_error(exc).message
70
71
  }`
71
72
  }
72
73
  }
@@ -22,6 +22,6 @@ type $$ComponentProps = {
22
22
  drag_dropped?: Crystal[];
23
23
  dragging?: boolean;
24
24
  } & ComponentProps<typeof ScatterPlot>;
25
- declare const RdfPlot: import("svelte").Component<$$ComponentProps, {}, "loading" | "error_msg" | "dragging" | "drag_dropped">;
25
+ declare const RdfPlot: import("svelte").Component<$$ComponentProps, {}, "loading" | "dragging" | "error_msg" | "drag_dropped">;
26
26
  type RdfPlot = ReturnType<typeof RdfPlot>;
27
27
  export default RdfPlot;
@@ -6,7 +6,7 @@ const sum_occu = (sites, elem) => sites.reduce((sum, site) => sum + get_occu(sit
6
6
  // Calculate radial distribution function
7
7
  export function calculate_rdf(structure, options = {}) {
8
8
  const { center_species, neighbor_species, cutoff = 15, n_bins = 75, auto_expand = true, expansion_factor = 2.0, } = options;
9
- let { pbc = [true, true, true] } = options;
9
+ const { pbc = [true, true, true] } = options;
10
10
  if (cutoff <= 0 || n_bins <= 0) {
11
11
  throw new Error(`cutoff and n_bins must be positive`);
12
12
  }
@@ -16,6 +16,7 @@ export function calculate_rdf(structure, options = {}) {
16
16
  }
17
17
  let lattice = structure.lattice.matrix;
18
18
  let { sites } = structure;
19
+ let center_sites = sites;
19
20
  // Expand structure if needed to ensure shortest lattice vector is expansion_factor× the cutoff
20
21
  // This prevents artificial close contacts at cell boundaries when using PBC
21
22
  // Standard practice uses 2.0-2.5× to eliminate finite-size effects
@@ -27,7 +28,10 @@ export function calculate_rdf(structure, options = {}) {
27
28
  const expanded_structure = make_supercell(structure, [n_a, n_b, n_c], false);
28
29
  sites = expanded_structure.sites;
29
30
  lattice = expanded_structure.lattice.matrix;
30
- pbc = [false, false, false]; // Disable PBC since we explicitly expanded the structure
31
+ // Keep PBC: min-image is exact once every lattice vector cutoff (disabling PBC
32
+ // starves boundary atoms and biases g(r) low). Under full PBC all periodic copies are
33
+ // equivalent, so restrict centers to the first copy (make_supercell emits (0,0,0) first)
34
+ center_sites = pbc.every(Boolean) ? sites.slice(0, structure.sites.length) : sites;
31
35
  }
32
36
  }
33
37
  const bin_size = cutoff / n_bins;
@@ -36,7 +40,7 @@ export function calculate_rdf(structure, options = {}) {
36
40
  if (sites.length === 0)
37
41
  return { r, g_r };
38
42
  // Get occupancy weight for a site-species pair (supports mixed occupancy)
39
- const centers = sites.filter((site) => has_species(site, center_species));
43
+ const centers = center_sites.filter((site) => has_species(site, center_species));
40
44
  const neighbors = sites.filter((site) => has_species(site, neighbor_species));
41
45
  if (centers.length === 0 || neighbors.length === 0) {
42
46
  const element_pair = center_species && neighbor_species
@@ -45,7 +49,7 @@ export function calculate_rdf(structure, options = {}) {
45
49
  return { r, g_r, element_pair };
46
50
  }
47
51
  // Calculate distances and bin them with occupancy weighting
48
- const use_pbc = pbc.some((flag) => flag);
52
+ const use_pbc = pbc.some(Boolean);
49
53
  const converters = use_pbc ? create_lattice_converters(lattice) : undefined;
50
54
  for (const center of centers) {
51
55
  for (const neighbor of neighbors) {
@@ -85,26 +89,9 @@ export function calculate_all_pair_rdfs(structure, options = {}) {
85
89
  const elems = [
86
90
  ...new Set(structure.sites.flatMap((site) => site.species.map((spec) => spec.element))),
87
91
  ].sort();
88
- // If auto_expand is true, expand the structure once and reuse it for all pairs
89
- // to avoid repeated supercell computations
90
- let structure_to_use = structure;
91
- if (options.auto_expand !== false) {
92
- const { cutoff = 15, expansion_factor = 2.0 } = options;
93
- const lattice = structure.lattice?.matrix;
94
- if (lattice) {
95
- const { a, b, c } = calc_lattice_params(lattice);
96
- const min_size = cutoff * expansion_factor;
97
- const [n_a, n_b, n_c] = [a, b, c].map((len) => Math.ceil(min_size / len));
98
- if (n_a > 1 || n_b > 1 || n_c > 1) {
99
- structure_to_use = make_supercell(structure, [n_a, n_b, n_c], false);
100
- }
101
- }
102
- }
103
- // Pass auto_expand=false since we've already expanded, and pbc=false for expanded structure
104
- const pbc = [false, false, false];
105
- const rdf_options = { ...options, auto_expand: false, pbc };
106
- return elems.flatMap((el1, idx1) => elems.slice(idx1).map((el2) => calculate_rdf(structure_to_use, {
107
- ...rdf_options,
92
+ // Forward options unchanged (preserves caller's pbc); each calculate_rdf expands itself
93
+ return elems.flatMap((el1, idx1) => elems.slice(idx1).map((el2) => calculate_rdf(structure, {
94
+ ...options,
108
95
  center_species: el1,
109
96
  neighbor_species: el2,
110
97
  })));
package/dist/sanitize.js CHANGED
@@ -53,7 +53,7 @@ function sanitize_svg_content(html, allowed_tags, allowed_attrs) {
53
53
  });
54
54
  const open_end = wrapped.indexOf(`>`);
55
55
  const close_start = wrapped.lastIndexOf(`</svg>`);
56
- if (open_end < 0 || close_start < 0)
56
+ if (open_end === -1 || close_start === -1)
57
57
  return wrapped;
58
58
  return wrapped.slice(open_end + 1, close_start);
59
59
  }
@@ -75,21 +75,32 @@ const stringify_html_input = (html) => {
75
75
  return ``;
76
76
  }
77
77
  };
78
+ // Memoize by input: two DOMPurify passes per call are costly when a component re-sanitizes
79
+ // many cells on every render (e.g. HeatmapTable). Sanitization is deterministic for the
80
+ // fixed config, so caching is output-identical.
81
+ const sanitize_cache = new Map();
78
82
  // Sanitize HTML string, allowing only safe formatting tags and links.
79
83
  // Two-pass: happy-dom promotes dangerous children when a non-allowed parent is
80
84
  // stripped (e.g. <div><script>…</script></div> → <script>…</script>). The first
81
85
  // pass explicitly removes dangerous tags so they can't survive promotion.
82
86
  export function sanitize_html(html) {
83
87
  const str = stringify_html_input(html);
88
+ const cached = sanitize_cache.get(str);
89
+ if (cached !== undefined)
90
+ return cached;
84
91
  const dp = get_purify();
85
92
  if (!dp)
86
- return str;
93
+ return str; // no DOM (SSR): return as-is, don't cache
87
94
  // oxfmt-ignore
88
95
  const safe = dp.sanitize(str, { ADD_ATTR: [`target`], FORBID_TAGS: [
89
96
  `script`, `style`, `iframe`, `object`, `embed`, `form`, `input`, `textarea`,
90
97
  `select`, `button`, `meta`, `link`, `base`, `template`, `noscript`,
91
98
  ] });
92
- return dp.sanitize(safe, { ALLOWED_TAGS: SAFE_TAGS, ALLOWED_ATTR: SAFE_ATTRS });
99
+ const result = dp.sanitize(safe, { ALLOWED_TAGS: SAFE_TAGS, ALLOWED_ATTR: SAFE_ATTRS });
100
+ if (sanitize_cache.size >= 4096)
101
+ sanitize_cache.clear(); // bound memory (rarely hit)
102
+ sanitize_cache.set(str, result);
103
+ return result;
93
104
  }
94
105
  export const compact_formula = (formula) => formula.replaceAll(/\s+/g, ``);
95
106
  // Sanitize a chemical formula with optional subscript formatting
@@ -0,0 +1,62 @@
1
+ <script lang="ts">
2
+ // Dual perspective/orthographic camera with OrbitControls + axis Gizmo, shared by BrillouinZoneScene, FermiSurfaceScene and StructureScene
3
+ import type { Vec3 } from '../math'
4
+ import { type CameraProjection, DEFAULTS } from '../settings'
5
+ import { T } from '@threlte/core'
6
+ import * as extras from '@threlte/extras'
7
+ import type { ComponentProps } from 'svelte'
8
+ import { build_gizmo_props, build_orbit_props } from './props'
9
+
10
+ let {
11
+ camera_projection = `perspective`,
12
+ position,
13
+ fov = DEFAULTS.structure.fov,
14
+ zoom = DEFAULTS.structure.initial_zoom,
15
+ near = undefined,
16
+ far = undefined,
17
+ orbit_props,
18
+ gizmo = false,
19
+ orbit_controls = $bindable(undefined),
20
+ }: {
21
+ camera_projection?: CameraProjection
22
+ position: Vec3 // camera position
23
+ fov?: number // perspective field of view
24
+ zoom?: number // orthographic zoom level
25
+ near?: number // perspective near plane (orthographic always uses -100)
26
+ far?: number // far plane (applied to either projection when provided)
27
+ orbit_props: ReturnType<typeof build_orbit_props>
28
+ gizmo?: boolean | ComponentProps<typeof extras.Gizmo>
29
+ orbit_controls?: ComponentProps<typeof extras.OrbitControls>[`ref`]
30
+ } = $props()
31
+
32
+ const gizmo_props = $derived(build_gizmo_props(gizmo))
33
+ // Only pass clipping planes that were explicitly provided so three.js defaults apply otherwise
34
+ const persp_planes = $derived({
35
+ ...(near !== undefined && { near }),
36
+ ...(far !== undefined && { far }),
37
+ })
38
+ const ortho_far = $derived(far !== undefined ? { far } : {})
39
+ </script>
40
+
41
+ {#snippet camera_contents()}
42
+ <extras.OrbitControls bind:ref={orbit_controls} {...orbit_props}>
43
+ {#if gizmo}<extras.Gizmo {...gizmo_props} />{/if}
44
+ </extras.OrbitControls>
45
+ {/snippet}
46
+
47
+ {#if camera_projection === `perspective`}
48
+ <T.PerspectiveCamera makeDefault {position} {fov} {...persp_planes}>
49
+ {@render camera_contents()}
50
+ </T.PerspectiveCamera>
51
+ {:else}
52
+ <T.OrthographicCamera makeDefault {position} {zoom} near={-100} {...ortho_far}>
53
+ {@render camera_contents()}
54
+ </T.OrthographicCamera>
55
+ {/if}
56
+
57
+ <style>
58
+ :global(.responsive-gizmo) {
59
+ width: clamp(70px, 18cqmin, 100px) !important;
60
+ height: clamp(70px, 18cqmin, 100px) !important;
61
+ }
62
+ </style>
@@ -0,0 +1,19 @@
1
+ import type { Vec3 } from '../math';
2
+ import { type CameraProjection } from '../settings';
3
+ import * as extras from '@threlte/extras';
4
+ import type { ComponentProps } from 'svelte';
5
+ import { build_orbit_props } from './props';
6
+ type $$ComponentProps = {
7
+ camera_projection?: CameraProjection;
8
+ position: Vec3;
9
+ fov?: number;
10
+ zoom?: number;
11
+ near?: number;
12
+ far?: number;
13
+ orbit_props: ReturnType<typeof build_orbit_props>;
14
+ gizmo?: boolean | ComponentProps<typeof extras.Gizmo>;
15
+ orbit_controls?: ComponentProps<typeof extras.OrbitControls>[`ref`];
16
+ };
17
+ declare const SceneCamera: import("svelte").Component<$$ComponentProps, {}, "orbit_controls">;
18
+ type SceneCamera = ReturnType<typeof SceneCamera>;
19
+ export default SceneCamera;
@@ -0,0 +1,2 @@
1
+ import type { Camera, Scene, WebGLRenderer } from 'three';
2
+ export declare function bind_renderer(on_bind: (scene: Scene, camera: Camera) => void, on_renderer?: (renderer: WebGLRenderer) => void): import("@threlte/core").ThrelteContext<WebGLRenderer>;
@@ -0,0 +1,14 @@
1
+ import { renderer_registry } from '../io/export';
2
+ import { useThrelte } from '@threlte/core';
3
+ // Mirror the Threlte scene + active camera into bindable props (for export panes etc.) and register the canvas->renderer mapping so PNG-export helpers can find it. Creates an $effect (call during component init). Returns the Threlte context for further use (e.g. clipping planes).
4
+ export function bind_renderer(on_bind, on_renderer) {
5
+ const threlte = useThrelte();
6
+ $effect(() => {
7
+ on_bind(threlte.scene, threlte.camera.current);
8
+ if (threlte.renderer) {
9
+ on_renderer?.(threlte.renderer);
10
+ renderer_registry.set(threlte.renderer.domElement, threlte.renderer);
11
+ }
12
+ });
13
+ return threlte;
14
+ }
@@ -0,0 +1,4 @@
1
+ export * from './bind-renderer.svelte';
2
+ export * from './props';
3
+ export { default as SceneCamera } from './SceneCamera.svelte';
4
+ export type * from './types';
@@ -0,0 +1,5 @@
1
+ // Shared Three.js/Threlte scene boilerplate (cameras, orbit controls, gizmo,
2
+ // renderer binding) used by BrillouinZoneScene, FermiSurfaceScene and StructureScene.
3
+ export * from './bind-renderer.svelte';
4
+ export * from './props';
5
+ export { default as SceneCamera } from './SceneCamera.svelte';
@@ -0,0 +1,52 @@
1
+ import { AXIS_COLORS, NEG_AXIS_COLORS } from '../colors';
2
+ // ScatterPlot3DScene keeps its own gizmo/orbit props on purpose: its gizmo offset is
3
+ // ColorBar-aware (build_gizmo_props' fixed offset would clobber it) and its orbit controls
4
+ // differ by design (no zoom-to-cursor / ortho zoom-doubling / camera-moving tracking).
5
+ // Shared Gizmo config: colored +/- axis handles, transparent background, responsive sizing. An object `gizmo` overrides the per-axis defaults.
6
+ export function build_gizmo_props(gizmo) {
7
+ return {
8
+ background: { enabled: false },
9
+ className: `responsive-gizmo`,
10
+ ...Object.fromEntries([...AXIS_COLORS, ...NEG_AXIS_COLORS].map(([axis, color, hover]) => [
11
+ axis,
12
+ {
13
+ color,
14
+ labelColor: `#111`,
15
+ opacity: axis.startsWith(`n`) ? 0.9 : 0.8,
16
+ hover: {
17
+ color: hover,
18
+ labelColor: `#222`,
19
+ opacity: axis.startsWith(`n`) ? 1 : 0.9,
20
+ },
21
+ },
22
+ ])),
23
+ ...(typeof gizmo === `object` ? gizmo : {}),
24
+ offset: { left: 5, bottom: 5 },
25
+ };
26
+ }
27
+ // Shared OrbitControls config; `onstart_extra` runs extra cleanup when the camera starts moving (e.g. StructureScene closes hover tooltips/context menus)
28
+ export function build_orbit_props(opts) {
29
+ const is_ortho = opts.camera_projection === `orthographic`;
30
+ return {
31
+ position: [0, 0, 0],
32
+ target: opts.target,
33
+ enableRotate: opts.rotate_speed > 0,
34
+ rotateSpeed: opts.rotate_speed,
35
+ enableZoom: opts.zoom_speed > 0,
36
+ zoomSpeed: is_ortho ? opts.zoom_speed * 2 : opts.zoom_speed,
37
+ zoomToCursor: opts.zoom_to_cursor,
38
+ enablePan: opts.pan_speed > 0,
39
+ panSpeed: opts.pan_speed,
40
+ maxZoom: opts.max_zoom,
41
+ minZoom: opts.min_zoom,
42
+ autoRotate: Boolean(opts.auto_rotate),
43
+ autoRotateSpeed: opts.auto_rotate,
44
+ enableDamping: Boolean(opts.rotation_damping),
45
+ dampingFactor: opts.rotation_damping,
46
+ onstart: () => {
47
+ opts.set_camera_is_moving?.(true);
48
+ opts.onstart_extra?.();
49
+ },
50
+ onend: () => opts.set_camera_is_moving?.(false),
51
+ };
52
+ }
@@ -0,0 +1,26 @@
1
+ import type { CameraProjection } from '../settings';
2
+ import type { Gizmo } from '@threlte/extras';
3
+ import type { ComponentProps } from 'svelte';
4
+ import type { Camera, Scene, Vector3 } from 'three';
5
+ export type ThreltePointerEvent = {
6
+ point: Vector3;
7
+ nativeEvent: PointerEvent;
8
+ };
9
+ export type SceneControlProps = {
10
+ camera_projection?: CameraProjection;
11
+ rotation_damping?: number;
12
+ max_zoom?: number;
13
+ min_zoom?: number;
14
+ rotate_speed?: number;
15
+ zoom_speed?: number;
16
+ pan_speed?: number;
17
+ zoom_to_cursor?: boolean;
18
+ fov?: number;
19
+ initial_zoom?: number;
20
+ ambient_light?: number;
21
+ directional_light?: number;
22
+ gizmo?: boolean | ComponentProps<typeof Gizmo>;
23
+ auto_rotate?: number;
24
+ scene?: Scene;
25
+ camera?: Camera;
26
+ };
@@ -0,0 +1 @@
1
+ export {};