matterviz 0.3.6 → 0.4.0

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 (926) hide show
  1. package/dist/EmptyState.svelte.d.ts +9 -0
  2. package/dist/FilePicker.svelte +360 -0
  3. package/dist/FilePicker.svelte.d.ts +17 -0
  4. package/dist/Icon.svelte +44 -0
  5. package/dist/Icon.svelte.d.ts +13 -0
  6. package/dist/MillerIndexInput.svelte +66 -0
  7. package/dist/MillerIndexInput.svelte.d.ts +7 -0
  8. package/dist/api/mp.d.ts +6 -0
  9. package/dist/api/mp.js +22 -0
  10. package/dist/api/optimade.d.ts +45 -0
  11. package/dist/api/optimade.js +141 -0
  12. package/dist/app.css +244 -0
  13. package/dist/brillouin/BrillouinZone.svelte +554 -0
  14. package/dist/brillouin/BrillouinZone.svelte.d.ts +84 -0
  15. package/dist/brillouin/BrillouinZoneControls.svelte +144 -0
  16. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +17 -0
  17. package/dist/brillouin/BrillouinZoneExportPane.svelte +146 -0
  18. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
  19. package/dist/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  20. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
  21. package/dist/brillouin/BrillouinZoneScene.svelte +522 -0
  22. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +49 -0
  23. package/dist/brillouin/BrillouinZoneTooltip.svelte +83 -0
  24. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +8 -0
  25. package/dist/brillouin/compute.d.ts +17 -0
  26. package/dist/brillouin/compute.js +422 -0
  27. package/dist/brillouin/index.d.ts +8 -0
  28. package/dist/brillouin/index.js +7 -0
  29. package/dist/brillouin/types.d.ts +43 -0
  30. package/dist/brillouin/types.js +1 -0
  31. package/dist/chempot-diagram/ChemPotDiagram.svelte +328 -0
  32. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  33. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +843 -0
  34. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  35. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3191 -0
  36. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  37. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  38. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  39. package/dist/chempot-diagram/async-compute.svelte.js +80 -0
  40. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  41. package/dist/chempot-diagram/chempot-worker.js +12 -0
  42. package/dist/chempot-diagram/color.d.ts +10 -0
  43. package/dist/chempot-diagram/color.js +32 -0
  44. package/dist/chempot-diagram/compute.d.ts +48 -0
  45. package/dist/chempot-diagram/compute.js +804 -0
  46. package/dist/chempot-diagram/index.d.ts +6 -0
  47. package/dist/chempot-diagram/index.js +6 -0
  48. package/dist/chempot-diagram/pointer.d.ts +16 -0
  49. package/dist/chempot-diagram/pointer.js +40 -0
  50. package/dist/chempot-diagram/temperature.d.ts +15 -0
  51. package/dist/chempot-diagram/temperature.js +34 -0
  52. package/dist/chempot-diagram/types.d.ts +81 -0
  53. package/dist/chempot-diagram/types.js +28 -0
  54. package/dist/colors/index.d.ts +47 -0
  55. package/dist/colors/index.js +204 -0
  56. package/dist/composition/BarChart.svelte +297 -0
  57. package/dist/composition/BarChart.svelte.d.ts +39 -0
  58. package/dist/composition/BubbleChart.svelte +218 -0
  59. package/dist/composition/BubbleChart.svelte.d.ts +28 -0
  60. package/dist/composition/Composition.svelte +165 -0
  61. package/dist/composition/Composition.svelte.d.ts +15 -0
  62. package/dist/composition/Formula.svelte +268 -0
  63. package/dist/composition/Formula.svelte.d.ts +19 -0
  64. package/dist/composition/FormulaFilter.svelte +1263 -0
  65. package/dist/composition/FormulaFilter.svelte.d.ts +51 -0
  66. package/dist/composition/PieChart.svelte +324 -0
  67. package/dist/composition/PieChart.svelte.d.ts +37 -0
  68. package/dist/composition/chem-sys.d.ts +8 -0
  69. package/dist/composition/chem-sys.js +85 -0
  70. package/dist/composition/format.d.ts +15 -0
  71. package/dist/composition/format.js +111 -0
  72. package/dist/composition/index.d.ts +21 -0
  73. package/dist/composition/index.js +15 -0
  74. package/dist/composition/parse.d.ts +56 -0
  75. package/dist/composition/parse.js +486 -0
  76. package/dist/constants.d.ts +29 -0
  77. package/dist/constants.js +99 -0
  78. package/dist/controls.d.ts +14 -0
  79. package/dist/controls.js +30 -0
  80. package/dist/convex-hull/ConvexHull.svelte +157 -0
  81. package/dist/convex-hull/ConvexHull.svelte.d.ts +13 -0
  82. package/dist/convex-hull/ConvexHull2D.svelte +827 -0
  83. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +11 -0
  84. package/dist/convex-hull/ConvexHull3D.svelte +1801 -0
  85. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +8 -0
  86. package/dist/convex-hull/ConvexHull4D.svelte +1394 -0
  87. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +8 -0
  88. package/dist/convex-hull/ConvexHullControls.svelte +535 -0
  89. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +48 -0
  90. package/dist/convex-hull/ConvexHullInfoPane.svelte +125 -0
  91. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +20 -0
  92. package/dist/convex-hull/ConvexHullStats.svelte +929 -0
  93. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +17 -0
  94. package/dist/convex-hull/ConvexHullTooltip.svelte +131 -0
  95. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +33 -0
  96. package/dist/convex-hull/GasPressureControls.svelte +247 -0
  97. package/dist/convex-hull/GasPressureControls.svelte.d.ts +11 -0
  98. package/dist/convex-hull/StructurePopup.svelte +151 -0
  99. package/dist/convex-hull/StructurePopup.svelte.d.ts +18 -0
  100. package/dist/convex-hull/TemperatureSlider.svelte +140 -0
  101. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +8 -0
  102. package/dist/convex-hull/barycentric-coords.d.ts +18 -0
  103. package/dist/convex-hull/barycentric-coords.js +182 -0
  104. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  105. package/dist/convex-hull/demo-temperature.js +38 -0
  106. package/dist/convex-hull/gas-thermodynamics.d.ts +16 -0
  107. package/dist/convex-hull/gas-thermodynamics.js +306 -0
  108. package/dist/convex-hull/helpers.d.ts +117 -0
  109. package/dist/convex-hull/helpers.js +718 -0
  110. package/dist/convex-hull/index.d.ts +119 -0
  111. package/dist/convex-hull/index.js +58 -0
  112. package/dist/convex-hull/thermodynamics.d.ts +67 -0
  113. package/dist/convex-hull/thermodynamics.js +1757 -0
  114. package/dist/convex-hull/types.d.ts +162 -0
  115. package/dist/convex-hull/types.js +36 -0
  116. package/dist/coordination/CoordinationBarPlot.svelte +311 -0
  117. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +30 -0
  118. package/dist/coordination/calc-coordination.d.ts +15 -0
  119. package/dist/coordination/calc-coordination.js +63 -0
  120. package/dist/coordination/index.d.ts +8 -0
  121. package/dist/coordination/index.js +7 -0
  122. package/dist/effects.svelte.d.ts +12 -0
  123. package/dist/effects.svelte.js +37 -0
  124. package/dist/element/BohrAtom.svelte.d.ts +20 -0
  125. package/dist/element/ElementHeading.svelte +26 -0
  126. package/dist/element/ElementHeading.svelte.d.ts +8 -0
  127. package/dist/element/ElementPhoto.svelte +57 -0
  128. package/dist/element/ElementPhoto.svelte.d.ts +9 -0
  129. package/dist/element/ElementStats.svelte +80 -0
  130. package/dist/element/ElementStats.svelte.d.ts +8 -0
  131. package/dist/element/ElementTile.svelte +484 -0
  132. package/dist/element/ElementTile.svelte.d.ts +29 -0
  133. package/dist/element/Nucleus.svelte.d.ts +17 -0
  134. package/dist/element/data.d.ts +2 -0
  135. package/dist/element/data.js +2 -0
  136. package/dist/element/index.d.ts +8 -0
  137. package/dist/element/index.js +7 -0
  138. package/dist/element/types.d.ts +57 -0
  139. package/dist/element/types.js +1 -0
  140. package/dist/feedback/ClickFeedback.svelte +58 -0
  141. package/dist/feedback/ClickFeedback.svelte.d.ts +12 -0
  142. package/dist/feedback/DragOverlay.svelte +42 -0
  143. package/dist/feedback/DragOverlay.svelte.d.ts +7 -0
  144. package/dist/feedback/Spinner.svelte.d.ts +7 -0
  145. package/dist/feedback/StatusMessage.svelte.d.ts +9 -0
  146. package/dist/feedback/index.d.ts +4 -0
  147. package/dist/feedback/index.js +4 -0
  148. package/dist/fermi-surface/FermiSlice.svelte +197 -0
  149. package/dist/fermi-surface/FermiSlice.svelte.d.ts +24 -0
  150. package/dist/fermi-surface/FermiSurface.svelte +606 -0
  151. package/dist/fermi-surface/FermiSurface.svelte.d.ts +83 -0
  152. package/dist/fermi-surface/FermiSurfaceControls.svelte +448 -0
  153. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +35 -0
  154. package/dist/fermi-surface/FermiSurfaceScene.svelte +797 -0
  155. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +50 -0
  156. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +85 -0
  157. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +8 -0
  158. package/dist/fermi-surface/compute.d.ts +5 -0
  159. package/dist/fermi-surface/compute.js +538 -0
  160. package/dist/fermi-surface/constants.d.ts +9 -0
  161. package/dist/fermi-surface/constants.js +27 -0
  162. package/dist/fermi-surface/export.d.ts +5 -0
  163. package/dist/fermi-surface/export.js +51 -0
  164. package/dist/fermi-surface/index.d.ts +12 -0
  165. package/dist/fermi-surface/index.js +13 -0
  166. package/dist/fermi-surface/marching-cubes.d.ts +2 -0
  167. package/dist/fermi-surface/marching-cubes.js +2 -0
  168. package/dist/fermi-surface/parse.d.ts +2 -0
  169. package/dist/fermi-surface/parse.js +494 -0
  170. package/dist/fermi-surface/symmetry.d.ts +3 -0
  171. package/dist/fermi-surface/symmetry.js +46 -0
  172. package/dist/fermi-surface/types.d.ts +111 -0
  173. package/dist/fermi-surface/types.js +4 -0
  174. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1547 -0
  175. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  176. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  177. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  178. package/dist/heatmap-matrix/index.d.ts +53 -0
  179. package/dist/heatmap-matrix/index.js +100 -0
  180. package/dist/heatmap-matrix/shared.d.ts +2 -0
  181. package/dist/heatmap-matrix/shared.js +4 -0
  182. package/dist/icons.d.ts +569 -0
  183. package/dist/icons.js +648 -0
  184. package/dist/index.d.ts +39 -0
  185. package/dist/index.js +39 -0
  186. package/dist/io/decompress.d.ts +11 -0
  187. package/dist/io/decompress.js +76 -0
  188. package/dist/io/export.d.ts +16 -0
  189. package/dist/io/export.js +338 -0
  190. package/dist/io/fetch.d.ts +5 -0
  191. package/dist/io/fetch.js +43 -0
  192. package/dist/io/file-drop.d.ts +7 -0
  193. package/dist/io/file-drop.js +42 -0
  194. package/dist/io/index.d.ts +7 -0
  195. package/dist/io/index.js +6 -0
  196. package/dist/io/is-binary.d.ts +1 -0
  197. package/dist/io/is-binary.js +20 -0
  198. package/dist/io/types.d.ts +8 -0
  199. package/dist/io/types.js +1 -0
  200. package/dist/io/url-drop.d.ts +2 -0
  201. package/dist/io/url-drop.js +154 -0
  202. package/dist/isosurface/Isosurface.svelte +285 -0
  203. package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
  204. package/dist/isosurface/IsosurfaceControls.svelte +277 -0
  205. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
  206. package/dist/isosurface/index.d.ts +5 -0
  207. package/dist/isosurface/index.js +6 -0
  208. package/dist/isosurface/parse.d.ts +6 -0
  209. package/dist/isosurface/parse.js +552 -0
  210. package/dist/isosurface/slice.d.ts +11 -0
  211. package/dist/isosurface/slice.js +141 -0
  212. package/dist/isosurface/types.d.ts +56 -0
  213. package/dist/isosurface/types.js +227 -0
  214. package/dist/keyboard.d.ts +3 -0
  215. package/dist/keyboard.js +23 -0
  216. package/dist/labels.d.ts +53 -0
  217. package/dist/labels.js +278 -0
  218. package/dist/layout/FullscreenToggle.svelte +50 -0
  219. package/dist/layout/FullscreenToggle.svelte.d.ts +7 -0
  220. package/dist/layout/InfoCard.svelte +120 -0
  221. package/dist/layout/InfoCard.svelte.d.ts +21 -0
  222. package/dist/layout/InfoTag.svelte +185 -0
  223. package/dist/layout/InfoTag.svelte.d.ts +19 -0
  224. package/dist/layout/PropertyFilter.svelte +247 -0
  225. package/dist/layout/PropertyFilter.svelte.d.ts +24 -0
  226. package/dist/layout/SettingsSection.svelte +148 -0
  227. package/dist/layout/SettingsSection.svelte.d.ts +17 -0
  228. package/dist/layout/SubpageGrid.svelte +82 -0
  229. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  230. package/dist/layout/fullscreen.d.ts +9 -0
  231. package/dist/layout/fullscreen.js +53 -0
  232. package/dist/layout/index.d.ts +10 -0
  233. package/dist/layout/index.js +8 -0
  234. package/dist/layout/json-tree/JsonNode.svelte +548 -0
  235. package/dist/layout/json-tree/JsonNode.svelte.d.ts +11 -0
  236. package/dist/layout/json-tree/JsonTree.svelte +1230 -0
  237. package/dist/layout/json-tree/JsonTree.svelte.d.ts +6 -0
  238. package/dist/layout/json-tree/JsonValue.svelte.d.ts +9 -0
  239. package/dist/layout/json-tree/index.d.ts +3 -0
  240. package/dist/layout/json-tree/index.js +3 -0
  241. package/dist/layout/json-tree/types.d.ts +74 -0
  242. package/dist/layout/json-tree/types.js +2 -0
  243. package/dist/layout/json-tree/utils.d.ts +29 -0
  244. package/dist/layout/json-tree/utils.js +642 -0
  245. package/dist/marching-cubes.d.ts +14 -0
  246. package/dist/marching-cubes.js +535 -0
  247. package/dist/math.d.ts +105 -0
  248. package/dist/math.js +920 -0
  249. package/dist/overlays/ContextMenu.svelte +162 -0
  250. package/dist/overlays/ContextMenu.svelte.d.ts +25 -0
  251. package/dist/overlays/CopyButton.svelte +45 -0
  252. package/dist/overlays/CopyButton.svelte.d.ts +8 -0
  253. package/dist/overlays/DragControlTab.svelte +98 -0
  254. package/dist/overlays/DragControlTab.svelte.d.ts +8 -0
  255. package/dist/overlays/DraggablePane.svelte +487 -0
  256. package/dist/overlays/DraggablePane.svelte.d.ts +36 -0
  257. package/dist/overlays/InfoPaneCards.svelte +149 -0
  258. package/dist/overlays/InfoPaneCards.svelte.d.ts +22 -0
  259. package/dist/overlays/index.d.ts +3 -0
  260. package/dist/overlays/index.js +3 -0
  261. package/dist/periodic-table/PeriodicTable.svelte +480 -0
  262. package/dist/periodic-table/PeriodicTable.svelte.d.ts +55 -0
  263. package/dist/periodic-table/PeriodicTableControls.svelte +557 -0
  264. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +24 -0
  265. package/dist/periodic-table/PropertySelect.svelte +38 -0
  266. package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
  267. package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
  268. package/dist/periodic-table/index.d.ts +10 -0
  269. package/dist/periodic-table/index.js +4 -0
  270. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1092 -0
  271. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +44 -0
  272. package/dist/phase-diagram/PhaseDiagramControls.svelte +444 -0
  273. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +30 -0
  274. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +127 -0
  275. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  276. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  277. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +19 -0
  278. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  279. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +16 -0
  280. package/dist/phase-diagram/TdbInfoPanel.svelte +203 -0
  281. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +12 -0
  282. package/dist/phase-diagram/build-diagram.d.ts +11 -0
  283. package/dist/phase-diagram/build-diagram.js +160 -0
  284. package/dist/phase-diagram/colors.d.ts +35 -0
  285. package/dist/phase-diagram/colors.js +51 -0
  286. package/dist/phase-diagram/diagram-input.d.ts +29 -0
  287. package/dist/phase-diagram/diagram-input.js +3 -0
  288. package/dist/phase-diagram/index.d.ts +13 -0
  289. package/dist/phase-diagram/index.js +11 -0
  290. package/dist/phase-diagram/parse.d.ts +55 -0
  291. package/dist/phase-diagram/parse.js +273 -0
  292. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  293. package/dist/phase-diagram/svg-to-diagram.js +867 -0
  294. package/dist/phase-diagram/types.d.ts +93 -0
  295. package/dist/phase-diagram/types.js +1 -0
  296. package/dist/phase-diagram/utils.d.ts +118 -0
  297. package/dist/phase-diagram/utils.js +600 -0
  298. package/dist/plot/bar/BarPlot.svelte +1755 -0
  299. package/dist/plot/bar/BarPlot.svelte.d.ts +84 -0
  300. package/dist/plot/bar/BarPlotControls.svelte +67 -0
  301. package/dist/plot/bar/BarPlotControls.svelte.d.ts +18 -0
  302. package/dist/plot/bar/SpacegroupBarPlot.svelte +293 -0
  303. package/dist/plot/bar/SpacegroupBarPlot.svelte.d.ts +9 -0
  304. package/dist/plot/bar/data.d.ts +40 -0
  305. package/dist/plot/bar/data.js +154 -0
  306. package/dist/plot/bar/geometry.d.ts +39 -0
  307. package/dist/plot/bar/geometry.js +60 -0
  308. package/dist/plot/bar/index.d.ts +3 -0
  309. package/dist/plot/bar/index.js +3 -0
  310. package/dist/plot/box/BoxPlot.svelte +1462 -0
  311. package/dist/plot/box/BoxPlot.svelte.d.ts +94 -0
  312. package/dist/plot/box/BoxPlotControls.svelte +109 -0
  313. package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
  314. package/dist/plot/box/Violin.svelte +14 -0
  315. package/dist/plot/box/Violin.svelte.d.ts +70 -0
  316. package/dist/plot/box/box-plot.d.ts +55 -0
  317. package/dist/plot/box/box-plot.js +126 -0
  318. package/dist/plot/box/index.d.ts +5 -0
  319. package/dist/plot/box/index.js +5 -0
  320. package/dist/plot/box/kde.d.ts +16 -0
  321. package/dist/plot/box/kde.js +160 -0
  322. package/dist/plot/box/quantile.d.ts +3 -0
  323. package/dist/plot/box/quantile.js +53 -0
  324. package/dist/plot/core/auto-place.d.ts +43 -0
  325. package/dist/plot/core/auto-place.js +122 -0
  326. package/dist/plot/core/axis-utils.d.ts +46 -0
  327. package/dist/plot/core/axis-utils.js +110 -0
  328. package/dist/plot/core/components/AxisLabel.svelte +51 -0
  329. package/dist/plot/core/components/AxisLabel.svelte.d.ts +16 -0
  330. package/dist/plot/core/components/ColorBar.svelte +724 -0
  331. package/dist/plot/core/components/ColorBar.svelte.d.ts +31 -0
  332. package/dist/plot/core/components/ColorScaleSelect.svelte +55 -0
  333. package/dist/plot/core/components/ColorScaleSelect.svelte.d.ts +15 -0
  334. package/dist/plot/core/components/ControlPane.svelte +46 -0
  335. package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
  336. package/dist/plot/core/components/FillArea.svelte +234 -0
  337. package/dist/plot/core/components/FillArea.svelte.d.ts +21 -0
  338. package/dist/plot/core/components/InteractiveAxisLabel.svelte +96 -0
  339. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +14 -0
  340. package/dist/plot/core/components/Line.svelte +101 -0
  341. package/dist/plot/core/components/Line.svelte.d.ts +15 -0
  342. package/dist/plot/core/components/PlotAxis.svelte +171 -0
  343. package/dist/plot/core/components/PlotAxis.svelte.d.ts +25 -0
  344. package/dist/plot/core/components/PlotControls.svelte +525 -0
  345. package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
  346. package/dist/plot/core/components/PlotLegend.svelte +580 -0
  347. package/dist/plot/core/components/PlotLegend.svelte.d.ts +30 -0
  348. package/dist/plot/core/components/PlotTooltip.svelte +83 -0
  349. package/dist/plot/core/components/PlotTooltip.svelte.d.ts +25 -0
  350. package/dist/plot/core/components/PortalSelect.svelte +257 -0
  351. package/dist/plot/core/components/PortalSelect.svelte.d.ts +16 -0
  352. package/dist/plot/core/components/ReferenceLine.svelte +204 -0
  353. package/dist/plot/core/components/ReferenceLine.svelte.d.ts +20 -0
  354. package/dist/plot/core/components/ReferenceLine3D.svelte +156 -0
  355. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +14 -0
  356. package/dist/plot/core/components/ReferencePlane.svelte +175 -0
  357. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +14 -0
  358. package/dist/plot/core/components/ZeroLines.svelte +97 -0
  359. package/dist/plot/core/components/ZeroLines.svelte.d.ts +33 -0
  360. package/dist/plot/core/components/ZoomRect.svelte +23 -0
  361. package/dist/plot/core/components/ZoomRect.svelte.d.ts +8 -0
  362. package/dist/plot/core/components/index.d.ts +17 -0
  363. package/dist/plot/core/components/index.js +17 -0
  364. package/dist/plot/core/data-cleaning.d.ts +107 -0
  365. package/dist/plot/core/data-cleaning.js +853 -0
  366. package/dist/plot/core/data-transform.d.ts +16 -0
  367. package/dist/plot/core/data-transform.js +45 -0
  368. package/dist/plot/core/fill-utils.d.ts +33 -0
  369. package/dist/plot/core/fill-utils.js +388 -0
  370. package/dist/plot/core/hover-lock.svelte.d.ts +14 -0
  371. package/dist/plot/core/hover-lock.svelte.js +45 -0
  372. package/dist/plot/core/index.d.ts +10 -0
  373. package/dist/plot/core/index.js +11 -0
  374. package/dist/plot/core/interactions.d.ts +35 -0
  375. package/dist/plot/core/interactions.js +195 -0
  376. package/dist/plot/core/layout.d.ts +79 -0
  377. package/dist/plot/core/layout.js +281 -0
  378. package/dist/plot/core/reference-line.d.ts +60 -0
  379. package/dist/plot/core/reference-line.js +301 -0
  380. package/dist/plot/core/scales.d.ts +48 -0
  381. package/dist/plot/core/scales.js +480 -0
  382. package/dist/plot/core/svg.d.ts +2 -0
  383. package/dist/plot/core/svg.js +41 -0
  384. package/dist/plot/core/types.d.ts +771 -0
  385. package/dist/plot/core/types.js +99 -0
  386. package/dist/plot/core/utils/label-placement.d.ts +68 -0
  387. package/dist/plot/core/utils/label-placement.js +326 -0
  388. package/dist/plot/core/utils/series-visibility.d.ts +26 -0
  389. package/dist/plot/core/utils/series-visibility.js +112 -0
  390. package/dist/plot/core/utils.d.ts +11 -0
  391. package/dist/plot/core/utils.js +27 -0
  392. package/dist/plot/histogram/Histogram.svelte +1418 -0
  393. package/dist/plot/histogram/Histogram.svelte.d.ts +50 -0
  394. package/dist/plot/histogram/HistogramControls.svelte +212 -0
  395. package/dist/plot/histogram/HistogramControls.svelte.d.ts +22 -0
  396. package/dist/plot/histogram/index.d.ts +2 -0
  397. package/dist/plot/histogram/index.js +2 -0
  398. package/dist/plot/index.d.ts +8 -0
  399. package/dist/plot/index.js +10 -0
  400. package/dist/plot/sankey/Sankey.svelte +700 -0
  401. package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
  402. package/dist/plot/sankey/SankeyControls.svelte +98 -0
  403. package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
  404. package/dist/plot/sankey/index.d.ts +4 -0
  405. package/dist/plot/sankey/index.js +3 -0
  406. package/dist/plot/sankey/sankey-types.d.ts +42 -0
  407. package/dist/plot/sankey/sankey-types.js +4 -0
  408. package/dist/plot/sankey/sankey.d.ts +52 -0
  409. package/dist/plot/sankey/sankey.js +187 -0
  410. package/dist/plot/scatter/BinnedScatterPlot.svelte +1116 -0
  411. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +66 -0
  412. package/dist/plot/scatter/ElementScatter.svelte +63 -0
  413. package/dist/plot/scatter/ElementScatter.svelte.d.ts +14 -0
  414. package/dist/plot/scatter/ScatterPlot.svelte +2357 -0
  415. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +96 -0
  416. package/dist/plot/scatter/ScatterPlotControls.svelte +307 -0
  417. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +17 -0
  418. package/dist/plot/scatter/ScatterPoint.svelte +182 -0
  419. package/dist/plot/scatter/ScatterPoint.svelte.d.ts +22 -0
  420. package/dist/plot/scatter/adaptive-density.d.ts +79 -0
  421. package/dist/plot/scatter/adaptive-density.js +217 -0
  422. package/dist/plot/scatter/binned-scatter-types.d.ts +59 -0
  423. package/dist/plot/scatter/binned-scatter-types.js +1 -0
  424. package/dist/plot/scatter/index.d.ts +7 -0
  425. package/dist/plot/scatter/index.js +5 -0
  426. package/dist/plot/scatter/scatter-data.d.ts +19 -0
  427. package/dist/plot/scatter/scatter-data.js +212 -0
  428. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +531 -0
  429. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +95 -0
  430. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +438 -0
  431. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +20 -0
  432. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +912 -0
  433. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +74 -0
  434. package/dist/plot/scatter-3d/Surface3D.svelte +197 -0
  435. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +13 -0
  436. package/dist/plot/scatter-3d/index.d.ts +4 -0
  437. package/dist/plot/scatter-3d/index.js +4 -0
  438. package/dist/plot/sunburst/Sunburst.svelte +1045 -0
  439. package/dist/plot/sunburst/Sunburst.svelte.d.ts +96 -0
  440. package/dist/plot/sunburst/SunburstControls.svelte +200 -0
  441. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
  442. package/dist/plot/sunburst/index.d.ts +4 -0
  443. package/dist/plot/sunburst/index.js +4 -0
  444. package/dist/plot/sunburst/render.d.ts +34 -0
  445. package/dist/plot/sunburst/render.js +122 -0
  446. package/dist/plot/sunburst/sunburst.d.ts +62 -0
  447. package/dist/plot/sunburst/sunburst.js +266 -0
  448. package/dist/rdf/RdfPlot.svelte +248 -0
  449. package/dist/rdf/RdfPlot.svelte.d.ts +27 -0
  450. package/dist/rdf/calc-rdf.d.ts +4 -0
  451. package/dist/rdf/calc-rdf.js +98 -0
  452. package/dist/rdf/index.d.ts +23 -0
  453. package/dist/rdf/index.js +2 -0
  454. package/dist/sanitize.d.ts +6 -0
  455. package/dist/sanitize.js +116 -0
  456. package/dist/settings.d.ts +319 -0
  457. package/dist/settings.js +1394 -0
  458. package/dist/spectral/Bands.svelte +1050 -0
  459. package/dist/spectral/Bands.svelte.d.ts +39 -0
  460. package/dist/spectral/BandsAndDos.svelte +134 -0
  461. package/dist/spectral/BandsAndDos.svelte.d.ts +18 -0
  462. package/dist/spectral/BrillouinBandsDos.svelte +264 -0
  463. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +20 -0
  464. package/dist/spectral/Dos.svelte +688 -0
  465. package/dist/spectral/Dos.svelte.d.ts +29 -0
  466. package/dist/spectral/helpers.d.ts +121 -0
  467. package/dist/spectral/helpers.js +1098 -0
  468. package/dist/spectral/index.d.ts +6 -0
  469. package/dist/spectral/index.js +6 -0
  470. package/dist/spectral/types.d.ts +84 -0
  471. package/dist/spectral/types.js +2 -0
  472. package/dist/state.svelte.d.ts +25 -0
  473. package/dist/state.svelte.js +45 -0
  474. package/dist/structure/Arrow.svelte +72 -0
  475. package/dist/structure/Arrow.svelte.d.ts +15 -0
  476. package/dist/structure/AtomLegend.svelte +814 -0
  477. package/dist/structure/AtomLegend.svelte.d.ts +35 -0
  478. package/dist/structure/Bond.svelte +140 -0
  479. package/dist/structure/Bond.svelte.d.ts +9 -0
  480. package/dist/structure/CanvasTooltip.svelte +33 -0
  481. package/dist/structure/CanvasTooltip.svelte.d.ts +12 -0
  482. package/dist/structure/CellSelect.svelte +348 -0
  483. package/dist/structure/CellSelect.svelte.d.ts +13 -0
  484. package/dist/structure/Cylinder.svelte +49 -0
  485. package/dist/structure/Cylinder.svelte.d.ts +13 -0
  486. package/dist/structure/Lattice.svelte +196 -0
  487. package/dist/structure/Lattice.svelte.d.ts +17 -0
  488. package/dist/structure/Structure.svelte +2254 -0
  489. package/dist/structure/Structure.svelte.d.ts +89 -0
  490. package/dist/structure/StructureControls.svelte +1273 -0
  491. package/dist/structure/StructureControls.svelte.d.ts +31 -0
  492. package/dist/structure/StructureExportPane.svelte +252 -0
  493. package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
  494. package/dist/structure/StructureInfoPane.svelte +736 -0
  495. package/dist/structure/StructureInfoPane.svelte.d.ts +19 -0
  496. package/dist/structure/StructureScene.svelte +2256 -0
  497. package/dist/structure/StructureScene.svelte.d.ts +111 -0
  498. package/dist/structure/atom-properties.d.ts +37 -0
  499. package/dist/structure/atom-properties.js +200 -0
  500. package/dist/structure/bond-order-perception.d.ts +13 -0
  501. package/dist/structure/bond-order-perception.js +384 -0
  502. package/dist/structure/bonding.d.ts +69 -0
  503. package/dist/structure/bonding.js +724 -0
  504. package/dist/structure/export.d.ts +20 -0
  505. package/dist/structure/export.js +731 -0
  506. package/dist/structure/index.d.ts +124 -0
  507. package/dist/structure/index.js +167 -0
  508. package/dist/structure/label-placement.d.ts +14 -0
  509. package/dist/structure/label-placement.js +72 -0
  510. package/dist/structure/measure.d.ts +7 -0
  511. package/dist/structure/measure.js +30 -0
  512. package/dist/structure/parse.d.ts +66 -0
  513. package/dist/structure/parse.js +1410 -0
  514. package/dist/structure/partial-occupancy.d.ts +25 -0
  515. package/dist/structure/partial-occupancy.js +99 -0
  516. package/dist/structure/pbc.d.ts +9 -0
  517. package/dist/structure/pbc.js +127 -0
  518. package/dist/structure/supercell.d.ts +8 -0
  519. package/dist/structure/supercell.js +170 -0
  520. package/dist/structure/validation.d.ts +2 -0
  521. package/dist/structure/validation.js +10 -0
  522. package/dist/symmetry/SymmetryStats.svelte +226 -0
  523. package/dist/symmetry/SymmetryStats.svelte.d.ts +21 -0
  524. package/dist/symmetry/WyckoffTable.svelte +120 -0
  525. package/dist/symmetry/WyckoffTable.svelte.d.ts +11 -0
  526. package/dist/symmetry/cell-transform.d.ts +12 -0
  527. package/dist/symmetry/cell-transform.js +91 -0
  528. package/dist/symmetry/index.d.ts +43 -0
  529. package/dist/symmetry/index.js +226 -0
  530. package/dist/symmetry/spacegroups.d.ts +16 -0
  531. package/dist/symmetry/spacegroups.js +429 -0
  532. package/dist/table/HeatmapTable.svelte +1885 -0
  533. package/dist/table/HeatmapTable.svelte.d.ts +49 -0
  534. package/dist/table/ToggleMenu.svelte +385 -0
  535. package/dist/table/ToggleMenu.svelte.d.ts +11 -0
  536. package/dist/table/index.d.ts +72 -0
  537. package/dist/table/index.js +38 -0
  538. package/dist/theme/ThemeControl.svelte +53 -0
  539. package/dist/theme/ThemeControl.svelte.d.ts +9 -0
  540. package/dist/theme/index.d.ts +29 -0
  541. package/dist/theme/index.js +79 -0
  542. package/dist/time.d.ts +4 -0
  543. package/dist/time.js +70 -0
  544. package/dist/tooltip/KCoords.svelte +45 -0
  545. package/dist/tooltip/KCoords.svelte.d.ts +8 -0
  546. package/dist/tooltip/TooltipContent.svelte +58 -0
  547. package/dist/tooltip/TooltipContent.svelte.d.ts +31 -0
  548. package/dist/tooltip/index.d.ts +3 -0
  549. package/dist/tooltip/index.js +2 -0
  550. package/dist/tooltip/types.d.ts +8 -0
  551. package/dist/tooltip/types.js +1 -0
  552. package/dist/trajectory/Trajectory.svelte +1571 -0
  553. package/dist/trajectory/Trajectory.svelte.d.ts +78 -0
  554. package/dist/trajectory/TrajectoryError.svelte +128 -0
  555. package/dist/trajectory/TrajectoryError.svelte.d.ts +13 -0
  556. package/dist/trajectory/TrajectoryExportPane.svelte +358 -0
  557. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +17 -0
  558. package/dist/trajectory/TrajectoryInfoPane.svelte +314 -0
  559. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +17 -0
  560. package/dist/trajectory/constants.d.ts +6 -0
  561. package/dist/trajectory/constants.js +7 -0
  562. package/dist/trajectory/extract.d.ts +5 -0
  563. package/dist/trajectory/extract.js +162 -0
  564. package/dist/trajectory/format-detect.d.ts +10 -0
  565. package/dist/trajectory/format-detect.js +90 -0
  566. package/dist/trajectory/frame-reader.d.ts +17 -0
  567. package/dist/trajectory/frame-reader.js +299 -0
  568. package/dist/trajectory/helpers.d.ts +15 -0
  569. package/dist/trajectory/helpers.js +164 -0
  570. package/dist/trajectory/index.d.ts +63 -0
  571. package/dist/trajectory/index.js +126 -0
  572. package/dist/trajectory/parse/ase.d.ts +2 -0
  573. package/dist/trajectory/parse/ase.js +73 -0
  574. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  575. package/dist/trajectory/parse/hdf5.js +127 -0
  576. package/dist/trajectory/parse/index.d.ts +12 -0
  577. package/dist/trajectory/parse/index.js +306 -0
  578. package/dist/trajectory/parse/lammps.d.ts +5 -0
  579. package/dist/trajectory/parse/lammps.js +179 -0
  580. package/dist/trajectory/parse/vasp.d.ts +2 -0
  581. package/dist/trajectory/parse/vasp.js +87 -0
  582. package/dist/trajectory/parse/xyz.d.ts +26 -0
  583. package/dist/trajectory/parse/xyz.js +123 -0
  584. package/dist/trajectory/plotting.d.ts +28 -0
  585. package/dist/trajectory/plotting.js +423 -0
  586. package/dist/trajectory/types.d.ts +11 -0
  587. package/dist/trajectory/types.js +1 -0
  588. package/dist/utils.d.ts +7 -0
  589. package/dist/utils.js +47 -0
  590. package/dist/xrd/XrdPlot.svelte +616 -0
  591. package/dist/xrd/XrdPlot.svelte.d.ts +28 -0
  592. package/dist/xrd/broadening.d.ts +20 -0
  593. package/dist/xrd/broadening.js +97 -0
  594. package/dist/xrd/calc-xrd.d.ts +37 -0
  595. package/dist/xrd/calc-xrd.js +339 -0
  596. package/dist/xrd/index.d.ts +37 -0
  597. package/dist/xrd/index.js +4 -0
  598. package/dist/xrd/parse.d.ts +13 -0
  599. package/dist/xrd/parse.js +749 -0
  600. package/license +1 -1
  601. package/package.json +237 -1458
  602. package/readme.md +98 -171
  603. package/.vscode/launch.json +0 -13
  604. package/.vscodeignore +0 -7
  605. package/dist/assets/STLExporter-BpTH3YHE.js +0 -8
  606. package/dist/assets/browser-DdDecX_W.js +0 -1
  607. package/dist/assets/export-qgn-H9y6.js +0 -2
  608. package/dist/assets/main-DiKYzti2.css +0 -1
  609. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  610. package/dist/extension.js +0 -31293
  611. package/dist/src/lib/FilePicker.svelte +0 -360
  612. package/dist/src/lib/Icon.svelte +0 -41
  613. package/dist/src/lib/MillerIndexInput.svelte +0 -66
  614. package/dist/src/lib/api/mp.ts +0 -26
  615. package/dist/src/lib/api/optimade.ts +0 -204
  616. package/dist/src/lib/app.css +0 -247
  617. package/dist/src/lib/brillouin/BrillouinZone.svelte +0 -549
  618. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +0 -144
  619. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +0 -146
  620. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  621. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +0 -476
  622. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +0 -92
  623. package/dist/src/lib/brillouin/compute.ts +0 -529
  624. package/dist/src/lib/brillouin/index.ts +0 -8
  625. package/dist/src/lib/brillouin/types.ts +0 -51
  626. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +0 -327
  627. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +0 -846
  628. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +0 -3193
  629. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +0 -94
  630. package/dist/src/lib/chempot-diagram/chempot-worker.ts +0 -11
  631. package/dist/src/lib/chempot-diagram/color.ts +0 -42
  632. package/dist/src/lib/chempot-diagram/compute.ts +0 -1014
  633. package/dist/src/lib/chempot-diagram/index.ts +0 -6
  634. package/dist/src/lib/chempot-diagram/pointer.ts +0 -56
  635. package/dist/src/lib/chempot-diagram/temperature.ts +0 -77
  636. package/dist/src/lib/chempot-diagram/types.ts +0 -130
  637. package/dist/src/lib/colors/index.ts +0 -249
  638. package/dist/src/lib/composition/BarChart.svelte +0 -297
  639. package/dist/src/lib/composition/BubbleChart.svelte +0 -218
  640. package/dist/src/lib/composition/Composition.svelte +0 -165
  641. package/dist/src/lib/composition/Formula.svelte +0 -268
  642. package/dist/src/lib/composition/FormulaFilter.svelte +0 -1257
  643. package/dist/src/lib/composition/PieChart.svelte +0 -323
  644. package/dist/src/lib/composition/format.ts +0 -155
  645. package/dist/src/lib/composition/index.ts +0 -37
  646. package/dist/src/lib/composition/parse.ts +0 -605
  647. package/dist/src/lib/constants.ts +0 -134
  648. package/dist/src/lib/controls.ts +0 -42
  649. package/dist/src/lib/convex-hull/ConvexHull.svelte +0 -157
  650. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +0 -825
  651. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +0 -1801
  652. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +0 -1398
  653. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +0 -535
  654. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +0 -125
  655. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +0 -929
  656. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +0 -131
  657. package/dist/src/lib/convex-hull/GasPressureControls.svelte +0 -247
  658. package/dist/src/lib/convex-hull/StructurePopup.svelte +0 -151
  659. package/dist/src/lib/convex-hull/TemperatureSlider.svelte +0 -140
  660. package/dist/src/lib/convex-hull/barycentric-coords.ts +0 -246
  661. package/dist/src/lib/convex-hull/demo-temperature.ts +0 -63
  662. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +0 -405
  663. package/dist/src/lib/convex-hull/helpers.ts +0 -932
  664. package/dist/src/lib/convex-hull/index.ts +0 -202
  665. package/dist/src/lib/convex-hull/thermodynamics.ts +0 -2192
  666. package/dist/src/lib/convex-hull/types.ts +0 -267
  667. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +0 -311
  668. package/dist/src/lib/coordination/calc-coordination.ts +0 -93
  669. package/dist/src/lib/coordination/index.ts +0 -9
  670. package/dist/src/lib/effects.svelte.ts +0 -48
  671. package/dist/src/lib/element/ElementHeading.svelte +0 -26
  672. package/dist/src/lib/element/ElementPhoto.svelte +0 -57
  673. package/dist/src/lib/element/ElementStats.svelte +0 -80
  674. package/dist/src/lib/element/ElementTile.svelte +0 -484
  675. package/dist/src/lib/element/data.ts +0 -14
  676. package/dist/src/lib/element/index.ts +0 -8
  677. package/dist/src/lib/element/types.ts +0 -62
  678. package/dist/src/lib/feedback/ClickFeedback.svelte +0 -58
  679. package/dist/src/lib/feedback/DragOverlay.svelte +0 -42
  680. package/dist/src/lib/feedback/index.ts +0 -4
  681. package/dist/src/lib/fermi-surface/FermiSlice.svelte +0 -189
  682. package/dist/src/lib/fermi-surface/FermiSurface.svelte +0 -600
  683. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +0 -448
  684. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +0 -794
  685. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  686. package/dist/src/lib/fermi-surface/compute.ts +0 -728
  687. package/dist/src/lib/fermi-surface/constants.ts +0 -32
  688. package/dist/src/lib/fermi-surface/export.ts +0 -64
  689. package/dist/src/lib/fermi-surface/index.ts +0 -14
  690. package/dist/src/lib/fermi-surface/marching-cubes.ts +0 -3
  691. package/dist/src/lib/fermi-surface/parse.ts +0 -574
  692. package/dist/src/lib/fermi-surface/symmetry.ts +0 -56
  693. package/dist/src/lib/fermi-surface/types.ts +0 -159
  694. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +0 -1545
  695. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  696. package/dist/src/lib/heatmap-matrix/index.ts +0 -167
  697. package/dist/src/lib/heatmap-matrix/shared.ts +0 -7
  698. package/dist/src/lib/icons.ts +0 -650
  699. package/dist/src/lib/index.ts +0 -61
  700. package/dist/src/lib/io/decompress.ts +0 -92
  701. package/dist/src/lib/io/export.ts +0 -385
  702. package/dist/src/lib/io/fetch.ts +0 -46
  703. package/dist/src/lib/io/file-drop.ts +0 -51
  704. package/dist/src/lib/io/index.ts +0 -7
  705. package/dist/src/lib/io/is-binary.ts +0 -24
  706. package/dist/src/lib/io/types.ts +0 -8
  707. package/dist/src/lib/io/url-drop.ts +0 -141
  708. package/dist/src/lib/isosurface/Isosurface.svelte +0 -285
  709. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +0 -277
  710. package/dist/src/lib/isosurface/index.ts +0 -7
  711. package/dist/src/lib/isosurface/parse.ts +0 -656
  712. package/dist/src/lib/isosurface/slice.ts +0 -175
  713. package/dist/src/lib/isosurface/types.ts +0 -309
  714. package/dist/src/lib/labels.ts +0 -320
  715. package/dist/src/lib/layout/FullscreenToggle.svelte +0 -50
  716. package/dist/src/lib/layout/InfoCard.svelte +0 -120
  717. package/dist/src/lib/layout/InfoTag.svelte +0 -185
  718. package/dist/src/lib/layout/PropertyFilter.svelte +0 -246
  719. package/dist/src/lib/layout/SettingsSection.svelte +0 -148
  720. package/dist/src/lib/layout/SubpageGrid.svelte +0 -82
  721. package/dist/src/lib/layout/fullscreen.ts +0 -65
  722. package/dist/src/lib/layout/index.ts +0 -11
  723. package/dist/src/lib/layout/json-tree/JsonNode.svelte +0 -548
  724. package/dist/src/lib/layout/json-tree/JsonTree.svelte +0 -1230
  725. package/dist/src/lib/layout/json-tree/index.ts +0 -3
  726. package/dist/src/lib/layout/json-tree/types.ts +0 -126
  727. package/dist/src/lib/layout/json-tree/utils.ts +0 -682
  728. package/dist/src/lib/marching-cubes.ts +0 -614
  729. package/dist/src/lib/math.ts +0 -1081
  730. package/dist/src/lib/overlays/ContextMenu.svelte +0 -162
  731. package/dist/src/lib/overlays/CopyButton.svelte +0 -45
  732. package/dist/src/lib/overlays/DragControlTab.svelte +0 -98
  733. package/dist/src/lib/overlays/DraggablePane.svelte +0 -487
  734. package/dist/src/lib/overlays/InfoPaneCards.svelte +0 -149
  735. package/dist/src/lib/overlays/index.ts +0 -3
  736. package/dist/src/lib/periodic-table/PeriodicTable.svelte +0 -469
  737. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +0 -557
  738. package/dist/src/lib/periodic-table/PropertySelect.svelte +0 -37
  739. package/dist/src/lib/periodic-table/index.ts +0 -12
  740. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1086
  741. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +0 -444
  742. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  743. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +0 -184
  744. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +0 -391
  745. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +0 -203
  746. package/dist/src/lib/phase-diagram/build-diagram.ts +0 -186
  747. package/dist/src/lib/phase-diagram/colors.ts +0 -58
  748. package/dist/src/lib/phase-diagram/diagram-input.ts +0 -40
  749. package/dist/src/lib/phase-diagram/index.ts +0 -13
  750. package/dist/src/lib/phase-diagram/parse.ts +0 -348
  751. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +0 -1023
  752. package/dist/src/lib/phase-diagram/types.ts +0 -144
  753. package/dist/src/lib/phase-diagram/utils.ts +0 -775
  754. package/dist/src/lib/plot/AxisLabel.svelte +0 -51
  755. package/dist/src/lib/plot/BarPlot.svelte +0 -2113
  756. package/dist/src/lib/plot/BarPlotControls.svelte +0 -66
  757. package/dist/src/lib/plot/BinnedScatterPlot.svelte +0 -1114
  758. package/dist/src/lib/plot/ColorBar.svelte +0 -721
  759. package/dist/src/lib/plot/ColorScaleSelect.svelte +0 -54
  760. package/dist/src/lib/plot/ElementScatter.svelte +0 -63
  761. package/dist/src/lib/plot/FillArea.svelte +0 -223
  762. package/dist/src/lib/plot/Histogram.svelte +0 -1558
  763. package/dist/src/lib/plot/HistogramControls.svelte +0 -212
  764. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +0 -96
  765. package/dist/src/lib/plot/Line.svelte +0 -84
  766. package/dist/src/lib/plot/PlotAxis.svelte +0 -169
  767. package/dist/src/lib/plot/PlotControls.svelte +0 -537
  768. package/dist/src/lib/plot/PlotLegend.svelte +0 -569
  769. package/dist/src/lib/plot/PlotTooltip.svelte +0 -67
  770. package/dist/src/lib/plot/PortalSelect.svelte +0 -253
  771. package/dist/src/lib/plot/ReferenceLine.svelte +0 -204
  772. package/dist/src/lib/plot/ReferenceLine3D.svelte +0 -156
  773. package/dist/src/lib/plot/ReferencePlane.svelte +0 -175
  774. package/dist/src/lib/plot/ScatterPlot.svelte +0 -2778
  775. package/dist/src/lib/plot/ScatterPlot3D.svelte +0 -529
  776. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +0 -437
  777. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +0 -912
  778. package/dist/src/lib/plot/ScatterPlotControls.svelte +0 -306
  779. package/dist/src/lib/plot/ScatterPoint.svelte +0 -182
  780. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +0 -293
  781. package/dist/src/lib/plot/Surface3D.svelte +0 -197
  782. package/dist/src/lib/plot/ZeroLines.svelte +0 -97
  783. package/dist/src/lib/plot/ZoomRect.svelte +0 -23
  784. package/dist/src/lib/plot/adaptive-density.ts +0 -316
  785. package/dist/src/lib/plot/auto-place.ts +0 -184
  786. package/dist/src/lib/plot/axis-utils.ts +0 -122
  787. package/dist/src/lib/plot/binned-scatter-types.ts +0 -83
  788. package/dist/src/lib/plot/data-cleaning.ts +0 -1069
  789. package/dist/src/lib/plot/data-transform.ts +0 -69
  790. package/dist/src/lib/plot/defaults.ts +0 -9
  791. package/dist/src/lib/plot/fill-utils.ts +0 -494
  792. package/dist/src/lib/plot/hover-lock.svelte.ts +0 -60
  793. package/dist/src/lib/plot/index.ts +0 -53
  794. package/dist/src/lib/plot/interactions.ts +0 -119
  795. package/dist/src/lib/plot/layout.ts +0 -425
  796. package/dist/src/lib/plot/reference-line.ts +0 -426
  797. package/dist/src/lib/plot/scales.ts +0 -654
  798. package/dist/src/lib/plot/svg.ts +0 -23
  799. package/dist/src/lib/plot/types.ts +0 -1144
  800. package/dist/src/lib/plot/utils/label-placement.ts +0 -541
  801. package/dist/src/lib/plot/utils/series-visibility.ts +0 -140
  802. package/dist/src/lib/plot/utils.ts +0 -11
  803. package/dist/src/lib/rdf/RdfPlot.svelte +0 -247
  804. package/dist/src/lib/rdf/calc-rdf.ts +0 -167
  805. package/dist/src/lib/rdf/index.ts +0 -27
  806. package/dist/src/lib/sanitize.ts +0 -126
  807. package/dist/src/lib/settings.ts +0 -1479
  808. package/dist/src/lib/spectral/Bands.svelte +0 -1040
  809. package/dist/src/lib/spectral/BandsAndDos.svelte +0 -134
  810. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +0 -252
  811. package/dist/src/lib/spectral/Dos.svelte +0 -697
  812. package/dist/src/lib/spectral/helpers.ts +0 -1381
  813. package/dist/src/lib/spectral/index.ts +0 -8
  814. package/dist/src/lib/spectral/types.ts +0 -112
  815. package/dist/src/lib/state.svelte.ts +0 -64
  816. package/dist/src/lib/structure/Arrow.svelte +0 -72
  817. package/dist/src/lib/structure/AtomLegend.svelte +0 -815
  818. package/dist/src/lib/structure/Bond.svelte +0 -140
  819. package/dist/src/lib/structure/CanvasTooltip.svelte +0 -33
  820. package/dist/src/lib/structure/CellSelect.svelte +0 -349
  821. package/dist/src/lib/structure/Cylinder.svelte +0 -45
  822. package/dist/src/lib/structure/Lattice.svelte +0 -196
  823. package/dist/src/lib/structure/Structure.svelte +0 -2248
  824. package/dist/src/lib/structure/StructureControls.svelte +0 -1273
  825. package/dist/src/lib/structure/StructureExportPane.svelte +0 -252
  826. package/dist/src/lib/structure/StructureInfoPane.svelte +0 -737
  827. package/dist/src/lib/structure/StructureScene.svelte +0 -2255
  828. package/dist/src/lib/structure/atom-properties.ts +0 -316
  829. package/dist/src/lib/structure/bond-order-perception.ts +0 -447
  830. package/dist/src/lib/structure/bonding.ts +0 -944
  831. package/dist/src/lib/structure/export.ts +0 -861
  832. package/dist/src/lib/structure/index.ts +0 -291
  833. package/dist/src/lib/structure/label-placement.ts +0 -130
  834. package/dist/src/lib/structure/measure.ts +0 -45
  835. package/dist/src/lib/structure/parse.ts +0 -1705
  836. package/dist/src/lib/structure/partial-occupancy.ts +0 -183
  837. package/dist/src/lib/structure/pbc.ts +0 -164
  838. package/dist/src/lib/structure/supercell.ts +0 -226
  839. package/dist/src/lib/structure/validation.ts +0 -11
  840. package/dist/src/lib/symmetry/SymmetryStats.svelte +0 -226
  841. package/dist/src/lib/symmetry/WyckoffTable.svelte +0 -120
  842. package/dist/src/lib/symmetry/cell-transform.ts +0 -118
  843. package/dist/src/lib/symmetry/index.ts +0 -348
  844. package/dist/src/lib/symmetry/spacegroups.ts +0 -404
  845. package/dist/src/lib/table/HeatmapTable.svelte +0 -1833
  846. package/dist/src/lib/table/ToggleMenu.svelte +0 -385
  847. package/dist/src/lib/table/index.ts +0 -139
  848. package/dist/src/lib/theme/ThemeControl.svelte +0 -53
  849. package/dist/src/lib/theme/index.ts +0 -107
  850. package/dist/src/lib/time.ts +0 -71
  851. package/dist/src/lib/tooltip/TooltipContent.svelte +0 -58
  852. package/dist/src/lib/tooltip/index.ts +0 -2
  853. package/dist/src/lib/tooltip/types.ts +0 -13
  854. package/dist/src/lib/trajectory/Trajectory.svelte +0 -1545
  855. package/dist/src/lib/trajectory/TrajectoryError.svelte +0 -128
  856. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +0 -357
  857. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +0 -313
  858. package/dist/src/lib/trajectory/constants.ts +0 -7
  859. package/dist/src/lib/trajectory/extract.ts +0 -196
  860. package/dist/src/lib/trajectory/format-detect.ts +0 -96
  861. package/dist/src/lib/trajectory/frame-reader.ts +0 -456
  862. package/dist/src/lib/trajectory/helpers.ts +0 -217
  863. package/dist/src/lib/trajectory/index.ts +0 -218
  864. package/dist/src/lib/trajectory/parse/ase.ts +0 -109
  865. package/dist/src/lib/trajectory/parse/hdf5.ts +0 -173
  866. package/dist/src/lib/trajectory/parse/index.ts +0 -411
  867. package/dist/src/lib/trajectory/parse/lammps.ts +0 -215
  868. package/dist/src/lib/trajectory/parse/vasp.ts +0 -102
  869. package/dist/src/lib/trajectory/parse/xyz.ts +0 -143
  870. package/dist/src/lib/trajectory/plotting.ts +0 -599
  871. package/dist/src/lib/trajectory/types.ts +0 -13
  872. package/dist/src/lib/utils.ts +0 -56
  873. package/dist/src/lib/xrd/XrdPlot.svelte +0 -615
  874. package/dist/src/lib/xrd/broadening.ts +0 -130
  875. package/dist/src/lib/xrd/calc-xrd.ts +0 -397
  876. package/dist/src/lib/xrd/index.ts +0 -38
  877. package/dist/src/lib/xrd/parse.ts +0 -858
  878. package/dist/webview.js +0 -29421
  879. package/icon.png +0 -0
  880. package/matterviz-0.3.2.vsix +0 -0
  881. package/matterviz-0.3.4.vsix +0 -0
  882. package/matterviz-0.3.5.vsix +0 -0
  883. package/scripts/sync-config.ts +0 -101
  884. package/src/declarations.d.ts +0 -2
  885. package/src/extension.ts +0 -972
  886. package/src/node-io.ts +0 -65
  887. package/src/types.ts +0 -17
  888. package/src/webview/JsonBrowser.svelte +0 -1079
  889. package/src/webview/PlotPanel.svelte +0 -346
  890. package/src/webview/detect.ts +0 -444
  891. package/src/webview/main.ts +0 -764
  892. package/src/webview/plot-utils.ts +0 -250
  893. package/test-fixtures/all-viz-types.json.gz +0 -0
  894. package/test-fixtures/plot-demo-data.json.gz +0 -0
  895. package/tests/detect.test.ts +0 -604
  896. package/tests/extension.test.ts +0 -2041
  897. package/tests/node-io.test.ts +0 -39
  898. package/tests/plot-utils.test.ts +0 -302
  899. package/tests/vite-plugin-json-gz.test.ts +0 -114
  900. package/tests/vscode-mock.ts +0 -18
  901. package/tests/webview.test.ts +0 -231
  902. package/tsconfig.json +0 -20
  903. package/vite-plugin-json-gz.ts +0 -29
  904. package/vite.config.ts +0 -34
  905. package/vite.extension.config.ts +0 -34
  906. /package/dist/{src/lib/EmptyState.svelte → EmptyState.svelte} +0 -0
  907. /package/dist/{src/lib/chempot-diagram → chempot-diagram}/ChemPotScene3D.svelte +0 -0
  908. /package/dist/{src/lib/colors → colors}/alloy-colors.json +0 -0
  909. /package/dist/{src/lib/colors → colors}/dark-mode-colors.json +0 -0
  910. /package/dist/{src/lib/colors → colors}/jmol-colors.json +0 -0
  911. /package/dist/{src/lib/colors → colors}/muted-colors.json +0 -0
  912. /package/dist/{src/lib/colors → colors}/pastel-colors.json +0 -0
  913. /package/dist/{src/lib/colors → colors}/vesta-colors.json +0 -0
  914. /package/dist/{src/lib/element → element}/BohrAtom.svelte +0 -0
  915. /package/dist/{src/lib/element → element}/Nucleus.svelte +0 -0
  916. /package/dist/{src/lib/element → element}/data.json +0 -0
  917. /package/dist/{src/lib/element → element}/data.json.gz +0 -0
  918. /package/dist/{src/lib/element → element}/data.json.gz.d.ts +0 -0
  919. /package/dist/{src/lib/element → element}/data.schema.json +0 -0
  920. /package/dist/{src/lib/element-image-urls.json → element-image-urls.json} +0 -0
  921. /package/dist/{src/lib/feedback → feedback}/Spinner.svelte +0 -0
  922. /package/dist/{src/lib/feedback → feedback}/StatusMessage.svelte +0 -0
  923. /package/dist/{src/lib/layout → layout}/json-tree/JsonValue.svelte +0 -0
  924. /package/dist/{src/lib/periodic-table → periodic-table}/TableInset.svelte +0 -0
  925. /package/dist/{src/lib/theme → theme}/themes.mjs +0 -0
  926. /package/dist/{src/lib/xrd → xrd}/atomic_scattering_params.json +0 -0
