matterviz 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (527) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +12 -14
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/app.css +53 -0
  6. package/dist/brillouin/BrillouinZone.svelte +132 -219
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +9 -20
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +47 -96
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +15 -42
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  13. package/dist/brillouin/BrillouinZoneScene.svelte +63 -230
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
  15. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  16. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  17. package/dist/brillouin/compute.d.ts +2 -0
  18. package/dist/brillouin/compute.js +80 -77
  19. package/dist/brillouin/geometry.d.ts +8 -0
  20. package/dist/brillouin/geometry.js +57 -0
  21. package/dist/brillouin/index.d.ts +2 -0
  22. package/dist/brillouin/index.js +2 -0
  23. package/dist/brillouin/types.d.ts +2 -2
  24. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  25. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  26. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +143 -246
  27. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  28. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +652 -976
  29. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  30. package/dist/chempot-diagram/async-compute.svelte.js +1 -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 +3 -3
  34. package/dist/chempot-diagram/compute.js +3 -1
  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.d.ts +0 -4
  45. package/dist/colors/index.js +21 -22
  46. package/dist/composition/BarChart.svelte +37 -31
  47. package/dist/composition/BubbleChart.svelte +17 -17
  48. package/dist/composition/Composition.svelte +7 -11
  49. package/dist/composition/Formula.svelte +18 -25
  50. package/dist/composition/FormulaFilter.svelte +96 -98
  51. package/dist/composition/PieChart.svelte +60 -46
  52. package/dist/composition/chem-sys.js +3 -2
  53. package/dist/composition/format.js +4 -3
  54. package/dist/composition/index.d.ts +2 -0
  55. package/dist/composition/index.js +14 -0
  56. package/dist/composition/parse.d.ts +2 -3
  57. package/dist/composition/parse.js +27 -28
  58. package/dist/constants.js +11 -9
  59. package/dist/controls.d.ts +1 -0
  60. package/dist/controls.js +0 -1
  61. package/dist/convex-hull/ConvexHull.svelte +20 -25
  62. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  63. package/dist/convex-hull/ConvexHull2D.svelte +176 -256
  64. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  65. package/dist/convex-hull/ConvexHull3D.svelte +269 -804
  66. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  67. package/dist/convex-hull/ConvexHull4D.svelte +236 -755
  68. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  69. package/dist/convex-hull/ConvexHullChrome.svelte +264 -0
  70. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  71. package/dist/convex-hull/ConvexHullControls.svelte +128 -49
  72. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  73. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  74. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  75. package/dist/convex-hull/ConvexHullStats.svelte +210 -351
  76. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  77. package/dist/convex-hull/ConvexHullTooltip.svelte +16 -14
  78. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  79. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  80. package/dist/convex-hull/StructurePopup.svelte +17 -21
  81. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  82. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  83. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  84. package/dist/convex-hull/barycentric-coords.js +6 -33
  85. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  86. package/dist/convex-hull/canvas-interactions.svelte.js +279 -0
  87. package/dist/convex-hull/helpers.d.ts +47 -17
  88. package/dist/convex-hull/helpers.js +186 -101
  89. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  90. package/dist/convex-hull/hull-state.svelte.js +124 -0
  91. package/dist/convex-hull/index.d.ts +9 -7
  92. package/dist/convex-hull/index.js +7 -2
  93. package/dist/convex-hull/thermodynamics.js +109 -937
  94. package/dist/convex-hull/types.d.ts +12 -4
  95. package/dist/convex-hull/types.js +12 -0
  96. package/dist/coordination/CoordinationBarPlot.svelte +41 -43
  97. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  98. package/dist/coordination/calc-coordination.d.ts +1 -1
  99. package/dist/coordination/calc-coordination.js +28 -25
  100. package/dist/element/BohrAtom.svelte +6 -8
  101. package/dist/element/ElementHeading.svelte +4 -1
  102. package/dist/element/ElementPhoto.svelte +11 -9
  103. package/dist/element/ElementStats.svelte +12 -10
  104. package/dist/element/ElementTile.svelte +24 -29
  105. package/dist/element/ElementTile.svelte.d.ts +1 -1
  106. package/dist/element/Nucleus.svelte +4 -2
  107. package/dist/element/data.d.ts +1 -2
  108. package/dist/element/helpers.d.ts +4 -0
  109. package/dist/element/helpers.js +18 -0
  110. package/dist/element/index.d.ts +1 -0
  111. package/dist/element/index.js +3 -0
  112. package/dist/feedback/DragOverlay.svelte +5 -3
  113. package/dist/feedback/DragOverlay.svelte.d.ts +2 -1
  114. package/dist/feedback/StatusMessage.svelte +20 -7
  115. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  116. package/dist/fermi-surface/FermiSurface.svelte +78 -165
  117. package/dist/fermi-surface/FermiSurface.svelte.d.ts +9 -20
  118. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  119. package/dist/fermi-surface/FermiSurfaceScene.svelte +93 -272
  120. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  121. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  122. package/dist/fermi-surface/compute.js +14 -13
  123. package/dist/fermi-surface/export.js +4 -15
  124. package/dist/fermi-surface/index.d.ts +0 -1
  125. package/dist/fermi-surface/index.js +0 -1
  126. package/dist/fermi-surface/parse.d.ts +1 -1
  127. package/dist/fermi-surface/parse.js +84 -97
  128. package/dist/fermi-surface/types.d.ts +2 -2
  129. package/dist/heatmap-matrix/HeatmapMatrix.svelte +161 -185
  130. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +6 -5
  131. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +12 -9
  132. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  133. package/dist/heatmap-matrix/index.d.ts +8 -2
  134. package/dist/icons.d.ts +4 -0
  135. package/dist/icons.js +4 -0
  136. package/dist/index.d.ts +1 -0
  137. package/dist/index.js +1 -0
  138. package/dist/io/ExportPane.svelte +170 -0
  139. package/dist/io/ExportPane.svelte.d.ts +17 -0
  140. package/dist/io/decompress.d.ts +2 -1
  141. package/dist/io/decompress.js +22 -36
  142. package/dist/io/export.d.ts +9 -1
  143. package/dist/io/export.js +37 -29
  144. package/dist/io/fetch.d.ts +2 -4
  145. package/dist/io/fetch.js +0 -11
  146. package/dist/io/file-drop.d.ts +7 -0
  147. package/dist/io/file-drop.js +13 -0
  148. package/dist/io/index.d.ts +1 -0
  149. package/dist/io/index.js +3 -0
  150. package/dist/io/is-binary.d.ts +9 -0
  151. package/dist/io/is-binary.js +45 -1
  152. package/dist/io/types.d.ts +13 -0
  153. package/dist/io/url-drop.js +13 -25
  154. package/dist/isosurface/Isosurface.svelte +17 -23
  155. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  156. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  157. package/dist/isosurface/parse-vaspwave.js +138 -0
  158. package/dist/isosurface/parse.js +50 -48
  159. package/dist/labels.d.ts +6 -2
  160. package/dist/labels.js +44 -14
  161. package/dist/layout/FullscreenButton.svelte +34 -0
  162. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  163. package/dist/layout/FullscreenToggle.svelte +12 -12
  164. package/dist/layout/InfoCard.svelte +7 -18
  165. package/dist/layout/InfoTag.svelte +1 -3
  166. package/dist/layout/NumberRangeInput.svelte +46 -0
  167. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  168. package/dist/layout/PropertyFilter.svelte +2 -6
  169. package/dist/layout/SettingsSection.svelte +21 -17
  170. package/dist/layout/SubpageGrid.svelte +3 -1
  171. package/dist/layout/ViewerChrome.svelte +115 -0
  172. package/dist/layout/ViewerChrome.svelte.d.ts +18 -0
  173. package/dist/layout/fullscreen.d.ts +4 -0
  174. package/dist/layout/fullscreen.js +3 -5
  175. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  176. package/dist/layout/fullscreen.svelte.js +36 -0
  177. package/dist/layout/index.d.ts +4 -0
  178. package/dist/layout/index.js +4 -0
  179. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  180. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  181. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  182. package/dist/layout/json-tree/utils.js +14 -23
  183. package/dist/math.d.ts +9 -3
  184. package/dist/math.js +37 -21
  185. package/dist/overlays/ContextMenu.svelte +4 -2
  186. package/dist/overlays/CopyButton.svelte +11 -5
  187. package/dist/overlays/DragControlTab.svelte +6 -1
  188. package/dist/overlays/DraggablePane.svelte +81 -26
  189. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  190. package/dist/overlays/GlassChip.svelte +30 -0
  191. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  192. package/dist/overlays/InfoPaneCards.svelte +11 -23
  193. package/dist/overlays/index.d.ts +11 -0
  194. package/dist/overlays/index.js +26 -0
  195. package/dist/overlays/portal.d.ts +2 -0
  196. package/dist/overlays/portal.js +14 -0
  197. package/dist/periodic-table/PeriodicTable.svelte +115 -146
  198. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  199. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  200. package/dist/periodic-table/TableInset.svelte +9 -4
  201. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  202. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  203. package/dist/phase-diagram/PhaseDiagramControls.svelte +73 -96
  204. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  205. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
  206. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  207. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +49 -134
  208. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  209. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  210. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  211. package/dist/phase-diagram/build-diagram.js +3 -3
  212. package/dist/phase-diagram/colors.js +1 -1
  213. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  214. package/dist/phase-diagram/parse.d.ts +2 -1
  215. package/dist/phase-diagram/parse.js +15 -15
  216. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  217. package/dist/phase-diagram/utils.js +2 -3
  218. package/dist/plot/bar/BarPlot.svelte +494 -692
  219. package/dist/plot/bar/BarPlot.svelte.d.ts +9 -15
  220. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  221. package/dist/plot/bar/BarPlotControls.svelte.d.ts +5 -7
  222. package/dist/plot/bar/SpacegroupBarPlot.svelte +31 -37
  223. package/dist/plot/bar/data.d.ts +5 -4
  224. package/dist/plot/bar/data.js +2 -1
  225. package/dist/plot/box/BoxPlot.svelte +361 -439
  226. package/dist/plot/box/BoxPlot.svelte.d.ts +6 -3
  227. package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
  228. package/dist/plot/box/Violin.svelte.d.ts +2 -1
  229. package/dist/plot/box/box-plot.d.ts +3 -2
  230. package/dist/plot/box/box-plot.js +6 -3
  231. package/dist/plot/box/kde.d.ts +2 -1
  232. package/dist/plot/box/kde.js +4 -4
  233. package/dist/plot/core/auto-place.d.ts +1 -1
  234. package/dist/plot/core/auto-place.js +5 -2
  235. package/dist/plot/core/axis-utils.d.ts +12 -7
  236. package/dist/plot/core/axis-utils.js +48 -48
  237. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  238. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  239. package/dist/plot/core/components/ColorBar.svelte +106 -111
  240. package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
  241. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  242. package/dist/plot/core/components/FillArea.svelte +10 -17
  243. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  244. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  245. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  246. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  247. package/dist/plot/core/components/Line.svelte +21 -11
  248. package/dist/plot/core/components/Line.svelte.d.ts +5 -2
  249. package/dist/plot/core/components/PlotAxis.svelte +42 -18
  250. package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
  251. package/dist/plot/core/components/PlotControls.svelte +65 -41
  252. package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
  253. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  254. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  255. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  256. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  257. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  258. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  259. package/dist/plot/core/components/ReferenceLine3D.svelte +56 -59
  260. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
  261. package/dist/plot/core/components/ReferencePlane.svelte +9 -10
  262. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
  263. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  264. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  265. package/dist/plot/core/components/index.d.ts +1 -0
  266. package/dist/plot/core/components/index.js +1 -0
  267. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  268. package/dist/plot/core/data-cleaning-signal.js +467 -0
  269. package/dist/plot/core/data-cleaning.d.ts +2 -42
  270. package/dist/plot/core/data-cleaning.js +29 -476
  271. package/dist/plot/core/data-transform.js +9 -5
  272. package/dist/plot/core/fill-utils.d.ts +7 -4
  273. package/dist/plot/core/fill-utils.js +34 -9
  274. package/dist/plot/core/index.d.ts +1 -0
  275. package/dist/plot/core/index.js +1 -0
  276. package/dist/plot/core/interactions.d.ts +5 -1
  277. package/dist/plot/core/interactions.js +14 -2
  278. package/dist/plot/core/layout.d.ts +3 -1
  279. package/dist/plot/core/layout.js +22 -13
  280. package/dist/plot/core/marginals.d.ts +170 -0
  281. package/dist/plot/core/marginals.js +436 -0
  282. package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
  283. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  284. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -0
  286. package/dist/plot/core/reference-line.d.ts +10 -10
  287. package/dist/plot/core/reference-line.js +7 -7
  288. package/dist/plot/core/scales.d.ts +40 -25
  289. package/dist/plot/core/scales.js +49 -21
  290. package/dist/plot/core/svg.d.ts +2 -1
  291. package/dist/plot/core/types/fills.d.ts +101 -0
  292. package/dist/plot/core/types/fills.js +15 -0
  293. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  294. package/dist/plot/core/types/plot-3d.js +4 -0
  295. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  296. package/dist/plot/core/types/reference-lines.js +9 -0
  297. package/dist/plot/core/types.d.ts +47 -331
  298. package/dist/plot/core/types.js +23 -20
  299. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  300. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  301. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  302. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  303. package/dist/plot/core/utils/label-placement.d.ts +1 -1
  304. package/dist/plot/core/utils/label-placement.js +5 -5
  305. package/dist/plot/core/utils.d.ts +2 -1
  306. package/dist/plot/histogram/Histogram.svelte +373 -631
  307. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  308. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  309. package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
  310. package/dist/plot/histogram/histogram.d.ts +31 -0
  311. package/dist/plot/histogram/histogram.js +70 -0
  312. package/dist/plot/histogram/index.d.ts +1 -0
  313. package/dist/plot/histogram/index.js +1 -0
  314. package/dist/plot/index.d.ts +1 -0
  315. package/dist/plot/index.js +1 -0
  316. package/dist/plot/sankey/Sankey.svelte +79 -73
  317. package/dist/plot/sankey/Sankey.svelte.d.ts +3 -3
  318. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  319. package/dist/plot/sankey/sankey.js +3 -1
  320. package/dist/plot/scatter/BinnedScatterPlot.svelte +264 -112
  321. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +11 -4
  322. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  323. package/dist/plot/scatter/ScatterPlot.svelte +623 -821
  324. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +9 -15
  325. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  326. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  327. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  328. package/dist/plot/scatter/binned-scatter-types.d.ts +6 -12
  329. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  330. package/dist/plot/scatter/index.d.ts +1 -1
  331. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  332. package/dist/plot/scatter/scatter-data.js +8 -7
  333. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +40 -60
  334. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
  335. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +17 -15
  336. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
  337. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +232 -234
  338. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
  339. package/dist/plot/scatter-3d/Surface3D.svelte +9 -17
  340. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
  341. package/dist/plot/sunburst/Sunburst.svelte +256 -338
  342. package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
  343. package/dist/plot/sunburst/index.d.ts +1 -1
  344. package/dist/plot/sunburst/index.js +2 -1
  345. package/dist/plot/sunburst/render.d.ts +2 -2
  346. package/dist/plot/sunburst/render.js +47 -22
  347. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  348. package/dist/plot/sunburst/sunburst.js +14 -4
  349. package/dist/plot/treemap/Treemap.svelte +907 -0
  350. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  351. package/dist/plot/treemap/index.d.ts +3 -0
  352. package/dist/plot/treemap/index.js +4 -0
  353. package/dist/plot/treemap/treemap.d.ts +26 -0
  354. package/dist/plot/treemap/treemap.js +99 -0
  355. package/dist/rdf/RdfPlot.svelte +22 -26
  356. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  357. package/dist/rdf/calc-rdf.js +4 -8
  358. package/dist/sanitize.js +14 -3
  359. package/dist/scene/SceneCamera.svelte +62 -0
  360. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  361. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  362. package/dist/scene/bind-renderer.svelte.js +22 -0
  363. package/dist/scene/index.d.ts +4 -0
  364. package/dist/scene/index.js +5 -0
  365. package/dist/scene/props.js +52 -0
  366. package/dist/scene/types.d.ts +26 -0
  367. package/dist/scene/types.js +1 -0
  368. package/dist/settings.d.ts +33 -11
  369. package/dist/settings.js +136 -51
  370. package/dist/spectral/Bands.svelte +231 -237
  371. package/dist/spectral/Bands.svelte.d.ts +3 -2
  372. package/dist/spectral/BandsAndDos.svelte +29 -29
  373. package/dist/spectral/BrillouinBandsDos.svelte +21 -29
  374. package/dist/spectral/Dos.svelte +75 -77
  375. package/dist/spectral/Dos.svelte.d.ts +2 -1
  376. package/dist/spectral/helpers.d.ts +9 -9
  377. package/dist/spectral/helpers.js +66 -70
  378. package/dist/state.svelte.d.ts +0 -7
  379. package/dist/state.svelte.js +5 -24
  380. package/dist/structure/Arrow.svelte +6 -21
  381. package/dist/structure/ArrowInstances.svelte +160 -0
  382. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  383. package/dist/structure/AtomLegend.svelte +115 -75
  384. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  385. package/dist/structure/Bond.svelte +31 -23
  386. package/dist/structure/CanvasTooltip.svelte +16 -3
  387. package/dist/structure/CellSelect.svelte +22 -29
  388. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  389. package/dist/structure/Cylinder.svelte +24 -40
  390. package/dist/structure/InstancedAtoms.svelte +114 -0
  391. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  392. package/dist/structure/Lattice.svelte +85 -149
  393. package/dist/structure/SiteLabels.svelte +122 -0
  394. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  395. package/dist/structure/Structure.svelte +725 -735
  396. package/dist/structure/Structure.svelte.d.ts +8 -16
  397. package/dist/structure/StructureCarousel.svelte +630 -0
  398. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  399. package/dist/structure/StructureControls.svelte +298 -325
  400. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  401. package/dist/structure/StructureExportPane.svelte +62 -168
  402. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  403. package/dist/structure/StructureInfoPane.svelte +77 -69
  404. package/dist/structure/StructureInfoPane.svelte.d.ts +6 -6
  405. package/dist/structure/StructureScene.svelte +758 -600
  406. package/dist/structure/StructureScene.svelte.d.ts +24 -20
  407. package/dist/structure/StructureViewport.svelte +386 -0
  408. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  409. package/dist/structure/atom-label-placement.d.ts +18 -0
  410. package/dist/structure/atom-label-placement.js +115 -0
  411. package/dist/structure/atom-properties.d.ts +3 -1
  412. package/dist/structure/atom-properties.js +115 -54
  413. package/dist/structure/bond-order-perception.js +2 -4
  414. package/dist/structure/bonding.d.ts +12 -2
  415. package/dist/structure/bonding.js +172 -73
  416. package/dist/structure/edit-history.d.ts +6 -0
  417. package/dist/structure/edit-history.js +27 -0
  418. package/dist/structure/export.d.ts +25 -4
  419. package/dist/structure/export.js +103 -153
  420. package/dist/structure/format-detect.d.ts +1 -0
  421. package/dist/structure/format-detect.js +22 -0
  422. package/dist/structure/geometry.d.ts +9 -0
  423. package/dist/structure/geometry.js +27 -0
  424. package/dist/structure/index.d.ts +18 -1
  425. package/dist/structure/index.js +15 -2
  426. package/dist/structure/measure.d.ts +1 -1
  427. package/dist/structure/measure.js +6 -12
  428. package/dist/structure/parse.d.ts +5 -3
  429. package/dist/structure/parse.js +551 -567
  430. package/dist/structure/partial-occupancy.d.ts +0 -1
  431. package/dist/structure/partial-occupancy.js +5 -3
  432. package/dist/structure/pbc.d.ts +1 -1
  433. package/dist/structure/pbc.js +204 -51
  434. package/dist/structure/polyhedra.d.ts +40 -0
  435. package/dist/structure/polyhedra.js +587 -0
  436. package/dist/structure/site.d.ts +4 -0
  437. package/dist/structure/site.js +1 -0
  438. package/dist/structure/supercell.d.ts +1 -2
  439. package/dist/structure/supercell.js +10 -15
  440. package/dist/structure/validation.js +5 -6
  441. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  442. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  443. package/dist/symmetry/SymmetryElements.svelte +350 -0
  444. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  445. package/dist/symmetry/SymmetryStats.svelte +142 -49
  446. package/dist/symmetry/WyckoffTable.svelte +58 -16
  447. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  448. package/dist/symmetry/cell-transform.js +8 -14
  449. package/dist/symmetry/index.d.ts +15 -4
  450. package/dist/symmetry/index.js +308 -81
  451. package/dist/symmetry/spacegroups.d.ts +5 -1
  452. package/dist/symmetry/spacegroups.js +18 -3
  453. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  454. package/dist/symmetry/symmetry-elements.js +521 -0
  455. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  456. package/dist/symmetry/wyckoff-db.js +87 -0
  457. package/dist/table/HeatmapTable.svelte +1104 -378
  458. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  459. package/dist/table/ToggleMenu.svelte +5 -12
  460. package/dist/table/index.d.ts +21 -6
  461. package/dist/table/index.js +34 -21
  462. package/dist/theme/ThemeControl.svelte +16 -8
  463. package/dist/theme/index.d.ts +1 -5
  464. package/dist/theme/index.js +4 -10
  465. package/dist/theme/themes.mjs +14 -7
  466. package/dist/tooltip/KCoords.svelte +4 -1
  467. package/dist/tooltip/TooltipContent.svelte +2 -5
  468. package/dist/trajectory/Trajectory.svelte +556 -352
  469. package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
  470. package/dist/trajectory/TrajectoryError.svelte +11 -8
  471. package/dist/trajectory/TrajectoryExportPane.svelte +28 -54
  472. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  473. package/dist/trajectory/TrajectoryInfoPane.svelte +88 -99
  474. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  475. package/dist/trajectory/constants.js +6 -2
  476. package/dist/trajectory/extract.js +73 -71
  477. package/dist/trajectory/format-detect.d.ts +0 -1
  478. package/dist/trajectory/format-detect.js +13 -17
  479. package/dist/trajectory/frame-reader.d.ts +2 -1
  480. package/dist/trajectory/frame-reader.js +74 -136
  481. package/dist/trajectory/helpers.d.ts +12 -2
  482. package/dist/trajectory/helpers.js +68 -37
  483. package/dist/trajectory/index.d.ts +1 -0
  484. package/dist/trajectory/index.js +3 -0
  485. package/dist/trajectory/parse/ase.d.ts +9 -1
  486. package/dist/trajectory/parse/ase.js +47 -32
  487. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  488. package/dist/trajectory/parse/diagnostics.js +14 -0
  489. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  490. package/dist/trajectory/parse/h5-utils.js +109 -0
  491. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  492. package/dist/trajectory/parse/hdf5.js +116 -106
  493. package/dist/trajectory/parse/index.d.ts +3 -4
  494. package/dist/trajectory/parse/index.js +68 -119
  495. package/dist/trajectory/parse/lammps.d.ts +0 -2
  496. package/dist/trajectory/parse/lammps.js +14 -16
  497. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  498. package/dist/trajectory/parse/pymatgen.js +74 -0
  499. package/dist/trajectory/parse/vasp.js +13 -9
  500. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  501. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  502. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  503. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  504. package/dist/trajectory/parse/xyz.d.ts +9 -21
  505. package/dist/trajectory/parse/xyz.js +38 -39
  506. package/dist/trajectory/plotting.d.ts +8 -10
  507. package/dist/trajectory/plotting.js +102 -127
  508. package/dist/utils.d.ts +4 -0
  509. package/dist/utils.js +8 -1
  510. package/dist/xrd/XrdPlot.svelte +56 -85
  511. package/dist/xrd/broadening.d.ts +2 -1
  512. package/dist/xrd/broadening.js +2 -1
  513. package/dist/xrd/calc-xrd.js +8 -15
  514. package/dist/xrd/index.d.ts +2 -2
  515. package/dist/xrd/parse.d.ts +0 -1
  516. package/dist/xrd/parse.js +56 -73
  517. package/package.json +77 -36
  518. package/dist/api/mp.d.ts +0 -6
  519. package/dist/api/mp.js +0 -22
  520. package/dist/element/data.json +0 -11864
  521. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  522. package/dist/fermi-surface/marching-cubes.js +0 -2
  523. package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
  524. package/dist/plot/core/hover-lock.svelte.js +0 -45
  525. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  526. package/dist/structure/label-placement.d.ts +0 -14
  527. package/dist/structure/label-placement.js +0 -72
