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
@@ -46,50 +46,27 @@
46
46
  const DEFAULT_SEARCH_EXAMPLES: SearchExampleCategory[] = [
47
47
  {
48
48
  label: `Has elements`,
49
- description:
50
- `Materials containing these elements. Operators/ranges: +Li,-O,Fe:1-2. Use * for any element.`,
49
+ description: `Materials containing these elements. Operators/ranges: +Li,-O,Fe:1-2. Use * for any element.`,
51
50
  examples: [`Li,Fe`, `+Li,-O`, `Li,*,*`],
52
51
  },
53
52
  {
54
53
  label: `Chemical system`,
55
- description:
56
- `Materials with only these elements (no others). Wildcards/ranges supported.`,
54
+ description: `Materials with only these elements (no others). Wildcards/ranges supported.`,
57
55
  examples: [`Li-Fe-O`, `Li-Fe-*-*`, `*-*-O`],
58
56
  },
59
57
  {
60
58
  label: `Exact formula`,
61
- description:
62
- `Materials with this exact stoichiometry. Unicode paste, wildcards, and canonicalization supported.`,
59
+ description: `Materials with this exact stoichiometry. Unicode paste, wildcards, and canonicalization supported.`,
63
60
  examples: [`LiFePO4`, `LiFe*2*`, `*2O3`],
64
61
  },
65
62
  ]
66
63
 
