matterviz 0.3.7 → 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 (324) hide show
  1. package/dist/Icon.svelte +7 -4
  2. package/dist/MillerIndexInput.svelte +1 -1
  3. package/dist/api/optimade.js +32 -26
  4. package/dist/app.css +0 -3
  5. package/dist/brillouin/BrillouinZone.svelte +8 -3
  6. package/dist/brillouin/BrillouinZone.svelte.d.ts +2 -1
  7. package/dist/brillouin/BrillouinZoneScene.svelte +52 -6
  8. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -0
  9. package/dist/brillouin/BrillouinZoneTooltip.svelte +16 -25
  10. package/dist/brillouin/compute.js +10 -14
  11. package/dist/chempot-diagram/ChemPotDiagram.svelte +14 -13
  12. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +12 -15
  13. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +8 -10
  14. package/dist/chempot-diagram/async-compute.svelte.js +3 -1
  15. package/dist/chempot-diagram/chempot-worker.js +2 -1
  16. package/dist/chempot-diagram/compute.d.ts +1 -1
  17. package/dist/chempot-diagram/compute.js +17 -19
  18. package/dist/colors/index.js +6 -5
  19. package/dist/composition/FormulaFilter.svelte +12 -6
  20. package/dist/composition/PieChart.svelte +6 -5
  21. package/dist/composition/chem-sys.d.ts +8 -0
  22. package/dist/composition/chem-sys.js +85 -0
  23. package/dist/composition/format.js +4 -2
  24. package/dist/composition/index.d.ts +1 -0
  25. package/dist/composition/index.js +1 -0
  26. package/dist/composition/parse.js +25 -13
  27. package/dist/convex-hull/ConvexHull2D.svelte +12 -10
  28. package/dist/convex-hull/ConvexHull3D.svelte +5 -5
  29. package/dist/convex-hull/ConvexHull4D.svelte +5 -9
  30. package/dist/convex-hull/ConvexHullStats.svelte +12 -12
  31. package/dist/convex-hull/GasPressureControls.svelte +4 -4
  32. package/dist/convex-hull/TemperatureSlider.svelte +2 -2
  33. package/dist/convex-hull/demo-temperature.d.ts +1 -1
  34. package/dist/convex-hull/demo-temperature.js +20 -22
  35. package/dist/convex-hull/gas-thermodynamics.d.ts +2 -2
  36. package/dist/convex-hull/gas-thermodynamics.js +22 -30
  37. package/dist/convex-hull/helpers.d.ts +3 -0
  38. package/dist/convex-hull/helpers.js +17 -9
  39. package/dist/convex-hull/index.d.ts +1 -1
  40. package/dist/convex-hull/thermodynamics.js +83 -78
  41. package/dist/convex-hull/types.d.ts +1 -1
  42. package/dist/coordination/CoordinationBarPlot.svelte +23 -23
  43. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  44. package/dist/element/ElementTile.svelte.d.ts +1 -1
  45. package/dist/fermi-surface/FermiSlice.svelte +13 -5
  46. package/dist/fermi-surface/FermiSurface.svelte +11 -5
  47. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  48. package/dist/fermi-surface/FermiSurfaceControls.svelte +1 -1
  49. package/dist/fermi-surface/FermiSurfaceScene.svelte +3 -0
  50. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +8 -34
  51. package/dist/fermi-surface/compute.js +59 -59
  52. package/dist/fermi-surface/export.js +3 -2
  53. package/dist/fermi-surface/parse.js +7 -4
  54. package/dist/fermi-surface/types.d.ts +1 -0
  55. package/dist/heatmap-matrix/HeatmapMatrix.svelte +23 -21
  56. package/dist/heatmap-matrix/index.js +1 -1
  57. package/dist/io/decompress.js +4 -2
  58. package/dist/io/export.d.ts +4 -4
  59. package/dist/io/export.js +47 -25
  60. package/dist/io/fetch.js +5 -1
  61. package/dist/io/file-drop.d.ts +1 -1
  62. package/dist/io/file-drop.js +35 -36
  63. package/dist/io/url-drop.js +64 -33
  64. package/dist/isosurface/parse.js +6 -7
  65. package/dist/isosurface/slice.js +5 -4
  66. package/dist/isosurface/types.js +1 -1
  67. package/dist/keyboard.d.ts +3 -0
  68. package/dist/keyboard.js +23 -0
  69. package/dist/labels.d.ts +1 -1
  70. package/dist/labels.js +8 -7
  71. package/dist/layout/PropertyFilter.svelte +3 -2
  72. package/dist/layout/SettingsSection.svelte +1 -1
  73. package/dist/layout/json-tree/JsonNode.svelte +1 -1
  74. package/dist/layout/json-tree/JsonTree.svelte +2 -2
  75. package/dist/layout/json-tree/utils.js +5 -4
  76. package/dist/marching-cubes.js +8 -13
  77. package/dist/math.d.ts +5 -1
  78. package/dist/math.js +24 -9
  79. package/dist/overlays/DraggablePane.svelte +4 -4
  80. package/dist/periodic-table/PeriodicTable.svelte +20 -9
  81. package/dist/periodic-table/PropertySelect.svelte +1 -0
  82. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +9 -3
  83. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  84. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  85. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  86. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +1 -1
  87. package/dist/phase-diagram/build-diagram.js +2 -2
  88. package/dist/phase-diagram/parse.js +6 -5
  89. package/dist/phase-diagram/types.d.ts +1 -1
  90. package/dist/phase-diagram/utils.d.ts +3 -3
  91. package/dist/phase-diagram/utils.js +8 -12
  92. package/dist/plot/{BarPlot.svelte → bar/BarPlot.svelte} +229 -587
  93. package/dist/plot/{BarPlot.svelte.d.ts → bar/BarPlot.svelte.d.ts} +5 -5
  94. package/dist/plot/{BarPlotControls.svelte → bar/BarPlotControls.svelte} +6 -5
  95. package/dist/plot/{BarPlotControls.svelte.d.ts → bar/BarPlotControls.svelte.d.ts} +3 -3
  96. package/dist/plot/{SpacegroupBarPlot.svelte → bar/SpacegroupBarPlot.svelte} +6 -6
  97. package/dist/plot/{SpacegroupBarPlot.svelte.d.ts → bar/SpacegroupBarPlot.svelte.d.ts} +1 -1
  98. package/dist/plot/bar/data.d.ts +40 -0
  99. package/dist/plot/bar/data.js +154 -0
  100. package/dist/plot/bar/geometry.d.ts +39 -0
  101. package/dist/plot/bar/geometry.js +60 -0
  102. package/dist/plot/bar/index.d.ts +3 -0
  103. package/dist/plot/bar/index.js +3 -0
  104. package/dist/plot/box/BoxPlot.svelte +1462 -0
  105. package/dist/plot/box/BoxPlot.svelte.d.ts +94 -0
  106. package/dist/plot/box/BoxPlotControls.svelte +109 -0
  107. package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
  108. package/dist/plot/box/Violin.svelte +14 -0
  109. package/dist/plot/box/Violin.svelte.d.ts +70 -0
  110. package/dist/plot/box/box-plot.d.ts +55 -0
  111. package/dist/plot/box/box-plot.js +126 -0
  112. package/dist/plot/box/index.d.ts +5 -0
  113. package/dist/plot/box/index.js +5 -0
  114. package/dist/plot/box/kde.d.ts +16 -0
  115. package/dist/plot/box/kde.js +160 -0
  116. package/dist/plot/box/quantile.d.ts +3 -0
  117. package/dist/plot/box/quantile.js +53 -0
  118. package/dist/plot/{auto-place.js → core/auto-place.js} +2 -2
  119. package/dist/plot/core/axis-utils.d.ts +46 -0
  120. package/dist/plot/core/axis-utils.js +110 -0
  121. package/dist/plot/{AxisLabel.svelte → core/components/AxisLabel.svelte} +2 -2
  122. package/dist/plot/{AxisLabel.svelte.d.ts → core/components/AxisLabel.svelte.d.ts} +1 -1
  123. package/dist/plot/{ColorBar.svelte → core/components/ColorBar.svelte} +36 -33
  124. package/dist/plot/{ColorBar.svelte.d.ts → core/components/ColorBar.svelte.d.ts} +2 -2
  125. package/dist/plot/{ColorScaleSelect.svelte → core/components/ColorScaleSelect.svelte} +4 -3
  126. package/dist/plot/{ColorScaleSelect.svelte.d.ts → core/components/ColorScaleSelect.svelte.d.ts} +2 -2
  127. package/dist/plot/core/components/ControlPane.svelte +46 -0
  128. package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
  129. package/dist/plot/{FillArea.svelte → core/components/FillArea.svelte} +17 -6
  130. package/dist/plot/{FillArea.svelte.d.ts → core/components/FillArea.svelte.d.ts} +1 -1
  131. package/dist/plot/{InteractiveAxisLabel.svelte → core/components/InteractiveAxisLabel.svelte} +3 -3
  132. package/dist/plot/{InteractiveAxisLabel.svelte.d.ts → core/components/InteractiveAxisLabel.svelte.d.ts} +2 -2
  133. package/dist/plot/{Line.svelte → core/components/Line.svelte} +30 -13
  134. package/dist/plot/{PlotAxis.svelte → core/components/PlotAxis.svelte} +7 -5
  135. package/dist/plot/{PlotAxis.svelte.d.ts → core/components/PlotAxis.svelte.d.ts} +3 -2
  136. package/dist/plot/{PlotControls.svelte → core/components/PlotControls.svelte} +17 -29
  137. package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
  138. package/dist/plot/{PlotLegend.svelte → core/components/PlotLegend.svelte} +21 -10
  139. package/dist/plot/{PlotLegend.svelte.d.ts → core/components/PlotLegend.svelte.d.ts} +3 -2
  140. package/dist/plot/{PlotTooltip.svelte → core/components/PlotTooltip.svelte} +17 -1
  141. package/dist/plot/{PlotTooltip.svelte.d.ts → core/components/PlotTooltip.svelte.d.ts} +8 -0
  142. package/dist/plot/{PortalSelect.svelte → core/components/PortalSelect.svelte} +11 -7
  143. package/dist/plot/{ReferenceLine.svelte → core/components/ReferenceLine.svelte} +3 -3
  144. package/dist/plot/{ReferenceLine.svelte.d.ts → core/components/ReferenceLine.svelte.d.ts} +1 -1
  145. package/dist/plot/{ReferenceLine3D.svelte → core/components/ReferenceLine3D.svelte} +4 -4
  146. package/dist/plot/{ReferenceLine3D.svelte.d.ts → core/components/ReferenceLine3D.svelte.d.ts} +2 -2
  147. package/dist/plot/{ReferencePlane.svelte → core/components/ReferencePlane.svelte} +7 -7
  148. package/dist/plot/{ReferencePlane.svelte.d.ts → core/components/ReferencePlane.svelte.d.ts} +2 -2
  149. package/dist/plot/{ZeroLines.svelte → core/components/ZeroLines.svelte} +3 -3
  150. package/dist/plot/{ZeroLines.svelte.d.ts → core/components/ZeroLines.svelte.d.ts} +3 -3
  151. package/dist/plot/{ZoomRect.svelte → core/components/ZoomRect.svelte} +1 -1
  152. package/dist/plot/{ZoomRect.svelte.d.ts → core/components/ZoomRect.svelte.d.ts} +1 -1
  153. package/dist/plot/core/components/index.d.ts +17 -0
  154. package/dist/plot/core/components/index.js +17 -0
  155. package/dist/plot/{data-cleaning.d.ts → core/data-cleaning.d.ts} +71 -1
  156. package/dist/plot/{data-cleaning.js → core/data-cleaning.js} +3 -5
  157. package/dist/plot/{data-transform.d.ts → core/data-transform.d.ts} +2 -2
  158. package/dist/plot/{data-transform.js → core/data-transform.js} +3 -3
  159. package/dist/plot/core/fill-utils.d.ts +33 -0
  160. package/dist/plot/core/fill-utils.js +388 -0
  161. package/dist/plot/{hover-lock.svelte.js → core/hover-lock.svelte.js} +5 -6
  162. package/dist/plot/core/index.d.ts +10 -0
  163. package/dist/plot/core/index.js +11 -0
  164. package/dist/plot/core/interactions.d.ts +35 -0
  165. package/dist/plot/core/interactions.js +195 -0
  166. package/dist/plot/{layout.d.ts → core/layout.d.ts} +1 -0
  167. package/dist/plot/{layout.js → core/layout.js} +16 -8
  168. package/dist/plot/{reference-line.d.ts → core/reference-line.d.ts} +1 -1
  169. package/dist/plot/{reference-line.js → core/reference-line.js} +23 -36
  170. package/dist/plot/{scales.d.ts → core/scales.d.ts} +2 -2
  171. package/dist/plot/{scales.js → core/scales.js} +84 -85
  172. package/dist/plot/core/svg.d.ts +2 -0
  173. package/dist/plot/core/svg.js +41 -0
  174. package/dist/plot/{types.d.ts → core/types.d.ts} +19 -79
  175. package/dist/plot/{types.js → core/types.js} +1 -1
  176. package/dist/plot/{utils → core/utils}/label-placement.d.ts +2 -2
  177. package/dist/plot/core/utils/series-visibility.d.ts +26 -0
  178. package/dist/plot/{utils → core/utils}/series-visibility.js +29 -2
  179. package/dist/plot/core/utils.d.ts +11 -0
  180. package/dist/plot/core/utils.js +27 -0
  181. package/dist/plot/{Histogram.svelte → histogram/Histogram.svelte} +154 -294
  182. package/dist/plot/{Histogram.svelte.d.ts → histogram/Histogram.svelte.d.ts} +2 -2
  183. package/dist/plot/{HistogramControls.svelte → histogram/HistogramControls.svelte} +6 -6
  184. package/dist/plot/{HistogramControls.svelte.d.ts → histogram/HistogramControls.svelte.d.ts} +4 -4
  185. package/dist/plot/histogram/index.d.ts +2 -0
  186. package/dist/plot/histogram/index.js +2 -0
  187. package/dist/plot/index.d.ts +8 -41
  188. package/dist/plot/index.js +10 -39
  189. package/dist/plot/sankey/Sankey.svelte +700 -0
  190. package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
  191. package/dist/plot/sankey/SankeyControls.svelte +98 -0
  192. package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
  193. package/dist/plot/sankey/index.d.ts +4 -0
  194. package/dist/plot/sankey/index.js +3 -0
  195. package/dist/plot/sankey/sankey-types.d.ts +42 -0
  196. package/dist/plot/sankey/sankey-types.js +4 -0
  197. package/dist/plot/sankey/sankey.d.ts +52 -0
  198. package/dist/plot/sankey/sankey.js +187 -0
  199. package/dist/plot/{BinnedScatterPlot.svelte → scatter/BinnedScatterPlot.svelte} +61 -59
  200. package/dist/plot/{BinnedScatterPlot.svelte.d.ts → scatter/BinnedScatterPlot.svelte.d.ts} +4 -4
  201. package/dist/plot/{ElementScatter.svelte → scatter/ElementScatter.svelte} +6 -6
  202. package/dist/plot/{ElementScatter.svelte.d.ts → scatter/ElementScatter.svelte.d.ts} +2 -2
  203. package/dist/plot/{ScatterPlot.svelte → scatter/ScatterPlot.svelte} +221 -642
  204. package/dist/plot/{ScatterPlot.svelte.d.ts → scatter/ScatterPlot.svelte.d.ts} +7 -7
  205. package/dist/plot/{ScatterPlotControls.svelte → scatter/ScatterPlotControls.svelte} +6 -5
  206. package/dist/plot/{ScatterPlotControls.svelte.d.ts → scatter/ScatterPlotControls.svelte.d.ts} +1 -1
  207. package/dist/plot/{ScatterPoint.svelte → scatter/ScatterPoint.svelte} +7 -7
  208. package/dist/plot/{ScatterPoint.svelte.d.ts → scatter/ScatterPoint.svelte.d.ts} +3 -3
  209. package/dist/plot/{adaptive-density.d.ts → scatter/adaptive-density.d.ts} +14 -4
  210. package/dist/plot/{adaptive-density.js → scatter/adaptive-density.js} +46 -20
  211. package/dist/plot/{binned-scatter-types.d.ts → scatter/binned-scatter-types.d.ts} +3 -3
  212. package/dist/plot/scatter/index.d.ts +7 -0
  213. package/dist/plot/scatter/index.js +5 -0
  214. package/dist/plot/scatter/scatter-data.d.ts +19 -0
  215. package/dist/plot/scatter/scatter-data.js +212 -0
  216. package/dist/plot/{ScatterPlot3D.svelte → scatter-3d/ScatterPlot3D.svelte} +12 -10
  217. package/dist/plot/{ScatterPlot3D.svelte.d.ts → scatter-3d/ScatterPlot3D.svelte.d.ts} +7 -7
  218. package/dist/plot/{ScatterPlot3DControls.svelte → scatter-3d/ScatterPlot3DControls.svelte} +5 -4
  219. package/dist/plot/{ScatterPlot3DControls.svelte.d.ts → scatter-3d/ScatterPlot3DControls.svelte.d.ts} +2 -2
  220. package/dist/plot/{ScatterPlot3DScene.svelte → scatter-3d/ScatterPlot3DScene.svelte} +11 -11
  221. package/dist/plot/{ScatterPlot3DScene.svelte.d.ts → scatter-3d/ScatterPlot3DScene.svelte.d.ts} +3 -3
  222. package/dist/plot/{Surface3D.svelte → scatter-3d/Surface3D.svelte} +1 -1
  223. package/dist/plot/{Surface3D.svelte.d.ts → scatter-3d/Surface3D.svelte.d.ts} +1 -1
  224. package/dist/plot/scatter-3d/index.d.ts +4 -0
  225. package/dist/plot/scatter-3d/index.js +4 -0
  226. package/dist/plot/sunburst/Sunburst.svelte +1045 -0
  227. package/dist/plot/sunburst/Sunburst.svelte.d.ts +96 -0
  228. package/dist/plot/sunburst/SunburstControls.svelte +200 -0
  229. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
  230. package/dist/plot/sunburst/index.d.ts +4 -0
  231. package/dist/plot/sunburst/index.js +4 -0
  232. package/dist/plot/sunburst/render.d.ts +34 -0
  233. package/dist/plot/sunburst/render.js +122 -0
  234. package/dist/plot/sunburst/sunburst.d.ts +62 -0
  235. package/dist/plot/sunburst/sunburst.js +266 -0
  236. package/dist/rdf/RdfPlot.svelte +2 -1
  237. package/dist/rdf/calc-rdf.js +11 -24
  238. package/dist/sanitize.js +1 -1
  239. package/dist/settings.d.ts +65 -1
  240. package/dist/settings.js +262 -0
  241. package/dist/spectral/Bands.svelte +39 -29
  242. package/dist/spectral/Bands.svelte.d.ts +3 -4
  243. package/dist/spectral/BandsAndDos.svelte +1 -1
  244. package/dist/spectral/BrillouinBandsDos.svelte +39 -27
  245. package/dist/spectral/Dos.svelte +10 -19
  246. package/dist/spectral/Dos.svelte.d.ts +2 -2
  247. package/dist/spectral/helpers.d.ts +3 -1
  248. package/dist/spectral/helpers.js +95 -29
  249. package/dist/structure/AtomLegend.svelte +8 -9
  250. package/dist/structure/CellSelect.svelte +1 -2
  251. package/dist/structure/Cylinder.svelte +12 -8
  252. package/dist/structure/Cylinder.svelte.d.ts +4 -1
  253. package/dist/structure/Structure.svelte +78 -72
  254. package/dist/structure/Structure.svelte.d.ts +1 -1
  255. package/dist/structure/StructureInfoPane.svelte +5 -6
  256. package/dist/structure/StructureScene.svelte +11 -10
  257. package/dist/structure/atom-properties.js +6 -6
  258. package/dist/structure/bond-order-perception.js +1 -1
  259. package/dist/structure/bonding.d.ts +1 -0
  260. package/dist/structure/bonding.js +43 -15
  261. package/dist/structure/export.js +27 -23
  262. package/dist/structure/index.d.ts +2 -4
  263. package/dist/structure/index.js +1 -3
  264. package/dist/structure/label-placement.js +4 -4
  265. package/dist/structure/measure.d.ts +3 -2
  266. package/dist/structure/measure.js +6 -5
  267. package/dist/structure/parse.js +121 -103
  268. package/dist/structure/pbc.js +4 -0
  269. package/dist/symmetry/SymmetryStats.svelte +2 -2
  270. package/dist/symmetry/index.d.ts +1 -1
  271. package/dist/symmetry/index.js +22 -24
  272. package/dist/symmetry/spacegroups.d.ts +7 -0
  273. package/dist/symmetry/spacegroups.js +48 -13
  274. package/dist/table/HeatmapTable.svelte +63 -11
  275. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  276. package/dist/table/index.d.ts +1 -3
  277. package/dist/table/index.js +1 -1
  278. package/dist/theme/index.js +8 -8
  279. package/dist/tooltip/KCoords.svelte +45 -0
  280. package/dist/tooltip/KCoords.svelte.d.ts +8 -0
  281. package/dist/tooltip/index.d.ts +1 -0
  282. package/dist/tooltip/index.js +1 -0
  283. package/dist/trajectory/Trajectory.svelte +66 -40
  284. package/dist/trajectory/Trajectory.svelte.d.ts +2 -1
  285. package/dist/trajectory/TrajectoryExportPane.svelte +2 -1
  286. package/dist/trajectory/TrajectoryInfoPane.svelte +2 -1
  287. package/dist/trajectory/format-detect.d.ts +1 -0
  288. package/dist/trajectory/format-detect.js +25 -11
  289. package/dist/trajectory/frame-reader.js +17 -50
  290. package/dist/trajectory/helpers.js +1 -1
  291. package/dist/trajectory/index.js +1 -1
  292. package/dist/trajectory/parse/hdf5.js +1 -1
  293. package/dist/trajectory/parse/index.js +14 -6
  294. package/dist/trajectory/parse/vasp.js +36 -17
  295. package/dist/trajectory/parse/xyz.d.ts +24 -0
  296. package/dist/trajectory/parse/xyz.js +102 -89
  297. package/dist/trajectory/plotting.d.ts +1 -1
  298. package/dist/trajectory/plotting.js +15 -15
  299. package/dist/utils.d.ts +1 -0
  300. package/dist/utils.js +6 -4
  301. package/dist/xrd/XrdPlot.svelte +2 -1
  302. package/dist/xrd/calc-xrd.js +15 -12
  303. package/dist/xrd/parse.js +2 -2
  304. package/package.json +22 -18
  305. package/dist/plot/PlotControls.svelte.d.ts +0 -4
  306. package/dist/plot/axis-utils.d.ts +0 -19
  307. package/dist/plot/axis-utils.js +0 -78
  308. package/dist/plot/defaults.d.ts +0 -19
  309. package/dist/plot/defaults.js +0 -9
  310. package/dist/plot/fill-utils.d.ts +0 -46
  311. package/dist/plot/fill-utils.js +0 -322
  312. package/dist/plot/interactions.d.ts +0 -12
  313. package/dist/plot/interactions.js +0 -101
  314. package/dist/plot/svg.d.ts +0 -1
  315. package/dist/plot/svg.js +0 -11
  316. package/dist/plot/utils/series-visibility.d.ts +0 -15
  317. package/dist/plot/utils.d.ts +0 -1
  318. package/dist/plot/utils.js +0 -14
  319. /package/dist/plot/{auto-place.d.ts → core/auto-place.d.ts} +0 -0
  320. /package/dist/plot/{Line.svelte.d.ts → core/components/Line.svelte.d.ts} +0 -0
  321. /package/dist/plot/{PortalSelect.svelte.d.ts → core/components/PortalSelect.svelte.d.ts} +0 -0
  322. /package/dist/plot/{hover-lock.svelte.d.ts → core/hover-lock.svelte.d.ts} +0 -0
  323. /package/dist/plot/{utils → core/utils}/label-placement.js +0 -0
  324. /package/dist/plot/{binned-scatter-types.js → scatter/binned-scatter-types.js} +0 -0
