matterviz 0.4.1 → 0.4.3

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 (499) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +48 -60
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/api/optimade.js +10 -7
  6. package/dist/app.css +68 -0
  7. package/dist/brillouin/BrillouinZone.svelte +90 -91
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  9. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  12. package/dist/brillouin/BrillouinZoneScene.svelte +46 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  14. package/dist/brillouin/compute.js +10 -16
  15. package/dist/brillouin/geometry.js +2 -2
  16. package/dist/chempot-diagram/ChemPotDiagram.svelte +48 -50
  17. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +61 -169
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +559 -755
  20. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  21. package/dist/chempot-diagram/async-compute.svelte.js +13 -14
  22. package/dist/chempot-diagram/color.d.ts +21 -1
  23. package/dist/chempot-diagram/color.js +70 -1
  24. package/dist/chempot-diagram/compute.d.ts +7 -0
  25. package/dist/chempot-diagram/compute.js +85 -26
  26. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  27. package/dist/chempot-diagram/export.js +1 -6
  28. package/dist/chempot-diagram/temperature.js +9 -10
  29. package/dist/colors/index.d.ts +0 -4
  30. package/dist/colors/index.js +19 -20
  31. package/dist/composition/BarChart.svelte +30 -26
  32. package/dist/composition/BubbleChart.svelte +17 -17
  33. package/dist/composition/Composition.svelte +10 -19
  34. package/dist/composition/Formula.svelte +20 -27
  35. package/dist/composition/FormulaFilter.svelte +115 -184
  36. package/dist/composition/PieChart.svelte +55 -41
  37. package/dist/composition/format.js +7 -9
  38. package/dist/composition/index.d.ts +2 -0
  39. package/dist/composition/index.js +14 -0
  40. package/dist/composition/parse.d.ts +2 -2
  41. package/dist/composition/parse.js +61 -115
  42. package/dist/constants.d.ts +0 -1
  43. package/dist/constants.js +17 -26
  44. package/dist/convex-hull/ConvexHull.svelte +12 -15
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +93 -94
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +127 -186
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +131 -180
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  53. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  54. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  55. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  56. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  57. package/dist/convex-hull/StructurePopup.svelte +18 -22
  58. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  59. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  60. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  61. package/dist/convex-hull/gas-thermodynamics.js +21 -53
  62. package/dist/convex-hull/helpers.d.ts +8 -10
  63. package/dist/convex-hull/helpers.js +37 -43
  64. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  65. package/dist/convex-hull/thermodynamics.js +37 -44
  66. package/dist/coordination/CoordinationBarPlot.svelte +49 -53
  67. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  68. package/dist/coordination/calc-coordination.d.ts +1 -1
  69. package/dist/coordination/calc-coordination.js +28 -25
  70. package/dist/element/BohrAtom.svelte +5 -9
  71. package/dist/element/ElementHeading.svelte +4 -1
  72. package/dist/element/ElementPhoto.svelte +11 -9
  73. package/dist/element/ElementStats.svelte +12 -10
  74. package/dist/element/ElementTile.svelte +44 -67
  75. package/dist/element/Nucleus.svelte +4 -2
  76. package/dist/element/data.d.ts +3 -2
  77. package/dist/element/data.js +5 -1
  78. package/dist/element/helpers.d.ts +4 -0
  79. package/dist/element/helpers.js +18 -0
  80. package/dist/element/index.d.ts +2 -5
  81. package/dist/element/index.js +4 -19
  82. package/dist/feedback/DragOverlay.svelte +5 -5
  83. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  84. package/dist/feedback/StatusMessage.svelte +7 -4
  85. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  86. package/dist/fermi-surface/FermiSurface.svelte +35 -44
  87. package/dist/fermi-surface/FermiSurface.svelte.d.ts +7 -13
  88. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  89. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  90. package/dist/fermi-surface/FermiSurfaceScene.svelte +64 -136
  91. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  92. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  93. package/dist/fermi-surface/compute.js +25 -58
  94. package/dist/fermi-surface/parse.js +54 -88
  95. package/dist/file-viewer/JsonBrowser.svelte +1043 -0
  96. package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
  97. package/dist/file-viewer/PlotPanel.svelte +350 -0
  98. package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
  99. package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
  100. package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
  101. package/dist/file-viewer/detect.d.ts +11 -0
  102. package/dist/file-viewer/detect.js +381 -0
  103. package/dist/file-viewer/eligibility.d.ts +4 -0
  104. package/dist/file-viewer/eligibility.js +53 -0
  105. package/dist/file-viewer/host-protocol.d.ts +50 -0
  106. package/dist/file-viewer/host-transfer.d.ts +25 -0
  107. package/dist/file-viewer/host-transfer.js +42 -0
  108. package/dist/file-viewer/index.d.ts +5 -0
  109. package/dist/file-viewer/index.js +5 -0
  110. package/dist/file-viewer/main.d.ts +44 -0
  111. package/dist/file-viewer/main.js +535 -0
  112. package/dist/file-viewer/parse.d.ts +9 -0
  113. package/dist/file-viewer/parse.js +170 -0
  114. package/dist/file-viewer/plot-utils.d.ts +24 -0
  115. package/dist/file-viewer/plot-utils.js +191 -0
  116. package/dist/file-viewer/types.d.ts +4 -0
  117. package/dist/file-viewer/types.js +5 -0
  118. package/dist/heatmap-matrix/HeatmapMatrix.svelte +153 -219
  119. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  120. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  121. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  122. package/dist/heatmap-matrix/index.d.ts +5 -0
  123. package/dist/icons.d.ts +4 -0
  124. package/dist/icons.js +4 -0
  125. package/dist/index.d.ts +2 -2
  126. package/dist/index.js +1 -1
  127. package/dist/io/ExportPane.svelte +11 -7
  128. package/dist/io/decompress.d.ts +4 -1
  129. package/dist/io/decompress.js +24 -36
  130. package/dist/io/export.d.ts +11 -4
  131. package/dist/io/export.js +75 -19
  132. package/dist/io/fetch.d.ts +0 -3
  133. package/dist/io/fetch.js +0 -11
  134. package/dist/io/file-drop.js +60 -35
  135. package/dist/io/index.d.ts +0 -1
  136. package/dist/io/index.js +2 -9
  137. package/dist/io/is-binary.d.ts +9 -0
  138. package/dist/io/is-binary.js +45 -1
  139. package/dist/io/url-drop.d.ts +2 -0
  140. package/dist/io/url-drop.js +40 -40
  141. package/dist/isosurface/Isosurface.svelte +700 -215
  142. package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
  143. package/dist/isosurface/IsosurfaceControls.svelte +590 -116
  144. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
  145. package/dist/isosurface/VolumeSlice.svelte +224 -0
  146. package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
  147. package/dist/isosurface/coloring.d.ts +20 -0
  148. package/dist/isosurface/coloring.js +118 -0
  149. package/dist/isosurface/geometry-worker-types.d.ts +38 -0
  150. package/dist/isosurface/geometry.worker.d.ts +1 -0
  151. package/dist/isosurface/geometry.worker.js +59 -0
  152. package/dist/isosurface/grid.d.ts +10 -0
  153. package/dist/isosurface/grid.js +31 -0
  154. package/dist/isosurface/index.d.ts +4 -0
  155. package/dist/isosurface/index.js +4 -0
  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 +6 -6
  159. package/dist/isosurface/profile.d.ts +12 -0
  160. package/dist/isosurface/profile.js +19 -0
  161. package/dist/isosurface/sampling.d.ts +34 -0
  162. package/dist/isosurface/sampling.js +408 -0
  163. package/dist/isosurface/slice-rendering.d.ts +13 -0
  164. package/dist/isosurface/slice-rendering.js +79 -0
  165. package/dist/isosurface/slice.d.ts +22 -2
  166. package/dist/isosurface/slice.js +200 -116
  167. package/dist/isosurface/types.d.ts +24 -1
  168. package/dist/isosurface/types.js +120 -8
  169. package/dist/json-path.d.ts +4 -0
  170. package/dist/json-path.js +89 -0
  171. package/dist/labels.d.ts +6 -2
  172. package/dist/labels.js +44 -14
  173. package/dist/layout/FullscreenButton.svelte +2 -1
  174. package/dist/layout/FullscreenToggle.svelte +10 -4
  175. package/dist/layout/InfoCard.svelte +8 -21
  176. package/dist/layout/InfoTag.svelte +1 -3
  177. package/dist/layout/NumberRangeInput.svelte +46 -0
  178. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  179. package/dist/layout/PropertyFilter.svelte +2 -6
  180. package/dist/layout/SettingsSection.svelte +57 -62
  181. package/dist/layout/SettingsSection.svelte.d.ts +6 -7
  182. package/dist/layout/SubpageGrid.svelte +3 -1
  183. package/dist/layout/ViewerChrome.svelte +16 -11
  184. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  185. package/dist/layout/fullscreen.js +3 -5
  186. package/dist/layout/fullscreen.svelte.js +1 -2
  187. package/dist/layout/index.d.ts +1 -0
  188. package/dist/layout/index.js +1 -0
  189. package/dist/layout/json-tree/JsonNode.svelte +22 -59
  190. package/dist/layout/json-tree/JsonTree.svelte +101 -172
  191. package/dist/layout/json-tree/JsonValue.svelte +9 -32
  192. package/dist/layout/json-tree/utils.d.ts +0 -3
  193. package/dist/layout/json-tree/utils.js +50 -188
  194. package/dist/marching-cubes.d.ts +8 -1
  195. package/dist/marching-cubes.js +115 -48
  196. package/dist/math.d.ts +5 -2
  197. package/dist/math.js +48 -38
  198. package/dist/overlays/ContextMenu.svelte +19 -34
  199. package/dist/overlays/CopyButton.svelte +11 -5
  200. package/dist/overlays/DragControlTab.svelte +6 -1
  201. package/dist/overlays/DraggablePane.svelte +110 -74
  202. package/dist/overlays/DraggablePane.svelte.d.ts +2 -1
  203. package/dist/overlays/GlassChip.svelte +32 -0
  204. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  205. package/dist/overlays/InfoPaneCards.svelte +11 -23
  206. package/dist/overlays/index.d.ts +7 -0
  207. package/dist/overlays/index.js +26 -0
  208. package/dist/overlays/portal.d.ts +2 -0
  209. package/dist/overlays/portal.js +14 -0
  210. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  211. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  212. package/dist/periodic-table/PeriodicTableControls.svelte +37 -115
  213. package/dist/periodic-table/TableInset.svelte +9 -4
  214. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +68 -105
  215. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  216. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  217. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  218. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  219. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  220. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  221. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  222. package/dist/phase-diagram/build-diagram.js +4 -9
  223. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  224. package/dist/phase-diagram/parse.js +15 -15
  225. package/dist/phase-diagram/svg-to-diagram.js +28 -27
  226. package/dist/phase-diagram/utils.js +2 -3
  227. package/dist/plot/bar/BarPlot.svelte +461 -426
  228. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  229. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  230. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  231. package/dist/plot/bar/SpacegroupBarPlot.svelte +46 -77
  232. package/dist/plot/bar/data.d.ts +5 -4
  233. package/dist/plot/bar/data.js +2 -1
  234. package/dist/plot/box/BoxPlot.svelte +322 -226
  235. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  236. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  237. package/dist/plot/box/box-plot.js +1 -1
  238. package/dist/plot/core/auto-place.d.ts +1 -1
  239. package/dist/plot/core/auto-place.js +2 -2
  240. package/dist/plot/core/axis-utils.d.ts +12 -7
  241. package/dist/plot/core/axis-utils.js +48 -48
  242. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  243. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  244. package/dist/plot/core/components/ColorBar.svelte +101 -106
  245. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  246. package/dist/plot/core/components/FillArea.svelte +10 -17
  247. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  248. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  249. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  250. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  251. package/dist/plot/core/components/Line.svelte +18 -9
  252. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  253. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  254. package/dist/plot/core/components/PlotControls.svelte +65 -41
  255. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  256. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  257. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  258. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  259. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  260. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  261. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  262. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  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 +27 -474
  271. package/dist/plot/core/data-transform.d.ts +1 -2
  272. package/dist/plot/core/data-transform.js +9 -15
  273. package/dist/plot/core/fill-utils.d.ts +3 -1
  274. package/dist/plot/core/fill-utils.js +28 -6
  275. package/dist/plot/core/index.d.ts +1 -0
  276. package/dist/plot/core/index.js +1 -0
  277. package/dist/plot/core/interactions.js +0 -2
  278. package/dist/plot/core/layout.d.ts +15 -6
  279. package/dist/plot/core/layout.js +57 -38
  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 +2 -4
  283. package/dist/plot/core/pan-zoom.svelte.js +34 -17
  284. package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -21
  286. package/dist/plot/core/reference-line.js +1 -1
  287. package/dist/plot/core/scales.d.ts +23 -0
  288. package/dist/plot/core/scales.js +39 -13
  289. package/dist/plot/core/svg.js +0 -1
  290. package/dist/plot/core/types/fills.d.ts +101 -0
  291. package/dist/plot/core/types/fills.js +15 -0
  292. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  293. package/dist/plot/core/types/plot-3d.js +4 -0
  294. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  295. package/dist/plot/core/types/reference-lines.js +9 -0
  296. package/dist/plot/core/types.d.ts +29 -324
  297. package/dist/plot/core/types.js +23 -20
  298. package/dist/plot/core/utils/hierarchy-chart.d.ts +52 -0
  299. package/dist/plot/core/utils/hierarchy-chart.js +191 -0
  300. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  301. package/dist/plot/core/utils/hierarchy-labels.js +100 -0
  302. package/dist/plot/core/utils/label-placement.js +2 -2
  303. package/dist/plot/histogram/Histogram.svelte +314 -340
  304. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  305. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  306. package/dist/plot/histogram/histogram.d.ts +31 -0
  307. package/dist/plot/histogram/histogram.js +70 -0
  308. package/dist/plot/histogram/index.d.ts +1 -0
  309. package/dist/plot/histogram/index.js +1 -0
  310. package/dist/plot/index.d.ts +1 -0
  311. package/dist/plot/index.js +1 -0
  312. package/dist/plot/sankey/Sankey.svelte +78 -69
  313. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  314. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  315. package/dist/plot/sankey/sankey.js +13 -9
  316. package/dist/plot/scatter/BinnedScatterPlot.svelte +311 -141
  317. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  318. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  319. package/dist/plot/scatter/ScatterPlot.svelte +517 -410
  320. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  321. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  322. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  323. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  324. package/dist/plot/scatter/adaptive-density.d.ts +1 -1
  325. package/dist/plot/scatter/adaptive-density.js +36 -20
  326. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  327. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  328. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  329. package/dist/plot/scatter/scatter-data.js +8 -7
  330. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  331. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  332. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  333. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  334. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  335. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  336. package/dist/plot/sunburst/Sunburst.svelte +269 -347
  337. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  338. package/dist/plot/sunburst/index.d.ts +1 -1
  339. package/dist/plot/sunburst/index.js +2 -1
  340. package/dist/plot/sunburst/render.d.ts +2 -2
  341. package/dist/plot/sunburst/render.js +47 -22
  342. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  343. package/dist/plot/sunburst/sunburst.js +10 -3
  344. package/dist/plot/treemap/Treemap.svelte +1022 -0
  345. package/dist/plot/treemap/Treemap.svelte.d.ts +90 -0
  346. package/dist/plot/treemap/index.d.ts +4 -0
  347. package/dist/plot/treemap/index.js +4 -0
  348. package/dist/plot/treemap/labels.d.ts +38 -0
  349. package/dist/plot/treemap/labels.js +80 -0
  350. package/dist/plot/treemap/treemap.d.ts +28 -0
  351. package/dist/plot/treemap/treemap.js +102 -0
  352. package/dist/rdf/RdfPlot.svelte +37 -59
  353. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  354. package/dist/rdf/calc-rdf.js +63 -52
  355. package/dist/rdf/index.d.ts +0 -1
  356. package/dist/sanitize.js +85 -27
  357. package/dist/scene/SceneCamera.svelte +1 -1
  358. package/dist/scene/SceneCamera.svelte.d.ts +1 -1
  359. package/dist/scene/bind-renderer.svelte.js +14 -6
  360. package/dist/scene/index.d.ts +1 -2
  361. package/dist/scene/index.js +1 -1
  362. package/dist/scene/{props.js → props.svelte.js} +15 -1
  363. package/dist/settings.d.ts +19 -9
  364. package/dist/settings.js +229 -525
  365. package/dist/spectral/Bands.svelte +207 -221
  366. package/dist/spectral/BandsAndDos.svelte +11 -9
  367. package/dist/spectral/BrillouinBandsDos.svelte +19 -42
  368. package/dist/spectral/Dos.svelte +92 -93
  369. package/dist/spectral/helpers.d.ts +3 -3
  370. package/dist/spectral/helpers.js +65 -140
  371. package/dist/state.svelte.js +5 -18
  372. package/dist/structure/Arrow.svelte +5 -18
  373. package/dist/structure/ArrowInstances.svelte +160 -0
  374. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  375. package/dist/structure/AtomLegend.svelte +120 -85
  376. package/dist/structure/AtomLegend.svelte.d.ts +2 -3
  377. package/dist/structure/Bond.svelte +31 -23
  378. package/dist/structure/CanvasTooltip.svelte +15 -3
  379. package/dist/structure/CellSelect.svelte +45 -35
  380. package/dist/structure/Cylinder.svelte +24 -40
  381. package/dist/structure/InstancedAtoms.svelte +114 -0
  382. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  383. package/dist/structure/Lattice.svelte +85 -149
  384. package/dist/structure/SiteLabels.svelte +122 -0
  385. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  386. package/dist/structure/Structure.svelte +636 -504
  387. package/dist/structure/Structure.svelte.d.ts +4 -2
  388. package/dist/structure/StructureCarousel.svelte +637 -0
  389. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  390. package/dist/structure/StructureControls.svelte +165 -425
  391. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  392. package/dist/structure/StructureExportPane.svelte +17 -21
  393. package/dist/structure/StructureInfoPane.svelte +128 -133
  394. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  395. package/dist/structure/StructureScene.svelte +535 -578
  396. package/dist/structure/StructureScene.svelte.d.ts +6 -2
  397. package/dist/structure/StructureViewport.svelte +451 -0
  398. package/dist/structure/StructureViewport.svelte.d.ts +65 -0
  399. package/dist/structure/atom-label-placement.d.ts +16 -12
  400. package/dist/structure/atom-label-placement.js +70 -37
  401. package/dist/structure/atom-properties.d.ts +2 -0
  402. package/dist/structure/atom-properties.js +105 -38
  403. package/dist/structure/bond-order-perception.js +3 -8
  404. package/dist/structure/bonding.d.ts +9 -3
  405. package/dist/structure/bonding.js +95 -46
  406. package/dist/structure/edit-history.d.ts +6 -0
  407. package/dist/structure/edit-history.js +27 -0
  408. package/dist/structure/export.d.ts +1 -0
  409. package/dist/structure/export.js +89 -105
  410. package/dist/structure/format-detect.d.ts +1 -0
  411. package/dist/structure/format-detect.js +20 -0
  412. package/dist/structure/geometry.d.ts +9 -0
  413. package/dist/structure/geometry.js +27 -0
  414. package/dist/structure/index.d.ts +16 -1
  415. package/dist/structure/index.js +15 -10
  416. package/dist/structure/measure.d.ts +1 -1
  417. package/dist/structure/measure.js +6 -12
  418. package/dist/structure/parse.d.ts +2 -1
  419. package/dist/structure/parse.js +272 -313
  420. package/dist/structure/partial-occupancy.js +10 -5
  421. package/dist/structure/pbc.js +85 -107
  422. package/dist/structure/polyhedra.d.ts +0 -1
  423. package/dist/structure/polyhedra.js +7 -21
  424. package/dist/structure/prop-groups.d.ts +85 -0
  425. package/dist/structure/prop-groups.js +18 -0
  426. package/dist/structure/supercell.d.ts +1 -2
  427. package/dist/structure/supercell.js +7 -13
  428. package/dist/symmetry/SymmetryElements.svelte +11 -15
  429. package/dist/symmetry/SymmetryStats.svelte +55 -71
  430. package/dist/symmetry/WyckoffTable.svelte +10 -28
  431. package/dist/symmetry/cell-transform.js +6 -14
  432. package/dist/symmetry/index.d.ts +1 -0
  433. package/dist/symmetry/index.js +13 -10
  434. package/dist/symmetry/spacegroups.js +3 -2
  435. package/dist/table/HeatmapTable.svelte +1142 -447
  436. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  437. package/dist/table/ToggleMenu.svelte +168 -53
  438. package/dist/table/ToggleMenu.svelte.d.ts +1 -1
  439. package/dist/table/index.d.ts +21 -6
  440. package/dist/table/index.js +34 -21
  441. package/dist/theme/ThemeControl.svelte +16 -8
  442. package/dist/theme/embedded.d.ts +18 -0
  443. package/dist/theme/embedded.js +206 -0
  444. package/dist/theme/index.d.ts +5 -5
  445. package/dist/theme/index.js +5 -12
  446. package/dist/theme/themes.mjs +44 -66
  447. package/dist/tooltip/KCoords.svelte +4 -1
  448. package/dist/tooltip/TooltipContent.svelte +3 -6
  449. package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
  450. package/dist/tooltip/index.d.ts +8 -1
  451. package/dist/trajectory/Trajectory.svelte +613 -386
  452. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  453. package/dist/trajectory/TrajectoryError.svelte +12 -74
  454. package/dist/trajectory/TrajectoryExportPane.svelte +14 -32
  455. package/dist/trajectory/TrajectoryInfoPane.svelte +127 -164
  456. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
  457. package/dist/trajectory/extract.js +61 -49
  458. package/dist/trajectory/format-detect.d.ts +2 -0
  459. package/dist/trajectory/format-detect.js +17 -13
  460. package/dist/trajectory/frame-reader.d.ts +2 -0
  461. package/dist/trajectory/frame-reader.js +35 -32
  462. package/dist/trajectory/helpers.d.ts +2 -0
  463. package/dist/trajectory/helpers.js +34 -56
  464. package/dist/trajectory/index.d.ts +1 -0
  465. package/dist/trajectory/index.js +5 -8
  466. package/dist/trajectory/parse/ase.js +1 -1
  467. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  468. package/dist/trajectory/parse/h5-utils.js +109 -0
  469. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  470. package/dist/trajectory/parse/hdf5.js +116 -106
  471. package/dist/trajectory/parse/index.d.ts +6 -6
  472. package/dist/trajectory/parse/index.js +25 -33
  473. package/dist/trajectory/parse/lammps.js +8 -12
  474. package/dist/trajectory/parse/vasp.js +10 -7
  475. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  476. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  477. package/dist/trajectory/parse/vaspout-h5.d.ts +4 -0
  478. package/dist/trajectory/parse/vaspout-h5.js +281 -0
  479. package/dist/trajectory/parse/xyz.js +59 -9
  480. package/dist/trajectory/plotting.d.ts +8 -9
  481. package/dist/trajectory/plotting.js +113 -64
  482. package/dist/utils.d.ts +3 -0
  483. package/dist/utils.js +7 -0
  484. package/dist/xrd/XrdPlot.svelte +79 -118
  485. package/dist/xrd/broadening.js +2 -1
  486. package/dist/xrd/calc-xrd.js +24 -62
  487. package/dist/xrd/parse.d.ts +0 -1
  488. package/dist/xrd/parse.js +69 -95
  489. package/package.json +94 -34
  490. package/readme.md +6 -5
  491. package/dist/api/mp.d.ts +0 -6
  492. package/dist/api/mp.js +0 -22
  493. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  494. package/dist/scene/types.d.ts +0 -26
  495. package/dist/tooltip/types.d.ts +0 -8
  496. package/dist/trajectory/constants.d.ts +0 -6
  497. package/dist/trajectory/constants.js +0 -11
  498. /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
  499. /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