@@ -1,9 +1,10 @@
1
1
  import type { D3InterpolateName } from '../colors';
2
+ import type { Vec2 } from '../math';
2
3
  import type { AxisConfig } from '../plot';
3
4
  import { type ComponentProps, type Snippet } from 'svelte';
4
5
  import type { HTMLAttributes } from 'svelte/elements';
5
6
  import HeatmapMatrixControls from './HeatmapMatrixControls.svelte';
6
- import type { AxisItem, CellContext, DomainMode, HeatmapExportFormat, HeatmapTooltipProp, LegendPosition, NormalizeMode, SymmetricMode } from './index';
7
+ import type { AxisItem, CellContext, DomainMode, HeatmapExportFormat, HeatmapTooltipProp, LegendPosition, MissingCellStyle, NormalizeMode, SymmetricMode } from './index';
7
8
  type CellValue = number | string | null;
8
9
  type SelectionMode = `single` | `multi` | `range`;
9
10
  type AxisOrderKey = `label` | `key` | `sort_value`;
@@ -19,7 +20,7 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `onclick` | `ondblc
19
20
  color_scale?: D3InterpolateName | ((val: number) => string);
20
21
  color_scale_range?: [number | null, number | null];
21
22
  color_overrides?: Record<string, string>;
22
- missing_color?: string;
23
+ missing?: MissingCellStyle;
23
24
  log?: boolean;
24
25
  value_transform?: (value: number, ctx: {
25
26
  x_item: AxisItem;
@@ -29,7 +30,7 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `onclick` | `ondblc
29
30
  }) => number | null;
