matterviz 0.3.1 → 0.3.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 (358) hide show
  1. package/dist/EmptyState.svelte +10 -2
  2. package/dist/FilePicker.svelte +154 -96
  3. package/dist/Icon.svelte +20 -14
  4. package/dist/MillerIndexInput.svelte +27 -21
  5. package/dist/api/optimade.js +6 -6
  6. package/dist/app.css +216 -178
  7. package/dist/brillouin/BrillouinZone.svelte +299 -198
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +74 -55
  11. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte +277 -165
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  15. package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
  16. package/dist/brillouin/compute.js +11 -6
  17. package/dist/chempot-diagram/ChemPotDiagram.svelte +327 -0
  18. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  19. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +847 -0
  20. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  21. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3194 -0
  22. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  23. package/dist/chempot-diagram/ChemPotScene3D.svelte +11 -0
  24. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  25. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  26. package/dist/chempot-diagram/async-compute.svelte.js +77 -0
  27. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  28. package/dist/chempot-diagram/chempot-worker.js +11 -0
  29. package/dist/chempot-diagram/color.d.ts +10 -0
  30. package/dist/chempot-diagram/color.js +32 -0
  31. package/dist/chempot-diagram/compute.d.ts +48 -0
  32. package/dist/chempot-diagram/compute.js +812 -0
  33. package/dist/chempot-diagram/index.d.ts +6 -0
  34. package/dist/chempot-diagram/index.js +6 -0
  35. package/dist/chempot-diagram/pointer.d.ts +16 -0
  36. package/dist/chempot-diagram/pointer.js +40 -0
  37. package/dist/chempot-diagram/temperature.d.ts +15 -0
  38. package/dist/chempot-diagram/temperature.js +36 -0
  39. package/dist/chempot-diagram/types.d.ts +86 -0
  40. package/dist/chempot-diagram/types.js +28 -0
  41. package/dist/colors/index.d.ts +3 -1
  42. package/dist/colors/index.js +9 -3
  43. package/dist/composition/BarChart.svelte +141 -77
  44. package/dist/composition/BubbleChart.svelte +107 -52
  45. package/dist/composition/Composition.svelte +100 -79
  46. package/dist/composition/Formula.svelte +108 -62
  47. package/dist/composition/FormulaFilter.svelte +973 -353
  48. package/dist/composition/FormulaFilter.svelte.d.ts +35 -1
  49. package/dist/composition/PieChart.svelte +199 -99
  50. package/dist/composition/PieChart.svelte.d.ts +1 -1
  51. package/dist/composition/format.d.ts +5 -0
  52. package/dist/composition/format.js +20 -3
  53. package/dist/composition/parse.js +14 -9
  54. package/dist/convex-hull/ConvexHull.svelte +93 -38
  55. package/dist/convex-hull/ConvexHull2D.svelte +551 -393
  56. package/dist/convex-hull/ConvexHull3D.svelte +1303 -825
  57. package/dist/convex-hull/ConvexHull4D.svelte +1012 -686
  58. package/dist/convex-hull/ConvexHullControls.svelte +115 -28
  59. package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
  60. package/dist/convex-hull/ConvexHullStats.svelte +821 -249
  61. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
  62. package/dist/convex-hull/ConvexHullTooltip.svelte +41 -16
  63. package/dist/convex-hull/GasPressureControls.svelte +104 -61
  64. package/dist/convex-hull/StructurePopup.svelte +25 -4
  65. package/dist/convex-hull/TemperatureSlider.svelte +45 -25
  66. package/dist/convex-hull/barycentric-coords.js +13 -7
  67. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  68. package/dist/convex-hull/demo-temperature.js +40 -0
  69. package/dist/convex-hull/gas-thermodynamics.js +17 -12
  70. package/dist/convex-hull/helpers.d.ts +10 -1
  71. package/dist/convex-hull/helpers.js +79 -38
  72. package/dist/convex-hull/index.d.ts +1 -0
  73. package/dist/convex-hull/index.js +1 -0
  74. package/dist/convex-hull/thermodynamics.d.ts +8 -21
  75. package/dist/convex-hull/thermodynamics.js +163 -69
  76. package/dist/convex-hull/types.d.ts +12 -12
  77. package/dist/convex-hull/types.js +0 -12
  78. package/dist/coordination/CoordinationBarPlot.svelte +232 -176
  79. package/dist/element/BohrAtom.svelte +56 -13
  80. package/dist/element/ElementHeading.svelte +7 -2
  81. package/dist/element/ElementPhoto.svelte +15 -9
  82. package/dist/element/ElementStats.svelte +10 -4
  83. package/dist/element/ElementTile.svelte +137 -73
  84. package/dist/element/Nucleus.svelte +39 -11
  85. package/dist/element/data.js +2 -14
  86. package/dist/element/data.json.gz +0 -0
  87. package/dist/element/types.d.ts +1 -0
  88. package/dist/feedback/ClickFeedback.svelte +16 -5
  89. package/dist/feedback/DragOverlay.svelte +10 -2
  90. package/dist/feedback/Spinner.svelte +4 -2
  91. package/dist/feedback/StatusMessage.svelte +8 -2
  92. package/dist/fermi-surface/FermiSlice.svelte +118 -88
  93. package/dist/fermi-surface/FermiSurface.svelte +336 -239
  94. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  95. package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
  96. package/dist/fermi-surface/FermiSurfaceScene.svelte +536 -343
  97. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  98. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
  99. package/dist/fermi-surface/compute.js +16 -20
  100. package/dist/fermi-surface/parse.js +37 -33
  101. package/dist/fermi-surface/symmetry.js +2 -7
  102. package/dist/fermi-surface/types.d.ts +3 -5
  103. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1527 -0
  104. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  105. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  106. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  107. package/dist/heatmap-matrix/index.d.ts +53 -0
  108. package/dist/heatmap-matrix/index.js +100 -0
  109. package/dist/heatmap-matrix/shared.d.ts +2 -0
  110. package/dist/heatmap-matrix/shared.js +4 -0
  111. package/dist/icons.d.ts +111 -0
  112. package/dist/icons.js +158 -0
  113. package/dist/index.d.ts +5 -2
  114. package/dist/index.js +5 -2
  115. package/dist/io/decompress.js +1 -1
  116. package/dist/io/export.d.ts +3 -0
  117. package/dist/io/export.js +138 -140
  118. package/dist/io/file-drop.d.ts +7 -0
  119. package/dist/io/file-drop.js +43 -0
  120. package/dist/io/index.d.ts +2 -2
  121. package/dist/io/index.js +2 -112
  122. package/dist/io/is-binary.js +2 -3
  123. package/dist/io/types.d.ts +1 -0
  124. package/dist/io/url-drop.d.ts +2 -0
  125. package/dist/io/url-drop.js +117 -0
  126. package/dist/isosurface/Isosurface.svelte +220 -110
  127. package/dist/isosurface/IsosurfaceControls.svelte +65 -28
  128. package/dist/isosurface/parse.js +104 -56
  129. package/dist/isosurface/slice.d.ts +2 -1
  130. package/dist/isosurface/slice.js +8 -13
  131. package/dist/isosurface/types.d.ts +14 -1
  132. package/dist/isosurface/types.js +152 -5
  133. package/dist/labels.d.ts +2 -1
  134. package/dist/labels.js +12 -8
  135. package/dist/layout/FullscreenToggle.svelte +11 -2
  136. package/dist/layout/InfoCard.svelte +38 -6
  137. package/dist/layout/InfoTag.svelte +125 -94
  138. package/dist/layout/PropertyFilter.svelte +82 -37
  139. package/dist/layout/SettingsSection.svelte +85 -55
  140. package/dist/layout/SubpageGrid.svelte +82 -0
  141. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  142. package/dist/layout/index.d.ts +1 -0
  143. package/dist/layout/index.js +1 -0
  144. package/dist/layout/json-tree/JsonNode.svelte +266 -223
  145. package/dist/layout/json-tree/JsonTree.svelte +516 -429
  146. package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
  147. package/dist/layout/json-tree/JsonValue.svelte +281 -173
  148. package/dist/layout/json-tree/types.d.ts +10 -2
  149. package/dist/layout/json-tree/utils.d.ts +2 -0
  150. package/dist/layout/json-tree/utils.js +37 -2
  151. package/dist/marching-cubes.js +25 -2
  152. package/dist/math.d.ts +20 -17
  153. package/dist/math.js +474 -57
  154. package/dist/overlays/ContextMenu.svelte +66 -40
  155. package/dist/overlays/DraggablePane.svelte +331 -154
  156. package/dist/overlays/DraggablePane.svelte.d.ts +2 -0
  157. package/dist/periodic-table/PeriodicTable.svelte +278 -145
  158. package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
  159. package/dist/periodic-table/PropertySelect.svelte +25 -7
  160. package/dist/periodic-table/TableInset.svelte +8 -3
  161. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +559 -267
  162. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -2
  163. package/dist/phase-diagram/PhaseDiagramControls.svelte +131 -51
  164. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +3 -2
  165. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  166. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  167. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +160 -110
  168. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +8 -1
  169. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +217 -86
  170. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +6 -3
  171. package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
  172. package/dist/phase-diagram/build-diagram.js +9 -9
  173. package/dist/phase-diagram/colors.js +1 -3
  174. package/dist/phase-diagram/index.d.ts +2 -0
  175. package/dist/phase-diagram/index.js +2 -0
  176. package/dist/phase-diagram/parse.js +10 -9
  177. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  178. package/dist/phase-diagram/svg-to-diagram.js +869 -0
  179. package/dist/phase-diagram/types.d.ts +10 -0
  180. package/dist/phase-diagram/utils.d.ts +8 -4
  181. package/dist/phase-diagram/utils.js +219 -74
  182. package/dist/plot/AxisLabel.svelte +51 -0
  183. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  184. package/dist/plot/BarPlot.svelte +1461 -768
  185. package/dist/plot/BarPlot.svelte.d.ts +3 -3
  186. package/dist/plot/BarPlotControls.svelte +33 -6
  187. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  188. package/dist/plot/ColorBar.svelte +533 -383
  189. package/dist/plot/ColorBar.svelte.d.ts +1 -1
  190. package/dist/plot/ColorScaleSelect.svelte +28 -7
  191. package/dist/plot/ElementScatter.svelte +38 -16
  192. package/dist/plot/FillArea.svelte +152 -92
  193. package/dist/plot/Histogram.svelte +1162 -709
  194. package/dist/plot/Histogram.svelte.d.ts +1 -1
  195. package/dist/plot/HistogramControls.svelte +81 -18
  196. package/dist/plot/HistogramControls.svelte.d.ts +6 -2
  197. package/dist/plot/InteractiveAxisLabel.svelte +34 -11
  198. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  199. package/dist/plot/Line.svelte +63 -28
  200. package/dist/plot/PlotControls.svelte +221 -96
  201. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  202. package/dist/plot/PlotLegend.svelte +174 -91
  203. package/dist/plot/PlotTooltip.svelte +45 -6
  204. package/dist/plot/PortalSelect.svelte +175 -146
  205. package/dist/plot/ReferenceLine.svelte +77 -22
  206. package/dist/plot/ReferenceLine.svelte.d.ts +1 -0
  207. package/dist/plot/ReferenceLine3D.svelte +132 -107
  208. package/dist/plot/ReferencePlane.svelte +146 -123
  209. package/dist/plot/ScatterPlot.svelte +1880 -1156
  210. package/dist/plot/ScatterPlot.svelte.d.ts +3 -3
  211. package/dist/plot/ScatterPlot3D.svelte +256 -131
  212. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  213. package/dist/plot/ScatterPlot3DControls.svelte +300 -297
  214. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
  215. package/dist/plot/ScatterPlot3DScene.svelte +608 -406
  216. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  217. package/dist/plot/ScatterPlotControls.svelte +150 -70
  218. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  219. package/dist/plot/ScatterPoint.svelte +98 -26
  220. package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
  221. package/dist/plot/SpacegroupBarPlot.svelte +142 -85
  222. package/dist/plot/Surface3D.svelte +159 -108
  223. package/dist/plot/ZeroLines.svelte +96 -0
  224. package/dist/plot/ZeroLines.svelte.d.ts +32 -0
  225. package/dist/plot/ZoomRect.svelte +23 -0
  226. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  227. package/dist/plot/axis-utils.d.ts +1 -1
  228. package/dist/plot/axis-utils.js +1 -3
  229. package/dist/plot/data-cleaning.js +12 -28
  230. package/dist/plot/data-transform.js +2 -1
  231. package/dist/plot/fill-utils.js +2 -0
  232. package/dist/plot/index.d.ts +6 -2
  233. package/dist/plot/index.js +6 -2
  234. package/dist/plot/interactions.d.ts +8 -10
  235. package/dist/plot/interactions.js +2 -3
  236. package/dist/plot/layout.d.ts +11 -2
  237. package/dist/plot/layout.js +44 -17
  238. package/dist/plot/reference-line.d.ts +5 -22
  239. package/dist/plot/reference-line.js +12 -84
  240. package/dist/plot/scales.js +24 -36
  241. package/dist/plot/types.d.ts +53 -40
  242. package/dist/plot/types.js +12 -7
  243. package/dist/plot/utils/label-placement.d.ts +32 -15
  244. package/dist/plot/utils/label-placement.js +227 -63
  245. package/dist/plot/utils/series-visibility.js +2 -3
  246. package/dist/plot/utils.d.ts +1 -0
  247. package/dist/plot/utils.js +14 -0
  248. package/dist/rdf/RdfPlot.svelte +173 -132
  249. package/dist/rdf/calc-rdf.js +4 -5
  250. package/dist/sanitize.d.ts +4 -0
  251. package/dist/sanitize.js +107 -0
  252. package/dist/settings.d.ts +21 -6
  253. package/dist/settings.js +63 -19
  254. package/dist/spectral/Bands.svelte +963 -412
  255. package/dist/spectral/Bands.svelte.d.ts +22 -2
  256. package/dist/spectral/BandsAndDos.svelte +90 -49
  257. package/dist/spectral/BrillouinBandsDos.svelte +151 -93
  258. package/dist/spectral/Dos.svelte +389 -258
  259. package/dist/spectral/helpers.d.ts +23 -1
  260. package/dist/spectral/helpers.js +119 -51
  261. package/dist/spectral/types.d.ts +2 -0
  262. package/dist/state.svelte.d.ts +1 -1
  263. package/dist/state.svelte.js +3 -2
  264. package/dist/structure/Arrow.svelte +59 -20
  265. package/dist/structure/AtomLegend.svelte +231 -129
  266. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  267. package/dist/structure/Bond.svelte +73 -47
  268. package/dist/structure/CanvasTooltip.svelte +10 -2
  269. package/dist/structure/CellSelect.svelte +148 -51
  270. package/dist/structure/Cylinder.svelte +33 -17
  271. package/dist/structure/Lattice.svelte +88 -33
  272. package/dist/structure/Structure.svelte +1077 -821
  273. package/dist/structure/Structure.svelte.d.ts +1 -1
  274. package/dist/structure/StructureControls.svelte +373 -139
  275. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  276. package/dist/structure/StructureExportPane.svelte +124 -89
  277. package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
  278. package/dist/structure/StructureInfoPane.svelte +304 -231
  279. package/dist/structure/StructureScene.svelte +919 -445
  280. package/dist/structure/StructureScene.svelte.d.ts +16 -7
  281. package/dist/structure/atom-properties.d.ts +6 -2
  282. package/dist/structure/atom-properties.js +42 -29
  283. package/dist/structure/bonding.js +6 -7
  284. package/dist/structure/export.js +22 -34
  285. package/dist/structure/ferrox-wasm-types.d.ts +3 -2
  286. package/dist/structure/ferrox-wasm-types.js +0 -3
  287. package/dist/structure/ferrox-wasm.d.ts +3 -2
  288. package/dist/structure/ferrox-wasm.js +2 -3
  289. package/dist/structure/index.d.ts +16 -0
  290. package/dist/structure/index.js +88 -6
  291. package/dist/structure/measure.d.ts +2 -2
  292. package/dist/structure/measure.js +4 -44
  293. package/dist/structure/parse.js +130 -155
  294. package/dist/structure/partial-occupancy.d.ts +25 -0
  295. package/dist/structure/partial-occupancy.js +99 -0
  296. package/dist/structure/pbc.d.ts +1 -0
  297. package/dist/structure/pbc.js +16 -6
  298. package/dist/structure/supercell.d.ts +2 -2
  299. package/dist/structure/supercell.js +12 -22
  300. package/dist/structure/validation.js +5 -3
  301. package/dist/symmetry/SymmetryStats.svelte +94 -37
  302. package/dist/symmetry/WyckoffTable.svelte +42 -14
  303. package/dist/symmetry/cell-transform.js +5 -3
  304. package/dist/symmetry/index.d.ts +7 -4
  305. package/dist/symmetry/index.js +87 -21
  306. package/dist/symmetry/spacegroups.js +148 -148
  307. package/dist/table/HeatmapTable.svelte +1112 -516
  308. package/dist/table/HeatmapTable.svelte.d.ts +12 -1
  309. package/dist/table/ToggleMenu.svelte +125 -90
  310. package/dist/table/index.d.ts +2 -0
  311. package/dist/table/index.js +2 -4
  312. package/dist/theme/ThemeControl.svelte +21 -12
  313. package/dist/time.js +4 -1
  314. package/dist/tooltip/TooltipContent.svelte +33 -8
  315. package/dist/trajectory/Trajectory.svelte +889 -687
  316. package/dist/trajectory/TrajectoryError.svelte +14 -3
  317. package/dist/trajectory/TrajectoryExportPane.svelte +148 -90
  318. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +1 -1
  319. package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
  320. package/dist/trajectory/constants.d.ts +6 -0
  321. package/dist/trajectory/constants.js +7 -0
  322. package/dist/trajectory/extract.js +13 -31
  323. package/dist/trajectory/format-detect.d.ts +9 -0
  324. package/dist/trajectory/format-detect.js +76 -0
  325. package/dist/trajectory/frame-reader.d.ts +17 -0
  326. package/dist/trajectory/frame-reader.js +332 -0
  327. package/dist/trajectory/helpers.d.ts +14 -0
  328. package/dist/trajectory/helpers.js +172 -0
  329. package/dist/trajectory/index.d.ts +1 -0
  330. package/dist/trajectory/index.js +23 -14
  331. package/dist/trajectory/parse/ase.d.ts +2 -0
  332. package/dist/trajectory/parse/ase.js +77 -0
  333. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  334. package/dist/trajectory/parse/hdf5.js +129 -0
  335. package/dist/trajectory/parse/index.d.ts +12 -0
  336. package/dist/trajectory/parse/index.js +299 -0
  337. package/dist/trajectory/parse/lammps.d.ts +5 -0
  338. package/dist/trajectory/parse/lammps.js +179 -0
  339. package/dist/trajectory/parse/vasp.d.ts +2 -0
  340. package/dist/trajectory/parse/vasp.js +68 -0
  341. package/dist/trajectory/parse/xyz.d.ts +2 -0
  342. package/dist/trajectory/parse/xyz.js +110 -0
  343. package/dist/trajectory/plotting.js +13 -8
  344. package/dist/trajectory/types.d.ts +11 -0
  345. package/dist/trajectory/types.js +1 -0
  346. package/dist/utils.d.ts +3 -0
  347. package/dist/utils.js +17 -0
  348. package/dist/xrd/XrdPlot.svelte +337 -245
  349. package/dist/xrd/broadening.js +14 -9
  350. package/dist/xrd/calc-xrd.js +12 -19
  351. package/dist/xrd/parse.d.ts +1 -1
  352. package/dist/xrd/parse.js +17 -17
  353. package/package.json +103 -101
  354. package/readme.md +4 -4
  355. package/dist/trajectory/parse.d.ts +0 -42
  356. package/dist/trajectory/parse.js +0 -1267
  357. /package/dist/element/{data.json.d.ts → data.json.gz.d.ts} +0 -0
  358. /package/dist/theme/{themes.js → themes.mjs} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { count_atoms_in_composition, extract_formula_elements, sort_by_electronegativity, } from '../composition';