@@ -1,8 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { contrast_color, default_element_colors } from '../colors'
3
3
  import type { CompositionType } from '../composition'
4
- import type { ElementSymbol } from '../element'
5
- import { element_data } from '../element'
4
+ import { element_by_symbol, is_elem_symbol, type ElementSymbol } from '../element'
6
5
  import Icon from '../Icon.svelte'
7
6
  import { ELEM_SYMBOLS, format_num } from '../labels'
8
7
  import { ColorBar } from '../plot'
@@ -10,10 +9,7 @@
10
9
  import { colors } from '../state.svelte'
11
10
  import type { AnyStructure } from './'
12
11
  import { atomic_radii } from './'
13
- import type {
14
- AtomColorConfig,
15
- AtomPropertyColors,
16
- } from './atom-properties'
12
+ import type { AtomColorConfig, AtomPropertyColors } from './atom-properties'
17
13
  import type { MoyoDataset } from '@spglib/moyo-wasm'
18
14
  import type { Snippet } from 'svelte'
19
15
  import { click_outside, tooltip } from 'svelte-multiselect/attachments'
@@ -29,7 +25,6 @@
29
25
  property_colors = null,
30
26
  elements,
31
27
  elem_color_picker_title = `Double click to reset color`,
32
- labels = $bindable([]),
33
28
  amount_format = `.3~f`,