@@ -1,1381 +0,0 @@
1
- // Helper utilities for band structure and DOS data processing
2
- import { SUBSCRIPT_MAP } from '$lib/labels'
3
- import { centered_frac, euclidean_dist } from '$lib/math'
4
- import type { Matrix3x3, Vec2, Vec3 } from '$lib/math'
5
- import type { AxisConfig } from '$lib/plot/types'
6
- import type * as types from './types'
7
- import type { RibbonConfig } from './types'
8
-
9
- const is_subscript_key = (key: string): key is keyof typeof SUBSCRIPT_MAP =>
10
- key in SUBSCRIPT_MAP
11
-
12
- // Check if range is a valid [min, max] tuple (strict 2-element array of finite numbers)
13
- export const is_valid_range = (range: unknown): range is Vec2 =>
14
- Array.isArray(range) &&
15
- range.length === 2 &&
16
- Number.isFinite(range[0]) &&
17
- Number.isFinite(range[1])
18
-
19
- // Check if two ranges are approximately equal (within tolerance)
20
- // Returns false if either range is invalid (null, undefined, or fails is_valid_range)
21
- // Negative tol is clamped to 0; tol=0 checks exact equality
22
- export const ranges_equal = (
23
- a: Vec2 | undefined | null,
24
- b: Vec2 | undefined | null,
25
- tol = 0.001,
26
- ): boolean => {
27
- const safe_tol = Math.max(0, tol)
28
- return (
29
- is_valid_range(a) &&
30
- is_valid_range(b) &&
31
- Math.abs(a[0] - b[0]) <= safe_tol &&
32
- Math.abs(a[1] - b[1]) <= safe_tol
33
- )
34
- }
35
-
36
- export const axis_with_range = (
37
- axis: AxisConfig | undefined,
38
- range: Vec2 | undefined,
39
- label?: string,
40
- ): AxisConfig => ({
41
- ...axis,
42
- ...(label !== undefined && { label }),
43
- ...(is_valid_range(range) && { range }),
44
- })
45
-
46
- // Detect which plot triggered a zoom change and return the new synced range.
47
- // Returns null to reset to shared range, undefined for no change, or Vec2 for new zoom.
48
- export function detect_zoom_change(
49
- bands_range: unknown,
50
- dos_range: unknown,
51
- shared_range: Vec2,
52
- current_synced: Vec2 | null,
53
- dos_enabled = true,
54
- ): Vec2 | null | undefined {
55
- const bands_valid = is_valid_range(bands_range)
56
- const dos_valid = dos_enabled && is_valid_range(dos_range)
57
-
58
- // Reset if either becomes invalid (auto-range reset) or returns to shared range
59
- if (current_synced !== null) {
60
- const bands_at_shared = bands_valid && ranges_equal(bands_range, shared_range)
61
- const dos_at_shared = dos_valid && ranges_equal(dos_range, shared_range)
62
- if (bands_at_shared || dos_at_shared || !bands_valid || (dos_enabled && !dos_valid)) {
63
- return null
64
- }
65
- }
66
-
67
- // Check for new zoom from either plot
68
- const bands_is_new =
69
- bands_valid &&
70
- !ranges_equal(bands_range, shared_range) &&
71
- !ranges_equal(bands_range, current_synced)
72
- const dos_is_new =
73
- dos_valid &&
74
- !ranges_equal(dos_range, shared_range) &&
75
- !ranges_equal(dos_range, current_synced)
76
-
77
- if (bands_is_new && !dos_is_new) return bands_range
78
- if (dos_is_new && !bands_is_new) return dos_range
79
- return undefined // no change
80
- }
81
-
82
- // Physical constants for unit conversions (SI units)
83
- const PLANCK = 6.62607015e-34 // J⋅s
84
- const EV_TO_J = 1.602176634e-19 // J
85
- const C_LIGHT = 299792458 // m/s
86
- const THz_TO_HZ = 1e12
87
- const THz_TO_EV = (PLANCK * THz_TO_HZ) / EV_TO_J
88
- const THz_TO_MEV = THz_TO_EV * 1000
89
- const THz_TO_HA = THz_TO_EV / 27.211386245988 // Hartree
90
- const THz_TO_CM = THz_TO_HZ / (C_LIGHT * 100) // cm^-1 (c in cm/s)
91
-
92
- // Band structure constants
93
- export const IMAGINARY_MODE_NOISE_THRESHOLD = 0.005 // Clamp negatives < 0.5% as noise
94
-
95
- // Convert symmetry point symbols to pretty-printed versions.
96
- // Handles Greek letters (both plain and LaTeX backslash-prefixed) and subscripts.
97
- export function pretty_sym_point(symbol: string): string {
98
- if (!symbol) return ``
99
-
100
- // Remove underscores (htmlify maps S0 → S<sub>0</sub> but leaves S_0 as is)
101
- // Replace common symmetry point names with Greek letters
102
- // Handle both plain names (GAMMA) and LaTeX notation (\Gamma) from pymatgen
103
- // Handle subscripts: convert S0 to S₀, K1 to K₁, Γ1 to Γ₁, etc.
104
- // Use \p{L} to match any Unicode letter (not just ASCII A-Z)
105
- return symbol
106
- .replace(/_/g, ``)
107
- .replace(/\\?GAMMA/gi, `Γ`)
108
- .replace(/\\?DELTA/gi, `Δ`)
109
- .replace(/\\?SIGMA/gi, `Σ`)
110
- .replace(/\\?LAMBDA/gi, `Λ`)
111
- .replace(
112
- /(\p{L})(\d+)/gu,
113
- (_, letter, num) =>
114
- letter +
115
- num
116
- .split(``)
117
- .map((digit: string) => (is_subscript_key(digit) ? SUBSCRIPT_MAP[digit] : digit))
118
- .join(``),
119
- )
120
- }
121
-
122
- // Create segment key from start and end labels
123
- export const get_segment_key = (start_label?: string, end_label?: string) =>
124
- `${start_label ?? `null`}_${end_label ?? `null`}`
125
-
126
- // Get ordered segment keys from a band structure, preserving physical path order.
127
- export const get_ordered_segments = (
128
- band_struct: types.BaseBandStructure | null,
129
- segments: Set<string>,
130
- ) => {
131
- if (!band_struct) return Array.from(segments)
132
-
133
- const ordered = band_struct.branches.map((branch) =>
134
- get_segment_key(
135
- band_struct.qpoints[branch.start_index]?.label ?? undefined,
136
- band_struct.qpoints[branch.end_index]?.label ?? undefined,
137
- ),
138
- )
139
- const remaining = Array.from(segments).filter((seg) => !ordered.includes(seg))
140
- return [...ordered, ...remaining]
141
- }
142
-
143
- // Scale segment distances to a target x-axis range [x_start, x_end].
144
- // Used by both band line series and fat band ribbons for consistent x-axis positioning.
145
- export function scale_segment_distances(
146
- segment_distances: number[],
147
- x_start: number,
148
- x_end: number,
149
- ): number[] {
150
- if (segment_distances.length === 0) return []
151
-
152
- const dist_min = segment_distances[0]
153
- const dist_range = (segment_distances.at(-1) ?? dist_min) - dist_min
154
-
155
- if (dist_range === 0) {
156
- // All points at same distance - place at midpoint
157
- return segment_distances.map(() => (x_start + x_end) / 2)
158
- }
159
-
160
- return segment_distances.map(
161
- (dist) => x_start + ((dist - dist_min) / dist_range) * (x_end - x_start),
162
- )
163
- }
164
-
165
- // Get ribbon config for a specific band structure label.
166
- // Supports both single global config (with primitive keys like opacity, max_width, scale, color)
167
- // and per-structure config (keyed by structure label).
168
- // Distinguishes between a global config and a per-structure config by checking if any
169
- // primitive-typed keys (opacity, max_width, scale, color) exist at the top level.
170
- export function get_ribbon_config(
171
- ribbon_config: RibbonConfig | Record<string, RibbonConfig>,
172
- label: string,
173
- ): RibbonConfig {
174
- const defaults: RibbonConfig = { opacity: 0.3, max_width: 6, scale: 1 }
175
- const config_record = ribbon_config as Record<string, unknown>
176
-
177
- // Check for primitive config values (not objects) to distinguish single vs per-structure config
178
- const has_primitive = [`opacity`, `max_width`, `scale`, `color`].some((key) => {
179
- const value = config_record[key]
180
- return value !== undefined && typeof value !== `object`
181
- })
182
-
183
- if (has_primitive) {
184
- // Single global config with primitive values - apply to all structures
185
- return { ...defaults, ...ribbon_config }
186
- }
187
-
188
- // Otherwise, treat as Record<string, RibbonConfig> and look up by label
189
- // Empty label skips lookup and uses defaults only
190
- const label_config = label ? config_record[label] : undefined
191
- return {
192
- ...defaults,
193
- ...(label_config && typeof label_config === `object` ? label_config : {}),
194
- }
195
- }
196
-
197
- // Extract tick positions and labels for a band structure plot.
198
- export function get_band_xaxis_ticks(
199
- band_struct: types.BaseBandStructure,
200
- branches: string[] | Set<string> = [],
201
- ): [number[], string[]] {
202
- const ticks_x_pos: number[] = []
203
- const tick_labels: string[] = []
204
- let prev_label = band_struct.qpoints[0]?.label || null
205
- let prev_branch = band_struct.branches[0]?.name || null
206
-
207
- // Convert branches to Set for consistent handling
208
- const branches_set = Array.isArray(branches) ? new Set(branches) : branches
209
-
210
- for (let idx = 0; idx < band_struct.qpoints.length; idx++) {
211
- const point = band_struct.qpoints[idx]
212
- if (point.label === null) continue
213
-
214
- // Find which branch this point belongs to
215
- const branch_names = band_struct.branches
216
- .filter((branch) => branch.start_index <= idx && idx <= branch.end_index)
217
- .map((branch) => branch.name)
218
- const this_branch = branch_names[0] || null
219
-
220
- if (point.label !== prev_label && prev_branch !== this_branch) {
221
- // Branch transition - combine labels
222
- tick_labels[tick_labels.length - 1] = `${prev_label || ``}|${point.label}`
223
- ticks_x_pos[ticks_x_pos.length - 1] = band_struct.distance[idx]
224
- } else if (branches_set.size === 0 || (this_branch && branches_set.has(this_branch))) {
225
- tick_labels.push(point.label)
226
- ticks_x_pos.push(band_struct.distance[idx])
227
- }
228
-
229
- prev_label = point.label
230
- prev_branch = this_branch
231
- }
232
-
233
- return [ticks_x_pos, tick_labels.map(pretty_sym_point)]
234
- }
235
-
236
- // Convert frequencies from THz to specified units.
237
- export function convert_frequencies(
238
- frequencies: number[],
239
- unit: types.FrequencyUnit = `THz`,
240
- ): number[] {
241
- const conversion_factors: Record<types.FrequencyUnit, number> = {
242
- THz: 1,
243
- eV: THz_TO_EV,
244
- meV: THz_TO_MEV,
245
- Ha: THz_TO_HA,
246
- 'cm-1': THz_TO_CM,
247
- }
248
-
249
- const factor = conversion_factors[unit]
250
- if (!factor) {
251
- const valid_units = Object.keys(conversion_factors).join(`, `)
252
- throw new Error(`Invalid unit: ${unit}. Must be one of ${valid_units}`)
253
- }
254
-
255
- return frequencies.map((freq) => freq * factor)
256
- }
257
-
258
- // Normalize DOS densities according to specified mode.
259
- export function normalize_densities(
260
- densities: number[],
261
- freqs_or_energies: number[],
262
- mode: types.NormalizationMode,
263
- ): number[] {
264
- if (!mode) return densities
265
-
266
- const normalized = [...densities]
267
-
268
- if (mode === `max`) {
269
- const max_val = Math.max(...normalized)
270
- if (max_val === 0) return normalized
271
- return normalized.map((dens) => dens / max_val)
272
- } else if (mode === `sum`) {
273
- const sum = normalized.reduce((acc, d) => acc + d, 0)
274
- if (sum === 0) return normalized
275
- return normalized.map((dens) => dens / sum)
276
- } else if (mode === `integral`) {
277
- if (freqs_or_energies.length < 2) return normalized
278
- const bin_width = freqs_or_energies[1] - freqs_or_energies[0]
279
- if (bin_width === 0) return normalized
280
- const sum = normalized.reduce((acc, d) => acc + d, 0)
281
- if (sum === 0) return normalized
282
- return normalized.map((dens) => dens / (sum * bin_width))
283
- }
284
-
285
- return normalized
286
- }
287
-
288
- // Simple LRU cache for Gaussian smearing results
289
- // Key: hash of (frequencies, densities, sigma), Value: smeared densities
290
- const SMEARING_CACHE_MAX_SIZE = 10
291
- const smearing_cache = new Map<string, number[]>()
292
-
293
- // FNV-1a hash for number arrays (fast, good distribution, O(n))
294
- function fnv1a_hash(arr: number[]): number {
295
- let hash = 2166136261 // FNV offset basis
296
- for (const val of arr) {
297
- // Convert float to int32 bits for consistent hashing
298
- const bits = new Float64Array([val])
299
- const int_view = new Uint32Array(bits.buffer)
300
- hash ^= int_view[0]
301
- hash = Math.imul(hash, 16777619) // FNV prime
302
- hash ^= int_view[1]
303
- hash = Math.imul(hash, 16777619)
304
- }
305
- return hash >>> 0 // Ensure unsigned
306
- }
307
-
308
- // Generate cache key using FNV-1a hash over full arrays (O(n), low collision risk)
309
- function generate_smearing_cache_key(
310
- freqs_or_energies: number[],
311
- densities: number[],
312
- sigma: number,
313
- ): string {
314
- const len = freqs_or_energies.length
315
- if (len === 0) return `0:${sigma.toFixed(6)}:0:0`
316
- return `${len}:${sigma.toFixed(6)}:${fnv1a_hash(freqs_or_energies).toString(16)}:${fnv1a_hash(
317
- densities,
318
- ).toString(16)}`
319
- }
320
-
321
- // Core Gaussian smearing computation (unmemoized)
322
- function apply_gaussian_smearing_core(
323
- freqs_or_energies: number[],
324
- densities: number[],
325
- sigma: number,
326
- ): number[] {
327
- const orig_sum = densities.reduce((acc, d) => acc + d, 0)
328
- if (sigma <= 0 || orig_sum === 0) return densities
329
-
330
- const smeared = Array(densities.length).fill(0)
331
- const truncation_width = 4 // Truncate Gaussian at ±4σ (contribution < 0.01%)
332
-
333
- for (let idx = 0; idx < freqs_or_energies.length; idx++) {
334
- const energy = freqs_or_energies[idx]
335
- const cutoff = truncation_width * sigma
336
-
337
- for (let jdx = 0; jdx < freqs_or_energies.length; jdx++) {
338
- const e_j = freqs_or_energies[jdx]
339
- const delta = Math.abs(energy - e_j)
340
-
341
- // Skip points beyond truncation width
342
- if (delta > cutoff) continue
343
-
344
- const gaussian = Math.exp(-((energy - e_j) ** 2) / (2 * sigma ** 2))
345
- smeared[idx] += densities[jdx] * gaussian
346
- }
347
- }
348
-
349
- // Normalize to preserve integral
350
- const smeared_sum = smeared.reduce((acc, d) => acc + d, 0)
351
- if (smeared_sum === 0) return densities
352
- const normalization = orig_sum / smeared_sum
353
- return smeared.map((dens) => dens * normalization)
354
- }
355
-
356
- // Apply Gaussian smearing to DOS densities with memoization.
357
- // Uses truncated Gaussian (±4σ) for O(n·w) complexity instead of O(n²).
358
- // Results are cached using an LRU cache to avoid recomputation on reactive updates.
359
- export function apply_gaussian_smearing(
360
- freqs_or_energies: number[],
361
- densities: number[],
362
- sigma: number,
363
- ): number[] {
364
- // Fast path: no smearing needed
365
- if (sigma <= 0) return densities
366
-
367
- const cache_key = generate_smearing_cache_key(freqs_or_energies, densities, sigma)
368
-
369
- // Check cache
370
- const cached = smearing_cache.get(cache_key)
371
- if (cached) {
372
- // Move to end (LRU behavior: most recently used last)
373
- smearing_cache.delete(cache_key)
374
- smearing_cache.set(cache_key, cached)
375
- return cached
376
- }
377
-
378
- // Compute and cache
379
- const result = apply_gaussian_smearing_core(freqs_or_energies, densities, sigma)
380
-
381
- // Evict oldest entry if cache is full (LRU: first entry is oldest)
382
- if (smearing_cache.size >= SMEARING_CACHE_MAX_SIZE) {
383
- const oldest_key = smearing_cache.keys().next().value
384
- if (oldest_key !== undefined) smearing_cache.delete(oldest_key)
385
- }
386
-
387
- smearing_cache.set(cache_key, result)
388
- return result
389
- }
390
-
391
- // Clear the smearing cache (useful for testing or memory management)
392
- export function clear_smearing_cache(): void {
393
- smearing_cache.clear()
394
- }
395
-
396
- // Type guards for pymatgen qpoint formats
397
- const is_vec3 = (val: unknown): val is Vec3 =>
398
- Array.isArray(val) && val.length >= 3 && val.slice(0, 3).every(Number.isFinite)
399
-
400
- interface PymatgenKpoint {
401
- frac_coords: Vec3
402
- label?: string | null
403
- }
404
- const is_kpoint = (val: unknown): val is PymatgenKpoint =>
405
- !!val && typeof val === `object` && `frac_coords` in val && is_vec3(val.frac_coords)
406
-
407
- const is_pymatgen_format = (obj: Record<string, unknown>): boolean => {
408
- // Check for explicit pymatgen markers
409
- if (typeof obj[`@class`] === `string` || typeof obj[`@module`] === `string`) {
410
- return true
411
- }
412
- // Check for pymatgen-style qpoints (phonon) or kpoints (electronic) without branches
413
- const points = obj.qpoints ?? obj.kpoints
414
- if (Array.isArray(points) && points.length > 0 && !Array.isArray(obj.branches)) {
415
- return is_vec3(points[0]) || is_kpoint(points[0])
416
- }
417
- return false
418
- }
419
-
420
- // Extract frac_coords/label from pymatgen qpoint, matching label from labels_dict if needed
421
- const parse_qpoint = (
422
- qpt: unknown,
423
- labels_dict?: Record<string, Vec3>,
424
- ): types.QPoint | null => {
425
- const frac_coords = is_vec3(qpt)
426
- ? ([qpt[0], qpt[1], qpt[2]] as Vec3)
427
- : is_kpoint(qpt)
428
- ? qpt.frac_coords
429
- : null
430
- if (!frac_coords) return null
431
-
432
- const label =
433
- (is_kpoint(qpt) && typeof qpt.label === `string` && qpt.label) ||
434
- Object.entries(labels_dict ?? {}).find(
435
- ([, c]) => euclidean_dist(frac_coords, c) < 1e-4,
436
- )?.[0] ||
437
- null
438
- return { label, frac_coords }
439
- }
440
-
441
- // Inverse conversion factors (derived from THz_TO_* for consistency)
442
- const EV_TO_THZ = 1 / THz_TO_EV
443
- const CM_TO_THZ = 1 / THz_TO_CM
444
-
445
- // Spin key constants for pymatgen spin-polarized data
446
- const SPIN_UP_KEYS = [`1`, `Spin.up`]
447
- const SPIN_DOWN_KEYS = [`-1`, `Spin.down`]
448
-
449
- // Extract both spin channels from pymatgen spin-keyed data.
450
- // Returns { up: T, down: T | null } where down is null for non-spin-polarized data.
451
- export function extract_spin_channels<T>(data: unknown): { up: T; down: T | null } | null {
452
- if (Array.isArray(data)) return { up: data as T, down: null }
453
- if (data && typeof data === `object`) {
454
- const record = data as Record<string, T>
455
- let spin_up: T | null = null
456
- let spin_down: T | null = null
457
-
458
- // Extract spin-up channel
459
- for (const key of SPIN_UP_KEYS) {
460
- if (key in record) {
461
- spin_up = record[key]
462
- break
463
- }
464
- }
465
- // Extract spin-down channel
466
- for (const key of SPIN_DOWN_KEYS) {
467
- if (key in record) {
468
- spin_down = record[key]
469
- break
470
- }
471
- }
472
-
473
- // Fall back to first key if no spin-up key found
474
- if (spin_up === null) {
475
- const keys = Object.keys(record)
476
- if (keys.length > 0) spin_up = record[keys[0]]
477
- }
478
-
479
- if (spin_up === null) return null
480
- return { up: spin_up, down: spin_down }
481
- }
482
- return null
483
- }
484
-
485
- // Convert pymatgen PhononBandStructureSymmLine or BandStructure to matterviz format
486
- function convert_pymatgen_band_structure(
487
- pmg: Record<string, unknown>,
488
- ): types.BaseBandStructure | null {
489
- // Support both qpoints (phonon) and kpoints (electronic)
490
- const raw_qpts = (pmg.qpoints ?? pmg.kpoints) as unknown[] | undefined
491
-
492
- // Handle bands in multiple formats:
493
- // 1. Standard pymatgen: bands as dict with spin keys {1: [[...], ...]}
494
- // 2. Custom phonon format: frequencies_cm as 2D array [[...], ...]
495
- // 3. Already normalized: bands as 2D array [[...], ...]
496
- const spin_channels = extract_spin_channels<number[][]>(pmg.bands)
497
- let raw_bands = spin_channels?.up ?? null
498
- let raw_spin_down_bands = spin_channels?.down ?? null
499
- const has_frequencies_cm = Array.isArray(pmg.frequencies_cm)
500
- if (!raw_bands && has_frequencies_cm) {
501
- // Phonon format: frequencies_cm is [n_qpoints x n_branches] - needs transpose
502
- const freqs = pmg.frequencies_cm as number[][]
503
- if (freqs.length > 0 && Array.isArray(freqs[0])) {
504
- // Transpose: [n_qpoints x n_branches] -> [n_branches x n_qpoints]
505
- raw_bands = Array.from({ length: freqs[0].length }, (_, band_idx) =>
506
- freqs.map((qpt_freqs) => qpt_freqs[band_idx]),
507
- )
508
- raw_spin_down_bands = null
509
- }
510
- }
511
-
512
- const labels_dict = pmg.labels_dict as Record<string, Vec3> | undefined
513
- const lattice_rec = pmg.lattice_rec as { matrix?: Matrix3x3 } | undefined
514
- // Determine unit: cm-1 if frequencies_cm present, else check explicit unit or default to THz
515
- const unit =
516
- (pmg.unit as string | undefined)?.toLowerCase() ?? (has_frequencies_cm ? `cm-1` : `thz`)
517
-
518
- if (
519
- !Array.isArray(raw_qpts) ||
520
- !Array.isArray(raw_bands) ||
521
- !raw_qpts.length ||
522
- !raw_bands.length
523
- )
524
- return null
525
-
526
- const qpoints = raw_qpts
527
- .map((qpoint) => parse_qpoint(qpoint, labels_dict))
528
- .filter((qpoint): qpoint is types.QPoint => qpoint !== null)
529
- if (!qpoints.length) return null
530
-
531
- // Step distances and discontinuity detection (5x median threshold)
532
- const steps = qpoints
533
- .slice(1)
534
- .map((qpoint, idx) => euclidean_dist(qpoints[idx].frac_coords, qpoint.frac_coords))
535
- const sorted = steps.slice().sort((a, b) => a - b)
536
- const threshold = (sorted[Math.floor(sorted.length / 2)] ?? 0) * 5
537
- const disc_set = new Set(
538
- steps
539
- .map((step, idx) => (step > threshold ? idx + 1 : -1))
540
- .filter((disc_idx) => disc_idx >= 0),
541
- )
542
-
543
- // Cumulative distance (skip discontinuities)
544
- const distance = steps.reduce(
545
- (acc, step, idx) => [...acc, disc_set.has(idx + 1) ? acc[idx] : acc[idx] + step],
546
- [0],
547
- )
548
-
549
- // Use pymatgen's branches if available - they correctly handle discontinuities
550
- // Otherwise, infer branches from discontinuities (robust fallback covering all qpoints)
551
- const pmg_branches = pmg.branches as types.Branch[] | undefined
552
- let branches: types.Branch[] = []
553
-
554
- if (Array.isArray(pmg_branches) && pmg_branches.length > 0) {
555
- // Validate and use pymatgen branches directly
556
- branches = pmg_branches.filter(
557
- (branch) =>
558
- typeof branch.start_index === `number` &&
559
- typeof branch.end_index === `number` &&
560
- branch.start_index >= 0 &&
561
- branch.end_index < qpoints.length &&
562
- branch.start_index <= branch.end_index,
563
- )
564
- }
565
-
566
- // Fallback: infer branches from discontinuities when none provided or all invalid
567
- if (branches.length === 0) {
568
- console.warn(
569
- `Band structure missing 'branches' field - inferring from path discontinuities`,
570
- )
571
- // Discontinuity indices mark points where the path jumps (disc before that index)
572
- // Create continuous segments between discontinuities
573
- const disc_indices = [...disc_set].sort((a, b) => a - b)
574
- // Segment boundaries: [0, first_disc), [first_disc, second_disc), ..., [last_disc, end]
575
- const segment_starts = [0, ...disc_indices]
576
- const segment_ends = [...disc_indices.map((idx) => idx - 1), qpoints.length - 1]
577
-
578
- branches = segment_starts
579
- .map((start, idx) => {
580
- const end = segment_ends[idx]
581
- const start_label = qpoints[start]?.label ?? `?`
582
- const end_label = qpoints[end]?.label ?? `?`
583
- return {
584
- start_index: start,
585
- end_index: end,
586
- name: `${start_label}-${end_label}`,
587
- }
588
- })
589
- .filter((branch) => branch.start_index <= branch.end_index)
590
- }
591
-
592
- if (!branches.length) {
593
- branches.push({ start_index: 0, end_index: qpoints.length - 1, name: `path` })
594
- }
595
-
596
- // Convert bands to THz based on input unit
597
- const convert_to_thz = (val: number): number => {
598
- if (unit === `ev`) return val * EV_TO_THZ
599
- if (unit === `cm-1`) return val * CM_TO_THZ
600
- return val // THz (default) - no conversion
601
- }
602
-
603
- const converted_bands = raw_bands.map((band) => band.map(convert_to_thz))
604
- const valid_spin_down_bands =
605
- Array.isArray(raw_spin_down_bands) &&
606
- raw_spin_down_bands.length === raw_bands.length &&
607
- raw_spin_down_bands.every(
608
- (band, band_idx) => Array.isArray(band) && band.length === raw_bands[band_idx]?.length,
609
- )
610
- ? raw_spin_down_bands
611
- : null
612
- const converted_spin_down_bands = valid_spin_down_bands?.map((band) =>
613
- band.map(convert_to_thz),
614
- )
615
-
616
- return {
617
- qpoints,
618
- branches,
619
- distance,
620
- bands: converted_bands,
621
- spin_down_bands: converted_spin_down_bands,
622
- nb_bands: raw_bands.length,
623
- labels_dict: labels_dict ?? {},
624
- recip_lattice: {
625
- matrix: lattice_rec?.matrix ?? [
626
- [1, 0, 0],
627
- [0, 1, 0],
628
- [0, 0, 1],
629
- ],
630
- },
631
- }
632
- }
633
-
634
- export function normalize_band_structure(bs: unknown): types.BaseBandStructure | null {
635
- if (!bs || typeof bs !== `object`) return null
636
-
637
- const band_struct = bs as Record<string, unknown>
638
-
639
- // Check if this is pymatgen format and convert if so
640
- if (is_pymatgen_format(band_struct)) {
641
- return convert_pymatgen_band_structure(band_struct)
642
- }
643
-
644
- // Standard matterviz format validation
645
- const { qpoints, branches, bands, distance } =
646
- band_struct as Partial<types.BaseBandStructure>
647
- if (
648
- !Array.isArray(qpoints) ||
649
- !Array.isArray(branches) ||
650
- !Array.isArray(bands) ||
651
- !Array.isArray(distance)
652
- )
653
- return null
654
-
655
- // Validate array lengths and branch indices
656
- const n_qpts = qpoints.length
657
- if (
658
- distance.length !== n_qpts ||
659
- bands.some((band) => !Array.isArray(band) || band.length !== n_qpts) ||
660
- branches.some(
661
- (branch) =>
662
- typeof branch.start_index !== `number` ||
663
- typeof branch.end_index !== `number` ||
664
- branch.start_index < 0 ||
665
- branch.end_index >= n_qpts ||
666
- branch.start_index > branch.end_index,
667
- )
668
- )
669
- return null
670
-
671
- return band_struct as unknown as types.BaseBandStructure
672
- }
673
-
674
- // Validate and normalize a DOS object.
675
- // Supports both matterviz and pymatgen formats.
676
- // Also auto-detects and converts cm⁻¹ to THz for legacy data (disable with auto_convert_units: false).
677
- export function normalize_dos(
678
- dos: unknown,
679
- options: { auto_convert_units?: boolean } = {},
680
- ): types.DosData | null {
681
- const { auto_convert_units = true } = options
682
- if (!dos || typeof dos !== `object`) return null
683
-
684
- const dos_obj = dos as Record<string, unknown>
685
-
686
- // Check for pymatgen format (has @class or @module)
687
- const is_pymatgen =
688
- typeof dos_obj[`@class`] === `string` || typeof dos_obj[`@module`] === `string`
689
-
690
- const { frequencies, energies, spin_polarized } = dos_obj
691
-
692
- // Handle densities as either array or dict with spin keys (pymatgen format)
693
- // Pymatgen stores densities as {1: [...], -1: [...]} or {"Spin.up": [...], ...}
694
- const spin_channels = extract_spin_channels<number[]>(dos_obj.densities)
695
- if (!spin_channels) return null
696
-
697
- const densities = spin_channels.up
698
- // Use extracted spin-down or fallback to explicit field (for already-normalized DosData)
699
- const spin_down_densities =
700
- spin_channels.down ?? (dos_obj.spin_down_densities as number[] | undefined) ?? null
701
-
702
- if (!Array.isArray(densities)) return null
703
-
704
- // Phonon DOS: has frequencies
705
- if (Array.isArray(frequencies)) {
706
- if (frequencies.length !== densities.length) return null
707
-
708
- // Auto-detect if frequencies are in cm⁻¹ instead of THz (unless disabled)
709
- // Typical phonon frequencies are < 50 THz for most materials
710
- // If max frequency > 100, it's almost certainly in cm⁻¹
711
- const max_freq = Math.max(...(frequencies as number[]))
712
- let final_frequencies = frequencies as number[]
713
-
714
- if (auto_convert_units && max_freq > 100) {
715
- // Likely in cm⁻¹, convert to THz
716
- final_frequencies = (frequencies as number[]).map((frequency) => frequency * CM_TO_THZ)
717
- console.warn(
718
- `Phonon DOS frequencies appear to be in cm⁻¹ (max: ${max_freq.toFixed(1)}). ` +
719
- `Converting to THz (max: ${(max_freq * CM_TO_THZ).toFixed(1)} THz).`,
720
- )
721
- }
722
-
723
- return { type: `phonon`, frequencies: final_frequencies, densities }
724
- }
725
-
726
- // Electronic DOS: has energies
727
- if (Array.isArray(energies)) {
728
- if (energies.length !== densities.length) return null
729
- // Detect spin-polarized from data if not explicitly set
730
- const is_spin_polarized =
731
- (spin_polarized as boolean | undefined) ??
732
- (spin_down_densities !== null && spin_down_densities.length === densities.length)
733
- return {
734
- type: `electronic`,
735
- energies,
736
- densities,
737
- spin_down_densities: is_spin_polarized ? (spin_down_densities ?? undefined) : undefined,
738
- spin_polarized: is_spin_polarized,
739
- }
740
- }
741
-
742
- // For pymatgen format, log a helpful message if format wasn't recognized
743
- if (is_pymatgen) {
744
- console.warn(
745
- `Pymatgen DOS format detected but missing required fields. ` +
746
- `Expected 'frequencies' (phonon) or 'energies' (electronic) arrays.`,
747
- )
748
- }
749
-
750
- return null
751
- }
752
-
753
- // Extract k-path points from band structure and convert to reciprocal space coordinates
754
- // Accepts a reciprocal lattice matrix (should include 2π factor for consistency with BZ)
755
- // Handles both matterviz format (qpoints as objects) and normalized pymatgen format
756
- // Optionally wraps fractional coordinates to first BZ (default: true)
757
- export function extract_k_path_points(
758
- band_struct: types.BaseBandStructure,
759
- recip_lattice_matrix: Matrix3x3,
760
- options: { wrap_to_bz?: boolean } = {},
761
- ): Vec3[] {
762
- const { wrap_to_bz = true } = options
763
- if (!band_struct?.qpoints || !recip_lattice_matrix) return []
764
-
765
- if (
766
- recip_lattice_matrix.length !== 3 ||
767
- recip_lattice_matrix.some((row) => row?.length !== 3)
768
- )
769
- throw new Error(`reciprocal_lattice_matrix must be a 3×3 matrix`)
770
-
771
- const [[m00, m01, m02], [m10, m11, m12], [m20, m21, m22]] = recip_lattice_matrix
772
-
773
- return band_struct.qpoints.map((qpoint): Vec3 => {
774
- let [x, y, z] = qpoint.frac_coords
775
- // Wrap to first BZ if enabled (handles [0,1] vs [-0.5,0.5] convention difference)
776
- if (wrap_to_bz) {
777
- x = centered_frac(x)
778
- y = centered_frac(y)
779
- z = centered_frac(z)
780
- }
781
- const kx = x * m00 + y * m10 + z * m20
782
- const ky = x * m01 + y * m11 + z * m21
783
- const kz = x * m02 + y * m12 + z * m22
784
- return [kx, ky, kz]
785
- })
786
- }
787
-
788
- // Find the q-point index closest to a given distance along the band structure path
789
- export function find_qpoint_at_distance(
790
- band_struct: types.BaseBandStructure,
791
- target: number,
792
- ): number | null {
793
- const { distance } = band_struct
794
- if (!distance?.length) return null
795
-
796
- return distance.reduce(
797
- (closest: number, dist: number, idx: number) =>
798
- Math.abs(dist - target) < Math.abs(distance[closest] - target) ? idx : closest,
799
- 0,
800
- )
801
- }
802
-
803
- // Find q-point index from rescaled x-coordinate (used in band structure plots)
804
- // This handles the case where the plot uses custom x-axis scaling per segment
805
- export function find_qpoint_at_rescaled_x(
806
- band_struct: types.BaseBandStructure,
807
- rescaled_x: number,
808
- x_positions: Record<string, [number, number]>,
809
- ): number | null {
810
- if (!band_struct?.branches?.length || !x_positions) return null
811
-
812
- // Find which segment contains this x coordinate
813
- for (const branch of band_struct.branches) {
814
- const start_idx = branch.start_index
815
- const end_idx = branch.end_index
816
- const start_label = band_struct.qpoints[start_idx]?.label ?? undefined
817
- const end_label = band_struct.qpoints[end_idx]?.label ?? undefined
818
- const segment_key = get_segment_key(start_label, end_label)
819
-
820
- const segment_range = x_positions[segment_key]
821
- if (!segment_range) continue
822
-
823
- const [x_start, x_end] = segment_range
824
-
825
- // Check if discontinuity (zero-length segment)
826
- const is_discontinuity = Math.abs(x_end - x_start) < 1e-6
827
- if (is_discontinuity) {
828
- // For discontinuities, check if x is exactly at this point
829
- if (Math.abs(rescaled_x - x_start) < 1e-6) {
830
- return start_idx
831
- }
832
- continue
833
- }
834
-
835
- // Check if x is within this segment (with small tolerance for edges)
836
- if (rescaled_x >= x_start - 1e-6 && rescaled_x <= x_end + 1e-6) {
837
- // Map from rescaled x back to original distance
838
- const segment_distances = band_struct.distance.slice(start_idx, end_idx + 1)
839
- const dist_min = segment_distances[0]
840
- const dist_max = segment_distances.at(-1) ?? dist_min
841
- const dist_range = dist_max - dist_min
842
-
843
- // Handle zero-length segments
844
- if (dist_range === 0) {
845
- return start_idx
846
- }
847
-
848
- // Inverse of the scaling: x = x_start + ((dist - dist_min) / dist_range) * (x_end - x_start)
849
- // Solving for dist: dist = dist_min + ((x - x_start) / (x_end - x_start)) * dist_range
850
- const normalized_x = (rescaled_x - x_start) / (x_end - x_start)
851
- const target_dist = dist_min + normalized_x * dist_range
852
-
853
- // Find closest qpoint in this branch to the target distance
854
- let closest_idx = start_idx
855
- let min_diff = Math.abs(band_struct.distance[start_idx] - target_dist)
856
-
857
- for (let idx = start_idx; idx <= end_idx; idx++) {
858
- const diff = Math.abs(band_struct.distance[idx] - target_dist)
859
- if (diff < min_diff) {
860
- min_diff = diff
861
- closest_idx = idx
862
- }
863
- }
864
-
865
- return closest_idx
866
- }
867
- }
868
-
869
- // Fallback: find closest labeled point
870
- let closest_idx = 0
871
- let min_dist = Infinity
872
-
873
- for (const branch of band_struct.branches) {
874
- const start_idx = branch.start_index
875
- const end_idx = branch.end_index
876
- const start_label = band_struct.qpoints[start_idx]?.label ?? undefined
877
- const end_label = band_struct.qpoints[end_idx]?.label ?? undefined
878
- const segment_key = get_segment_key(start_label, end_label)
879
- const segment_range = x_positions[segment_key]
880
-
881
- if (!segment_range) continue
882
-
883
- const [x_start, x_end] = segment_range
884
-
885
- for (const [x_pos, idx] of [
886
- [x_start, start_idx],
887
- [x_end, end_idx],
888
- ] as const) {
889
- const dist = Math.abs(rescaled_x - x_pos)
890
- if (dist < min_dist) {
891
- min_dist = dist
892
- closest_idx = idx
893
- }
894
- }
895
- }
896
-
897
- return closest_idx
898
- }
899
-
900
- // Type definitions for pymatgen DOS formats
901
- // Densities can be spin-keyed: {1: number[], -1: number[]} or {"Spin.up": number[], ...}
902
- type SpinDensities = Record<string, number[]>
903
-
904
- // Pymatgen Dos base class format
905
- export interface PymatgenDos {
906
- '@class': string
907
- '@module': string
908
- energies: number[]
909
- densities: SpinDensities | number[]
910
- efermi: number
911
- }
912
-
913
- // Pymatgen CompleteDos format (includes projected DOS)
914
- export interface PymatgenCompleteDos extends PymatgenDos {
915
- '@class': `CompleteDos` | `LobsterCompleteDos`
916
- structure?: Record<string, unknown>
917
- pdos?: Record<string, SpinDensities>[]
918
- atom_dos?: Record<string, PymatgenDos>
919
- spd_dos?: Record<string, PymatgenDos>
920
- }
921
-
922
- // Extract projected DOS from pymatgen CompleteDos format.
923
- // Returns a dict of label → DosData for each atom or orbital.
924
- // filter_keys: optional list of keys to include (e.g., ["Fe", "O"] for atoms or ["s", "p", "d"] for orbitals)
925
- export function extract_pdos(
926
- dos: unknown,
927
- pdos_type: types.PdosType,
928
- filter_keys?: string[],
929
- ): Record<string, types.ElectronicDos> | null {
930
- if (!dos || typeof dos !== `object`) return null
931
-
932
- const dos_obj = dos as Record<string, unknown>
933
-
934
- // Get the appropriate projected DOS dict
935
- const pdos_dict =
936
- pdos_type === `atom`
937
- ? (dos_obj.atom_dos as Record<string, PymatgenDos> | undefined)
938
- : (dos_obj.spd_dos as Record<string, PymatgenDos> | undefined)
939
-
940
- if (!pdos_dict || typeof pdos_dict !== `object`) return null
941
-
942
- const result: Record<string, types.ElectronicDos> = {}
943
-
944
- for (const [key, nested_dos] of Object.entries(pdos_dict)) {
945
- // Apply filter if provided
946
- if (filter_keys && filter_keys.length > 0 && !filter_keys.includes(key)) continue
947
-
948
- if (!nested_dos || typeof nested_dos !== `object`) continue
949
-
950
- const energies = nested_dos.energies
951
- const spin_channels = extract_spin_channels<number[]>(nested_dos.densities)
952
-
953
- if (!Array.isArray(energies) || !spin_channels) continue
954
-
955
- const densities = spin_channels.up
956
- if (!Array.isArray(densities) || energies.length !== densities.length) continue
957
-
958
- const is_spin_polarized =
959
- spin_channels.down !== null && spin_channels.down.length === densities.length
960
-
961
- result[key] = {
962
- type: `electronic`,
963
- energies,
964
- densities,
965
- spin_down_densities: is_spin_polarized ? (spin_channels.down ?? undefined) : undefined,
966
- spin_polarized: is_spin_polarized,
967
- efermi: nested_dos.efermi,
968
- }
969
- }
970
-
971
- return Object.keys(result).length > 0 ? result : null
972
- }
973
-
974
- // Shift a single DOS object's energies by the given amount
975
- const shift_dos_energies = <T extends PymatgenDos>(dos: T, shift: number): T => ({
976
- ...dos,
977
- efermi: dos.efermi - shift,
978
- energies: dos.energies.map((energy) => energy - shift),
979
- })
980
-
981
- // Shift DOS energies relative to Fermi energy so E_F = 0
982
- // Recursively shifts nested DOS in atom_dos and spd_dos for consistency
983
- export function shift_to_fermi(dos: PymatgenCompleteDos): PymatgenCompleteDos {
984
- const shift = dos.efermi
985
-
986
- // Shift root DOS energies using the shared helper
987
- const shifted_root = shift_dos_energies(dos, shift)
988
-
989
- // Shift nested atom_dos if present
990
- const atom_dos = dos.atom_dos
991
- ? Object.fromEntries(
992
- Object.entries(dos.atom_dos).map(([key, nested_dos]) => [
993
- key,
994
- shift_dos_energies(nested_dos, shift),
995
- ]),
996
- )
997
- : undefined
998
-
999
- // Shift nested spd_dos if present
1000
- const spd_dos = dos.spd_dos
1001
- ? Object.fromEntries(
1002
- Object.entries(dos.spd_dos).map(([key, nested_dos]) => [
1003
- key,
1004
- shift_dos_energies(nested_dos, shift),
1005
- ]),
1006
- )
1007
- : undefined
1008
-
1009
- return {
1010
- ...shifted_root,
1011
- efermi: 0, // Explicitly set to 0 (shift_dos_energies would give efermi - shift)
1012
- ...(atom_dos && { atom_dos }),
1013
- ...(spd_dos && { spd_dos }),
1014
- }
1015
- }
1016
-
1017
- // Generate an SVG path for a fat band ribbon.
1018
- // Creates a closed polygon by tracing the upper edge (y - half_width) forward,
1019
- // then tracing the lower edge (y + half_width) backward.
1020
- // Non-finite or non-positive widths are clamped to 0.
1021
- export function generate_ribbon_path(
1022
- x_values: number[],
1023
- y_values: number[],
1024
- width_values: number[],
1025
- x_scale_fn: (x: number) => number,
1026
- y_scale_fn: (y: number) => number,
1027
- max_width_px: number,
1028
- scale: number = 1,
1029
- ): string {
1030
- const len = x_values.length
1031
- if (len < 2 || len !== y_values.length || len !== width_values.length) return ``
1032
-
1033
- // Normalize width values to [0, 1] range based on the max positive finite value
1034
- const finite_positive_widths = width_values.filter(
1035
- (width) => Number.isFinite(width) && width > 0,
1036
- )
1037
- if (finite_positive_widths.length === 0) return ``
1038
- const max_width_val = Math.max(...finite_positive_widths)
1039
-
1040
- // Build upper edge path (forward direction)
1041
- const upper_points: string[] = []
1042
- const lower_points: string[] = []
1043
-
1044
- for (let idx = 0; idx < x_values.length; idx++) {
1045
- const x_px = x_scale_fn(x_values[idx])
1046
- const y_data = y_values[idx]
1047
- const raw_width = width_values[idx] ?? 0
1048
- const width_normalized =
1049
- Number.isFinite(raw_width) && raw_width > 0 ? raw_width / max_width_val : 0
1050
- const half_width_px = width_normalized * max_width_px * scale
1051
-
1052
- // In SVG, y increases downward, so upper edge has smaller y value
1053
- const y_upper_px = y_scale_fn(y_data) - half_width_px
1054
- const y_lower_px = y_scale_fn(y_data) + half_width_px
1055
-
1056
- upper_points.push(`${x_px.toFixed(2)},${y_upper_px.toFixed(2)}`)
1057
- lower_points.push(`${x_px.toFixed(2)},${y_lower_px.toFixed(2)}`)
1058
- }
1059
-
1060
- // Combine: upper edge forward, lower edge backward, close path
1061
- const path_parts = [
1062
- `M${upper_points[0]}`,
1063
- ...upper_points.slice(1).map((pt) => `L${pt}`),
1064
- ...lower_points.toReversed().map((pt) => `L${pt}`),
1065
- `Z`,
1066
- ]
1067
-
1068
- return path_parts.join(` `)
1069
- }
1070
-
1071
- // Extract efermi from a data source (band structure or DOS).
1072
- // Handles both single objects with an efermi field and dicts of objects.
1073
- // Returns undefined if no valid efermi is found or if the source is empty.
1074
- export function extract_efermi(data: unknown): number | undefined {
1075
- if (!data || typeof data !== `object`) return undefined
1076
- const obj = data as Record<string, unknown>
1077
-
1078
- // Direct efermi field on the object
1079
- if (`efermi` in obj && typeof obj.efermi === `number`) return obj.efermi
1080
-
1081
- // Dict of objects - try to get efermi from first value
1082
- const values = Object.values(obj)
1083
- if (values.length === 0) return undefined
1084
-
1085
- const first_val = values[0]
1086
- if (first_val && typeof first_val === `object`) {
1087
- const efermi = (first_val as Record<string, unknown>).efermi
1088
- if (typeof efermi === `number`) return efermi
1089
- }
1090
-
1091
- return undefined
1092
- }
1093
-
1094
- // Calculate fraction of |values| that are negative. Used to detect imaginary phonon modes.
1095
- export function negative_fraction(values: number[]): number {
1096
- let [neg, total] = [0, 0]
1097
- for (const val of values) {
1098
- if (!Number.isFinite(val)) continue
1099
- const abs_val = Math.abs(val)
1100
- total += abs_val
1101
- if (val < 0) neg += abs_val
1102
- }
1103
- return total > 0 ? neg / total : 0
1104
- }
1105
-
1106
- // Check if raw band structure input has electronic markers (efermi, kpoints, or electronic @class).
1107
- // Must be called on raw input before normalization since these fields aren't preserved.
1108
- function is_electronic_band_struct(bs: unknown): boolean {
1109
- if (!bs || typeof bs !== `object`) return false
1110
- const obj = bs as Record<string, unknown>
1111
- // Electronic band structures have efermi field
1112
- if (`efermi` in obj && typeof obj.efermi === `number`) return true
1113
- // Pymatgen electronic format uses kpoints (not qpoints)
1114
- if (`kpoints` in obj && Array.isArray(obj.kpoints) && obj.kpoints.length > 0) {
1115
- return true
1116
- }
1117
- // Pymatgen @class: BandStructure* but not Phonon*
1118
- const raw_class = obj[`@class`]
1119
- const py_class_name = typeof raw_class === `string` ? raw_class : ``
1120
- if (py_class_name.startsWith(`BandStructure`) && !py_class_name.includes(`Phonon`)) {
1121
- return true
1122
- }
1123
- return false
1124
- }
1125
-
1126
- // Compute frequency/energy range from bands and DOS. Clamps phonon min to 0 if noise < 0.5%.
1127
- export function compute_frequency_range(
1128
- band_structs: unknown,
1129
- doses: unknown,
1130
- padding_factor = 0.02,
1131
- ): [number, number] | undefined {
1132
- let [min_val, max_val, is_phonon] = [Infinity, -Infinity, false]
1133
- const all_freqs: number[] = []
1134
-
1135
- // Check raw band_structs for electronic markers before normalization
1136
- // (normalized structures always have qpoints, so we can't detect from them)
1137
- let has_electronic_bs = false
1138
- // Support both qpoints (phonon) and kpoints (electronic) to detect single vs dict
1139
- const is_single_bs =
1140
- band_structs &&
1141
- typeof band_structs === `object` &&
1142
- (`qpoints` in band_structs || `kpoints` in band_structs)
1143
- if (band_structs && typeof band_structs === `object`) {
1144
- // Single structure check
1145
- if (is_electronic_band_struct(band_structs)) {
1146
- has_electronic_bs = true
1147
- } else if (!is_single_bs) {
1148
- // Dict of band structures - check each value
1149
- for (const bs_val of Object.values(band_structs)) {
1150
- if (is_electronic_band_struct(bs_val)) {
1151
- has_electronic_bs = true
1152
- break
1153
- }
1154
- }
1155
- }
1156
- }
1157
-
1158
- const bs_list = band_structs
1159
- ? is_single_bs
1160
- ? [normalize_band_structure(band_structs)]
1161
- : Object.values(band_structs as object).map(normalize_band_structure)
1162
- : []
1163
-
1164
- // If band structures exist and aren't electronic, mark as phonon
1165
- const has_band_structs = bs_list.some(Boolean)
1166
- if (has_band_structs && !has_electronic_bs) is_phonon = true
1167
-
1168
- for (const bs of bs_list) {
1169
- if (!bs) continue
1170
- for (const band of bs.bands) {
1171
- for (const val of band) {
1172
- if (!Number.isFinite(val)) continue
1173
- all_freqs.push(val)
1174
- min_val = Math.min(min_val, val)
1175
- max_val = Math.max(max_val, val)
1176
- }
1177
- }
1178
- }
1179
-
1180
- const dos_list = doses
1181
- ? `densities` in (doses as object)
1182
- ? [normalize_dos(doses)]
1183
- : Object.values(doses as object).map((dos) => normalize_dos(dos))
1184
- : []
1185
- for (const dos of dos_list) {
1186
- if (!dos) continue
1187
- // DOS type detection: explicit type field is authoritative
1188
- if (dos.type === `phonon`) is_phonon = true
1189
- if (dos.type === `electronic`) is_phonon = false
1190
- for (const val of dos.type === `phonon` ? dos.frequencies : dos.energies) {
1191
- if (!Number.isFinite(val)) continue
1192
- all_freqs.push(val)
1193
- min_val = Math.min(min_val, val)
1194
- max_val = Math.max(max_val, val)
1195
- }
1196
- }
1197
-
1198
- if (!Number.isFinite(min_val) || !Number.isFinite(max_val)) return undefined
1199
- const clamp_min =
1200
- is_phonon &&
1201
- min_val < 0 && // clamp phonon noise to 0
1202
- negative_fraction(all_freqs) < IMAGINARY_MODE_NOISE_THRESHOLD
1203
- if (clamp_min) min_val = 0
1204
- // Calculate padding from (possibly clamped) range for consistency with Bands.svelte
1205
- const padding = (max_val - min_val) * padding_factor
1206
- return [min_val === 0 ? 0 : min_val - padding, max_val + padding]
1207
- }
1208
-
1209
- // Parse axis label: "Frequency (THz)" → { name: "Frequency", unit: "THz" }
1210
- function parse_axis_label(label: string): { name: string; unit?: string } {
1211
- const match = /^(.+?)\s*\(([^)]+)\)$/.exec(label)
1212
- return match ? { name: match[1], unit: match[2] } : { name: label }
1213
- }
1214
-
1215
- const format_tooltip_line = (name: string, value: string, unit?: string) =>
1216
- `${name}: ${value}${unit ? ` ${unit}` : ``}`
1217
-
1218
- // Format DOS tooltip content from axis labels and values
1219
- export function format_dos_tooltip(
1220
- x_formatted: string,
1221
- y_formatted: string,
1222
- label: string | null,
1223
- is_horizontal: boolean,
1224
- is_phonon: boolean,
1225
- units: types.FrequencyUnit,
1226
- x_axis_label: string,
1227
- y_axis_label: string,
1228
- num_series: number,
1229
- ): { title?: string; lines: string[] } {
1230
- const x_parsed = parse_axis_label(x_axis_label)
1231
- const y_parsed = parse_axis_label(y_axis_label)
1232
- const freq_defaults = {
1233
- name: is_phonon ? `Frequency` : `Energy`,
1234
- unit: is_phonon ? units : `eV`,
1235
- }
1236
-
1237
- const lines = is_horizontal
1238
- ? [
1239
- format_tooltip_line(
1240
- y_parsed.name || freq_defaults.name,
1241
- y_formatted,
1242
- y_parsed.unit || freq_defaults.unit,
1243
- ),
1244
- format_tooltip_line(x_parsed.name || `Density`, x_formatted),
1245
- ]
1246
- : [
1247
- format_tooltip_line(y_parsed.name || `Density`, y_formatted),
1248
- format_tooltip_line(
1249
- x_parsed.name || freq_defaults.name,
1250
- x_formatted,
1251
- x_parsed.unit || freq_defaults.unit,
1252
- ),
1253
- ]
1254
-
1255
- return { title: num_series > 1 && label ? label : undefined, lines }
1256
- }
1257
-
1258
- // Spin mode options for DOS visualization
1259
- export const SPIN_MODES = [
1260
- { value: `mirror`, label: `↕`, title: `Mirror: spin-up above, spin-down below zero` },
1261
- { value: `overlay`, label: `≡`, title: `Overlay: both spins on same axis` },
1262
- { value: `up_only`, label: `↑`, title: `Show spin-up only` },
1263
- { value: `down_only`, label: `↓`, title: `Show spin-down only` },
1264
- ] as const satisfies readonly { value: types.SpinMode; label: string; title: string }[]
1265
-
1266
- // Normalization mode options
1267
- export const NORMALIZATION_MODES = [
1268
- { value: null, label: `None` },
1269
- { value: `max`, label: `Max=1` },
1270
- { value: `sum`, label: `Sum=1` },
1271
- { value: `integral`, label: `∫=1` },
1272
- ] as const satisfies readonly { value: types.NormalizationMode; label: string }[]
1273
-
1274
- // Available frequency units for phonon DOS
1275
- export const FREQUENCY_UNITS: types.FrequencyUnit[] = [`THz`, `eV`, `meV`, `cm-1`, `Ha`]
1276
-
1277
- // Default values for DOS controls
1278
- export const DEFAULT_SPIN_MODE: types.SpinMode = `mirror`
1279
- export const DEFAULT_SIGMA = 0
1280
- export const DEFAULT_NORMALIZE: types.NormalizationMode = null
1281
- export const DEFAULT_UNITS: types.FrequencyUnit = `THz`
1282
-
1283
- // Format sigma with adaptive precision: 0→"0", <0.01→exp, <1→3dp, else→2dp
1284
- export function format_sigma(val: number): string {
1285
- if (val === 0) return `0`
1286
- if (val < 0.01) return val.toExponential(1)
1287
- return val.toFixed(val < 1 ? 3 : 2)
1288
- }
1289
-
1290
- // Validate sigma_range: ensures min < max, returns [0, 1] if invalid
1291
- export const validate_sigma_range = ([min, max]: [number, number]): [number, number] =>
1292
- Number.isFinite(min) && Number.isFinite(max) && min < max ? [min, max] : [0, 1]
1293
-
1294
- // Calculate slider step: 1/100th of range, or 0.01 fallback
1295
- export function calculate_sigma_step(range: [number, number]): number {
1296
- const [min, max] = validate_sigma_range(range)
1297
- return (max - min) / 100 || 0.01
1298
- }
1299
-
1300
- // === Band Tooltip Helpers ===
1301
-
1302
- // Per-point metadata for band tooltip display
1303
- export interface BandPointMeta extends Record<string, unknown> {
1304
- band_idx: number
1305
- spin: `up` | `down`
1306
- is_acoustic: boolean | null
1307
- nb_bands: number
1308
- frac_coords: Vec3 | null
1309
- qpoint_label: string | null
1310
- band_width: number | null
1311
- slope: number | null
1312
- }
1313
-
1314
- // Central difference for local slope (dω/dk or dE/dk).
1315
- // Uses forward/backward difference at endpoints, central difference for interior points.
1316
- export function compute_slope(x_vals: number[], y_vals: number[], idx: number): number | null {
1317
- const len = Math.min(x_vals.length, y_vals.length)
1318
- if (len < 2 || idx < 0 || idx >= len) return null
1319
- const lo = idx === 0 ? 0 : idx - 1
1320
- const hi = idx >= len - 1 ? len - 1 : idx + 1
1321
- const dx = x_vals[hi] - x_vals[lo]
1322
- return dx ? (y_vals[hi] - y_vals[lo]) / dx : null
1323
- }
1324
-
1325
- // Find Gamma-point indices (q ≈ integer lattice point) in a band structure.
1326
- // Returns indices of q-points whose fractional coordinates are all within 0.01 of integers.
1327
- export function find_gamma_indices(bs: types.BaseBandStructure): number[] {
1328
- const indices: number[] = []
1329
- for (let q_idx = 0; q_idx < bs.qpoints.length; q_idx++) {
1330
- const coords = bs.qpoints[q_idx]?.frac_coords
1331
- if (coords?.every((coord) => Math.abs(coord - Math.round(coord)) < 0.01)) {
1332
- indices.push(q_idx)
1333
- }
1334
- }
1335
- return indices
1336
- }
1337
-
1338
- // Threshold below which a band's frequency at Gamma is considered acoustic (THz).
1339
- // Assumes bands are stored in THz (normalize_band_structure converts to THz).
1340
- export const ACOUSTIC_FREQ_THRESHOLD = 0.5
1341
-
1342
- // Classify a band as acoustic based on near-zero frequency at Gamma points.
1343
- // Returns true (acoustic), false (optical), or null (no Gamma points → can't determine).
1344
- export function classify_acoustic(
1345
- bs: types.BaseBandStructure,
1346
- band_idx: number,
1347
- gamma_indices: number[],
1348
- threshold = ACOUSTIC_FREQ_THRESHOLD,
1349
- ): boolean | null {
1350
- if (gamma_indices.length === 0) return null
1351
- return gamma_indices.some(
1352
- (gamma_idx) => Math.abs(bs.bands[band_idx]?.[gamma_idx] ?? Infinity) < threshold,
1353
- )
1354
- }
1355
-
1356
- // Build per-point metadata array for a band series in the tooltip.
1357
- export function build_point_metadata(opts: {
1358
- x_vals: number[]
1359
- y_vals: number[]
1360
- band_idx: number
1361
- spin: `up` | `down`
1362
- is_acoustic: boolean | null
1363
- bs: types.BaseBandStructure
1364
- start_idx: number
1365
- }): BandPointMeta[] {
1366
- const { x_vals, y_vals, band_idx, spin, is_acoustic, bs, start_idx } = opts
1367
- return x_vals.map((_, pt_idx) => {
1368
- const global_idx = start_idx + pt_idx
1369
- const qpoint = bs.qpoints[global_idx]
1370
- return {
1371
- band_idx,
1372
- spin,
1373
- is_acoustic,
1374
- nb_bands: bs.nb_bands,
1375
- frac_coords: qpoint?.frac_coords ?? null,
1376
- qpoint_label: qpoint?.label ?? null,
1377
- band_width: bs.band_widths?.[band_idx]?.[global_idx] ?? null,
1378
- slope: compute_slope(x_vals, y_vals, pt_idx),
1379
- }
1380
- })
1381
- }