2
2
  import * as math from '../math';
3
3
  import { barycentric_to_ternary_xyz, barycentric_to_tetrahedral, composition_to_barycentric_3d, composition_to_barycentric_4d, composition_to_barycentric_nd, } from './barycentric-coords';
4
- import { is_unary_entry } from './types';
4
+ import { get_arity, HULL_STABILITY_TOL, is_on_hull, is_unary_entry } from './helpers';
5
5
  // Track warned keys to avoid log spam on large datasets with repeated invalid keys
6
6
  const warned_keys = new Set();
7
7
  // Normalize convex hull composition keys by stripping oxidation states (e.g. "V4+" -> "V")
@@ -41,7 +41,7 @@ export function process_hull_entries(entries) {
41
41
  for (const entry of normalized_entries) {
42
42
  const stable = typeof entry.is_stable === `boolean`
43
43
  ? entry.is_stable
44
- : (entry.e_above_hull ?? Infinity) <= 1e-6;
44
+ : (entry.e_above_hull ?? Infinity) <= HULL_STABILITY_TOL;
45
45
  (stable ? stable_entries : unstable_entries).push(entry);
46
46
  }
47
47
  // Extract unique element symbols from normalized compositions
@@ -120,9 +120,9 @@ export function calculate_e_above_hull(input, reference_entries) {
120
120
  }
121
121
  // 3. Compute formation energies
122
122
  const refs = find_lowest_energy_unary_refs(reference_entries);
123
- const compute_e_form = (e) => typeof e.e_form_per_atom === `number`
124
- ? e.e_form_per_atom
125
- : compute_e_form_per_atom(e, refs);
123
+ const compute_e_form = (entry) => typeof entry.e_form_per_atom === `number`
124
+ ? entry.e_form_per_atom
125
+ : compute_e_form_per_atom(entry, refs);
126
126
  const interest_data = entries_of_interest.map((entry) => ({
127
127
  entry,
128
128
  e_form: compute_e_form(entry),
@@ -192,8 +192,8 @@ export function calculate_e_above_hull(input, reference_entries) {
192
192
  continue;
193
193
  try {
194
194
  const bary = composition_to_barycentric_3d(ref.composition, elements);
195
- const p = barycentric_to_ternary_xyz(bary, e_form);
196
- ref_points.push(p);
195
+ const point = barycentric_to_ternary_xyz(bary, e_form);
196
+ ref_points.push(point);
197
197
  }
198
198
  catch {
199
199
  // Ignore invalid compositions
@@ -202,7 +202,7 @@ export function calculate_e_above_hull(input, reference_entries) {
202
202
  // Ensure corner points (pure elements default to e_form = 0)
203
203
  for (const el of elements) {
204
204
  const corner = barycentric_to_ternary_xyz(composition_to_barycentric_3d({ [el]: 1 }, elements), 0);
205
- if (!ref_points.some((p) => Math.hypot(p.x - corner.x, p.y - corner.y, p.z - corner.z) < 1e-9)) {
205
+ if (!ref_points.some((point) => Math.hypot(point.x - corner.x, point.y - corner.y, point.z - corner.z) < 1e-9)) {
206
206
  ref_points.push(corner);
207
207
  }
208
208
  }
@@ -216,9 +216,9 @@ export function calculate_e_above_hull(input, reference_entries) {
216
216
  }
217
217
  try {
218
218
  const bary = composition_to_barycentric_3d(entry.composition, elements);
219
- const p = barycentric_to_ternary_xyz(bary, e_form);
220
- const z_hull = e_hull_at_xy(hull_models, p.x, p.y);
221
- results[id] = z_hull === null ? NaN : Math.max(0, p.z - z_hull);
219
+ const point = barycentric_to_ternary_xyz(bary, e_form);
220
+ const z_hull = e_hull_at_xy(hull_models, point.x, point.y);
221
+ results[id] = z_hull === null ? NaN : Math.max(0, point.z - z_hull);
222
222
  }
223
223
  catch {
224
224
  results[id] = NaN;
@@ -245,8 +245,8 @@ export function calculate_e_above_hull(input, reference_entries) {
245
245
  for (const el of elements) {
246
246
  const tet = barycentric_to_tetrahedral(composition_to_barycentric_4d({ [el]: 1 }, elements));
247
247
  const corner = { ...tet, w: 0 };
248
- const dist = (p) => Math.hypot(p.x - corner.x, p.y - corner.y, p.z - corner.z, p.w);
249
- if (!ref_points.some((p) => dist(p) < 1e-9))
248
+ const dist = (point) => Math.hypot(point.x - corner.x, point.y - corner.y, point.z - corner.z, point.w);
249
+ if (!ref_points.some((point) => dist(point) < 1e-9))
250
250
  ref_points.push(corner);
251
251
  }
252
252
  const hull_tetrahedra = compute_lower_hull_4d(ref_points);
@@ -359,38 +359,62 @@ export function calculate_e_above_hull(input, reference_entries) {
359
359
  }
360
360
  }
361
361
  if (is_single) {
362
- const id = entries_of_interest[0].entry_id ??
363
- JSON.stringify(entries_of_interest[0].composition);
362
+ const id = entries_of_interest[0].entry_id ?? JSON.stringify(entries_of_interest[0].composition);
364
363
  return results[id];
365
364
  }
366
365
  return results;
367
366
  }
368
- export function get_convex_hull_stats(processed_entries, elements, max_arity) {
369
- if (!processed_entries || processed_entries.length === 0)
367
+ export function get_convex_hull_stats(processed_entries, elements, max_arity = 4) {
368
+ if (processed_entries.length === 0)
370
369
  return null;
371
- const composition_counts = (max_arity === 4 ? [1, 2, 3, 4] : [1, 2, 3]).map((target) => processed_entries.filter((entry) => Object.keys(entry.composition).filter((el) => (entry.composition[el] ?? 0) > 0).length === target).length);
372
- const [unary, binary, ternary, quaternaryMaybe] = composition_counts;
373
- const quaternary = max_arity === 4 ? (quaternaryMaybe ?? 0) : 0;
374
- const stable_count = processed_entries.filter((e) => e.is_stable === true ||
375
- (typeof e.e_above_hull === `number` && e.e_above_hull < 1e-6)).length;
370
+ max_arity = Math.max(1, max_arity);
371
+ let unary = 0;
372
+ let binary = 0;
373
+ let ternary = 0;
374
+ let quaternary = 0;
375
+ let quinary_plus = 0;
376
+ for (const entry of processed_entries) {
377
+ const arity = get_arity(entry);
378
+ if (arity === 1)
379
+ unary++;
380
+ else if (arity === 2)
381
+ binary++;
382
+ else if (arity === 3)
383
+ ternary++;
384
+ else if (arity === 4)
385
+ quaternary++;
386
+ else if (arity >= 5)
387
+ quinary_plus++;
388
+ }
389
+ // Zero out counts beyond system dimensionality for cleaner display
390
+ // quinary_plus is intentionally not zeroed — it's a catch-all bucket that
391
+ // is naturally 0 for systems with fewer than 5 elements
392
+ if (max_arity < 4)
393
+ quaternary = 0;
394
+ if (max_arity < 3)
395
+ ternary = 0;
396
+ if (max_arity < 2)
397
+ binary = 0;
398
+ const stable_count = processed_entries.filter((entry) => is_on_hull(entry)).length;
376
399
  const unstable_count = processed_entries.length - stable_count;
377
400
  const energies = processed_entries
378
- .map((e) => e.e_form_per_atom ?? e.energy_per_atom)
379
- .filter((v) => typeof v === `number` && Number.isFinite(v));
401
+ .map((entry) => entry.e_form_per_atom ?? entry.energy_per_atom ?? get_energy_per_atom(entry))
402
+ .filter(Number.isFinite);
403
+ // Use reduce instead of Math.min/max(...arr) to avoid stack overflow on large datasets
380
404
  const energy_range = energies.length > 0
381
405
  ? {
382
- min: Math.min(...energies),
383
- max: Math.max(...energies),
384
- avg: energies.reduce((a, b) => a + b, 0) / energies.length,
406
+ min: energies.reduce((min, val) => (val < min ? val : min), Infinity),
407
+ max: energies.reduce((max, val) => (val > max ? val : max), -Infinity),
408
+ avg: energies.reduce((sum, val) => sum + val, 0) / energies.length,
385
409
  }
386
410
  : { min: 0, max: 0, avg: 0 };
387
411
  const hull_distances = processed_entries
388
- .map((e) => e.e_above_hull)
389
- .filter((v) => typeof v === `number` && v >= 0);
412
+ .map((entry) => entry.e_above_hull)
413
+ .filter((val) => typeof val === `number` && val >= 0);
390
414
  const hull_distance = hull_distances.length > 0
391
415
  ? {
392
- max: Math.max(...hull_distances),
393
- avg: hull_distances.reduce((a, b) => a + b, 0) / hull_distances.length,
416
+ max: hull_distances.reduce((max, val) => (val > max ? val : max), -Infinity),
417
+ avg: hull_distances.reduce((sum, val) => sum + val, 0) / hull_distances.length,
394
418
  }
395
419
  : { max: 0, avg: 0 };
396
420
  return {
@@ -399,26 +423,90 @@ export function get_convex_hull_stats(processed_entries, elements, max_arity) {
399
423
  binary,
400
424
  ternary,
401
425
  quaternary,
426
+ quinary_plus,
402
427
  stable: stable_count,
403
428
  unstable: unstable_count,
404
429
  energy_range,
405
430
  hull_distance,
406
431
  elements: elements.length,
407
432
  chemical_system: sort_by_electronegativity([...elements]).join(`-`),
433
+ max_arity,
434
+ };
435
+ }
436
+ // Convert a PhaseData entry to a ConvexHullEntry with default visual fields.
437
+ // x/y/z default to 0 since high-dim systems aren't visually plotted.
438
+ function to_hull_entry(entry) {
439
+ return {
440
+ ...entry,
441
+ visible: true,
442
+ is_element: get_arity(entry) === 1,
443
+ x: 0,
444
+ y: 0,
445
+ z: 0,
446
+ };
447
+ }
448
+ // Process raw hull entries for high-dimensional systems (5+ elements) where the
449
+ // ConvexHull visual component can't render. Computes formation energies, hull distances,
450
+ // stable/unstable classification, and phase stats. Returns null on failure.
451
+ // Optionally accepts `elements` to scope the chemical system; if omitted, elements
452
+ // are derived from the entries' compositions.
453
+ export function process_hull_for_stats(entries, elements) {
454
+ if (!entries.length)
455
+ return null;
456
+ const processed = process_hull_entries(entries);
457
+ if (!processed.entries.length)
458
+ return null;
459
+ const hull_elements = elements ?? processed.elements;
460
+ // Compute formation energies
461
+ const el_refs = find_lowest_energy_unary_refs(processed.entries);
462
+ for (const entry of processed.entries) {
463
+ if (entry.e_form_per_atom === undefined) {
464
+ const e_form = compute_e_form_per_atom(entry, el_refs);
465
+ if (e_form !== null)
466
+ entry.e_form_per_atom = e_form;
467
+ }
468
+ }
469
+ // Compute hull distances. Note: entries without entry_id are keyed by
470
+ // JSON.stringify(composition), so polymorphs at the same composition
471
+ // collide — the last-processed entry's distance wins for all of them.
472
+ try {
473
+ const hull_distances = calculate_e_above_hull(processed.entries, processed.entries);
474
+ for (const entry of processed.entries) {
475
+ const dist = hull_distances[entry.entry_id ?? JSON.stringify(entry.composition)];
476
+ if (typeof dist === `number` && Number.isFinite(dist)) {
477
+ entry.e_above_hull = dist;
478
+ entry.is_stable = dist < HULL_STABILITY_TOL;
479
+ }
480
+ else {
481
+ // Clear stale hull metadata so previous values don't persist
482
+ entry.e_above_hull = undefined;
483
+ entry.is_stable = undefined;
484
+ }
485
+ }
486
+ }
487
+ catch (err) {
488
+ console.warn(`Failed to compute high-dim hull:`, err);
489
+ return null;
490
+ }
491
+ const hull_entries = processed.entries.map(to_hull_entry);
492
+ return {
493
+ stable_entries: hull_entries.filter((entry) => is_on_hull(entry)),
494
+ unstable_entries: hull_entries.filter((entry) => !is_on_hull(entry)),
495
+ phase_stats: get_convex_hull_stats(processed.entries, hull_elements, hull_elements.length),
408
496
  };
409
497
  }
410
498
  // --- 2D Convex Hull (Binary Phase Diagrams) ---
411
499
  export function compute_lower_hull_2d(points) {
412
500
  // Andrew's monotone chain for lower hull
413
501
  // Sort by x then y
414
- const sorted = [...points].sort((p1, p2) => (p1.x - p2.x) || (p1.y - p2.y));
502
+ const sorted = [...points].sort((p1, p2) => p1.x - p2.x || p1.y - p2.y);
415
503
  const lower = [];
416
504
  const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
417
- for (const p of sorted) {
505
+ for (const point of sorted) {
418
506
  while (lower.length >= 2 &&
419
- cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0)
507
+ cross(lower[lower.length - 2], lower[lower.length - 1], point) <= 0)
420
508
  lower.pop();
421
- lower.push(p);
509
+ lower.push(point);
422
510
  }
423
511
  return lower;
424
512
  }
@@ -466,8 +554,7 @@ function compute_plane(p1, p2, p3) {
466
554
  const offset = -(normal.x * p1.x + normal.y * p1.y + normal.z * p1.z);
467
555
  return { normal, offset };
468
556
  }
469
- const point_plane_signed_distance = (plane, point) => plane.normal.x * point.x + plane.normal.y * point.y + plane.normal.z * point.z +
470
- plane.offset;
557
+ const point_plane_signed_distance = (plane, point) => plane.normal.x * point.x + plane.normal.y * point.y + plane.normal.z * point.z + plane.offset;
471
558
  const compute_centroid = (p1, p2, p3) => ({
472
559
  x: (p1.x + p2.x + p3.x) / 3,
473
560
  y: (p1.y + p2.y + p3.y) / 3,
@@ -569,7 +656,11 @@ function build_horizon(faces, visible_face_indices) {
569
656
  for (const face_idx of visible_face_indices) {
570
657
  const face = faces[face_idx];
571
658
  const [a, b, c] = face.vertices;
572
- const edges = [[a, b], [b, c], [c, a]];
659
+ const edges = [
660
+ [a, b],
661
+ [b, c],
662
+ [c, a],
663
+ ];
573
664
  for (const [u, v] of edges) {
574
665
  const key = u < v ? `${u}|${v}` : `${v}|${u}`;
575
666
  if (!edge_count.has(key))
@@ -692,8 +783,7 @@ export const build_lower_hull_model = (faces) => faces.map((tri) => {
692
783
  return { a: 0, b: 0, c: (z1 + z2 + z3) / 3 };
693
784
  const a = (z1 * (y2 - y3) + z2 * (y3 - y1) + z3 * (y1 - y2)) / det;
694
785
  const b = (z1 * (x3 - x2) + z2 * (x1 - x3) + z3 * (x2 - x1)) / det;
695
- const c = (z1 * (x2 * y3 - x3 * y2) + z2 * (x3 * y1 - x1 * y3) + z3 * (x1 * y2 - x2 * y1)) /
696
- det;
786
+ const c = (z1 * (x2 * y3 - x3 * y2) + z2 * (x3 * y1 - x1 * y3) + z3 * (x1 * y2 - x2 * y1)) / det;
697
787
  return { a, b, c };
698
788
  })();
699
789
  const [min_x, _mx, max_x] = [p1.x, p2.x, p3.x].sort((a, b) => a - b);
@@ -731,22 +821,24 @@ function point_in_triangle_xy(model, x, y) {
731
821
  }
732
822
  export function e_hull_at_xy(models, x, y) {
733
823
  let z = null;
734
- for (const m of models) {
735
- if (x < m.min_x - 1e-9 || x > m.max_x + 1e-9 || y < m.min_y - 1e-9 || y > m.max_y + 1e-9)
824
+ for (const model of models) {
825
+ if (x < model.min_x - 1e-9 ||
826
+ x > model.max_x + 1e-9 ||
827
+ y < model.min_y - 1e-9 ||
828
+ y > model.max_y + 1e-9)
736
829
  continue;
737
- if (!point_in_triangle_xy(m, x, y))
830
+ if (!point_in_triangle_xy(model, x, y))
738
831
  continue;
739
- const z_face = m.a * x + m.b * y + m.c;
832
+ const z_face = model.a * x + model.b * y + model.c;
740
833
  z = z === null ? z_face : Math.min(z, z_face);
741
834
  }
742
835
  return z;
743
836
  }
744
- export const compute_e_above_hull_for_points = (points, models) => points.map((p) => {
745
- const z_hull = e_hull_at_xy(models, p.x, p.y);
837
+ export const compute_e_above_hull_for_points = (points, models) => points.map((point) => {
838
+ const z_hull = e_hull_at_xy(models, point.x, point.y);
746
839
  if (z_hull === null)
747
840
  return 0;
748
- const e_above_hull = p.z - z_hull;
749
- return e_above_hull > EPS ? e_above_hull : 0;
841
+ return point.z - z_hull;
750
842
  });
751
843
  const subtract_4d = (pt1, pt2) => ({
752
844
  x: pt1.x - pt2.x,
@@ -816,8 +908,7 @@ function compute_plane_4d(p1, p2, p3, p4) {
816
908
  const [x, y, z, w] = normal_components;
817
909
  const normal = normalize_4d({ x, y, z, w });
818
910
  // Guard against degenerate (nearly co-planar) points
819
- const normal_magnitude = Math.abs(normal.x) + Math.abs(normal.y) + Math.abs(normal.z) +
820
- Math.abs(normal.w);
911
+ const normal_magnitude = Math.abs(normal.x) + Math.abs(normal.y) + Math.abs(normal.z) + Math.abs(normal.w);
821
912
  if (normal_magnitude < EPS) {
822
913
  return { normal: { x: 0, y: 0, z: 0, w: 0 }, offset: 0 };
823
914
  }
@@ -900,8 +991,7 @@ function choose_initial_4_simplex(points) {
900
991
  continue;
901
992
  const pa = points[idx_a];
902
993
  const pb = points[idx_b];
903
- const dist_sq = (pa.x - pb.x) ** 2 + (pa.y - pb.y) ** 2 + (pa.z - pb.z) ** 2 +
904
- (pa.w - pb.w) ** 2;
994
+ const dist_sq = (pa.x - pb.x) ** 2 + (pa.y - pb.y) ** 2 + (pa.z - pb.z) ** 2 + (pa.w - pb.w) ** 2;
905
995
  if (dist_sq > max_dist_sq) {
906
996
  max_dist_sq = dist_sq;
907
997
  idx_far_a = idx_a;
@@ -944,7 +1034,9 @@ function choose_initial_4_simplex(points) {
944
1034
  let idx_far_hyperplane = -1;
945
1035
  let best_dist_hyperplane = -1;
946
1036
  for (let idx = 0; idx < points.length; idx++) {
947
- if (idx === idx_far_a || idx === idx_far_b || idx === idx_far_line ||
1037
+ if (idx === idx_far_a ||
1038
+ idx === idx_far_b ||
1039
+ idx === idx_far_line ||
948
1040
  idx === idx_far_plane)
949
1041
  continue;
950
1042
  const dist = Math.abs(point_plane_signed_distance_4d(plane0, points[idx]));
@@ -1007,7 +1099,12 @@ function build_horizon_4d(faces, visible_face_indices) {
1007
1099
  const face = faces[face_idx];
1008
1100
  const [a, b, c, d] = face.vertices;
1009
1101
  // Each tetrahedron face has 4 triangular ridges
1010
- const ridges = [[a, b, c], [a, b, d], [a, c, d], [b, c, d]];
1102
+ const ridges = [
1103
+ [a, b, c],
1104
+ [a, b, d],
1105
+ [a, c, d],
1106
+ [b, c, d],
1107
+ ];
1011
1108
  for (const ridge of ridges) {
1012
1109
  const sorted = ridge.slice().sort((x, y) => x - y);
1013
1110
  const key = sorted.join(`|`);
@@ -1163,8 +1260,8 @@ function point_in_tetrahedron_3d(p0, p1, p2, p3, point) {
1163
1260
  }
1164
1261
  // Check if inside: all barycentric coords must be >= 0 and sum to 1
1165
1262
  const eps_bary = -1e-9;
1166
- const inside = bary.every((l) => l >= eps_bary) &&
1167
- Math.abs(bary.reduce((s, l) => s + l, 0) - 1) < 1e-6;
1263
+ const inside = bary.every((coord) => coord >= eps_bary) &&
1264
+ Math.abs(bary.reduce((sum, coord) => sum + coord, 0) - 1) < 1e-6;
1168
1265
  return { inside, bary };
1169
1266
  }
1170
1267
  const build_tetrahedron_models = (hull_tetrahedra) => hull_tetrahedra.map((tet) => {
@@ -1197,17 +1294,19 @@ export const compute_e_above_hull_4d = (points, hull_tetrahedra) => {
1197
1294
  let hull_w = null;
1198
1295
  for (const model of models) {
1199
1296
  // Fast bounding box prefilter
1200
- if (x < model.min_x - EPS || x > model.max_x + EPS ||
1201
- y < model.min_y - EPS || y > model.max_y + EPS ||
1202
- z < model.min_z - EPS || z > model.max_z + EPS)
1297
+ if (x < model.min_x - EPS ||
1298
+ x > model.max_x + EPS ||
1299
+ y < model.min_y - EPS ||
1300
+ y > model.max_y + EPS ||
1301
+ z < model.min_z - EPS ||
1302
+ z > model.max_z + EPS)
1203
1303
  continue;
1204
1304
  // Check if point's (x,y,z) is inside the 3D projection of the tetrahedron
1205
1305
  const { inside, bary } = point_in_tetrahedron_3d(model.vertices_3d[0], model.vertices_3d[1], model.vertices_3d[2], model.vertices_3d[3], { x, y, z });
1206
1306
  if (inside) {
1207
1307
  // Compute w on the hull at this (x,y,z) using barycentric interpolation
1208
1308
  const [p0, p1, p2, p3] = model.vertices;
1209
- const w_on_hull = bary[0] * p0.w + bary[1] * p1.w + bary[2] * p2.w +
1210
- bary[3] * p3.w;
1309
+ const w_on_hull = bary[0] * p0.w + bary[1] * p1.w + bary[2] * p2.w + bary[3] * p3.w;
1211
1310
  hull_w = hull_w === null ? w_on_hull : Math.min(hull_w, w_on_hull);
1212
1311
  }
1213
1312
  }
@@ -1215,8 +1314,7 @@ export const compute_e_above_hull_4d = (points, hull_tetrahedra) => {
1215
1314
  // composition domain. Return NaN to indicate invalid input.
1216
1315
  if (hull_w === null)
1217
1316
  return NaN;
1218
- const distance = w - hull_w;
1219
- return distance > EPS ? distance : 0;
1317
+ return w - hull_w;
1220
1318
  });
1221
1319
  };
1222
1320
  // --- N-Dimensional Convex Hull (for 5+ element systems) ---
@@ -1254,10 +1352,7 @@ function compute_hyperplane_nd(points) {
1254
1352
  const normal_components = [];
1255
1353
  for (let col = 0; col < dim; col++) {
1256
1354
  // Build (N-1)×(N-1) submatrix by removing column col
1257
- const submatrix = edges.map((row) => [
1258
- ...row.slice(0, col),
1259
- ...row.slice(col + 1),
1260
- ]);
1355
+ const submatrix = edges.map((row) => [...row.slice(0, col), ...row.slice(col + 1)]);
1261
1356
  const sign = col % 2 === 0 ? 1 : -1;
1262
1357
  normal_components.push(sign * math.det_nxn(submatrix));
1263
1358
  }
@@ -1652,7 +1747,6 @@ export function compute_e_above_hull_nd(query_points, hull_facets, all_points) {
1652
1747
  // would falsely imply the point is stable/on-hull).
1653
1748
  if (hull_energy === null)
1654
1749
  return NaN;
1655
- const distance = energy - hull_energy;
1656
- return distance > EPS ? distance : 0;
1750
+ return energy - hull_energy;
1657
1751
  });
1658
1752
  }
@@ -3,12 +3,14 @@ import type { ShowControlsProp } from '../controls';
3
3
  import type { ElementSymbol } from '../element';
4
4
  import type { Vec3 } from '../math';
5
5
  import type { Sides } from '../plot';
6
+ import type { Rect } from '../plot/layout';
6
7
  export interface PhaseData {
7
8
  composition: CompositionType;
8
9
  energy: number;
9
10
  entry_id?: string;
10
11
  e_above_hull?: number;
11
12
  is_stable?: boolean;
13
+ exclude_from_hull?: boolean;
12
14
  energy_per_atom?: number;
13
15
  e_form_per_atom?: number;
14
16
  reduced_formula?: string;
@@ -38,7 +40,8 @@ export interface Point2D {
38
40
  export interface Point3D extends Point2D {
39
41
  z: number;
40
42
  }
41
- export type MarkerSymbol = `circle` | `star` | `triangle` | `cross` | `diamond` | `square` | `wye`;
43
+ export type MarkerSymbol = // Marker symbol types for convex hull entries
44
+ `circle` | `star` | `triangle` | `cross` | `diamond` | `square` | `wye`;
42
45
  export type HullFaceColorMode = `uniform` | `formation_energy` | `dominant_element` | `facet_index`;
43
46
  export declare const HULL_FACE_COLOR_MODES: readonly HullFaceColorMode[];
44
47
  export interface ConvexHullEntry extends PhaseData, Point3D {
@@ -93,6 +96,11 @@ export interface ConvexHullTriangle {
93
96
  normal: Point3D;
94
97
  centroid: Point3D;
95
98
  }
99
+ export interface LabelPlacement {
100
+ x: number;
101
+ y: number;
102
+ rect: Rect;
103
+ }
96
104
  export interface HoverData3D<T = ConvexHullEntry> {
97
105
  entry: T;
98
106
  position: {
@@ -106,6 +114,7 @@ export interface PhaseStats {
106
114
  binary: number;
107
115
  ternary: number;
108
116
  quaternary: number;
117
+ quinary_plus: number;
109
118
  stable: number;
110
119
  unstable: number;
111
120
  energy_range: {
@@ -119,18 +128,9 @@ export interface PhaseStats {
119
128
  };
120
129
  elements: number;
121
130
  chemical_system: string;
131
+ max_arity: number;
122
132
  }
123
- export declare const get_arity: (entry: PhaseData) => number;
124
- export declare const is_unary_entry: (entry: PhaseData) => boolean;
125
- export declare const is_binary_entry: (entry: PhaseData) => boolean;
126
- export declare const is_ternary_entry: (entry: PhaseData) => boolean;
127
- export declare const is_quaternary_entry: (entry: PhaseData) => boolean;
128
- export declare const is_quinary_entry: (entry: PhaseData) => boolean;
129
- export declare const is_senary_entry: (entry: PhaseData) => boolean;
130
- export declare const is_septenary_entry: (entry: PhaseData) => boolean;
131
- export declare const is_octonary_entry: (entry: PhaseData) => boolean;
132
- export declare const is_nonary_entry: (entry: PhaseData) => boolean;
133
- export declare const is_denary_entry: (entry: PhaseData) => boolean;
133
+ export type PhaseArityField = Extract<keyof PhaseStats, `unary` | `binary` | `ternary` | `quaternary` | `quinary_plus`>;
134
134
  export interface HighlightStyle {
135
135
  effect?: `pulse` | `glow` | `size` | `color` | `both`;
136
136
  color?: string;
@@ -4,18 +4,6 @@ export const HULL_FACE_COLOR_MODES = [
4
4
  `dominant_element`,
5
5
  `facet_index`,
6
6
  ];
7
- // Arity helpers (inlined from former arity.ts)
8
- export const get_arity = (entry) => Object.values(entry.composition).filter((count) => count > 0).length;
9
- export const is_unary_entry = (entry) => get_arity(entry) === 1;
10
- export const is_binary_entry = (entry) => get_arity(entry) === 2;
11
- export const is_ternary_entry = (entry) => get_arity(entry) === 3;
12
- export const is_quaternary_entry = (entry) => get_arity(entry) === 4;
13
- export const is_quinary_entry = (entry) => get_arity(entry) === 5;
14
- export const is_senary_entry = (entry) => get_arity(entry) === 6;
15
- export const is_septenary_entry = (entry) => get_arity(entry) === 7;
16
- export const is_octonary_entry = (entry) => get_arity(entry) === 8;
17
- export const is_nonary_entry = (entry) => get_arity(entry) === 9;
18
- export const is_denary_entry = (entry) => get_arity(entry) === 10;
19
7
  // --- Gas Phase Thermodynamics ---
20
8
  // Default temperature (Kelvin) for gas corrections when no temperature is specified
21
9
  export const DEFAULT_GAS_TEMP = 300;