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
@@ -31,9 +31,7 @@
31
31
 
32
32
  // Extract max_string_length threshold for reuse
33
33
  let max_len = $derived(ctx?.settings.max_string_length ?? 200)
34
- let is_long_string = $derived(
35
- value_type === `string` && (value as string).length > max_len,
36
- )
34
+ let is_long_string = $derived(value_type === `string` && (value as string).length > max_len)
37
35
 
38
36
  // Check for changes on mount and when value changes
39
37
  $effect(() => {
@@ -89,9 +87,7 @@
89
87
  if (value_type === `circular`) return `[Circular]`
90
88
  if (value_type === `string`) {
91
89
  const str = value as string
92
- return is_long_string && !is_expanded
93
- ? `"${str.slice(0, max_len)}..."`
94
- : `"${str}"`
90
+ return is_long_string && !is_expanded ? `"${str.slice(0, max_len)}..."` : `"${str}"`
95
91
  }
96
92
  return format_preview(value)
97
93
  })
@@ -200,17 +196,11 @@
200
196
  ...
201
197
  </button>
202
198
  {:else if is_long_string && is_expanded}
203
- <button
204
- type="button"
205
- class="expand-btn"
206
- onclick={toggle_expand}
207
- title="Collapse string"
208
- >
199
+ <button type="button" class="expand-btn" onclick={toggle_expand} title="Collapse string">
209
200
 
210
201
  </button>
211
202
  {/if}