package/dist/Icon.svelte CHANGED
@@ -1,7 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { SVGAttributes } from 'svelte/elements'
3
3
  import { ICON_DATA, type IconName } from './icons'
4
- import { sanitize_icon_svg } from './sanitize'
5
4
 
6
5
  type IconData = { path: string; viewBox: string; stroke?: string }
7
6
  let { icon, path, viewBox = `0 0 24 24`, stroke, ...rest }:
@@ -10,11 +9,15 @@
10
9
  & SVGAttributes<SVGSVGElement> = $props()
11
10
 
12
11
  const data: IconData = $derived.by(() => {
13
- if (path) return { path, viewBox: viewBox ?? `0 0 24 24`, stroke }
12
+ if (path) return { path, viewBox, stroke }
14
13
  if (icon && icon in ICON_DATA) return ICON_DATA[icon]
15
14
  if (icon) console.error(`Icon '${icon}' not found`)
16
15
  return ICON_DATA.Alert
17
16
  })
17
+
18
+ // {@html} only ever gets trusted ICON_DATA, never the user `path` prop (which renders as an
19
+ // escaped <path d> below) — so no XSS via path and identical SSR/CSR output (no hydration mismatch)
20
+ const icon_markup = $derived(!path && data.path.trim().startsWith(`<`) ? data.path : null)
18
21
  </script>