67
- const SUBSCRIPT_TO_ASCII: Record<string, string> = {
68
- [`\u2080`]: `0`,
69
- [`\u2081`]: `1`,
70
- [`\u2082`]: `2`,
71
- [`\u2083`]: `3`,
72
- [`\u2084`]: `4`,
73
- [`\u2085`]: `5`,
74
- [`\u2086`]: `6`,
75
- [`\u2087`]: `7`,
76
- [`\u2088`]: `8`,
77
- [`\u2089`]: `9`,
78
- }
79
-
80
- const SUPERSCRIPT_TO_ASCII: Record<string, string> = {
81
- [`\u2070`]: `0`,
82
- [`\u00B9`]: `1`,
83
- [`\u00B2`]: `2`,
84
- [`\u00B3`]: `3`,
85
- [`\u2074`]: `4`,
86
- [`\u2075`]: `5`,
87
- [`\u2076`]: `6`,
88
- [`\u2077`]: `7`,
89
- [`\u2078`]: `8`,
90
- [`\u2079`]: `9`,
91
- [`\u207A`]: `+`,
92
- [`\u207B`]: `-`,
64
+ // Unicode subscript/superscript digits and signs -> ASCII equivalents
65
+ const UNICODE_TO_ASCII: Record<string, string> = {
66
+ ...Object.fromEntries([...`₀₁₂₃₄₅₆₇₈₉`].map((char, digit) => [char, `${digit}`])),
67
+ ...Object.fromEntries([...`⁰¹²³⁴⁵⁶⁷⁸⁹`].map((char, digit) => [char, `${digit}`])),
68
+ [`⁺`]: `+`,
69
+ [`⁻`]: `-`,
93
70
  }
94
71
 
95
72
  let {
@@ -155,52 +132,31 @@
155
132
  const has_storage = typeof localStorage !== `undefined`
156
133
  const history_pins_key = $derived(`${history_key}-pins`)
157
134
 
158
- function load_history(): string[] {
135
+ function load_entries(key: string): string[] {
159
136
  if (max_history <= 0 || !has_storage) return []
160
137
  try {
161
- const raw = localStorage.getItem(history_key)
162
- if (!raw) return []
163
- const parsed: unknown = JSON.parse(raw)
138
+ const parsed: unknown = JSON.parse(localStorage.getItem(key) ?? `null`)
164
139
  if (!Array.isArray(parsed)) return []
165
- return parsed.filter((item): item is string => typeof item === `string`).slice(
166
- 0,
167
- max_history,
168
- )
140
+ return parsed.filter((item): item is string => typeof item === `string`)
169
141
  } catch {
170
142
  return []
171
143
  }
172
144
  }
173
145
 
174
- function save_history(entries: string[]): void {
146
+ function save_entries(key: string, entries: string[]): void {
175
147
  if (max_history <= 0 || !has_storage) return
176
148
  try {
177
- localStorage.setItem(history_key, JSON.stringify(entries.slice(0, max_history)))
149
+ localStorage.setItem(key, JSON.stringify(entries))
178
150
  } catch {
179
151
  // localStorage may be unavailable (e.g. private browsing)
180
152
  }
181
153
  }
182
154
 
183
- function load_pinned(): string[] {
184
- if (max_history <= 0 || !has_storage) return []
185
- try {
186
- const raw = localStorage.getItem(history_pins_key)
187
- if (!raw) return []
188
- const parsed: unknown = JSON.parse(raw)
189
- if (!Array.isArray(parsed)) return []
190
- return parsed.filter((item): item is string => typeof item === `string`)
191
- } catch {
192
- return []
193
- }
194
- }
195
-
196
- function save_pinned(entries: string[]): void {
197
- if (max_history <= 0 || !has_storage) return
198
- try {
199
- localStorage.setItem(history_pins_key, JSON.stringify(entries))
200
- } catch {
201
- // localStorage may be unavailable
202
- }
203
- }
155
+ const load_history = () => load_entries(history_key).slice(0, max_history)
156
+ const load_pinned = () => load_entries(history_pins_key)
157
+ const save_history = (entries: string[]) =>
158
+ save_entries(history_key, entries.slice(0, max_history))
159
+ const save_pinned = (entries: string[]) => save_entries(history_pins_key, entries)
204
160
 
205
161
  let history = $state<string[]>(load_history())
206
162
  let pinned_history = $state<string[]>(load_pinned())
@@ -249,9 +205,7 @@
249
205
  let visible_history = $derived.by(() => {
250
206
  const filtered = history
251
207
  .filter((item) => item !== value)
252
- .filter((item) =>
253
- item.toLowerCase().includes(history_query.toLowerCase().trim())
254
- )
208
+ .filter((item) => item.toLowerCase().includes(history_query.toLowerCase().trim()))
255
209
  const pinned = filtered.filter((item) => pinned_history.includes(item))
256
210
  const unpinned = filtered.filter((item) => !pinned_history.includes(item))
257
211
  return [...pinned, ...unpinned]
@@ -305,9 +259,9 @@
305
259
  $effect(() => {
306
260
  if (!examples_open || !examples_wrapper) return
307
261
  requestAnimationFrame(() => {
308
- const dropdown = examples_wrapper?.querySelector(`.examples-dropdown`) as
309
- | HTMLElement
310
- | null
262
+ const dropdown = examples_wrapper?.querySelector(
263
+ `.examples-dropdown`,
264
+ ) as HTMLElement | null
311
265
  if (!dropdown) return
312
266
  const rect = dropdown.getBoundingClientRect()
313
267
  if (rect.right > window.innerWidth && !anchor_left) anchor_left = true
@@ -331,17 +285,16 @@
331
285
 
332
286
  function normalize_unicode_formula(input: string): string {
333
287
  let normalized = input
334
- for (const [subscript, ascii] of Object.entries(SUBSCRIPT_TO_ASCII)) {
335
- normalized = normalized.replaceAll(subscript, ascii)
336
- }
337
- for (const [superscript, ascii] of Object.entries(SUPERSCRIPT_TO_ASCII)) {
338
- normalized = normalized.replaceAll(superscript, ascii)
288
+ for (const [unicode_char, ascii] of Object.entries(UNICODE_TO_ASCII)) {
289
+ normalized = normalized.replaceAll(unicode_char, ascii)
339
290
  }
340
- return normalized
341
- // keep hydrate dots (deleting would glue digits: CuSO4·5H2O -> CuSO45H2O)
342
- .replaceAll(`⋅`, `·`)
343
- .replaceAll(`−`, `-`)
344
- .replaceAll(/\s+/g, ``)
291
+ return (
292
+ normalized
293
+ // keep hydrate dots (deleting would glue digits: CuSO4·5H2O -> CuSO45H2O)
294
+ .replaceAll(`⋅`, `·`)
295
+ .replaceAll(`−`, `-`)
296
+ .replaceAll(/\s+/g, ``)
297
+ )
345
298
  }
346
299
 
347
300
  function normalize_exact_formula(input: string): string {
@@ -356,8 +309,9 @@
356
309
  try {
357
310
  const tokens = parse_formula_with_wildcards(sanitized_input)
358
311
  const explicit = tokens
359
- .filter((token): token is { element: ElementSymbol; count: number } =>
360
- token.element !== null
312
+ .filter(
313
+ (token): token is { element: ElementSymbol; count: number } =>
314
+ token.element !== null,
361
315
  )
362
316
  .map((token) => ({ element: token.element, count: token.count }))
363
317
  const wildcard_tokens = tokens.filter((token) => token.element === null)
@@ -365,21 +319,19 @@
365
319
  // Merge explicit element counts before sorting.
366
320
  const merged_explicit: { element: string; count: number }[] = []
367
321
  for (const token of explicit) {
368
- const existing = merged_explicit.find((item) =>
369
- item.element === token.element
370
- )
322
+ const existing = merged_explicit.find((item) => item.element === token.element)
371
323
  if (existing) existing.count += token.count
372
324
  else merged_explicit.push(token)
373
325
  }
374
326
  const sorted_explicit = merged_explicit.sort((elem_a, elem_b) =>
375
- elem_a.element.localeCompare(elem_b.element)
327
+ elem_a.element.localeCompare(elem_b.element),
376
328
  )
377
- const wildcard_str = wildcard_tokens.map((token) =>
378
- token.count > 1 ? `*${token.count}` : `*`
379
- ).join(``)
380
- const explicit_str = sorted_explicit.map((token) =>
381
- token.count > 1 ? `${token.element}${token.count}` : token.element
382
- ).join(``)
329
+ const wildcard_str = wildcard_tokens
330
+ .map((token) => (token.count > 1 ? `*${token.count}` : `*`))
331
+ .join(``)
332
+ const explicit_str = sorted_explicit
333
+ .map((token) => (token.count > 1 ? `${token.element}${token.count}` : token.element))
334
+ .join(``)
383
335
  return `${explicit_str}${wildcard_str}`
384
336
  } catch {
385
337
  return sanitized_input
@@ -388,16 +340,18 @@
388
340
 
389
341
  function is_valid_constraint(constraint: string): boolean {
390
342
  if (!constraint) return true
391
- return /^\d+$/.test(constraint) || /^\d+-\d+$/.test(constraint) ||
392
- /^(>=|<=|>|<)\d+$/.test(constraint)
343
+ return (
344
+ /^\d+$/.test(constraint) ||
345
+ /^\d+-\d+$/.test(constraint) ||
346
+ /^(?:>=|<=|>|<)\d+$/.test(constraint)
347
+ )
393
348
  }
394
349
 
395
- function strip_operator_prefix(
396
- token: string,
397
- ): { operator: FormulaFilterToken[`operator`]; value: string } {
398
- const operator = token.startsWith(`-`) || token.startsWith(`!`)
399
- ? `exclude`
400
- : `include`
350
+ function strip_operator_prefix(token: string): {
351
+ operator: FormulaFilterToken[`operator`]
352
+ value: string
353
+ } {
354
+ const operator = token.startsWith(`-`) || token.startsWith(`!`) ? `exclude` : `include`
401
355
  const stripped_value =
402
356
  token.startsWith(`+`) || token.startsWith(`-`) || token.startsWith(`!`)
403
357
  ? token.slice(1)
@@ -413,13 +367,10 @@
413
367
  return `${prefix}${token.element}${suffix}`
414
368
  }
415
369
 
416
- function token_chip_label(
370
+ // Chip labels show an explicit + prefix for include tokens; serialized values omit it
371
+ const token_chip_label = (
417
372
  token: Pick<FormulaFilterToken, `operator` | `element` | `constraint`>,
418
- ): string {
419
- const prefix = token.operator === `exclude` ? `-` : `+`
420
- const suffix = token.constraint ? `:${token.constraint}` : ``
421
- return `${prefix}${token.element}${suffix}`
422
- }
373
+ ): string => (token.operator === `include` ? `+` : ``) + serialize_token(token)
423
374
 
424
375
  function parse_token(raw_token: string): FormulaFilterToken {
425
376
  const token = raw_token.trim()
@@ -429,8 +380,9 @@
429
380
  const is_wildcard = element === `*`
430
381
  const is_valid_element = is_wildcard || is_elem_symbol(element)
431
382
  const normalized_constraint = constraint?.trim() || null
432
- const is_valid = is_valid_element && (normalized_constraint === null ||
433
- is_valid_constraint(normalized_constraint))
383
+ const is_valid =
384
+ is_valid_element &&
385
+ (normalized_constraint === null || is_valid_constraint(normalized_constraint))
434
386
 
435
387
  return {
436
388
  raw: raw_token,
@@ -442,36 +394,37 @@
442
394
  }
443
395
  }
444
396
 
445
- function tokenize_query(
446
- input: string,
447
- mode: FormulaSearchMode,
448
- ): FormulaFilterToken[] {
397
+ function tokenize_query(input: string, mode: FormulaSearchMode): FormulaFilterToken[] {
449
398
  const trimmed = input.trim()
450
399
  if (!trimmed) return []
451
400
  if (mode === `exact`) {
452
- return [{
453
- raw: trimmed,
454
- element: trimmed,
455
- operator: `include`,
456
- constraint: null,
457
- is_wildcard: has_wildcards(trimmed),
458
- is_valid: sanitize_exact_formula(trimmed).is_valid,
459
- }]
401
+ return [
402
+ {
403
+ raw: trimmed,
404
+ element: trimmed,
405
+ operator: `include`,
406
+ constraint: null,
407
+ is_wildcard: has_wildcards(trimmed),
408
+ is_valid: sanitize_exact_formula(trimmed).is_valid,
409
+ },
410
+ ]
460
411
  }
461
412
  const normalized = mode === `chemsys` ? trimmed.replaceAll(`,`, `-`) : trimmed
462
- const tokens = mode === `chemsys`
463
- // Keep range constraints like Fe:1-2 intact while splitting token separators.
464
- ? normalized.split(/-(?!\d)/)
465
- : normalized.split(`,`)
413
+ const tokens =
414
+ mode === `chemsys`
415
+ ? // Keep range constraints like Fe:1-2 intact while splitting token separators.
416
+ normalized.split(/-(?!\d)/)
417
+ : normalized.split(`,`)
466
418
  return tokens
467
419
  .map((token) => token.trim())
468
420
  .filter(Boolean)
469
421
  .map(parse_token)
470
422
  }
471
423
 
472
- function sanitize_exact_formula(
473
- input: string,
474
- ): { is_valid: boolean; error_message: string | null } {
424
+ function sanitize_exact_formula(input: string): {
425
+ is_valid: boolean
426
+ error_message: string | null
427
+ } {
475
428
  const trimmed = input.trim()
476
429
  if (!trimmed) return { is_valid: true, error_message: null }
477
430
  try {
@@ -510,9 +463,7 @@
510
463
  return token_a.element.localeCompare(token_b.element)
511
464
  })
512
465
 
513
- return normalized_tokens
514
- .map(serialize_token)
515
- .join(separator)
466
+ return normalized_tokens.map(serialize_token).join(separator)
516
467
  }
517
468
 
518
469
  function parse_query(
@@ -521,14 +472,15 @@
521
472
  ): FormulaFilterParseResult {
522
473
  const tokens = tokenize_query(normalized_value, mode)
523
474
  const first_invalid_token = tokens.find((token) => !token.is_valid)
524
- const exact_validation = mode === `exact`
525
- ? sanitize_exact_formula(normalized_value)
526
- : {
527
- is_valid: !first_invalid_token,
528
- error_message: first_invalid_token
529
- ? `Invalid token: ${first_invalid_token.raw}`
530
- : null,
531
- }
475
+ const exact_validation =
476
+ mode === `exact`
477
+ ? sanitize_exact_formula(normalized_value)
478
+ : {
479
+ is_valid: !first_invalid_token,
480
+ error_message: first_invalid_token
481
+ ? `Invalid token: ${first_invalid_token.raw}`
482
+ : null,
483
+ }
532
484
  return {
533
485
  value: normalized_value,
534
486
  normalized_value,
@@ -559,7 +511,10 @@
559
511
  if (!trimmed) return []
560
512
  // If contains commas or dashes, split by those and sort alphabetically
561
513
  if (trimmed.includes(`,`) || trimmed.includes(`-`)) {
562
- const parts = trimmed.split(/[-,]/).map((str) => str.trim()).filter(Boolean)
514
+ const parts = trimmed
515
+ .split(/[-,]/)
516
+ .map((str) => str.trim())
517
+ .filter(Boolean)
563
518
  // Separate wildcards from regular elements
564
519
  const wildcards = parts.filter((part) => part === `*`)
565
520
  const regular_parts = parts.filter((part) => part !== `*`)
@@ -569,18 +524,10 @@
569
524
  }
570
525
  // Otherwise parse as formula (already returns sorted by default)
571
526
  // For formulas with wildcards, we can't parse them normally
572
- if (has_wildcards(trimmed)) { // Use shared utility and extract unique elements
527
+ if (has_wildcards(trimmed)) {
573
528
  const tokens = parse_formula_with_wildcards(trimmed)
574
- const unique_elements: string[] = []
575
- for (const token of tokens) {
576
- if (token.element !== null && !unique_elements.includes(token.element)) {
577
- unique_elements.push(token.element)
578
- }
579
- }
580
- const elements = unique_elements.sort()
581
- const wildcards = tokens.filter((token) => token.element === null).map(() =>
582
- `*`
583
- )
529
+ const elements = [...new Set(tokens.flatMap((token) => token.element ?? []))].sort()
530
+ const wildcards = tokens.filter((token) => token.element === null).map(() => `*`)
584
531
  return [...elements, ...wildcards]
585
532
  }
586
533
  try {
@@ -672,9 +619,7 @@
672
619
  focused_history_idx = (focused_history_idx + 1) % len
673
620
  } else if (event.key === `ArrowUp`) {
674
621
  event.preventDefault()
675
- focused_history_idx = focused_history_idx <= 0
676
- ? len - 1
677
- : focused_history_idx - 1
622
+ focused_history_idx = focused_history_idx <= 0 ? len - 1 : focused_history_idx - 1
678
623
  }
679
624
  }
680
625
  }
@@ -709,8 +654,8 @@
709
654
  function handle_menu_keydown(event: KeyboardEvent): void {
710
655
  const len = all_examples.length
711
656
  if (!len) return
712
- const is_button_activation = (event.key === `Enter` || event.key === ` `) &&
713
- event.target instanceof HTMLButtonElement
657
+ const is_button_activation =
658
+ (event.key === `Enter` || event.key === ` `) && event.target instanceof HTMLButtonElement
714
659
  if (is_button_activation) return
715
660
 
716
661
  const key_actions: Record<string, () => void> = {
@@ -734,8 +679,9 @@
734
679
  function remove_token(token_idx: number): void {
735
680
  if (search_mode === `exact`) return
736
681
  const separator = search_mode === `chemsys` ? `-` : `,`
737
- const tokens = tokenize_query(input_value, search_mode)
738
- .filter((_, idx) => idx !== token_idx)
682
+ const tokens = tokenize_query(input_value, search_mode).filter(
683
+ (_, idx) => idx !== token_idx,
684
+ )
739
685
  const next_value = tokens.map(serialize_token).join(separator)
740
686
  input_value = next_value
741
687
  set_value(next_value, search_mode)
@@ -752,8 +698,8 @@
752
698
  search_mode === `chemsys`
753
699
  ? `Li-Fe-O or Li-*-*`
754
700
  : search_mode === `exact`
755
- ? `LiFePO4 or LiFe*2*`
756
- : `Li,Fe,O or Li,*,*`,
701
+ ? `LiFePO4 or LiFe*2*`
702
+ : `Li,Fe,O or Li,*,*`,
757
703
  )
758
704
 
759
705
  const MODE_LABELS: Record<FormulaSearchMode, string> = {
@@ -877,8 +823,8 @@
877
823
  class:locked={mode_locked}
878
824
  onclick={cycle_mode}
879
825
  title={mode_locked
880
- ? `Mode is locked`
881
- : `Click to switch to '${next_mode.mode}' → ${next_mode.value}`}
826
+ ? `Mode is locked`
827
+ : `Click to switch to '${next_mode.mode}' → ${next_mode.value}`}
882
828
  {@attach tooltip()}
883
829
  aria-label="Change search mode"
884
830
  >
@@ -959,11 +905,7 @@
959
905
  </div>
960
906
  {#if show_chip_row}
961
907
  <div class="token-chip-row">
962
- {#each parsed_tokens as
963
- token,
964
- idx
965
- (`${token.operator}:${token.element}:${token.constraint ?? ``}:${idx}`)
966
- }
908
+ {#each parsed_tokens as token, idx (`${token.operator}:${token.element}:${token.constraint ?? ``}:${idx}`)}
967
909
  <button
968
910
  type="button"
969
911
  class="token-chip"
@@ -1037,7 +979,9 @@
1037
979
  cursor: pointer;
1038
980
  color: var(--highlight, #4db6ff);
1039
981
  opacity: 0.8;
1040
- transition: opacity 0.15s, background 0.15s;
982
+ transition:
983
+ opacity 0.15s,
984
+ background 0.15s;
1041
985
  &:hover {
1042
986
  opacity: 1;
1043
987
  background: rgba(77, 182, 255, 0.2);
@@ -1127,24 +1071,7 @@
1127
1071
  font-size: 0.88em;
1128
1072
  color: inherit;
1129
1073
  }
1130
- .history-remove {
1131
- min-width: 24px;
1132
- min-height: 24px;
1133
- display: flex;
1134
- align-items: center;
1135
- justify-content: center;
1136
- background: none;
1137
- border: none;
1138
- cursor: pointer;
1139
- padding: 3pt;
1140
- border-radius: 50%;
1141
- opacity: 0.3;
1142
- color: inherit;
1143
- &:hover {
1144
- opacity: 0.8;
1145
- background: rgba(128, 128, 128, 0.15);
1146
- }
1147
- }
1074
+ .history-remove,
1148
1075
  .history-pin {
1149
1076
  display: flex;
1150
1077
  align-items: center;
@@ -1161,6 +1088,10 @@
1161
1088
  background: rgba(128, 128, 128, 0.15);
1162
1089
  }
1163
1090
  }
1091
+ .history-remove {
1092
+ min-width: 24px;
1093
+ min-height: 24px;
1094
+ }
1164
1095
  .examples-wrapper {
1165
1096
  position: relative;
1166
1097
  }
@@ -6,7 +6,12 @@
6
6
  import { format_num } from '../labels'
7
7
  import type { Snippet } from 'svelte'
8
8
  import type { SVGAttributes } from 'svelte/elements'
9
- import { type ChartSegmentData, get_chart_font_scale } from './index'
9
+ import {
10
+ chart_segment_label,
11
+ chart_segment_suffix,
12
+ type ChartSegmentData,
13
+ get_chart_font_scale,
14
+ } from './index'
10
15
  import { count_atoms_in_composition, fractional_composition } from './parse'
11
16
 
12
17
  // Constants for pie chart calculations
@@ -81,15 +86,19 @@
81
86
  const outer_arc = `M ${center} ${center - radius} A ${radius} ${radius} 0 1 1 ${center} ${
82
87
  center + radius
83
88
  } A ${radius} ${radius} 0 1 1 ${center} ${center - radius} Z`
84
- const path = ir > 0
85
- ? `${outer_arc} M ${center} ${
86
- center - ir
87
- } A ${ir} ${ir} 0 1 0 ${center} ${
88
- center + ir
89
- } A ${ir} ${ir} 0 1 0 ${center} ${center - ir} Z`
90
- : outer_arc
91
- const label_text = element + (show_amounts ? String(amount) : ``) +
92
- (show_percentages ? `${format_num(fraction, `.1~%`)}` : ``)
89
+ const path =
90
+ ir > 0
91
+ ? `${outer_arc} M ${center} ${center - ir} A ${ir} ${ir} 0 1 0 ${center} ${
92
+ center + ir
93
+ } A ${ir} ${ir} 0 1 0 ${center} ${center - ir} Z`
94
+ : outer_arc
95
+ const label_text = chart_segment_label(
96
+ element,
97
+ amount,
98
+ fraction,
99
+ show_amounts,
100
+ show_percentages,
101
+ )
93
102
  return {
94
103
  element,
95
104
  amount,
@@ -132,14 +141,15 @@
132
141
  const large_arc = angle_span > 180 ? 1 : 0
133
142
 
134
143
  // Create donut path if inner radius > 0, otherwise regular pie slice
135
- const path = inner_radius_adjusted > 0
136
- ? `M ${x1_outer} ${y1_outer} A ${outer_radius} ${outer_radius} 0 ${large_arc} 1 ${x2_outer} ${y2_outer} L ${x2_inner} ${y2_inner} A ${inner_radius_adjusted} ${inner_radius_adjusted} 0 ${large_arc} 0 ${x1_inner} ${y1_inner} Z`
137
- : `M ${center} ${center} L ${x1_outer} ${y1_outer} A ${outer_radius} ${outer_radius} 0 ${large_arc} 1 ${x2_outer} ${y2_outer} Z`
144
+ const path =
145
+ inner_radius_adjusted > 0
146
+ ? `M ${x1_outer} ${y1_outer} A ${outer_radius} ${outer_radius} 0 ${large_arc} 1 ${x2_outer} ${y2_outer} L ${x2_inner} ${y2_inner} A ${inner_radius_adjusted} ${inner_radius_adjusted} 0 ${large_arc} 0 ${x1_inner} ${y1_inner} Z`
147
+ : `M ${center} ${center} L ${x1_outer} ${y1_outer} A ${outer_radius} ${outer_radius} 0 ${large_arc} 1 ${x2_outer} ${y2_outer} Z`
138
148
 
139
149
  // Position labels with three-tier strategy
140
150
  const is_very_thin_slice = angle_span < VERY_THIN_SLICE_THRESHOLD // Place outside
141
- const is_medium_slice = angle_span >= VERY_THIN_SLICE_THRESHOLD &&
142
- angle_span < MEDIUM_SLICE_THRESHOLD // Near outer edge
151
+ const is_medium_slice =
152
+ angle_span >= VERY_THIN_SLICE_THRESHOLD && angle_span < MEDIUM_SLICE_THRESHOLD // Near outer edge
143
153
 
144
154
  let label_radius: number
145
155
  let is_outside_slice = false
@@ -159,22 +169,22 @@
159
169
  // Calculate font scale based on slice size and smart text fitting
160
170
  const [min_font_scale, max_font_scale] = [1.4, 2] as const
161
171
  const scale_factor = angle_span / MAX_ANGLE_FOR_FULL_SCALE
162
- const base_scale = min_font_scale +
163
- scale_factor * (max_font_scale - min_font_scale)
164
- const label_text = element + (show_amounts ? amount?.toString() ?? `` : ``) +
165
- (show_percentages ? `${format_num(fraction, `.1~%`)}` : ``)
172
+ const base_scale = min_font_scale + scale_factor * (max_font_scale - min_font_scale)
173
+ const label_text = chart_segment_label(
174
+ element,
175
+ amount,
176
+ fraction,
177
+ show_amounts,
178
+ show_percentages,
179
+ )
166
180
  const available_space = is_very_thin_slice
167
181
  ? outer_radius * 0.8 // More space outside the slice
168
182
  : Math.min(
169
- outer_radius - inner_radius_adjusted, // Radial space
170
- (angle_span * Math.PI / 180) * label_radius * 0.8, // Arc space at label radius
171
- )
183
+ outer_radius - inner_radius_adjusted, // Radial space
184
+ ((angle_span * Math.PI) / 180) * label_radius * 0.8, // Arc space at label radius
185
+ )
172
186
 
173
- const font_scale = get_chart_font_scale(
174
- base_scale,
175
- label_text,
176
- available_space,
177
- )
187
+ const font_scale = get_chart_font_scale(base_scale, label_text, available_space)
178
188
 
179
189
  return {
180
190
  element,
@@ -202,7 +212,7 @@
202
212
  viewBox="0 0 {size} {size}"
203
213
  style:max-width="{size}px"
204
214
  {...rest}
205
- class="pie-chart {rest.class ?? ``}"
215
+ class={[`pie-chart`, rest.class]}
206
216
  bind:this={svg_node}
207
217
  >
208
218
  {#each segments as segment (segment.element)}
@@ -211,10 +221,10 @@
211
221
  fill={segment.color}
212
222
  stroke="white"
213
223
  stroke-width={segments.length === 1
214
- ? 0
215
- : hovered_element === segment.element
216
- ? stroke_width + 1
217
- : stroke_width}
224
+ ? 0
225
+ : hovered_element === segment.element
226
+ ? stroke_width + 1
227
+ : stroke_width}
218
228
  class="pie-segment"
219
229
  class:interactive
220
230
  class:hovered={hovered_element === segment.element}
@@ -254,15 +264,18 @@
254
264
  class:outside-slice={segment.is_outside_slice}
255
265
  style:color={segment.text_color}
256
266
  >
257
- <span class="element-symbol" style:font-size="{14 * segment.font_scale}px">{
258
- segment.element
259
- }</span>
267
+ <span class="element-symbol" style:font-size="{14 * segment.font_scale}px"
268
+ >{segment.element}</span
269
+ >
260
270
  {#if show_amounts || show_percentages}
261
- <sub class="amount" style:font-size="{8 * segment.font_scale}px">{
262
- show_amounts ? segment.amount : ``
263
- }{show_amounts && show_percentages ? `=` : ``}{
264
- show_percentages ? format_num(segment.fraction, `.1~%`) : ``
265
- }</sub>
271
+ <sub class="amount" style:font-size="{8 * segment.font_scale}px"
272
+ >{chart_segment_suffix(
273
+ segment.amount,
274
+ segment.fraction,
275
+ show_amounts,
276
+ show_percentages,
277
+ )}</sub
278
+ >
266
279
  {/if}
267
280
  </div>
268
281
  </foreignObject>
@@ -285,7 +298,8 @@
285
298
  .pie-segment.interactive {
286
299
  cursor: pointer;
287
300
  }
288
- .pie-segment.interactive:hover, .pie-segment.hovered {
301
+ .pie-segment.interactive:hover,
302
+ .pie-segment.hovered {
289
303
  filter: brightness(1.1);
290
304
  }
291
305
  .pie-segment.interactive:focus {