30
31
  normalize?: NormalizeMode;
31
32
  domain_mode?: DomainMode;
32
- quantile_clip?: [number, number];
33
+ quantile_clip?: Vec2;
33
34
  show_legend?: boolean;
34
35
  legend_position?: LegendPosition;
35
36
  legend_label?: string;
@@ -51,8 +52,8 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `onclick` | `ondblc
51
52
  oncontextmenu?: (cell: CellContext, event: MouseEvent) => void;
52
53
  enable_brush?: boolean;
53
54
  onbrush?: (payload: {
54
- x_range: [number, number];
55
- y_range: [number, number];
55
+ x_range: Vec2;
56
+ y_range: Vec2;
56
57
  cells: CellContext[];
57
58
  }) => void;
58
59
  tile_size?: string;
@@ -1,11 +1,16 @@
1
1
  <script lang="ts">
2
+ import type { PaneProps, PaneToggleProps } from '../overlays'
2
3
  import DraggablePane from '../overlays/DraggablePane.svelte'
3
4
  import type { ComponentProps, Snippet } from 'svelte'
4
- import {
5
- ELEMENT_ORDERINGS,
6
- ORDERING_LABELS,
5
+ import { ELEMENT_ORDERINGS, ORDERING_LABELS } from './index'
6
+ import type {
7
+ ElementAxisOrderingKey,
8
+ DomainMode,
9
+ HeatmapExportFormat,
10
+ LegendPosition,
11
+ NormalizeMode,
12
+ SymmetricMode,
7
13
  } from './index'
8
- import type { ElementAxisOrderingKey, DomainMode, HeatmapExportFormat, LegendPosition, NormalizeMode, SymmetricMode } from './index'
9
14
 
10
15
  let {
11
16
  ordering = $bindable(`atomic_number`),
@@ -46,15 +51,13 @@
46
51
  export_formats?: HeatmapExportFormat[]
47
52
  onexport?: (format: HeatmapExportFormat) => void
48
53
  show_pane?: boolean
49
- pane_props?: ComponentProps<typeof DraggablePane>[`pane_props`]
50
- toggle_props?: ComponentProps<typeof DraggablePane>[`toggle_props`]
54
+ pane_props?: PaneProps
55
+ toggle_props?: PaneToggleProps
51
56
  children?: Snippet<[{ controls_open: boolean }]>
52
57
  } = $props()
53
58
 
54
59
  function merge_styles(base_style: string, override_style: unknown): string {
55
- const override_style_str = typeof override_style === `string`
56
- ? override_style
57
- : ``
60
+ const override_style_str = typeof override_style === `string` ? override_style : ``
58
61
  return override_style_str ? `${base_style}; ${override_style_str}` : base_style
59
62
  }
60
63
 
@@ -1,5 +1,5 @@
1
- import DraggablePane from '../overlays/DraggablePane.svelte';
2
- import type { ComponentProps, Snippet } from 'svelte';
1
+ import type { PaneProps, PaneToggleProps } from '../overlays';
2
+ import type { Snippet } from 'svelte';
3
3
  import type { ElementAxisOrderingKey, DomainMode, HeatmapExportFormat, LegendPosition, NormalizeMode, SymmetricMode } from './index';
4
4
  type $$ComponentProps = {
5
5
  ordering?: ElementAxisOrderingKey;
@@ -19,12 +19,12 @@ type $$ComponentProps = {
19
19
  export_formats?: HeatmapExportFormat[];
20
20
  onexport?: (format: HeatmapExportFormat) => void;
21
21
  show_pane?: boolean;
22
- pane_props?: ComponentProps<typeof DraggablePane>[`pane_props`];
23
- toggle_props?: ComponentProps<typeof DraggablePane>[`toggle_props`];
22
+ pane_props?: PaneProps;
23
+ toggle_props?: PaneToggleProps;
24
24
  children?: Snippet<[{
25
25
  controls_open: boolean;
26
26
  }]>;
27
27
  };
28
- declare const HeatmapMatrixControls: import("svelte").Component<$$ComponentProps, {}, "normalize" | "theme" | "show_legend" | "controls_open" | "show_values" | "ordering" | "toggle_visible" | "domain_mode" | "legend_position" | "search_query" | "symmetric" | "show_row_summaries" | "show_col_summaries">;
28
+ declare const HeatmapMatrixControls: import("svelte").Component<$$ComponentProps, {}, "normalize" | "theme" | "show_values" | "show_legend" | "controls_open" | "ordering" | "search_query" | "toggle_visible" | "domain_mode" | "legend_position" | "symmetric" | "show_row_summaries" | "show_col_summaries">;
29
29
  type HeatmapMatrixControls = ReturnType<typeof HeatmapMatrixControls>;
30
30
  export default HeatmapMatrixControls;
@@ -1,4 +1,5 @@
1
1
  import type { ChemicalElement, ElementSymbol } from '../element';
2
+ import type { Vec2 } from '../math';
2
3
  import type { Snippet } from 'svelte';
3
4
  export { COLOR_OVERRIDE_KEY_SEPARATOR, make_color_override_key } from './shared';
4
5
  export type AxisItem<T = Record<string, unknown>> = {
@@ -16,6 +17,11 @@ export type CellContext = {
16
17
  value: number | string | null;
17
18
  bg_color: string | null;
18
19
  };
20
+ export interface MissingCellStyle {
21
+ color?: `element-category` | (string & {});
22
+ label?: string;
23
+ style?: string;
24
+ }
19
25
  export declare const ORDERING_LABELS: {
20
26
  readonly atomic_number: "Atomic Number";
21
27
  readonly mendeleev_number: "Pettifor Chemical Similarity";
@@ -41,8 +47,8 @@ export type HeatmapSelection = {
41
47
  };
42
48
  export type HeatmapExportFormat = `csv` | `json`;
43
49
  export type HeatmapBrushPayload = {
44
- x_range: [number, number];
45
- y_range: [number, number];
50
+ x_range: Vec2;
51
+ y_range: Vec2;
46
52
  cells: CellContext[];
47
53
  };
48
54
  export declare const ELEMENT_ORDERINGS: ElementAxisOrderingKey[];
package/dist/icons.d.ts CHANGED
@@ -540,6 +540,10 @@ export declare const ICON_DATA: {
540
540
  readonly viewBox: "0 0 24 24";
541
541
  readonly path: "<path fill=\"currentColor\" d=\"M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M4 4h5v16H4zm7 0h9v8h-9zm0 10h9v6h-9z\"/>";
542
542
  };
543
+ readonly Grid2x2: {
544
+ readonly viewBox: "0 0 24 24";
545
+ readonly path: "<path fill=\"currentColor\" d=\"M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M4 4h7v7H4zm0 9h7v7H4zm9-9h7v7h-7zm0 9h7v7h-7z\"/>";
546
+ };
543
547
  readonly FermiSurface: {
544
548
  readonly viewBox: "0 0 24 24";
545
549
  readonly stroke: "currentColor";
package/dist/icons.js CHANGED
@@ -620,6 +620,10 @@ export const ICON_DATA = {
620
620
  viewBox: `0 0 24 24`,
621
621
  path: `<path fill="currentColor" d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M4 4h5v16H4zm7 0h9v8h-9zm0 10h9v6h-9z"/>`,