19
22
 
20
23
  <svg
@@ -24,8 +27,8 @@
24
27
  viewBox={data.viewBox}
25
28
  {...rest}
26
29
  >
27
- {#if data.path.trim().startsWith(`<`)}
28
- {@html sanitize_icon_svg(data.path)}
30
+ {#if icon_markup != null}
31
+ {@html icon_markup}
29
32
  {:else}
30
33
  <path d={data.path} />
31
34
  {/if}
@@ -19,7 +19,7 @@
19
19
  if (nums.every((num) => !isNaN(num))) return nums as Vec3
20
20
  }
21
21
  // Fall back to compact single-digit format: "001", "-101"
22
- const compact = input.replace(/\s+/g, ``)
22
+ const compact = input.replaceAll(/\s+/g, ``)
23
23
  const match = compact.match(/^(-?\d)(-?\d)(-?\d)$/)
24
24
  if (match) return [Number(match[1]), Number(match[2]), Number(match[3])] as Vec3
25
25
  return null
@@ -1,34 +1,41 @@
1
1
  // OPTIMADE API utilities for fetching structure data
2
2
  // Based on OPTIMADE 1.2.0 specification
3
- // Multiple CORS proxies for fallback reliability
3
+ // CORS proxies for fallback reliability. Query-style proxies need the target URL
4
+ // percent-encoded; path-suffix proxies need it verbatim (encoded can never succeed).
4
5
  const CORS_PROXIES = [
5
- `https://corsproxy.io/?`,
6
- `https://api.allorigins.win/raw?url=`,
7
- `https://cors-anywhere.herokuapp.com/`,
8
- `https://thingproxy.freeboard.io/fetch/`,
9
- `https://cors.bridged.cc/`,
6
+ { prefix: `https://corsproxy.io/?`, encode: true },
7
+ { prefix: `https://api.allorigins.win/raw?url=`, encode: true },
8
+ { prefix: `https://cors-anywhere.herokuapp.com/`, encode: false },
9
+ { prefix: `https://thingproxy.freeboard.io/fetch/`, encode: false },
10
+ { prefix: `https://cors.bridged.cc/`, encode: false },
10
11
  ];
11
12
  let cached_providers = null;
12
13
  let providers_cache_time = 0;
13
14
  const CACHE_DURATION = 5 * 60 * 1000;
15
+ // Per-key timestamps: a shared one would let any resolution refresh every entry's TTL
14
16
  const resolved_provider_urls = {};
15
- let resolved_urls_cache_time = 0;
16
17
  const RESOLVED_URLS_CACHE_DURATION = 10 * 60 * 1000;
17
18
  async function fetch_with_cors_proxy(url) {
19
+ const headers = { Accept: `application/vnd.api+json`, 'User-Agent': `MatterViz/1.0` };
20
+ let direct;
18
21
  try {
19
- const direct_response = await fetch(url, {
20
- headers: { Accept: `application/vnd.api+json`, 'User-Agent': `MatterViz/1.0` },
21
- });
22
- if (direct_response.ok)
23
- return direct_response;
22
+ direct = await fetch(url, { headers });
24
23
  }
25
24
  catch {
26
- // Direct access failed, will try CORS proxies
25
+ // No response at all (network/CORS failure) — fall back to CORS proxies below
27
26
  }
28
- for (const proxy of CORS_PROXIES) {
27
+ // A returned response means CORS succeeded. Surface a definitive HTTP error status
28
+ // directly (rather than masking a 404/500 behind callers' JSON.parse or the proxy
29
+ // fallback); only a thrown fetch (no response) warrants the proxies.
30
+ if (direct) {
31
+ if (direct.ok)
32
+ return direct;
33
+ throw new Error(`Request failed: ${direct.status} ${direct.statusText} for ${url}`);
34
+ }
35
+ for (const { prefix, encode } of CORS_PROXIES) {
29
36
  try {
30
- const response = await fetch(`${proxy}${encodeURIComponent(url)}`, {
31
- headers: { Accept: `application/vnd.api+json`, 'User-Agent': `MatterViz/1.0` },
37
+ const response = await fetch(`${prefix}${encode ? encodeURIComponent(url) : url}`, {
38
+ headers,
32
39
  });
33
40
  if (response.ok)
34
41
  return response;
@@ -41,9 +48,9 @@ async function fetch_with_cors_proxy(url) {
41
48
  }
42
49
  async function resolve_provider_url(provider_base_url) {
43
50
  const now = Date.now();
44
- if (resolved_provider_urls[provider_base_url] &&
45
- now - resolved_urls_cache_time < RESOLVED_URLS_CACHE_DURATION) {
46
- return resolved_provider_urls[provider_base_url];
51
+ const cached = resolved_provider_urls[provider_base_url];
52
+ if (cached && now - cached.time < RESOLVED_URLS_CACHE_DURATION) {
53
+ return cached.url;
47
54
  }
48
55
  for (const endpoint of [`/links`, `/v1/links`]) {
49
56
  try {
@@ -52,18 +59,17 @@ async function resolve_provider_url(provider_base_url) {
52
59
  const self_link = data.data?.find((link) => link.type === `links` &&
53
60
  link.attributes?.base_url &&
54
61
  link.attributes.link_type === `child`);
55
- if (self_link?.attributes.base_url) {
56
- resolved_provider_urls[provider_base_url] = self_link.attributes.base_url;
57
- resolved_urls_cache_time = now;
58
- return self_link.attributes.base_url;
62
+ const url = self_link?.attributes.base_url;
63
+ if (url) {
64
+ resolved_provider_urls[provider_base_url] = { url, time: now };
65
+ return url;
59
66
  }
60
67
  }
61
68
  catch {
62
69
  // Try next endpoint
63
70
  }
64
71
  }
65
- resolved_provider_urls[provider_base_url] = provider_base_url;
66
- resolved_urls_cache_time = now;
72
+ resolved_provider_urls[provider_base_url] = { url: provider_base_url, time: now };
67
73
  return provider_base_url;
68
74
  }
69
75
  export async function fetch_optimade_providers() {
@@ -97,7 +103,7 @@ export async function fetch_optimade_providers() {
97
103
  }
98
104
  }
99
105
  // URL encode/decode utilities for structure IDs with special characters
100
- export const encode_structure_id = (id) => encodeURIComponent(id).replace(/\./g, `%2E`).replace(/\//g, `%2F`);
106
+ export const encode_structure_id = (id) => encodeURIComponent(id).replaceAll('.', `%2E`).replaceAll('/', `%2F`);
101
107
  export const decode_structure_id = (encoded_id) => decodeURIComponent(encoded_id);
102
108
  export function detect_provider_from_slug(slug, providers) {
103
109
  const decoded_slug = decode_structure_id(slug);
package/dist/app.css CHANGED
@@ -1,6 +1,3 @@
1
- /* Starry-night syntax highlighting (GitHub-style, auto light/dark) */
2
- @import '@wooorm/starry-night/style/both';
3
-
4
1
  /* CSS variables are unlayered so they're available to both layers and to
5
2
  components that reference them via var(). Custom properties inherit
6
3
  naturally regardless of layer ordering. */
@@ -29,6 +29,7 @@
29
29
  extract_point_group_from_operations,
30
30
  reciprocal_lattice,
31
31
  } from './compute'
32
+ import { to_error } from '../utils'
32
33
  import type {
33
34
  BrillouinZoneData,
34
35
  BZHoverData,
@@ -83,6 +84,7 @@
83
84
  k_path_labels = [],
84
85
  hovered_k_point = null,
85
86
  hovered_qpoint_index = null,
87
+ on_kpath_hover,
86
88
  children,
87
89
  tooltip_config,
88
90
  on_file_load,
@@ -144,6 +146,8 @@
144
146
  hovered_k_point?: Vec3 | null
145
147
  // Index of the currently hovered q-point in the band structure
146
148
  hovered_qpoint_index?: number | null
149
+ // Called with the q-point index when the user hovers the k-path in the BZ (null on leave)
150
+ on_kpath_hover?: (qpoint_index: number | null) => void
147
151
  children?: Snippet<
148
152
  [{ structure?: Crystal; bz_data?: BrillouinZoneData }]
149
153
  >
@@ -189,7 +193,7 @@
189
193
  parse_structure(content, filename)
190
194
  } catch (err) {
191
195
  error_msg = `Failed to parse ${filename}: ${
192
- err instanceof Error ? err.message : err
196
+ to_error(err).message
193
197
  }`
194
198
  on_error?.({ error_msg, filename })
195
199
  }
@@ -211,7 +215,7 @@
211
215
  const valid_order = Math.min(Math.max(1, bz_order), 3) as 1 | 2 | 3
212
216
  bz_data = compute_brillouin_zone(k_lattice, valid_order)
213
217
  } catch (err) {
214
- const msg = err instanceof Error ? err.message : String(err)
218
+ const msg = to_error(err).message
215
219
  error_msg = `BZ computation failed: ${msg}`
216
220
  bz_data = undefined
217
221
  untrack(() => on_error?.({ error_msg, structure, bz_order }))
@@ -250,7 +254,7 @@
250
254
  // Load structure from URL or string
251
255
  $effect(() => {
252
256
  const handle_error = (err: unknown, source: string) => {
253
- error_msg = err instanceof Error ? err.message : String(err)
257
+ error_msg = to_error(err).message
254
258
  on_error?.({ error_msg, filename: source })
255
259
  }
256
260
 
@@ -430,6 +434,7 @@
430
434
  {k_path_labels}
431
435
  {hovered_k_point}
432
436
  {hovered_qpoint_index}
437
+ {on_kpath_hover}
433
438
  {show_ibz}
434
439
  {ibz_data}
435
440
  {ibz_color}
@@ -66,6 +66,7 @@ type $$ComponentProps = {
66
66
  }[];
67
67
  hovered_k_point?: Vec3 | null;
68
68
  hovered_qpoint_index?: number | null;
69
+ on_kpath_hover?: (qpoint_index: number | null) => void;
69
70
  children?: Snippet<[
70
71
  {
71
72
  structure?: Crystal;
@@ -78,6 +79,6 @@ type $$ComponentProps = {
78
79
  on_fullscreen_change?: (data: BZHandlerData) => void;
79
80
  on_hover?: (data: BZHoverData | null) => void;
80
81
  } & HTMLAttributes<HTMLDivElement>;
81
- declare const BrillouinZone: import("svelte").Component<$$ComponentProps, {}, "structure" | "height" | "width" | "dragover" | "loading" | "fullscreen" | "hovered" | "controls_open" | "camera_projection" | "vector_scale" | "info_pane_open" | "wrapper" | "png_dpi" | "error_msg" | "bz_order" | "surface_color" | "surface_opacity" | "edge_color" | "edge_width" | "show_vectors" | "show_ibz" | "ibz_color" | "ibz_opacity" | "bz_data" | "ibz_data">;
82
+ declare const BrillouinZone: import("svelte").Component<$$ComponentProps, {}, "structure" | "dragover" | "height" | "width" | "fullscreen" | "hovered" | "controls_open" | "loading" | "png_dpi" | "camera_projection" | "vector_scale" | "info_pane_open" | "wrapper" | "error_msg" | "bz_order" | "surface_color" | "surface_opacity" | "edge_color" | "edge_width" | "show_vectors" | "show_ibz" | "ibz_color" | "ibz_opacity" | "bz_data" | "ibz_data">;
82
83
  type BrillouinZone = ReturnType<typeof BrillouinZone>;
83
84
  export default BrillouinZone;
@@ -51,6 +51,7 @@
51
51
  hovered_k_point = null,
52
52
  hovered_qpoint_index = null,
53
53
  hover_data = $bindable<BZHoverData | null>(null),
54
+ on_kpath_hover,
54
55
  }: {
55
56
  bz_data?: BrillouinZoneData
56
57
  camera_position?: Vec3 | undefined
@@ -87,6 +88,7 @@
87
88
  hovered_k_point?: Vec3 | null
88
89
  hovered_qpoint_index?: number | null
89
90
  hover_data?: BZHoverData | null
91
+ on_kpath_hover?: (qpoint_index: number | null) => void
90
92
  } = $props()
91
93
 
92
94
  const threlte = useThrelte()
@@ -167,6 +169,23 @@
167
169
  const vector_colors = [`red`, `green`, `blue`]
168
170
  const vector_labels = [`b₁`, `b₂`, `b₃`]
169
171
 
172
+ // K-path styling. The invisible hover proxy is twice the visible thickness so the cursor
173
+ // snaps to the path even when it isn't directly over the thin visible segment.
174
+ const KPATH_THICKNESS = 0.12
175
+ const KPATH_HOVER_THICKNESS = KPATH_THICKNESS * 2
176
+
177
+ // Threshold for skipping k-path segments that bridge a path discontinuity (e.g. `U|K`).
178
+ // Band paths are densely sampled, so legit segments are tiny; a discontinuity jumps by
179
+ // a fraction of the zone. Skip segments far longer than the median sampling step.
180
+ const k_path_seg_cutoff = $derived.by(() => {
181
+ if (!k_path_points || k_path_points.length < 3) return Infinity
182
+ const lens = k_path_points
183
+ .slice(1)
184
+ .map((pt, idx) => Math.hypot(...math.subtract(pt as Vec3, k_path_points[idx] as Vec3)))
185
+ .sort((len_a, len_b) => len_a - len_b)
186
+ return lens[Math.floor(lens.length / 2)] * 10
187
+ })
188
+
170
189
  // Create mesh geometry from faces with fan triangulation
171
190
  function create_mesh_geometry(
172
191
  vertices: Vec3[],
@@ -311,6 +330,16 @@
311
330
  if (is_ibz) ibz_hovered = false
312
331
  if (is_ibz || !ibz_hovered) hover_data = null
313
332
  }
333
+
334
+ // K-path hover: report the nearer endpoint's q-point index of the hovered segment
335
+ function handle_kpath_hover(event: ThreltePointerEvent, seg_idx: number): void {
336
+ const { point } = event
337
+ const [from, to] = [k_path_points[seg_idx], k_path_points[seg_idx + 1]]
338
+ if (!from || !to) return
339
+ const dist_sq = (pt: Vec3) =>
340
+ (point.x - pt[0]) ** 2 + (point.y - pt[1]) ** 2 + (point.z - pt[2]) ** 2
341
+ on_kpath_hover?.(dist_sq(from) <= dist_sq(to) ? seg_idx : seg_idx + 1)
342
+ }
314
343
  </script>
315
344
 
316
345
  {#if camera_projection === `perspective`}
@@ -395,6 +424,9 @@
395
424
  vector={scaled_vec}
396
425
  color={vector_colors[idx]}
397
426
  scale={1}
427
+ shaft_radius={bz_size * 0.008}
428
+ arrow_head_radius={bz_size * 0.028}
429
+ arrow_head_length={-0.1}
398
430
  />
399
431
  <!-- Vector label beyond tip -->
400
432
  <extras.HTML center position={label_position}>
@@ -416,14 +448,28 @@
416
448
  (`${from_point}-${k_path_points[idx + 1]}#${idx}`)
417
449
  }
418
450
  {@const to_point = k_path_points[idx + 1]}
451
+ {@const seg_len = Math.hypot(
452
+ ...math.subtract(to_point as Vec3, from_point as Vec3),
453
+ )}
419
454
  {@const is_hovered = hovered_qpoint_index !== null &&
420
455
  (idx === hovered_qpoint_index || idx === hovered_qpoint_index - 1)}
421
- <Cylinder
422
- from={from_point as Vec3}
423
- to={to_point as Vec3}
424
- thickness={0.08}
425
- color={is_hovered ? `#ff6b35` : `#ffcc00`}
426
- />
456
+ {#if seg_len <= k_path_seg_cutoff}
457
+ <Cylinder
458
+ from={from_point as Vec3}
459
+ to={to_point as Vec3}
460
+ thickness={KPATH_THICKNESS}
461
+ color={is_hovered ? `#ff6b35` : `#ffcc00`}
462
+ />
463
+ <!-- Invisible wider proxy: lets the cursor snap to the path within ~2× its radius -->
464
+ <Cylinder
465
+ from={from_point as Vec3}
466
+ to={to_point as Vec3}
467
+ thickness={KPATH_HOVER_THICKNESS}
468
+ opacity={0}
469
+ onpointermove={(event: ThreltePointerEvent) => handle_kpath_hover(event, idx)}
470
+ onpointerleave={() => on_kpath_hover?.(null)}
471
+ />
472
+ {/if}
427
473
  {/each}
428
474
  {/if}
429
475
 
@@ -42,6 +42,7 @@ type $$ComponentProps = {
42
42
  hovered_k_point?: Vec3 | null;
43
43
  hovered_qpoint_index?: number | null;
44
44
  hover_data?: BZHoverData | null;
45
+ on_kpath_hover?: (qpoint_index: number | null) => void;
45
46
  };
46
47
  declare const BrillouinZoneScene: import("svelte").Component<$$ComponentProps, {}, "camera_position" | "camera_projection" | "vector_scale" | "camera" | "scene" | "camera_is_moving" | "surface_color" | "surface_opacity" | "edge_color" | "edge_width" | "show_vectors" | "bz_data" | "hover_data">;
47
48
  type BrillouinZoneScene = ReturnType<typeof BrillouinZoneScene>;
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  // Tooltip component for Brillouin zone hover information
3
3
  // Displays k-coordinates, BZ order, volume, and IBZ-specific info
4
- import { format_num, format_vec3 } from '../labels'
5
- import { TooltipContent } from '../tooltip'
4
+ import { format_num } from '../labels'
5
+ import { KCoords, TooltipContent } from '../tooltip'
6
6
  import type { BZHoverData, BZTooltipProp } from './types'
7
7
 
8
8
  let {
@@ -19,33 +19,26 @@
19
19
 
20
20
  <TooltipContent data={hover_data} snippet_arg={{ hover_data }} {tooltip}>
21
21
  <div class="bz-tooltip-content">
22
- <div class="bz-tooltip-title">
23
- <strong>{hover_data.is_ibz ? `Irreducible BZ` : `Brillouin Zone`}</strong>
24
- {#if hover_data.bz_order > 1}
25
- <span class="bz-tooltip-badge">{ordinal(hover_data.bz_order)}</span>
26
- {/if}
27
- </div>
28
- <div class="bz-tooltip-row">
29
- <span class="bz-tooltip-label">k (Å⁻¹):</span>
30
- <span class="bz-tooltip-value">{format_vec3(hover_data.position_cartesian)}</span>
31
- </div>
32
- {#if hover_data.position_fractional}
33
- <div class="bz-tooltip-row">
34
- <span class="bz-tooltip-label">k (frac):</span>
35
- <span class="bz-tooltip-value">{
36
- format_vec3(hover_data.position_fractional)
37
- }</span>
22
+ {#if hover_data.is_ibz || hover_data.bz_order > 1}
23
+ <div class="bz-tooltip-title">
24
+ {#if hover_data.is_ibz}<strong>Irreducible BZ</strong>{/if}
25
+ {#if hover_data.bz_order > 1}
26
+ <span class="bz-tooltip-badge">{ordinal(hover_data.bz_order)}</span>
27
+ {/if}
38
28
  </div>
39
29
  {/if}
30
+ <KCoords
31
+ cartesian={hover_data.position_cartesian}
32
+ fractional={hover_data.position_fractional}
33
+ />
40
34
  <div class="bz-tooltip-row">
41
35
  <span class="bz-tooltip-label">BZ Volume:</span>
42
- <span class="bz-tooltip-value">{format_num(hover_data.bz_volume, `.4~`)} Å⁻³</span>
36
+ <span>{format_num(hover_data.bz_volume, `.4~`)} Å⁻³</span>
43
37
  </div>
44
38
  {#if hover_data.is_ibz && hover_data.ibz_volume != null}
45
39
  <div class="bz-tooltip-row">
46
40
  <span class="bz-tooltip-label">IBZ Volume:</span>
47
- <span class="bz-tooltip-value">{format_num(hover_data.ibz_volume, `.4~`)}
48
- Å⁻³</span>
41
+ <span>{format_num(hover_data.ibz_volume, `.4~`)} Å⁻³</span>
49
42
  </div>
50
43
  {#if hover_data.symmetry_multiplicity != null}
51
44
  <div class="bz-tooltip-symmetry">
@@ -59,7 +52,6 @@
59
52
  <style>
60
53
  .bz-tooltip-content {
61
54
  max-width: var(--bz-tooltip-max-width, 250px);
62
- text-align: left;
63
55
  }
64
56
  .bz-tooltip-title {
65
57
  margin-bottom: 4px;
@@ -71,6 +63,8 @@
71
63
  font-weight: 500;
72
64
  background: #666;
73
65
  color: white;
66
+ }
67
+ .bz-tooltip-badge:not(:first-child) {
74
68
  margin-left: 6px;
75
69
  }
76
70
  .bz-tooltip-row {
@@ -81,9 +75,6 @@
81
75
  opacity: 0.8;
82
76
  min-width: 75px;
83
77
  }
84
- .bz-tooltip-value {
85
- font-family: monospace;
86
- }
87
78
  .bz-tooltip-symmetry {
88
79
  margin-top: 2px;
89
80
  opacity: 0.8;
@@ -20,7 +20,8 @@ export function extract_point_group_from_operations(operations) {
20
20
  if (seen.has(key))
21
21
  continue;
22
22
  seen.add(key);
23
- const rot = math.vec9_to_mat3x3(Array.from(rotation));
23
+ // moyo serializes rotations COLUMN-major; vec9_to_mat3x3 reads row-major → transpose to get W
24
+ const rot = math.transpose_3x3_matrix(math.vec9_to_mat3x3(Array.from(rotation)));
24
25
  unique_rotations.push(rot);
25
26
  }
26
27
  return unique_rotations;
@@ -39,20 +40,15 @@ function mat3x3_multiply(A, B) {
39
40
  }
40
41
  return result;
41
42
  }
42
- // Convert fractional-coordinate rotation W to Cartesian k-space rotation.
43
- // In reciprocal space: R_cart = B · W^{-T} · B^{-1}, where B is the k_lattice
44
- // and W^{-T} is the inverse transpose of the direct-space rotation matrix.
45
- // This follows the dual-basis relation: if direct fractional rotation is x' = W·x,
46
- // then reciprocal fractional rotation is q' = W^{-T}·q. For non-orthogonal lattices
47
- // (monoclinic, triclinic, hexagonal), W^{-1} ≠ W^T since integer rotation matrices
48
- // are not orthogonal in these systems.
43
+ // Convert fractional rotation W to Cartesian k-space rotation. k_lattice stores reciprocal
44
+ // vectors as ROWS (k_cart = Bᵀ·q) and reciprocal fractional rotation is q' = W^{-T}·q, so
45
+ // R_cart = Bᵀ·W^{-T}·B^{-T}. For non-orthogonal lattices W^{-1} Wᵀ, so the transpose matters.
49
46
  export function fractional_to_cartesian_rotation(W, k_lattice) {
50
47
  try {
51
- const k_lattice_inv = math.matrix_inverse_3x3(k_lattice);
52
- const W_inv = math.matrix_inverse_3x3(W);
53
- const W_inv_T = math.transpose_3x3_matrix(W_inv);
54
- // R_cart = B · W^{-T} · B^{-1}
55
- return mat3x3_multiply(mat3x3_multiply(k_lattice, W_inv_T), k_lattice_inv);
48
+ const B_T = math.transpose_3x3_matrix(k_lattice);
49
+ const W_inv_T = math.transpose_3x3_matrix(math.matrix_inverse_3x3(W));
50
+ // R_cart = Bᵀ · W^{-T} · B^{-T}
51
+ return mat3x3_multiply(mat3x3_multiply(B_T, W_inv_T), math.matrix_inverse_3x3(B_T));
56
52
  }
57
53
  catch {
58
54
  // Fallback to identity if inversion fails (shouldn't happen for valid rotations)
@@ -382,7 +378,7 @@ function try_build_hull(vertices, edge_sharp_angle_deg) {
382
378
  // Compute the irreducible Brillouin zone by clipping the full BZ with symmetry planes
383
379
  export function compute_irreducible_bz(bz_data, point_group_ops, edge_sharp_angle_deg = 5) {
384
380
  // Convert fractional rotations to Cartesian k-space rotations
385
- // R_cart = B · W^{-T} · B^{-1}, where B is k_lattice and W^{-T} is inverse-transpose
381
+ // R_cart = B · W^{-T} · B^{-T}, where B is k_lattice (reciprocal vectors as rows)
386
382
  const cartesian_ops = point_group_ops.map((W) => fractional_to_cartesian_rotation(W, bz_data.k_lattice));
387
383
  const clipping_planes = compute_ibz_clipping_planes(cartesian_ops);
388
384
  if (clipping_planes.length === 0) {
@@ -1,20 +1,21 @@
1
1
  <script lang="ts">
2
- import { get_electro_neg_formula } from '../composition/format';
3
- import type { PhaseData } from '../convex-hull/types';
4
- import Spinner from '../feedback/Spinner.svelte';
5
- import { format_num } from '../labels';
6
- import { constrain_tooltip_position } from '../plot/layout';
7
- import { sanitize_html } from '../sanitize';
8
- import { compute_chempot_async } from './async-compute.svelte';
9
- import ChemPotDiagram2D from './ChemPotDiagram2D.svelte';
10
- import ChemPotDiagram3D from './ChemPotDiagram3D.svelte';
11
- import { get_ternary_combinations } from './compute';
2
+ import { get_electro_neg_formula } from '../composition/format'
3
+ import type { PhaseData } from '../convex-hull/types'
4
+ import Spinner from '../feedback/Spinner.svelte'
5
+ import { format_num } from '../labels'
6
+ import { constrain_tooltip_position } from '../plot/core/layout'
7
+ import { sanitize_html } from '../sanitize'
8
+ import { compute_chempot_async } from './async-compute.svelte'
9
+ import ChemPotDiagram2D from './ChemPotDiagram2D.svelte'
10
+ import ChemPotDiagram3D from './ChemPotDiagram3D.svelte'
11
+ import { get_ternary_combinations } from './compute'
12
12
  import type {
13
13
  ChemPotDiagramConfig,
14
14
  ChemPotHoverInfo,
15
15
  ChemPotHoverInfo3D,
16
- } from './types';
17
- import { CHEMPOT_DEFAULTS } from './types';
16
+ } from './types'
17
+ import { CHEMPOT_DEFAULTS } from './types'
18
+ import { to_error } from '../utils'
18
19
 
19
20
  let {
20
21
  entries = [],
@@ -84,7 +85,7 @@
84
85
  .catch((err) => {
85
86
  if (cancelled) return
86
87
  console.error(`Grid precompute failed:`, err)
87
- grid_error = err instanceof Error ? err.message : String(err)
88
+ grid_error = to_error(err).message
88
89
  })
89
90
  return () => { cancelled = true }
90
91
  })
@@ -9,8 +9,8 @@
9
9
  import { download } from '../io/fetch'
10
10
  import DraggablePane from '../overlays/DraggablePane.svelte'
11
11
  import { ColorBar, ScatterPlot } from '../plot'
12
- import { constrain_tooltip_position } from '../plot/layout'
13
- import type { DataSeries, UserContentProps } from '../plot/types'
12
+ import { constrain_tooltip_position } from '../plot/core/layout'
13
+ import type { DataSeries, UserContentProps } from '../plot/core/types'
14
14
  import { sanitize_html } from '../sanitize'
15
15
  import { onDestroy } from 'svelte'
16
16
  import { SvelteMap } from 'svelte/reactivity'
@@ -28,7 +28,12 @@
28
28
  } from './compute'
29
29
  import { with_hover_pointer } from './pointer'
30
30
  import { get_temp_filter_payload, get_valid_temperature } from './temperature'
31
- import type { ChemPotDiagramConfig, ChemPotDiagramData, ChemPotHoverInfo } from './types'
31
+ import type {
32
+ ChemPotColorMode,
33
+ ChemPotDiagramConfig,
34
+ ChemPotDiagramData,
35
+ ChemPotHoverInfo,
36
+ } from './types'
32
37
  import { CHEMPOT_DEFAULTS } from './types'
33
38
 
34
39
  let {
@@ -78,11 +83,7 @@
78
83
  default_min_limit_override ??
79
84
  (config.default_min_limit ?? CHEMPOT_DEFAULTS.default_min_limit),
80
85
  )
81
- let color_mode_override = $state<
82
- NonNullable<ChemPotDiagramConfig[`color_mode`]> | null
83
- >(
84
- null,
85
- )
86
+ let color_mode_override = $state<ChemPotColorMode | null>(null)
86
87
  let color_scale_override = $state<D3InterpolateName | null>(null)
87
88
  let reverse_color_scale_override = $state<boolean | null>(null)
88
89
  const color_mode = $derived(
@@ -199,10 +200,7 @@
199
200
  matching_entry_count: number
200
201
  min_energy_per_atom: number | null
201
202
  }
202
- type NumericColorMode = Exclude<
203
- NonNullable<ChemPotDiagramConfig[`color_mode`]>,
204
- `none` | `arity`
205
- >
203
+ type NumericColorMode = Exclude<ChemPotColorMode, `none` | `arity`>
206
204
 
207
205
  const raw_el_refs = $derived(
208
206
  get_min_entries_and_el_refs(temp_filtered_entries).el_refs,
@@ -436,8 +434,8 @@
436
434
  const get_svg_element = (): SVGSVGElement | null =>
437
435
  scatter_wrapper?.querySelector<SVGSVGElement>(`svg`) ?? null
438
436
 
439
- function get_json_string(): string {
440
- return JSON.stringify(
437
+ const get_json_string = (): string =>
438
+ JSON.stringify(
441
439
  {
442
440
  elements: diagram_data?.elements ?? [],
443
441
  domains: draw_domains,
@@ -446,7 +444,6 @@
446
444
  null,
447
445
  2,
448
446
  )
449
- }
450
447
 
451
448
  function export_json_file(): void {
452
449
  download(
@@ -14,7 +14,7 @@
14
14
  convex_hull_2d,
15
15
  cross_3d,
16
16
  merge_coplanar_triangles,
17
- normalize_vec3,
17
+ normalize_vec,
18
18
  } from '../math'
19
19
  import DraggablePane from '../overlays/DraggablePane.svelte'
20
20
  import { ColorBar, ScatterPlot3DControls } from '../plot'
@@ -22,13 +22,13 @@
22
22
  constrain_tooltip_position,
23
23
  pad_rect,
24
24
  rects_overlap,
25
- } from '../plot/layout'
25
+ } from '../plot/core/layout'
26
26
  import type {
27
27
  AxisConfig3D,
28
28
  CameraProjection3D,
29
29
  DataSeries3D,
30
30
  DisplayConfig3D,
31
- } from '../plot/types'
31
+ } from '../plot/core/types'
32
32
  import { Canvas, T } from '@threlte/core'
33
33
  import * as extras from '@threlte/extras'
34
34
  import { scaleLinear } from 'd3-scale'
@@ -953,7 +953,7 @@
953
953
  pos.getY(base + 2) - pos.getY(base),
954
954
  pos.getZ(base + 2) - pos.getZ(base),
955
955
  ]
956
- normals.push(normalize_vec3(cross_3d(e1, e2)))
956
+ normals.push(normalize_vec(cross_3d(e1, e2)))
957
957
  }
958
958
  // Build edge → face adjacency
959
959
  const edge_faces = new SvelteMap<string, number[]>()
@@ -2017,14 +2017,13 @@
2017
2017
  }, `image/png`)
2018
2018
  }
2019
2019
 
2020
- function xml_escape(text: string): string {
2021
- return text
2020
+ const xml_escape = (text: string): string =>
2021
+ text
2022
2022
  .replaceAll(`&`, `&amp;`)
2023
2023
  .replaceAll(`<`, `&lt;`)
2024
2024
  .replaceAll(`>`, `&gt;`)
2025
2025
  .replaceAll(`"`, `&quot;`)
2026
2026
  .replaceAll(`'`, `&#39;`)
2027
- }
2028
2027
 
2029
2028
  function export_svg_file(): void {
2030
2029
  if (!wrapper) return
@@ -2128,8 +2127,8 @@
2128
2127
  )
2129
2128
  }
2130
2129
 
2131
- function get_json_string(): string {
2132
- return JSON.stringify(
2130
+ const get_json_string = (): string =>
2131
+ JSON.stringify(
2133
2132
  {
2134
2133
  elements: diagram_data?.elements ?? [],
2135
2134
  domains: render_domains.map((domain) => ({
@@ -2142,7 +2141,6 @@
2142
2141
  null,
2143
2142
  2,
2144
2143
  )
2145
- }
2146
2144
 
2147
2145
  function export_json_file(): void {
2148
2146
  download_blob(