212
- {#if ctx?.settings.show_data_types && value_type !== `null` &&
213
- value_type !== `undefined`}
203
+ {#if ctx?.settings.show_data_types && value_type !== `null` && value_type !== `undefined`}
214
204
  <span class="type-annotation">{value_type}</span>
215
205
  {/if}
216
206
  </span>
@@ -235,7 +225,9 @@
235
225
  .json-value {
236
226
  cursor: pointer;
237
227
  border-radius: 2px;
238
- transition: background-color 0.15s, color 0.15s;
228
+ transition:
229
+ background-color 0.15s,
230
+ color 0.15s;
239
231
  &:hover {
240
232
  background: var(
241
233
  --jt-hover-bg,
@@ -299,8 +299,16 @@ export function parse_path(path) {
299
299
  const segments = [];
300
300
  let current = ``;
301
301
  let in_bracket = false;
302
- for (let idx = 0; idx < path.length; idx++) {
303
- const char = path[idx];
302
+ // Bracket tokens are numeric indices or quoted keys (quotes stripped, \" unescaped)
303
+ const push_bracket_token = (token) => {
304
+ const num = Number(token);
305
+ if (Number.isNaN(num)) {
306
+ segments.push(token.replaceAll(/^"|"$/g, ``).replaceAll(String.raw `\"`, `"`));
307
+ }
308
+ else
309
+ segments.push(num);
310
+ };
311
+ for (const char of path) {
304
312
  if (char === `.` && !in_bracket) {
305
313
  if (current)
306
314
  segments.push(current);
@@ -313,17 +321,8 @@ export function parse_path(path) {
313
321
  in_bracket = true;
314
322
  }
315
323
  else if (char === `]`) {
316
- if (current) {
317
- // Check if it's a number index
318
- const num = Number(current);
319
- if (Number.isNaN(num)) {
320
- // Remove surrounding quotes and unescape internal quotes
321
- const unquoted = current.replaceAll(/^"|"$/g, ``).replaceAll('\\"', `"`);
322
- segments.push(unquoted);
323
- }
324
- else
325
- segments.push(num);
326
- }
324
+ if (current)
325
+ push_bracket_token(current);
327
326
  current = ``;
328
327
  in_bracket = false;
329
328
  }
@@ -332,16 +331,8 @@ export function parse_path(path) {
332
331
  }
333
332
  // Handle trailing content (e.g., unclosed bracket like "a[0")
334
333
  if (current) {
335
- if (in_bracket) {
336
- // Apply same numeric/quoted-string logic as inside brackets
337
- const num = Number(current);
338
- if (Number.isNaN(num)) {
339
- const unquoted = current.replaceAll(/^"|"$/g, ``).replaceAll('\\"', `"`);
340
- segments.push(unquoted);
341
- }
342
- else
343
- segments.push(num);
344
- }
334
+ if (in_bracket)
335
+ push_bracket_token(current);
345
336
  else
346
337
  segments.push(current);
347
338
  }
package/dist/math.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { LatticeParams, Pbc } from './structure/index';
2
2
  export type Vec2 = [number, number];
3
3
  export type Vec3 = [number, number, number];
4
4
  export type Vec4 = [number, number, number, number];
5
+ export type Vec5 = [number, number, number, number, number];
5
6
  export type Vec9 = [number, number, number, number, number, number, number, number, number];
6
7
  export type Point2D = {
7
8
  x: number;
@@ -51,12 +52,14 @@ export declare function matrix_inverse_3x3(matrix: Matrix3x3): Matrix3x3;
51
52
  export declare function mat3x3_vec3_multiply(matrix: Matrix3x3, vector: Vec3): Vec3;
52
53
  export declare function add<T extends NdVector>(...vecs: T[]): T;
53
54
  export declare function subtract<T extends NdVector>(vec1: T, vec2: T): T;
55
+ export declare function dot(vec1: Matrix3x3, vec2: Matrix3x3): Matrix3x3;
56
+ export declare function dot(vec1: Matrix3x3, vec2: Vec3): Vec3;
54
57
  export declare function dot(vec1: NdVector, vec2: NdVector): number;
55
58
  export declare function dot(vec1: NdVector[], vec2: NdVector): number[];
56
59
  export declare function dot(vec1: NdVector[], vec2: NdVector[]): number[][];
57
60
  export declare function to_voigt(tensor: number[][]): number[];
58
- export declare function from_voigt(voigt: number[]): number[][];
59
- export declare function vec9_to_mat3x3(flat_array: number[]): number[][];
61
+ export declare function from_voigt(voigt: number[]): Matrix3x3;
62
+ export declare function vec9_to_mat3x3(flat_array: number[]): Matrix3x3;
60
63
  export declare function tensor_to_flat_array(tensor: number[][]): number[];
61
64
  export declare const transpose_3x3_matrix: (matrix: Matrix3x3) => Matrix3x3;
62
65
  export declare function scale_lattice_matrix(orig_matrix: Matrix3x3, scaling_factors: Vec3): Matrix3x3;
@@ -74,6 +77,8 @@ export declare function get_coefficient_of_variation(values: number[]): number;
74
77
  export declare function det_4x4(matrix: Matrix4x4): number;
75
78
  export declare function det_nxn(matrix: number[][]): number;
76
79
  export declare const cross_3d: (vec1: Vec3, vec2: Vec3) => Vec3;
80
+ export declare function cell_heights(matrix: Matrix3x3): Vec3;
81
+ export declare const frac_cutoff_per_axis: (matrix: Matrix3x3, dist: number) => Vec3;
77
82
  export declare const lerp: (start: number, end: number, t: number) => number;
78
83
  export declare const lerp_vec3: (start: Vec3, end: Vec3, t: number) => Vec3;
79
84
  export declare const centered_frac: (val: number) => number;
@@ -89,7 +94,7 @@ export declare function compute_bounding_box(vertices: Vec3[]): {
89
94
  min: Vec3;
90
95
  max: Vec3;
91
96
  };
92
- export declare function is_square_matrix(matrix: unknown, dim: number): boolean;
97
+ export declare function is_square_matrix(matrix: unknown, dim: number): matrix is number[][];
93
98
  export declare function point_in_polygon(point_x: number, point_y: number, vertices: Vec2[]): boolean;
94
99
  export declare function compute_bounding_box_2d(vertices: Vec2[]): {
95
100
  min: Vec2;
@@ -101,5 +106,6 @@ export declare function polygon_centroid(vertices: Vec2[]): Vec2;
101
106
  export declare function solve_linear_system(A: number[][], // NxN coefficient matrix
102
107
  b: number[]): number[] | null;
103
108
  export declare const cross_2d: (origin: Vec2, point_a: Vec2, point_b: Vec2) => number;
109
+ export declare const monotone_chain: (sorted: Vec2[]) => Vec2[];
104
110
  export declare function convex_hull_2d(points: Vec2[]): Vec2[];
105
111
  export {};
package/dist/math.js CHANGED
@@ -426,6 +426,25 @@ export const cross_3d = (vec1, vec2) => [
426
426
  vec1[2] * vec2[0] - vec1[0] * vec2[2],
427
427
  vec1[0] * vec2[1] - vec1[1] * vec2[0],
428
428
  ];
429
+ // Perpendicular distance between opposite cell faces per axis: volume / opposite-
430
+ // face area. This (not the lattice vector length) is the correct denominator for
431
+ // per-axis fractional reach in oblique cells. Degenerate (zero-volume) cells →
432
+ // Infinity so callers' `dist / height` collapses to 0.
433
+ export function cell_heights(matrix) {
434
+ const [a_vec, b_vec, c_vec] = matrix;
435
+ const cross_bc = cross_3d(b_vec, c_vec);
436
+ const volume = Math.abs(dot(a_vec, cross_bc));
437
+ if (volume === 0)
438
+ return [Infinity, Infinity, Infinity];
439
+ // height along axis k = volume / area of the face spanned by the OTHER two vectors
440
+ const height_a = volume / Math.hypot(...cross_bc); // face b×c ⟂ a
441
+ const height_b = volume / Math.hypot(...cross_3d(a_vec, c_vec)); // face a×c ⟂ b
442
+ const height_c = volume / Math.hypot(...cross_3d(a_vec, b_vec)); // face a×b ⟂ c
443
+ return [height_a, height_b, height_c];
444
+ }
445
+ // `dist` Å of real-space reach as a fractional pad per axis (via cell heights,
446
+ // correct for oblique cells). Degenerate cells → 0 (no images).
447
+ export const frac_cutoff_per_axis = (matrix, dist) => cell_heights(matrix).map((height) => dist / height);
429
448
  // Scalar linear interpolation
430
449
  export const lerp = (start, end, t) => start + t * (end - start);
431
450
  // Vec3 linear interpolation
@@ -737,13 +756,14 @@ export function compute_bounding_box(vertices) {
737
756
  }
738
757
  return { min, max };
739
758
  }
740
- // Check if a matrix is square with dimension NxN
759
+ // Check if a matrix is a finite-numeric square matrix of dimension NxN (type predicate
760
+ // so callers get number[][] narrowing without assertions). Rejects NaN/Infinity entries.
741
761
  export function is_square_matrix(matrix, dim) {
742
762
  if (!Array.isArray(matrix))
743
763
  return false;
744
764
  if (matrix.length !== dim)
745
765
  return false;
746
- return matrix.every((row) => Array.isArray(row) && row.length === dim);
766
+ return matrix.every((row) => Array.isArray(row) && row.length === dim && row.every((val) => Number.isFinite(val)));
747
767
  }
748
768
  // --- 2D Geometry Utilities ---
749
769
  // Point-in-polygon test using ray casting algorithm
@@ -888,31 +908,27 @@ b) {
888
908
  }
889
909
  export const cross_2d = (origin, point_a, point_b) => (point_a[0] - origin[0]) * (point_b[1] - origin[1]) -
890
910
  (point_a[1] - origin[1]) * (point_b[0] - origin[0]);
911
+ // One half of Andrew's monotone chain built from x-then-y *pre-sorted* points
912
+ // (lower chain; pass reversed input for the upper chain).
913
+ export const monotone_chain = (sorted) => {
914
+ const chain = [];
915
+ for (const pt of sorted) {
916
+ while (chain.length >= 2 &&
917
+ cross_2d(chain[chain.length - 2], chain[chain.length - 1], pt) <= 0) {
918
+ chain.pop();
919
+ }
920
+ chain.push(pt);
921
+ }
922
+ return chain;
923
+ };
891
924
  // Full 2D convex hull via Andrew's monotone chain algorithm.
892
925
  // Returns vertices in counter-clockwise order.
893
926
  export function convex_hull_2d(points) {
894
927
  if (points.length < 3)
895
928
  return [...points];
896
929
  const sorted = points.toSorted((a, b) => a[0] - b[0] || a[1] - b[1]);
897
- // Lower hull
898
- const lower = [];
899
- for (const pt of sorted) {
900
- while (lower.length >= 2 &&
901
- cross_2d(lower[lower.length - 2], lower[lower.length - 1], pt) <= 0) {
902
- lower.pop();
903
- }
904
- lower.push(pt);
905
- }
906
- // Upper hull
907
- const upper = [];
908
- for (let idx = sorted.length - 1; idx >= 0; idx--) {
909
- const pt = sorted[idx];
910
- while (upper.length >= 2 &&
911
- cross_2d(upper[upper.length - 2], upper[upper.length - 1], pt) <= 0) {
912
- upper.pop();
913
- }
914
- upper.push(pt);
915
- }
930
+ const lower = monotone_chain(sorted);
931
+ const upper = monotone_chain(sorted.toReversed());
916
932
  // Remove last point of each half (it's the first point of the other)
917
933
  lower.pop();
918
934
  upper.pop();
@@ -78,7 +78,7 @@
78
78
  {#if visible}
79
79
  {@const { x, y } = get_smart_position()}
80
80
  {@const style = `position: absolute; left: ${x}px; top: ${y}px; ${rest.style ?? ``}`}
81
- <div {...rest} class="context-menu {rest.class ?? ``}" {style} bind:this={menu_element}>
81
+ <div {...rest} class={[`context-menu`, rest.class]} {style} bind:this={menu_element}>
82
82
  {#each sections as { title, options } (title)}
83
83
  <div class="section">
84
84
  <div class="header">{title}</div>
@@ -104,7 +104,9 @@
104
104
  background: var(--surface-bg);
105
105
  border: 1px solid var(--border-color);
106
106
  border-radius: var(--context-menu-border-radius, var(--border-radius, 3pt));
107
- box-shadow: 0 8px 16px -4px rgba(0, 0, 0, 0.3), 0 4px 8px -2px rgba(0, 0, 0, 0.1);
107
+ box-shadow:
108
+ 0 8px 16px -4px rgba(0, 0, 0, 0.3),
109
+ 0 4px 8px -2px rgba(0, 0, 0, 0.1);
108
110
  backdrop-filter: blur(4px);
109
111
  min-width: var(--context-menu-min-width, 160px);
110
112
  overflow: hidden;
@@ -2,16 +2,22 @@
2
2
  import Icon from '../Icon.svelte'
3
3
  import type { HTMLButtonAttributes } from 'svelte/elements'
4
4
 
5
- let { copied = false, label, title = label, onclick, ...rest }: Omit<
6
- HTMLButtonAttributes,
7
- `type` | `aria-label`
8
- > & { copied?: boolean; label: string } = $props()
5
+ let {
6
+ copied = false,
7
+ label,
8
+ title = label,
9
+ onclick,
10
+ ...rest
11
+ }: Omit<HTMLButtonAttributes, `type` | `aria-label`> & {
12
+ copied?: boolean
13
+ label: string
14
+ } = $props()
9
15
  </script>
10
16
 
11
17
  <button
12
18
  {...rest}
13
19
  type="button"
14
- class="copy-button {rest.class ?? ``}"
20
+ class={[`copy-button`, rest.class]}
15
21
  aria-label={label}
16
22
  {title}
17
23
  {onclick}
@@ -13,7 +13,12 @@
13
13
  } = $props()
14
14
  </script>
15
15
 
16
- {#snippet control_button(callback: () => void, css_class: string, icon: IconName, label: string)}
16
+ {#snippet control_button(
17
+ callback: () => void,
18
+ css_class: string,
19
+ icon: IconName,
20
+ label: string,
21
+ )}
17
22
  <button
18
23
  type="button"
19
24
  class={css_class}
@@ -25,16 +25,19 @@
25
25
  has_been_dragged = $bindable(false),
26
26
  currently_dragging = $bindable(false),
27
27
  resizable = `none`,
28
+ position = `absolute`,
28
29
  }: {
29
30
  show?: boolean
30
31
  show_pane?: boolean
31
32
  children: Snippet<
32
- [{
33
- show: boolean
34
- show_control_buttons: boolean
35
- has_been_dragged: boolean
36
- currently_dragging: boolean
37
- }]
33
+ [
34
+ {
35
+ show: boolean
36
+ show_control_buttons: boolean
37
+ has_been_dragged: boolean
38
+ currently_dragging: boolean
39
+ },
40
+ ]
38
41
  >
39
42
  // Toggle button
40
43
  toggle_props?: HTMLAttributes<HTMLButtonElement>
@@ -49,6 +52,10 @@
49
52
  persistent?: boolean
50
53
  // Resize mode: 'both' | 'width' | 'height' | 'none'
51
54
  resizable?: `both` | `width` | `height` | `none`
55
+ // 'fixed' renders the pane relative to the viewport so it escapes
56
+ // overflow-clipping ancestors (e.g. cards/tables with overflow: hidden)
57
+ // and clamps its max-height to the space below the toggle button.
58
+ position?: `absolute` | `fixed`
52
59
  // Callbacks
53
60
  onclose?: () => void
54
61
  on_drag_start?: () => void
@@ -63,6 +70,8 @@
63
70
  let show_control_buttons = $state(false)
64
71
  let resizing = $state(false)
65
72
  let resize_end_time = 0
73
+ const viewport_margin_px = 8
74
+ const min_reachable_pane_height_px = 180
66
75
 
67
76
  // Resize via bottom-right grip
68
77
  function handle_resize_start(event: PointerEvent) {
@@ -83,9 +92,7 @@
83
92
  pane_div.style.width = `${Math.max(200, start_w + evt.clientX - start_x)}px`
84
93
  }
85
94
  if (resizable !== `width`) {
86
- pane_div.style.maxHeight = `${
87
- Math.max(100, start_h + evt.clientY - start_y)
88
- }px`
95
+ pane_div.style.maxHeight = `${Math.max(100, start_h + evt.clientY - start_y)}px`
89
96
  }
90
97
  }
91
98
  function on_up() {
@@ -124,6 +131,10 @@
124
131
  width: ``,
125
132
  maxHeight: ``,
126
133
  })
134
+ // Refresh --pane-viewport-clamp for the new position (matches
135
+ // handle_resize and the mount effect; without this a reset after a
136
+ // drag + window resize keeps a stale bottom-edge cap)
137
+ apply_viewport_clamp()
127
138
  }
128
139
  }
129
140
  // Hide the control buttons after reset
@@ -147,10 +158,31 @@
147
158
  const pane_width = pane_div?.getBoundingClientRect().width || 450
148
159
  const ox = offset.x ?? 5
149
160
  const oy = offset.y ?? 5
161
+
162
+ if (position === `fixed`) {
163
+ // Viewport-relative: keep the pane reachable within the screen.
164
+ const left = Math.max(
165
+ viewport_margin_px,
166
+ Math.min(
167
+ toggle_rect.right - pane_width + ox,
168
+ window.innerWidth - pane_width - viewport_margin_px,
169
+ ),
170
+ )
171
+ const top = Math.max(
172
+ viewport_margin_px,
173
+ Math.min(
174
+ toggle_rect.bottom + oy,
175
+ window.innerHeight - min_reachable_pane_height_px - viewport_margin_px,
176
+ ),
177
+ )
178
+ return { left: `${left}px`, top: `${top}px` }
179
+ }
180
+
150
181
  const positioned_ancestor = toggle_pane_btn.offsetParent
151
182
  const ancestor_rect = positioned_ancestor?.getBoundingClientRect()
152
183
 
153
- if (!ancestor_rect) { // Fallback to document positioning
184
+ if (!ancestor_rect) {
185
+ // Fallback to document positioning
154
186
  const scroll_x = window.scrollX || document.documentElement.scrollLeft
155
187
  const scroll_y = window.scrollY || document.documentElement.scrollTop
156
188
  return {
@@ -173,10 +205,11 @@
173
205
  if (Date.now() - resize_end_time < 200) return
174
206
 
175
207
  const target = event.target
176
- const is_toggle_button = target instanceof Node &&
208
+ const is_toggle_button =
209
+ target instanceof Node &&
177
210
  (target === toggle_pane_btn || (toggle_pane_btn?.contains(target) ?? false))
178
- const is_inside_pane = target instanceof Node &&
179
- (target === pane_div || (pane_div?.contains(target) ?? false))
211
+ const is_inside_pane =
212
+ target instanceof Node && (target === pane_div || (pane_div?.contains(target) ?? false))
180
213
 
181
214
  if (!is_toggle_button && !is_inside_pane && !currently_dragging && !resizing) {
182
215
  close_pane()
@@ -186,7 +219,8 @@
186
219
  // Debounced resize handler for better performance
187
220
  let resize_timeout: ReturnType<typeof setTimeout> | undefined = $state(undefined)
188
221
 
189
- function handle_resize() { // Only reposition if pane is visible and hasn't been manually dragged
222
+ function handle_resize() {
223
+ // Only reposition if pane is visible and hasn't been manually dragged
190
224
  if (!show || has_been_dragged || currently_dragging) return
191
225
 
192
226
  if (resize_timeout) clearTimeout(resize_timeout)
@@ -197,11 +231,30 @@
197
231
  initial_position = pos
198
232
  pane_div.style.left = pos.left
199
233
  pane_div.style.top = pos.top
234
+ apply_viewport_clamp()
200
235
  }
201
236
  }, 50) // Debounce resize events
202
237
  resize_timeout = current_timeout
203
238
  }
204
239
 
240
+ // Fixed panes must never extend past the bottom viewport edge: cap the
241
+ // --pane-viewport-clamp var (combined with --pane-max-height via min() in
242
+ // CSS) to the space below the pane's top edge. No minimum here — usability
243
+ // is handled by calculate_position, which clamps the top so at least
244
+ // min_reachable_pane_height_px of space remains below.
245
+ function apply_viewport_clamp(): void {
246
+ if (position !== `fixed` || !pane_div || !toggle_pane_btn) return
247
+ // style.top is a `${n}px` string when set; "0px" is a valid position, so only
248
+ // fall back to the live rect when the inline style is unset or non-numeric
249
+ const parsed_top = Number(pane_div.style.top.replace(/px$/, ``))
250
+ const pane_top =
251
+ pane_div.style.top && !Number.isNaN(parsed_top)
252
+ ? parsed_top
253
+ : pane_div.getBoundingClientRect().top
254
+ const available = window.innerHeight - pane_top - viewport_margin_px
255
+ pane_div.style.setProperty(`--pane-viewport-clamp`, `${Math.max(0, available)}px`)
256
+ }
257
+
205
258
  // Position pane when shown
206
259
  $effect(() => {
207
260
  if (show && toggle_pane_btn && !has_been_dragged) {
@@ -216,6 +269,7 @@
216
269
  width: ``,
217
270
  maxHeight: ``,
218
271
  })
272
+ apply_viewport_clamp()
219
273
  }
220
274
  }
221
275
  })
@@ -240,7 +294,7 @@
240
294
  {...toggle_props}
241
295
  style={toggle_props.style ?? ``}
242
296
  onclick={toggle_pane}
243
- class="pane-toggle {toggle_props.class ?? ``}"
297
+ class={[`pane-toggle`, toggle_props.class]}
244
298
  {@attach tooltip({ content: toggle_props.title ?? (show ? `Close pane` : `Open pane`) })}
245
299
  >
246
300
  <Icon icon={show ? open_icon : closed_icon} style={icon_style} />
@@ -256,12 +310,13 @@
256
310
  role="dialog"
257
311
  aria-label="Draggable pane"
258
312
  aria-modal="false"
313
+ style:position
259
314
  style:max-width={max_width}
260
315
  style:top={initial_position.top}
261
316
  style:left={initial_position.left}
262
317
  style:display={show ? `grid` : `none`}
263
318
  {...pane_props}
264
- class="draggable-pane toc-exclude {show ? `pane-open` : ``} {pane_props.class ?? ``}"
319
+ class={[`draggable-pane toc-exclude`, show && `pane-open`, pane_props.class]}
265
320
  >
266
321
  <DragControlTab
267
322
  show_controls={show_control_buttons}
@@ -329,21 +384,24 @@
329
384
  box-sizing: border-box;
330
385
  box-shadow: var(
331
386
  --pane-box-shadow,
332
- light-dark(
333
- 0 4px 20px -4px rgba(0, 0, 0, 0.15),
334
- 0 8px 16px -4px rgba(0, 0, 0, 0.3)
335
- )
387
+ light-dark(0 4px 20px -4px rgba(0, 0, 0, 0.15), 0 8px 16px -4px rgba(0, 0, 0, 0.3))
336
388
  );
337
389
  z-index: var(--pane-z-index, 10);
338
390
  display: grid;
339
391
  text-align: left;
340
392
  /* Exclude position from being transitioned to prevent sluggish dragging */
341
- transition: opacity 0.3s, background-color 0.3s, border-color 0.3s, box-shadow 0.3s;
393
+ transition:
394
+ opacity 0.3s,
395
+ background-color 0.3s,
396
+ border-color 0.3s,
397
+ box-shadow 0.3s;
342
398
  width: 28em;
343
399
  max-width: var(--pane-max-width, 80cqw);
344
400
  overflow: visible; /* Allow control-tab to protrude above the pane border */
345
401
  min-height: var(--pane-min-height, auto);
346
- max-height: var(--pane-max-height, 80vh);
402
+ /* --pane-viewport-clamp (set for position="fixed" panes) keeps the pane
403
+ above the bottom viewport edge even when the toggle sits low on screen */
404
+ max-height: min(var(--pane-max-height, 80vh), var(--pane-viewport-clamp, 200vh));
347
405
  }
348
406
  .draggable-pane .pane-content {
349
407
  padding: var(--pane-padding, 1ex);
@@ -368,10 +426,7 @@
368
426
  }
369
427
  .draggable-pane :global(hr) {
370
428
  border: none;
371
- background: var(
372
- --pane-hr-bg,
373
- light-dark(rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.1))
374
- );
429
+ background: var(--pane-hr-bg, light-dark(rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.1)));
375
430
  margin: var(--pane-hr-margin, 4pt 0);
376
431
  height: 1px;
377
432
  }
@@ -24,6 +24,7 @@ type $$ComponentProps = {
24
24
  pane_props?: HTMLAttributes<HTMLDivElement>;
25
25
  persistent?: boolean;
26
26
  resizable?: `both` | `width` | `height` | `none`;
27
+ position?: `absolute` | `fixed`;
27
28
  onclose?: () => void;
28
29
  on_drag_start?: () => void;
29
30
  toggle_pane_btn?: HTMLButtonElement;
@@ -0,0 +1,30 @@
1
+ <!-- Small text overlay with a frosted-glass backdrop, for annotating visual
2
+ content (3D structure viewers, plots) without fully obscuring it. Shared by
3
+ StructurePopup's stats block and StructureCarousel's card headers so both
4
+ render identically. Position/size via --glass-chip-* custom properties. -->
5
+ <script lang="ts">
6
+ import type { Snippet } from 'svelte'
7
+ import type { HTMLAttributes } from 'svelte/elements'
8
+
9
+ let { children, ...rest }: HTMLAttributes<HTMLDivElement> & { children: Snippet } = $props()
10
+ </script>
11
+
12
+ <div {...rest} class={[`glass-chip`, rest.class]}>
13
+ {@render children()}
14
+ </div>
15
+
16
+ <style>
17
+ .glass-chip {
18
+ position: absolute;
19
+ top: var(--glass-chip-top, 10px);
20
+ left: var(--glass-chip-left, 10px);
21
+ z-index: var(--glass-chip-z, 2);
22
+ max-width: var(--glass-chip-max-width, calc(100% - 20px));
23
+ padding: 4px 8px;
24
+ border-radius: 6px;
25
+ background: var(--glass-chip-bg, transparent);
26
+ backdrop-filter: blur(8px);
27
+ color: var(--text-color);
28
+ font-size: var(--glass-chip-font-size, 0.85em);
29
+ }
30
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
4
+ children: Snippet;
5
+ };
6
+ declare const GlassChip: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type GlassChip = ReturnType<typeof GlassChip>;
8
+ export default GlassChip;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { sanitize_html } from '../sanitize'
3
3
  import type { HTMLAttributes } from 'svelte/elements'
4
- import { SvelteSet } from 'svelte/reactivity'
4
+ import { create_clipboard_feedback } from './'
5
5
  import CopyButton from './CopyButton.svelte'
6
6
 
7
7
  type InfoPaneRow = {
@@ -33,7 +33,7 @@
33
33
  } = $props()
34
34
 
35
35
  let info_filter = $state(``)
36
- const copied_items = new SvelteSet<string>()
36
+ const { copied, copy } = create_clipboard_feedback()
37
37
  const row_key = (card_title: string, row: InfoPaneRow, row_idx: number): string =>
38
38
  row.key ?? `${card_title}:${row.label}:${row.value}:${row_idx}`
39
39
 
@@ -44,27 +44,16 @@
44
44
  .map((card) => ({
45
45
  ...card,
46
46
  rows: card.rows.filter(({ label, value }) =>
47
- `${card.title} ${label} ${value}`.toLowerCase().includes(filter)
47
+ `${card.title} ${label} ${value}`.toLowerCase().includes(filter),
48
48
  ),
49
49
  }))
50
50
  .filter(({ rows }) => rows.length > 0)
51
51
  })