622
622
  },
623
+ Grid2x2: {
624
+ viewBox: `0 0 24 24`,
625
+ path: `<path fill="currentColor" d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M4 4h7v7H4zm0 9h7v7H4zm9-9h7v7h-7zm0 9h7v7h-7z"/>`,
626
+ },
623
627
  FermiSurface: {
624
628
  viewBox: `0 0 24 24`,
625
629
  stroke: `currentColor`,
package/dist/index.d.ts CHANGED
@@ -27,6 +27,7 @@ export * from './phase-diagram';
27
27
  export * from './plot';
28
28
  export * from './rdf';
29
29
  export * from './sanitize';
30
+ export * from './scene';
30
31
  export * from './settings';
31
32
  export * from './spectral';
32
33
  export * from './structure';
package/dist/index.js CHANGED
@@ -27,6 +27,7 @@ export * from './phase-diagram';
27
27
  export * from './plot';
28
28
  export * from './rdf';
29
29
  export * from './sanitize';
30
+ export * from './scene';
30
31
  export * from './settings';
31
32
  export * from './spectral';
32
33
  export * from './structure';
@@ -0,0 +1,170 @@
1
+ <script lang="ts">
2
+ import type { PaneProps, PaneToggleProps } from '../overlays'
3
+ import type { ExportItem, ExportSection } from './types'
4
+ import DraggablePane from '../overlays/DraggablePane.svelte'
5
+ import { sanitize_html } from '../sanitize'
6
+ import { type ComponentProps, onDestroy, type Snippet } from 'svelte'
7
+ import { tooltip } from 'svelte-multiselect/attachments'
8
+ import type { HTMLAttributes } from 'svelte/elements'
9
+
10
+ let {
11
+ export_pane_open = $bindable(false),
12
+ sections = [],
13
+ png_dpi = $bindable(150),
14
+ dpi_range = [50, 600],
15
+ icon_style = ``,
16
+ toggle_props = {},
17
+ pane_props = {},
18
+ children = undefined,
19
+ ...rest
20
+ }: HTMLAttributes<HTMLDivElement> & {
21
+ export_pane_open?: boolean
22
+ sections?: ExportSection[]
23
+ png_dpi?: number
24
+ dpi_range?: readonly [number, number]
25
+ icon_style?: string
26
+ toggle_props?: PaneToggleProps
27
+ pane_props?: PaneProps
28
+ // Pane-specific extras rendered below the sections (e.g. video export controls)
29
+ children?: Snippet
30
+ } = $props()
31
+
32
+ // Clamp DPI into dpi_range on input change (fires on blur, before any download click)
33
+ function clamp_dpi(): void {
34
+ const [min_dpi, max_dpi] = dpi_range
35
+ if (typeof png_dpi !== `number` || !Number.isFinite(png_dpi)) png_dpi = 150
36
+ else png_dpi = Math.round(Math.min(max_dpi, Math.max(min_dpi, png_dpi)))
37
+ }
38
+
39
+ // Copy-to-clipboard with temporary ✅ feedback; copy_text runs only on click
40
+ let copied_key = $state<string | null>(null)
41
+ let copied_timeout: ReturnType<typeof setTimeout> | undefined
42
+ async function handle_copy(item: ExportItem, key: string): Promise<void> {
43
+ if (item.disabled) return
44
+ const text = item.copy_text?.()
45
+ if (!text) return
46
+ try {
47
+ await navigator.clipboard.writeText(text)
48
+ copied_key = key
49
+ clearTimeout(copied_timeout)
50
+ copied_timeout = setTimeout(() => (copied_key = null), 1000)
51
+ } catch (error) {
52
+ console.error(`Failed to copy ${item.label} to clipboard`, error)
53
+ }
54
+ }
55
+ onDestroy(() => clearTimeout(copied_timeout))
56
+ </script>
57
+
58
+ <DraggablePane
59
+ bind:show={export_pane_open}
60
+ open_icon="Cross"
61
+ closed_icon="Export"
62
+ {icon_style}
63
+ pane_props={{
64
+ ...rest,
65
+ ...pane_props,
66
+ class: `export-pane ${rest.class ?? ``} ${pane_props?.class ?? ``}`.trim(),
67
+ }}
68
+ {toggle_props}
69
+ >
70
+ {#each sections as section, sec_idx (section.title ?? sec_idx)}
71
+ {#if section.title}
72
+ <h4
73
+ {@attach section.tooltip
74
+ ? tooltip({ allow_html: true, content: sanitize_html(section.tooltip) })
75
+ : () => {}}
76
+ >
77
+ {section.title}
78
+ </h4>
79
+ {/if}
80
+ <div class="export-grid">
81
+ {#each section.items as item, item_idx (item.label)}
82
+ {@const copy_key = `${sec_idx}-${item_idx}`}
83
+ <!-- not a <label>: it would forward label-text clicks to the first (download) button -->
84
+ <span class="export-item">
85
+ {#if item.hint}
86
+ <span {@attach tooltip({ allow_html: true, content: sanitize_html(item.hint) })}
87
+ >{item.label}</span
88
+ >
89
+ {:else}
90
+ {item.label}
91
+ {/if}
92
+ {#if item.on_download}
93
+ <button
94
+ type="button"
95
+ onclick={item.on_download}
96
+ disabled={item.disabled ?? false}
97
+ aria-label={`Download ${item.label}`}
98
+ title={`Download ${item.label}${item.show_dpi ? ` (${png_dpi} DPI)` : ``}`}
99
+ >
100
+
101
+ </button>
102
+ {/if}
103
+ {#if item.copy_text}
104
+ <button
105
+ type="button"
106
+ onclick={() => handle_copy(item, copy_key)}
107
+ disabled={item.disabled ?? false}
108
+ aria-label="Copy {item.label} to clipboard"
109
+ title="Copy {item.label} to clipboard"
110
+ >
111
+ {copied_key === copy_key ? `✅` : `📋`}
112
+ </button>
113
+ {/if}
114
+ {#if item.show_dpi}
115
+ <span class="dpi-input"
116
+ >(DPI: <input
117
+ type="number"
118
+ min={dpi_range[0]}
119
+ max={dpi_range[1]}
120
+ bind:value={png_dpi}
121
+ onchange={clamp_dpi}
122
+ title="Export resolution in dots per inch"
123
+ />)</span
124
+ >
125
+ {/if}
126
+ </span>
127
+ {/each}
128
+ </div>
129
+ {/each}
130
+ {@render children?.()}
131
+ </DraggablePane>
132
+
133
+ <style>
134
+ h4 {
135
+ display: flex;
136
+ align-items: center;
137
+ margin: 0;
138
+ }
139
+ .export-grid {
140
+ display: flex;
141
+ flex-wrap: wrap;
142
+ align-items: center;
143
+ gap: 4pt 10pt;
144
+ font-size: 0.95em;
145
+ }
146
+ .export-item {
147
+ display: flex;
148
+ align-items: center;
149
+ gap: 4pt;
150
+ white-space: nowrap;
151
+ }
152
+ .export-grid button {
153
+ min-width: 1.9em;
154
+ height: 1.6em;
155
+ padding: 0 4pt;
156
+ box-sizing: border-box;
157
+ display: inline-flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+ }
161
+ .export-grid input[type='number'] {
162
+ width: 3.5em;
163
+ }
164
+ .dpi-input {
165
+ display: inline-flex;
166
+ align-items: center;
167
+ gap: 2pt;
168
+ white-space: nowrap;
169
+ }
170
+ </style>
@@ -0,0 +1,17 @@
1
+ import type { PaneProps, PaneToggleProps } from '../overlays';
2
+ import type { ExportSection } from './types';
3
+ import { type Snippet } from 'svelte';
4
+ import type { HTMLAttributes } from 'svelte/elements';
5
+ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
6
+ export_pane_open?: boolean;
7
+ sections?: ExportSection[];
8
+ png_dpi?: number;
9
+ dpi_range?: readonly [number, number];
10
+ icon_style?: string;
11
+ toggle_props?: PaneToggleProps;
12
+ pane_props?: PaneProps;
13
+ children?: Snippet;
14
+ };
15
+ declare const ExportPane: import("svelte").Component<$$ComponentProps, {}, "export_pane_open" | "png_dpi">;
16
+ type ExportPane = ReturnType<typeof ExportPane>;
17
+ export default ExportPane;
@@ -1,11 +1,12 @@
1
1
  import type { COMPRESSION_EXTENSIONS } from '../constants';
2
2
  import { COMPRESSION_FORMATS } from '../constants';
3
+ export declare function strip_compression_extensions(filename: string): string;
3
4
  export type CompressionFormat = keyof typeof COMPRESSION_FORMATS;
4
5
  export type CompressionExtension = (typeof COMPRESSION_EXTENSIONS)[number];
5
6
  export declare function detect_compression_format(filename: string): CompressionFormat | null;
6
7
  export declare function decompress_data(data: ArrayBuffer | ReadableStream<Uint8Array> | null, format: CompressionFormat): Promise<string>;
7
8
  export declare function decompress_data_binary(data: ArrayBuffer | ReadableStream<Uint8Array> | null, format: CompressionFormat): Promise<ArrayBuffer>;
8
9
  export declare function decompress_file(file: File): Promise<{
9
- content: string;
10
+ content: string | ArrayBuffer;
10
11
  filename: string;
11
12
  }>;
@@ -1,5 +1,13 @@
1
1
  import { COMPRESSION_EXTENSIONS_REGEX, COMPRESSION_FORMATS } from '../constants';
2
- import { to_error } from '../utils';
2
+ import { is_binary_payload } from './is-binary';
3
+ // Lowercase a filename and strip all trailing compression extensions (.gz, .zip, ...)
4
+ export function strip_compression_extensions(filename) {
5
+ let base_name = filename.toLowerCase();
6
+ while (COMPRESSION_EXTENSIONS_REGEX.test(base_name)) {
7
+ base_name = base_name.replace(COMPRESSION_EXTENSIONS_REGEX, ``);
8
+ }
9
+ return base_name;
10
+ }
3
11
  export function detect_compression_format(filename) {
4
12
  const lower = filename.toLowerCase();
5
13
  for (const [format, extensions] of Object.entries(COMPRESSION_FORMATS)) {
@@ -16,7 +24,6 @@ export async function decompress_data(data, format) {
16
24
  // Decompress data and return as ArrayBuffer (for binary files like .brml.gz)
17
25
  export async function decompress_data_binary(data, format) {
18
26
  try {
19
- // Handle unsupported formats
20
27
  if (format === `zip` || format === `xz` || format === `bz2`) {
21
28
  throw new Error(`${format.toUpperCase()} decompression is not supported in the browser. ` +
22
29
  `Please extract the ${format.toUpperCase()} file first.`);
@@ -38,39 +45,18 @@ export async function decompress_data_binary(data, format) {
38
45
  throw new Error(`Failed to decompress ${format} file: ${error}`, { cause: error });
39
46
  }
40
47
  }
41
- export function decompress_file(file) {
48
+ const to_content = (filename, buffer) => is_binary_payload(filename, buffer) ? buffer : new TextDecoder().decode(buffer);
49
+ // Read a dropped file, decompressing supported formats. Binary payloads (by extension or
50
+ // magic bytes) return as ArrayBuffer so parsers get raw bytes; text decodes to string.
51
+ export async function decompress_file(file) {
42
52
  const format = detect_compression_format(file.name);
43
- const is_supported = Boolean(format && ![`zip`, `xz`, `bz2`].includes(format));
44
- return new Promise((resolve, reject) => {
45
- const reader = new FileReader();
46
- reader.addEventListener(`load`, () => {
47
- try {
48
- const result = reader.result;
49
- // strict null check: empty files legitimately read as '' (falsy)
50
- if (result === null)
51
- throw new Error(`Failed to read file`);
52
- if (is_supported && format) {
53
- if (!(result instanceof ArrayBuffer))
54
- throw new Error(`Expected binary file data`);
55
- decompress_data(result, format).then((content) => {
56
- const filename = file.name.replace(COMPRESSION_EXTENSIONS_REGEX, ``);
57
- resolve({ content, filename });
58
- }, reject);
59
- }
60
- else {
61
- if (typeof result !== `string`)
62
- throw new Error(`Expected text file data`);
63
- resolve({ content: result, filename: file.name });
64
- }
65
- }
66
- catch (error) {
67
- reject(to_error(error));
68
- }
69
- }, { once: true });
70
- reader.addEventListener(`error`, () => reject(new Error(`Failed to read file ${file.name}`)));
71
- if (is_supported)
72
- reader.readAsArrayBuffer(file);
73
- else
74
- reader.readAsText(file);
75
- });
53
+ // zip/xz/bz2 are handled by their own code paths; null = not compressed
54
+ const decompressible = format !== null && format !== `zip` && format !== `xz` && format !== `bz2` ? format : null;
55
+ const buffer = await file.arrayBuffer();
56
+ if (decompressible) {
57
+ const filename = file.name.replace(COMPRESSION_EXTENSIONS_REGEX, ``);
58
+ const decompressed = await decompress_data_binary(buffer, decompressible);
59
+ return { content: to_content(filename, decompressed), filename };
60
+ }
61
+ return { content: to_content(file.name, buffer), filename: file.name };
76
62
  }
@@ -1,11 +1,19 @@
1
1
  import type { AnyStructure } from '../structure';
2
- import { type Camera, type Scene } from 'three';
2
+ import { type Camera, type Scene, type WebGLRenderer } from 'three';
3
+ export declare const renderer_registry: WeakMap<HTMLCanvasElement, WebGLRenderer>;
4
+ export declare const scene_registry: WeakMap<HTMLCanvasElement, {
5
+ scene: Scene;
6
+ camera: Camera;
7
+ }>;
8
+ export declare const dpi_to_scale: (png_dpi: number) => number;
3
9
  export declare function canvas_to_png_blob(canvas: HTMLCanvasElement, png_dpi?: number, scene?: Scene | null, camera?: Camera | null): Promise<Blob>;
4
10
  export declare function export_canvas_as_png(canvas: HTMLCanvasElement | null, structure_or_filename: AnyStructure | string | undefined, png_dpi?: number, scene?: Scene | null, camera?: Camera | null): void;
5
11
  export declare function svg_to_svg_string(svg_element: SVGElement, inline_styles?: readonly string[]): string;
6
12
  export declare function export_svg_as_svg(svg_element: SVGElement | null, filename: string, inline_styles?: readonly string[]): void;
7
13
  export declare function svg_to_png_blob(svg_element: SVGElement, png_dpi?: number, inline_styles?: readonly string[]): Promise<Blob>;
8
14
  export declare function export_svg_as_png(svg_element: SVGElement | null, filename: string, png_dpi?: number, inline_styles?: readonly string[]): void;
15
+ export declare function observe_canvas_presence(wrapper: HTMLElement | undefined, set: (has_canvas: boolean) => void): (() => void) | undefined;
16
+ export declare const estimate_video_bitrate: (pixel_count: number, fps: number) => number;
9
17
  export declare function get_ffmpeg_conversion_command(input_filename: string): string;
10
18
  export declare function export_trajectory_video(canvas: HTMLCanvasElement | null, filename: string, options?: {
11
19
  fps?: number;
package/dist/io/export.js CHANGED
@@ -2,29 +2,24 @@ import { download } from './fetch';
2
2
  import { create_structure_filename } from '../structure/export';
3
3
  import { to_error } from '../utils';
4
4
  import { Vector2 } from 'three';
5
- function is_webgl_renderer_like(value) {
6
- if (typeof value !== `object` || !value)
7
- return false;
8
- const renderer_obj = value;
9
- return (typeof renderer_obj.render === `function` &&
10
- typeof renderer_obj.getPixelRatio === `function` &&
11
- typeof renderer_obj.setPixelRatio === `function` &&
12
- typeof renderer_obj.getSize === `function` &&
13
- typeof renderer_obj.setSize === `function`);
14
- }
15
- function get_canvas_renderer(canvas) {
16
- // oxlint-disable-next-line no-underscore-dangle -- three.js stores its renderer here
17
- const renderer_val = canvas.__renderer;
18
- return is_webgl_renderer_like(renderer_val) ? renderer_val : undefined;
19
- }
5
+ // Maps a Threlte canvas to its WebGLRenderer so PNG export can look up the renderer for a
6
+ // given canvas without mutating the DOM element. Populated by bind_renderer (scene/).
7
+ export const renderer_registry = new WeakMap();
8
+ // Companion scene+camera mapping: WebGL buffers are cleared after present
9
+ // (preserveDrawingBuffer is off), so any capture of a live canvas must
10
+ // re-render synchronously first — which needs the scene and active camera.
11
+ export const scene_registry = new WeakMap();
12
+ // PNG DPI -> render scale relative to the 72 DPI baseline, capped at 10x. DPI floors
13
+ // at 1 (non-finite -> 72) so bad inputs can't yield 0x0 canvases or NaN pixel ratios.
14
+ export const dpi_to_scale = (png_dpi) => Math.min(Math.max(1, Number.isFinite(png_dpi) ? png_dpi : 72) / 72, 10);
20
15
  // Capture a WebGL canvas as a PNG Blob at the given DPI.
21
16
  // Temporarily adjusts renderer pixel ratio for high-res capture, then restores.
22
17
  // Returns data directly (no browser download), suitable for programmatic capture
23
18
  // in test suites, server-side rendering, or Python widget integration via anywidget.
24
19
  // DPI is converted to a resolution multiplier relative to 72 DPI baseline, capped at 10x.
25
20
  export function canvas_to_png_blob(canvas, png_dpi = 150, scene = null, camera = null) {
26
- const resolution_multiplier = Math.min(png_dpi / 72, 10);
27
- const renderer = get_canvas_renderer(canvas);
21
+ const resolution_multiplier = dpi_to_scale(png_dpi);
22
+ const renderer = renderer_registry.get(canvas);
28
23
  if (resolution_multiplier <= 1.1 || !renderer) {
29
24
  if (renderer && scene && camera)
30
25
  renderer.render(scene, camera);
@@ -168,9 +163,10 @@ export function svg_to_png_blob(svg_element, png_dpi = 150, inline_styles = [])
168
163
  if (!Number.isFinite(png_dpi) || png_dpi <= 0) {
169
164
  return Promise.reject(new Error(`Invalid PNG DPI for export`));
170
165
  }
171
- const resolution_multiplier = Math.min(png_dpi / 72, 10);
172
- const pixel_width = Math.round(width * resolution_multiplier);
173
- const pixel_height = Math.round(height * resolution_multiplier);
166
+ const resolution_multiplier = dpi_to_scale(png_dpi);
167
+ // Floor at 1px: small viewBoxes at low DPI round to 0 and make toBlob fail confusingly
168
+ const pixel_width = Math.max(1, Math.round(width * resolution_multiplier));
169
+ const pixel_height = Math.max(1, Math.round(height * resolution_multiplier));
174
170
  const canvas = document.createElement(`canvas`);
175
171
  const ctx = canvas.getContext(`2d`);
176
172
  if (!ctx)
@@ -217,6 +213,23 @@ export function export_svg_as_png(svg_element, filename, png_dpi = 150, inline_s
217
213
  .then((blob) => download(blob, filename, `image/png`))
218
214
  .catch((error) => console.error(`Error exporting PNG:`, error));
219
215
  }
216
+ // Watch a wrapper element for <canvas> insertion/removal: calls set(bool) immediately
217
+ // and on every DOM mutation. Returns a cleanup that disconnects the observer (or
218
+ // undefined when no wrapper is given). Used by export panes to enable canvas exports.
219
+ export function observe_canvas_presence(wrapper, set) {
220
+ if (!wrapper) {
221
+ set(false);
222
+ return undefined;
223
+ }
224
+ const check = () => set(Boolean(wrapper.querySelector(`canvas`)));
225
+ check();
226
+ const observer = new MutationObserver(check);
227
+ observer.observe(wrapper, { childList: true, subtree: true });
228
+ return () => observer.disconnect();
229
+ }
230
+ // Estimate VP9 video bitrate (bits/s) from pixel count and frame rate.
231
+ // VP9 needs ~0.1 bits per pixel per frame for good quality; clamped to [1, 200] Mbps.
232
+ export const estimate_video_bitrate = (pixel_count, fps) => Math.max(1_000_000, Math.min(pixel_count * fps * 0.1, 200_000_000));
220
233
  // Generate FFmpeg command for WebM to MP4 conversion
221
234
  export function get_ffmpeg_conversion_command(input_filename) {
222
235
  const output = input_filename.replace(/\.webm$/i, `.mp4`);
@@ -230,7 +243,7 @@ export async function export_trajectory_video(canvas, filename, options = {}) {
230
243
  typeof MediaRecorder === `undefined` ||
231
244
  !MediaRecorder.isTypeSupported(`video/webm;codecs=vp9`))
232
245
  throw new Error(`WebM video recording not supported in this browser`);
233
- const renderer = get_canvas_renderer(canvas);
246
+ const renderer = renderer_registry.get(canvas);
234
247
  // Store original renderer settings if changing resolution
235
248
  let orig_pixel_ratio;
236
249
  let orig_size;
@@ -242,13 +255,8 @@ export async function export_trajectory_video(canvas, filename, options = {}) {
242
255
  renderer.setSize(orig_size.width, orig_size.height, false);
243
256
  }
244
257
  // Calculate bitrate based on actual video dimensions
245
- // VP9 typically needs 0.08-0.12 bits per pixel per frame for good quality
246
- // canvas dimensions include device pixel ratio and any resolution_multiplier
247
- const pixels_per_frame = canvas.width * canvas.height;
248
- const bits_per_pixel_per_frame = 0.1; // Good quality for VP9
249
- // Clamp bitrate to reasonable bounds (1 Mbps min, 200 Mbps max)
250
- const calculated_bitrate = pixels_per_frame * fps * bits_per_pixel_per_frame;
251
- const bitrate = Math.max(1_000_000, Math.min(calculated_bitrate, 200_000_000));
258
+ // (canvas dimensions include device pixel ratio and any resolution_multiplier)
259
+ const bitrate = estimate_video_bitrate(canvas.width * canvas.height, fps);
252
260
  const stream = canvas.captureStream(0);
253
261
  const chunks = [];
254
262
  const recorder = new MediaRecorder(stream, {
@@ -299,7 +307,7 @@ export async function export_trajectory_video(canvas, filename, options = {}) {
299
307
  is_resolved = true;
300
308
  try {
301
309
  const blob = new Blob(chunks, { type: `video/webm` });
302
- const webm_filename = filename.replace(/\.(mp4|webm)$/i, `.webm`);
310
+ const webm_filename = filename.replace(/\.(?:mp4|webm)$/i, `.webm`);
303
311
  download(blob, webm_filename, `video/webm`);
304
312
  on_progress?.(100);
305
313
  resolve();
@@ -1,5 +1,3 @@
1
1
  export declare const to_query: (params: Record<string, string | number | undefined>) => string;
2
- export declare function fetch_zipped<T>(url: string, { unzip }?: {
3
- unzip?: boolean | undefined;
4
- }): Promise<T | null>;
5
- export declare function download(data: string | Blob, filename: string, type: string): void;
2
+ export type DownloadData = string | Blob | ArrayBuffer | ArrayBufferView<ArrayBuffer>;
3
+ export declare function download(data: DownloadData, filename: string, type: string): void;
package/dist/io/fetch.js CHANGED
@@ -1,19 +1,8 @@
1
- import { decompress_data } from './decompress';
2
1
  // Convert params object to URL query string, omitting empty/undefined values.
3
2
  // Example: {foo: "bar", baz: 42, empty: ""} → "foo=bar&baz=42"
4
3
  export const to_query = (params) => new URLSearchParams(Object.entries(params)
5
4
  .filter(([, val]) => val !== `` && val !== undefined)
6
5
  .map(([key, val]) => [key, String(val)])).toString();
7
- export async function fetch_zipped(url, { unzip = true } = {}) {
8
- const response = await fetch(url);
9
- if (!response.ok) {
10
- console.error(`${response.status} ${response.statusText} for ${response.url}`);
11
- return null;
12
- }
13
- if (!unzip)
14
- return (await response.blob());
15
- return JSON.parse(await decompress_data(response.body, `gzip`));
16
- }
17
6
  // Original download implementation
18
7
  function default_download(data, filename, type) {
19
8
  const file = new Blob([data], { type });
@@ -4,4 +4,11 @@ export interface FileDropOptions {
4
4
  on_error?: (msg: string) => void;
5
5
  set_loading?: (loading: boolean) => void;
6
6
  }
7
+ export declare const drag_over_handlers: (opts: {
8
+ allow?: () => boolean;
9
+ set_dragover: (over: boolean) => void;
10
+ }) => {
11
+ ondragover: (event: DragEvent) => void;
12
+ ondragleave: () => void;
13
+ };
7
14
  export declare const create_file_drop_handler: (opts: FileDropOptions) => ((event: DragEvent) => Promise<void>);