34
29
  show_amounts = true,
35
30
  get_element_label,
@@ -52,7 +47,6 @@
52
47
  property_colors?: AtomPropertyColors | null
53
48
  elements?: CompositionType
54
49
  elem_color_picker_title?: string
55
- labels?: HTMLLabelElement[]
56
50
  amount_format?: string // Float formatting for element amounts (default: 3 significant digits)
57
51
  show_amounts?: boolean // Whether to show element amounts
58
52
  get_element_label?: (element: string, amount: number) => string // Custom label function
@@ -77,8 +71,7 @@
77
71
  }
78
72
 
79
73
  let show_element_legend = $derived(
80
- atom_color_config.mode === `element` && elements &&
81
- Object.keys(elements).length > 0,
74
+ atom_color_config.mode === `element` && elements && Object.keys(elements).length > 0,
82
75
  )
83
76
  let show_property_legend = $derived(
84
77
  atom_color_config.mode !== `element` && property_colors?.colors.length,
@@ -111,33 +104,43 @@
111
104
  let format_value = (val: number | string): string => {
112
105
  if (typeof val === `number`) return format_num(val, `.3~f`)
113
106
 
114
- if (typeof val === `string` && val.includes(`|`)) { // Format Wyckoff orbit IDs
107
+ if (typeof val === `string` && val.includes(`|`)) {
108
+ // Format Wyckoff orbit IDs
115
109
  const [wyckoff, element] = val.split(`|`, 2)
116
110
  // Count how many sites have this wyckoff+element combination
117
- const count = property_colors?.values.filter((property_value) =>
118
- property_value === val
119
- ).length ?? 0
111
+ const count =
112
+ property_colors?.values.filter((property_value) => property_value === val).length ?? 0
120
113
  return `${element}:${count}${wyckoff}`
121
114
  }
122
115
  return String(val)
123
116
  }
124
117
 
125
- // Map from property value to color (computed once, reused in categorical legend)
126
- let color_map = $derived(
127
- new Map(
128
- // Use unique_values instead of values to avoid undefined colors from duplicates
129
- property_colors?.unique_values?.flatMap((val) => {
130
- const idx = property_colors.values.indexOf(val)
131
- return idx !== -1 ? [[val, property_colors.colors[idx]]] : []
132
- }),
133
- ),
134
- )
118
+ // Map each property value to its first color in a single O(n) pass (reused in
119
+ // categorical and discrete legends). Skips undefined colors if arrays ever drift.
120
+ let color_map = $derived.by(() => {
121
+ const map = new Map<number | string, string>()
122
+ const { values = [], colors: value_colors = [] } = property_colors ?? {}
123
+ for (const [idx, val] of values.entries()) {
124
+ const color = value_colors[idx]
125
+ if (color !== undefined && !map.has(val)) map.set(val, color)
126
+ }
127
+ return map
128
+ })
129
+
130
+ // Continuous integer properties (e.g. coordination numbers) render as a discrete
131
+ // segmented bar with one labeled block per integer value instead of a smooth gradient.
132
+ // Cap segment count so high-cardinality numeric properties keep the gradient bar.
133
+ const MAX_DISCRETE_SEGMENTS = 20
134
+ let is_discrete_numeric = $derived.by(() => {
135
+ const uniq = property_colors?.unique_values
136
+ // Number.isInteger is false for strings/non-numbers (no coercion), so it also
137
+ // excludes categorical (e.g. Wyckoff) data without a separate type check
138
+ return Boolean(
139
+ uniq?.length && uniq.length <= MAX_DISCRETE_SEGMENTS && uniq.every(Number.isInteger),
140
+ )
141
+ })
135
142
 
136
- function toggle_visibility<T>(
137
- set: Set<T>,
138
- value: T,
139
- event: MouseEvent,
140
- ): Set<T> {
143
+ function toggle_visibility<T>(set: Set<T>, value: T, event: MouseEvent): Set<T> {
141
144
  event.preventDefault()
142
145
  event.stopPropagation()
143
146
  const new_set = new SvelteSet(set)
@@ -155,25 +158,20 @@
155
158
  if (!remap_search) return ELEM_SYMBOLS
156
159
  const query = remap_search.toLowerCase()
157
160
  return ELEM_SYMBOLS.filter((elem) => {
158
- const data = element_data?.find((el) => el.symbol === elem)
159
- return elem.toLowerCase().includes(query) ||
160
- data?.name?.toLowerCase().includes(query)
161
+ const data = element_by_symbol.get(elem)
162
+ return elem.toLowerCase().includes(query) || data?.name?.toLowerCase().includes(query)
161
163
  })
162
164
  })
163
165
 
164
- const known_element_symbols = new Set(ELEM_SYMBOLS)
165
166
  let sorted_element_entries = $derived.by(() => {
166
167
  if (!elements) return []
167
168
  const element_amounts = elements as Record<string, number>
168
- const ordered_known_entries = ELEM_SYMBOLS
169
- .flatMap((element_symbol) => {
170
- const amount = element_amounts[element_symbol]
171
- return amount === undefined ? [] : [[element_symbol, amount] as const]
172
- })
169
+ const ordered_known_entries = ELEM_SYMBOLS.flatMap((element_symbol) => {
170
+ const amount = element_amounts[element_symbol]
171
+ return amount === undefined ? [] : [[element_symbol, amount] as const]
172
+ })
173
173
  const unknown_entries = Object.entries(element_amounts)
174
- .filter(([element_symbol]) =>
175
- !known_element_symbols.has(element_symbol as ElementSymbol)
176
- )
174
+ .filter(([element_symbol]) => !is_elem_symbol(element_symbol))
177
175
  .sort(([element_a], [element_b]) => element_a.localeCompare(element_b))
178
176
  return [...ordered_known_entries, ...unknown_entries]
179
177
  })
@@ -195,7 +193,7 @@
195
193
  const MAX_RADIUS = 5
196
194
 
197
195
  const parse_radius = (value: string): number | null => {
198
- const num = parseFloat(value)
196
+ const num = Number(value)
199
197
  return !isNaN(num) && num >= MIN_RADIUS && num <= MAX_RADIUS ? num : null
200
198
  }
201
199
 
@@ -238,7 +236,7 @@
238
236
  {#snippet mode_selector_snippet()}
239
237
  <div
240
238
  class="mode-selector"
241
- {@attach click_outside({ callback: () => mode_menu_open = false })}
239
+ {@attach click_outside({ callback: () => (mode_menu_open = false) })}
242
240
  >
243
241
  <button
244
242
  class="mode-toggle"
@@ -254,10 +252,7 @@
254
252
  </button>
255
253
  {#if mode_menu_open}
256
254
  <div class="mode-dropdown">
257
- {#each Object.entries(SETTINGS_CONFIG.structure.atom_color_mode.enum || {}) as
258
- [value, label]
259
- (value)
260
- }
255
+ {#each Object.entries(SETTINGS_CONFIG.structure.atom_color_mode.enum || {}) as [value, label] (value)}
261
256
  <button
262
257
  class="mode-option"
263
258
  class:selected={atom_color_config.mode === value}
@@ -323,15 +318,15 @@
323
318
  {/snippet}
324
319
 
325
320
  {#if show_element_legend}
326
- <div {...rest} class="atom-legend element-legend {rest.class ?? ``}">
321
+ <div {...rest} class={[`atom-legend element-legend`, rest.class]}>
327
322
  {@render mode_selector_snippet()}
328
- {#each sorted_element_entries as [elem, amt], idx (elem)}
323
+ {#each sorted_element_entries as [elem, amt] (elem)}
329
324
  {@const is_hidden = hidden_elements.has(elem as ElementSymbol)}
330
325
  {@const displayed_elem = element_mapping?.[elem as ElementSymbol] || elem}
331
326
  <div class="legend-item">
332
327
  <label
333
- bind:this={labels[idx]}
334
- title="{element_data?.find((el) => el.symbol === displayed_elem)?.name ?? ``}{displayed_elem !== elem ? ` (remapped from ${elem})` : ``}"
328
+ title="{element_by_symbol.get(displayed_elem as ElementSymbol)?.name ??
329
+ ``}{displayed_elem !== elem ? ` (remapped from ${elem})` : ``}"
335
330
  {@attach tooltip()}
336
331
  style:background-color={colors.element[displayed_elem]}
337
332
  class:hidden={is_hidden}
@@ -364,13 +359,12 @@
364
359
  <button
365
360
  class="toggle-visibility"
366
361
  class:element-hidden={is_hidden}
367
- onclick={(
368
- event,
369
- ) => (hidden_elements = toggle_visibility(
370
- hidden_elements,
371
- elem as ElementSymbol,
372
- event,
373
- ))}
362
+ onclick={(event) =>
363
+ (hidden_elements = toggle_visibility(
364
+ hidden_elements,
365
+ elem as ElementSymbol,
366
+ event,
367
+ ))}
374
368
  title={is_hidden ? `Show ${elem} atoms` : `Hide ${elem} atoms`}
375
369
  {@attach tooltip({ placement: `top` })}
376
370
  type="button"
@@ -390,8 +384,8 @@
390
384
  <div class="radius-control">
391
385
  <label
392
386
  title={displayed_elem !== elem
393
- ? `Radius for ${elem} atoms (displayed as ${displayed_elem})`
394
- : `Radius for ${elem} atoms`}
387
+ ? `Radius for ${elem} atoms (displayed as ${displayed_elem})`
388
+ : `Radius for ${elem} atoms`}
395
389
  {@attach tooltip({ placement: `top` })}
396
390
  >
397
391
  <span>Radius ({elem})</span>
@@ -403,10 +397,7 @@
403
397
  value={get_element_radius(elem as ElementSymbol)}
404
398
  oninput={(event) => {
405
399
  if (event.target instanceof HTMLInputElement) {
406
- update_element_radius(
407
- elem as ElementSymbol,
408
- event.target.value,
409
- )
400
+ update_element_radius(elem as ElementSymbol, event.target.value)
410
401
  }
411
402
  }}
412
403
  />
@@ -447,7 +438,7 @@
447
438
  </button>
448
439
  {/if}
449
440
  {#each filtered_elements as target_elem (target_elem)}
450
- {@const elem_info = element_data?.find((el) => el.symbol === target_elem)}
441
+ {@const elem_info = element_by_symbol.get(target_elem)}
451
442
  <button
452
443
  class="remap-option"
453
444
  class:selected={displayed_elem === target_elem}
@@ -480,11 +471,29 @@
480
471
  <h4>{legend_title}</h4>
481
472
  </div>
482
473
  {/if}
483
- {#if atom_color_config.scale_type === `continuous` && property_colors}
484
- <div
485
- title={legend_title}
486
- {@attach tooltip({ placement: `top` })}
487
- >
474
+ {#if atom_color_config.scale_type === `continuous` && property_colors && is_discrete_numeric}
475
+ <div class="discrete-colorbar">
476
+ {#each property_colors.unique_values ?? [] as value (value)}
477
+ {@const color = color_map.get(value)}
478
+ {@const is_hidden = hidden_prop_vals.has(value)}
479
+ <button
480
+ type="button"
481
+ class="discrete-segment"
482
+ class:hidden={is_hidden}
483
+ style:background-color={color}
484
+ aria-pressed={is_hidden}
485
+ onclick={(event) =>
486
+ (hidden_prop_vals = toggle_visibility(hidden_prop_vals, value, event))}
487
+ title={is_hidden ? `Show ${format_value(value)}` : `Hide ${format_value(value)}`}
488
+ {@attach tooltip({ placement: `top` })}
489
+ {@attach contrast_color()}
490
+ >
491
+ {format_value(value)}
492
+ </button>
493
+ {/each}
494
+ </div>
495
+ {:else if atom_color_config.scale_type === `continuous` && property_colors}
496
+ <div title={legend_title} {@attach tooltip({ placement: `top` })}>
488
497
  <ColorBar
489
498
  color_scale={atom_color_config.scale}
490
499
  range={[property_colors.min_value ?? 0, property_colors.max_value ?? 0]}
@@ -499,10 +508,7 @@
499
508
  />
500
509
  </div>
501
510
  {:else if atom_color_config.scale_type === `categorical` && property_colors}
502
- {#each property_colors.unique_values || [] as
503
- value
504
- (`${atom_color_config.mode}-${value}`)
505
- }
511
+ {#each property_colors.unique_values || [] as value (`${atom_color_config.mode}-${value}`)}
506
512
  {@const color = color_map.get(value)}
507
513
  {@const is_hidden = hidden_prop_vals.has(value)}
508
514
  <div class="legend-item">
@@ -517,13 +523,8 @@
517
523
  <button
518
524
  class="toggle-visibility"
519
525
  class:element-hidden={is_hidden}
520
- onclick={(
521
- event,
522
- ) => (hidden_prop_vals = toggle_visibility(
523
- hidden_prop_vals,
524
- value,
525
- event,
526
- ))}
526
+ onclick={(event) =>
527
+ (hidden_prop_vals = toggle_visibility(hidden_prop_vals, value, event))}
527
528
  title={is_hidden ? `Show ${format_value(value)}` : `Hide ${format_value(value)}`}
528
529
  {@attach tooltip({ placement: `top` })}
529
530
  type="button"
@@ -542,6 +543,8 @@
542
543
  .atom-legend {
543
544
  position: absolute;
544
545
  z-index: var(--legend-z-index, 1);
546
+ /* own compositing layer, or WKWebView paints the canvas over this (see app.css) */
547
+ will-change: transform;
545
548
  pointer-events: auto;
546
549
  visibility: visible;
547
550
  filter: var(--legend-filter, grayscale(10%) brightness(0.95) saturate(0.8));
@@ -552,7 +555,9 @@
552
555
  gap: var(--struct-legend-gap, clamp(3pt, 2cqmin, 7pt));
553
556
  }
554
557
  .element-legend {
555
- font-size: var(--struct-legend-font, clamp(7pt, 2.5cqmin, 12pt));
558
+ /* 9pt floor keeps chips legible in small embeds (carousel cards) where
559
+ the cqmin term collapses */
560
+ font-size: var(--struct-legend-font, clamp(9pt, 2.5cqmin, 12pt));
556
561
  }
557
562
  .atom-legend .legend-item {
558
563
  position: relative;
@@ -598,7 +603,10 @@
598
603
  display: grid;
599
604
  place-items: center;
600
605
  opacity: 0;
601
- transition: opacity 0.2s ease, background 0.2s ease, transform 0.1s ease;
606
+ transition:
607
+ opacity 0.2s ease,
608
+ background 0.2s ease,
609
+ transform 0.1s ease;
602
610
  z-index: 2;
603
611
  pointer-events: auto;
604
612
  }
@@ -717,7 +725,7 @@
717
725
 
718
726
  /* Property Legend Styles */
719
727
  .property-legend {
720
- font-size: var(--struct-legend-font, clamp(8pt, 3cqmin, 14pt));
728
+ font-size: var(--struct-legend-font, clamp(9pt, 3cqmin, 14pt));
721
729
  }
722
730
  .mode-selector {
723
731
  position: relative;
@@ -753,7 +761,9 @@
753
761
  margin-bottom: 0.25rem;
754
762
  background: var(--surface-bg);
755
763
  border-radius: var(--border-radius, 3pt);
756
- box-shadow: 0 8px 16px -4px rgba(0, 0, 0, 0.3), 0 4px 8px -2px rgba(0, 0, 0, 0.1);
764
+ box-shadow:
765
+ 0 8px 16px -4px rgba(0, 0, 0, 0.3),
766
+ 0 4px 8px -2px rgba(0, 0, 0, 0.1);
757
767
  display: flex;
758
768
  flex-direction: column;
759
769
  z-index: 10;
@@ -795,6 +805,31 @@
795
805
  .mode-option span {
796
806
  white-space: nowrap;
797
807
  }
808
+ /* Discrete color bar: contiguous integer-labeled segments (e.g. coordination numbers) */
809
+ .discrete-colorbar {
810
+ display: flex;
811
+ height: var(--struct-discrete-bar-height, 16px);
812
+ border-radius: var(--border-radius, 3pt);
813
+ overflow: hidden;
814
+ }
815
+ .discrete-segment {
816
+ flex: 1 1 0;
817
+ min-width: 1.7em;
818
+ margin: 0;
819
+ padding: 0 4pt;
820
+ border: none;
821
+ border-radius: 0;
822
+ font-size: 0.85em;
823
+ line-height: 1;
824
+ cursor: pointer;
825
+ display: grid;
826
+ place-items: center;
827
+ transition: opacity 0.2s ease;
828
+ }
829
+ .discrete-segment.hidden {
830
+ opacity: 0.35;
831
+ text-decoration: line-through;
832
+ }
798
833
  .category-label {
799
834
  padding: var(--struct-legend-padding, 0 4pt);
800
835
  border-radius: var(--struct-legend-radius, var(--border-radius, 3pt));
@@ -1,5 +1,5 @@
1
1
  import type { CompositionType } from '../composition';
2
- import type { ElementSymbol } from '../element';
2
+ import { type ElementSymbol } from '../element';
3
3
  import type { AnyStructure } from './';
4
4
  import type { AtomColorConfig, AtomPropertyColors } from './atom-properties';
5
5
  import type { MoyoDataset } from '@spglib/moyo-wasm';
@@ -11,7 +11,6 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `children`> & {
11
11
  property_colors?: AtomPropertyColors | null;
12
12
  elements?: CompositionType;
13
13
  elem_color_picker_title?: string;
14
- labels?: HTMLLabelElement[];
15
14
  amount_format?: string;
16
15
  show_amounts?: boolean;
17
16
  get_element_label?: (element: string, amount: number) => string;
@@ -30,6 +29,6 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `children`> & {
30
29
  structure?: AnyStructure | null;
31
30
  }]>;
32
31
  };
33
- declare const AtomLegend: import("svelte").Component<$$ComponentProps, {}, "labels" | "atom_color_config" | "hidden_elements" | "hidden_prop_vals" | "element_mapping" | "element_radius_overrides" | "site_radius_overrides">;
32
+ declare const AtomLegend: import("svelte").Component<$$ComponentProps, {}, "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "site_radius_overrides" | "atom_color_config" | "element_mapping">;
34
33
  type AtomLegend = ReturnType<typeof AtomLegend>;
35
34
  export default AtomLegend;
@@ -4,7 +4,11 @@
4
4
  import type { InstancedMesh } from 'three'
5
5
  import { Color, InstancedBufferAttribute, Matrix4, ShaderMaterial } from 'three'
6
6
 
7
- let { group, saturation = 0.5, brightness = 0.7 }: {
7
+ let {
8
+ group,
9
+ saturation = 0.5,
10
+ brightness = 0.7,
11
+ }: {
8
12
  group: BondGroupWithGradients
9
13
  saturation?: number
10
14
  brightness?: number
@@ -104,12 +108,10 @@
104
108
 
105
109
  // Update geometry color attributes
106
110
  const { geometry } = mesh
107
- for (
108
- const [name, buffer] of [
109
- [`instanceColorStart`, colors_start],
110
- [`instanceColorEnd`, colors_end],
111
- ] as const
112
- ) {
111
+ for (const [name, buffer] of [
112
+ [`instanceColorStart`, colors_start],
113
+ [`instanceColorEnd`, colors_end],
114
+ ] as const) {
113
115
  const existing = geometry.getAttribute(name)
114
116
  if (existing?.array === buffer) existing.needsUpdate = true
115
117
  else geometry.setAttribute(name, new InstancedBufferAttribute(buffer, 3))
@@ -118,23 +120,29 @@
118
120
  mesh.count = count
119
121
  })
120
122
 
121
- let shader_material = $derived(
122
- new ShaderMaterial({
123
- vertexShader: vertex_shader,
124
- fragmentShader: fragment_shader,
125
- uniforms: {
126
- ambientIntensity: { value: group.ambient_light ?? 0.7 },
127
- directionalIntensity: { value: group.directional_light ?? 0.3 },
128
- saturation: { value: saturation },
129
- brightness: { value: brightness },
130
- },
131
- }),
132
- )
123
+ // Create the GPU material once + mutate uniforms reactively (a $derived would leak a new
124
+ // ShaderMaterial per lighting tweak). The $effect sets real uniform values before paint.
125
+ const shader_material = new ShaderMaterial({
126
+ vertexShader: vertex_shader,
127
+ fragmentShader: fragment_shader,
128
+ uniforms: {
129
+ ambientIntensity: { value: 0.7 },
130
+ directionalIntensity: { value: 0.3 },
131
+ saturation: { value: 0.5 },
132
+ brightness: { value: 0.7 },
133
+ },
134
+ })
135
+
136
+ $effect(() => {
137
+ shader_material.uniforms.ambientIntensity.value = group.ambient_light ?? 0.7
138
+ shader_material.uniforms.directionalIntensity.value = group.directional_light ?? 0.3
139
+ shader_material.uniforms.saturation.value = saturation
140
+ shader_material.uniforms.brightness.value = brightness
141
+ })
142
+
143
+ $effect(() => () => shader_material.dispose())
133
144
  </script>
134
145
 
135
- <T.InstancedMesh
136
- args={[undefined, shader_material, group.instances.length]}
137
- bind:ref={mesh}
138
- >
146
+ <T.InstancedMesh args={[undefined, shader_material, group.instances.length]} bind:ref={mesh}>
139
147
  <T.CylinderGeometry args={[group.thickness, group.thickness, 1, 8]} />
140
148
  </T.InstancedMesh>
@@ -4,13 +4,22 @@
4
4
  import type { HTMLAttributes } from 'svelte/elements'
5
5
  import type { Vec3 } from '../math'
6
6
 
7
- let { position, children, ...rest }: HTMLAttributes<HTMLDivElement> & {
7
+ let {
8
+ position,
9
+ children,
10
+ ...rest
11
+ }: HTMLAttributes<HTMLDivElement> & {
8
12
  position: Vec3
9
13
  children: Snippet<[{ position: Vec3 }]>
10
14
  } = $props()
11
15
  </script>
12
16
 
13
- <HTML {position} pointerEvents="none">
17
+ <!-- Constant zIndexRange: threlte's default [16777271, 0] maps camera distance
18
+ over [near, far], which extrapolates to a NEGATIVE z-index for sites beyond
19
+ camera.far (common in zoomed-out carousel cards) — painting the tooltip
20
+ behind the canvas. A degenerate range pins z-index at 1000, always above the
21
+ canvas and sibling overlays. -->
22
+ <HTML {position} pointerEvents="none" zIndexRange={[1000, 1000]}>
14
23
  <div {...rest} role="tooltip">
15
24
  {@render children({ position })}
16
25
  </div>
@@ -23,7 +32,10 @@
23
32
  box-sizing: border-box;
24
33
  text-align: var(--canvas-tooltip-text-align, left);
25
34
  border-radius: var(--canvas-tooltip-border-radius, var(--border-radius, 3pt));
26
- background: var(--canvas-tooltip-bg, light-dark(rgba(226, 232, 240, 0.96), rgba(15, 23, 42, 0.96)));
35
+ background: var(
36
+ --canvas-tooltip-bg,
37
+ light-dark(rgba(226, 232, 240, 0.96), rgba(15, 23, 42, 0.96))
38
+ );
27
39
  padding: var(--canvas-tooltip-padding, 1pt 5pt);
28
40
  color: var(--canvas-tooltip-text-color, light-dark(#0f172a, #f8fafc));
29
41
  font-family: var(--canvas-tooltip-font-family);
@@ -29,6 +29,26 @@
29
29
  let input_value = $state(supercell_scaling)
30
30
  let input_valid = $derived(is_valid_supercell_input(input_value))
31
31
 
32
+ // Hover-intent gate: opening instantly on mouseenter made the menu pop open
33
+ // when merely scrubbing the pointer across compact embeds (carousel cards).
34
+ // Deliberate hovers still open it; keyboard focus and clicks open instantly.
35
+ const hover_open_delay_ms = 200
36
+ let hover_timer: ReturnType<typeof setTimeout> | undefined
37
+
38
+ const schedule_hover_open = () => {
39
+ if (suppress_hover) return
40
+ clearTimeout(hover_timer)
41
+ // re-check suppression at fire time: a sibling popover may have opened meanwhile
42
+ hover_timer = setTimeout(() => (menu_open = !suppress_hover), hover_open_delay_ms)
43
+ }
44
+
45
+ const close_menu = () => {
46
+ clearTimeout(hover_timer)
47
+ menu_open = false
48
+ }
49
+
50
+ $effect(() => () => clearTimeout(hover_timer))
51
+
32
52
  const supercell_presets = [`1x1x1`, `2x2x2`, `3x3x3`, `2x2x1`, `3x3x1`, `2x1x1`]
33
53
 
34
54
  // Always show all 3 cell types - Prim/Conv disabled without sym_data
@@ -51,13 +71,13 @@
51
71
  function apply_preset(preset: string) {
52
72
  supercell_scaling = preset
53
73
  input_value = preset
54
- menu_open = false
74
+ close_menu()
55
75
  }
56
76
 
57
77
  function handle_input_submit() {
58
78
  if (input_valid && input_value !== supercell_scaling) {
59
79
  supercell_scaling = input_value
60
- menu_open = false
80
+ close_menu()
61
81
  }
62
82
  }
63
83
 
@@ -68,11 +88,12 @@
68
88
  !(current_target instanceof Node) ||
69
89
  !(next_target instanceof Node) ||
70
90
  !current_target.contains(next_target)
71
- ) menu_open = false
91
+ )
92
+ close_menu()
72
93
  }
73
94
 
74
95
  function handle_key_down(event: KeyboardEvent, submit_on_enter: boolean = false) {
75
- if (event.key === `Escape`) menu_open = false
96
+ if (event.key === `Escape`) close_menu()
76
97
  if (submit_on_enter && event.key === `Enter`) handle_input_submit()
77
98
  }
78
99
 
@@ -86,22 +107,25 @@
86
107
  // Close + keep closed while suppressed so the menu can't obscure a sibling popover
87
108
  // (e.g. the atom color-mode dropdown) the user is actively interacting with
88
109
  $effect(() => {
89
- if (suppress_hover) menu_open = false
110
+ if (suppress_hover) close_menu()
90
111
  })
91
112
  </script>
92
113
 
93
114
  <div
94
115
  class="cell-select"
95
116
  role="group"
96
- {@attach click_outside({ callback: () => (menu_open = false) })}
97
- onmouseenter={() => (menu_open = !suppress_hover)}
98
- onmouseleave={() => (menu_open = false)}
117
+ {@attach click_outside({ callback: close_menu })}
118
+ onmouseenter={schedule_hover_open}
119
+ onmouseleave={close_menu}
99
120
  onfocusin={() => (menu_open = !suppress_hover)}
100
121
  onfocusout={handle_focus_out}
101
122
  >
102
123
  <button
103
124
  type="button"
104
- onclick={() => (menu_open = !suppress_hover && !menu_open)}
125
+ onclick={() => {
126
+ clearTimeout(hover_timer)
127
+ menu_open = !suppress_hover && !menu_open
128
+ }}
105
129
  onkeydown={handle_key_down}
106
130
  class="toggle-btn"
107
131
  class:active={menu_open}
@@ -113,9 +137,9 @@
113
137
  style="--spinner-border-width: 2px; --spinner-size: 1em; --spinner-margin: 0; display: inline-block; vertical-align: middle"
114
138
  />
115
139
  {:else}
116
- {cell_type !== `original` ? `${cell_labels[cell_type]} ` : ``}{
117
- format_supercell_label(supercell_scaling)
118
- }
140
+ {cell_type !== `original` ? `${cell_labels[cell_type]} ` : ``}{format_supercell_label(
141
+ supercell_scaling,
142
+ )}
119
143
  {/if}
120
144
  </button>
121
145
 
@@ -131,8 +155,8 @@
131
155
  {@const disabled = type !== `original` && !sym_data}
132
156
  {@const label = cell_labels[type]}
133
157
  {@const tooltip_text = disabled
134
- ? `${cell_tooltips[type]} - requires symmetry data`
135
- : cell_tooltips[type]}
158
+ ? `${cell_tooltips[type]} - requires symmetry data`
159
+ : cell_tooltips[type]}
136
160
  <button
137
161
  class="cell-type-btn"
138
162
  class:selected={cell_type === type}
@@ -223,7 +247,9 @@
223
247
  display: flex;
224
248
  flex-direction: column;
225
249
  gap: 5px;
226
- z-index: 100;
250
+ z-index: var(--z-index-viewer-dropdown, 100);
251
+ /* own compositing layer, or WKWebView paints the canvas over this (see app.css) */
252
+ will-change: transform;
227
253
  font-size: var(--struct-cell-select-dropdown-font, max(10px, 1em));
228
254
  min-width: 118px;
229
255
  }
@@ -282,16 +308,8 @@
282
308
  }
283
309
  .cell-type-btn.selected {
284
310
  color: var(--cell-select-accent);
285
- background: color-mix(
286
- in srgb,
287
- var(--cell-select-accent) 18%,
288
- var(--cell-select-surface)
289
- );
290
- border-color: color-mix(
291
- in srgb,
292
- var(--cell-select-accent) 45%,
293
- var(--cell-select-border)
294
- );
311
+ background: color-mix(in srgb, var(--cell-select-accent) 18%, var(--cell-select-surface));
312
+ border-color: color-mix(in srgb, var(--cell-select-accent) 45%, var(--cell-select-border));
295
313
  }
296
314
  .cell-type-btn.disabled {
297
315
  opacity: 0.4;
@@ -319,16 +337,8 @@
319
337
  }
320
338
  .preset-btn.selected {
321
339
  color: var(--cell-select-accent);
322
- background: color-mix(
323
- in srgb,
324
- var(--cell-select-accent) 18%,
325
- var(--cell-select-surface)
326
- );
327
- border-color: color-mix(
328
- in srgb,
329
- var(--cell-select-accent) 45%,
330
- var(--cell-select-border)
331
- );
340
+ background: color-mix(in srgb, var(--cell-select-accent) 18%, var(--cell-select-surface));
341
+ border-color: color-mix(in srgb, var(--cell-select-accent) 45%, var(--cell-select-border));
332
342
  }
333
343
 
334
344
  .custom-input-row {