52
52
 
53
- async function copy_row(
54
- card_title: string,
55
- row: InfoPaneRow,
56
- row_idx: number,
57
- ): Promise<void> {
58
- const key = row_key(card_title, row, row_idx)
59
- try {
60
- await navigator.clipboard.writeText(`${row.label}: ${row.value}`)
61
- copied_items.add(key)
62
- setTimeout(() => copied_items.delete(key), 1000)
63
- } catch (error) {
64
- console.error(`Failed to copy to clipboard:`, error)
65
- }
66
- }
53
+ const copy_row = (card_title: string, row: InfoPaneRow, row_idx: number): Promise<void> =>
54
+ copy(`${row.label}: ${row.value}`, row_key(card_title, row, row_idx))
67
55
  </script>
56
+
68
57
  {#if show_filter}
69
58
  <input
70
59
  class="info-filter"
@@ -78,7 +67,7 @@
78
67
  {#if filtered_cards.length === 0}
79
68
  <p class="empty-filter">No {empty_label} matches "{info_filter}".</p>
80
69
  {:else}
81
- <div {...rest} class="info-cards {rest.class ?? ``}" style:--row-label-min={row_label_min}>
70
+ <div {...rest} class={[`info-cards`, rest.class]} style:--row-label-min={row_label_min}>
82
71
  {#each filtered_cards as card (card.title)}
83
72
  <section class="info-card">
84
73
  <svelte:element this={`h${heading_level}`}>{card.title}</svelte:element>
@@ -89,7 +78,7 @@
89
78
  <CopyButton
90
79
  label="Copy {row.label}: {row.value}"
91
80
  title="Copy {row.label}"
92
- copied={copied_items.has(row_key(card.title, row, row_idx))}
81
+ copied={copied.has(row_key(card.title, row, row_idx))}
93
82
  onclick={() => copy_row(card.title, row, row_idx)}
94
83
  />
95
84
  </div>
@@ -129,10 +118,9 @@
129
118
  }
130
119
  .info-row {
131
120
  display: grid;
132
- grid-template-columns: minmax(var(--row-label-min), var(--row-label-max, 0.8fr)) minmax(
133
- 0,
134
- 1fr
135
- ) auto;
121
+ grid-template-columns:
122
+ minmax(var(--row-label-min), var(--row-label-max, 0.8fr)) minmax(0, 1fr)
123
+ auto;
136
124
  align-items: center;
137
125
  gap: 5pt;
138
126
  padding: var(--info-row-padding, 1pt 0);