matterviz 0.4.0 → 0.4.2

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 (527) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +12 -14
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/app.css +53 -0
  6. package/dist/brillouin/BrillouinZone.svelte +132 -219
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +9 -20
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +47 -96
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +15 -42
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  13. package/dist/brillouin/BrillouinZoneScene.svelte +63 -230
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
  15. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  16. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  17. package/dist/brillouin/compute.d.ts +2 -0
  18. package/dist/brillouin/compute.js +80 -77
  19. package/dist/brillouin/geometry.d.ts +8 -0
  20. package/dist/brillouin/geometry.js +57 -0
  21. package/dist/brillouin/index.d.ts +2 -0
  22. package/dist/brillouin/index.js +2 -0
  23. package/dist/brillouin/types.d.ts +2 -2
  24. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  25. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  26. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +143 -246
  27. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  28. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +652 -976
  29. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  30. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  31. package/dist/chempot-diagram/color.d.ts +3 -6
  32. package/dist/chempot-diagram/color.js +5 -5
  33. package/dist/chempot-diagram/compute.d.ts +3 -3
  34. package/dist/chempot-diagram/compute.js +3 -1
  35. package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
  36. package/dist/chempot-diagram/controls-state.svelte.js +42 -0
  37. package/dist/chempot-diagram/export.d.ts +47 -0
  38. package/dist/chempot-diagram/export.js +133 -0
  39. package/dist/chempot-diagram/index.d.ts +1 -0
  40. package/dist/chempot-diagram/index.js +1 -0
  41. package/dist/chempot-diagram/pointer.d.ts +0 -10
  42. package/dist/chempot-diagram/pointer.js +4 -4
  43. package/dist/chempot-diagram/types.d.ts +3 -3
  44. package/dist/colors/index.d.ts +0 -4
  45. package/dist/colors/index.js +21 -22
  46. package/dist/composition/BarChart.svelte +37 -31
  47. package/dist/composition/BubbleChart.svelte +17 -17
  48. package/dist/composition/Composition.svelte +7 -11
  49. package/dist/composition/Formula.svelte +18 -25
  50. package/dist/composition/FormulaFilter.svelte +96 -98
  51. package/dist/composition/PieChart.svelte +60 -46
  52. package/dist/composition/chem-sys.js +3 -2
  53. package/dist/composition/format.js +4 -3
  54. package/dist/composition/index.d.ts +2 -0
  55. package/dist/composition/index.js +14 -0
  56. package/dist/composition/parse.d.ts +2 -3
  57. package/dist/composition/parse.js +27 -28
  58. package/dist/constants.js +11 -9
  59. package/dist/controls.d.ts +1 -0
  60. package/dist/controls.js +0 -1
  61. package/dist/convex-hull/ConvexHull.svelte +20 -25
  62. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  63. package/dist/convex-hull/ConvexHull2D.svelte +176 -256
  64. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  65. package/dist/convex-hull/ConvexHull3D.svelte +269 -804
  66. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  67. package/dist/convex-hull/ConvexHull4D.svelte +236 -755
  68. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  69. package/dist/convex-hull/ConvexHullChrome.svelte +264 -0
  70. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  71. package/dist/convex-hull/ConvexHullControls.svelte +128 -49
  72. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  73. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  74. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  75. package/dist/convex-hull/ConvexHullStats.svelte +210 -351
  76. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  77. package/dist/convex-hull/ConvexHullTooltip.svelte +16 -14
  78. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  79. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  80. package/dist/convex-hull/StructurePopup.svelte +17 -21
  81. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  82. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  83. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  84. package/dist/convex-hull/barycentric-coords.js +6 -33
  85. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  86. package/dist/convex-hull/canvas-interactions.svelte.js +279 -0
  87. package/dist/convex-hull/helpers.d.ts +47 -17
  88. package/dist/convex-hull/helpers.js +186 -101
  89. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  90. package/dist/convex-hull/hull-state.svelte.js +124 -0
  91. package/dist/convex-hull/index.d.ts +9 -7
  92. package/dist/convex-hull/index.js +7 -2
  93. package/dist/convex-hull/thermodynamics.js +109 -937
  94. package/dist/convex-hull/types.d.ts +12 -4
  95. package/dist/convex-hull/types.js +12 -0
  96. package/dist/coordination/CoordinationBarPlot.svelte +41 -43
  97. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  98. package/dist/coordination/calc-coordination.d.ts +1 -1
  99. package/dist/coordination/calc-coordination.js +28 -25
  100. package/dist/element/BohrAtom.svelte +6 -8
  101. package/dist/element/ElementHeading.svelte +4 -1
  102. package/dist/element/ElementPhoto.svelte +11 -9
  103. package/dist/element/ElementStats.svelte +12 -10
  104. package/dist/element/ElementTile.svelte +24 -29
  105. package/dist/element/ElementTile.svelte.d.ts +1 -1
  106. package/dist/element/Nucleus.svelte +4 -2
  107. package/dist/element/data.d.ts +1 -2
  108. package/dist/element/helpers.d.ts +4 -0
  109. package/dist/element/helpers.js +18 -0
  110. package/dist/element/index.d.ts +1 -0
  111. package/dist/element/index.js +3 -0
  112. package/dist/feedback/DragOverlay.svelte +5 -3
  113. package/dist/feedback/DragOverlay.svelte.d.ts +2 -1
  114. package/dist/feedback/StatusMessage.svelte +20 -7
  115. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  116. package/dist/fermi-surface/FermiSurface.svelte +78 -165
  117. package/dist/fermi-surface/FermiSurface.svelte.d.ts +9 -20
  118. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  119. package/dist/fermi-surface/FermiSurfaceScene.svelte +93 -272
  120. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  121. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  122. package/dist/fermi-surface/compute.js +14 -13
  123. package/dist/fermi-surface/export.js +4 -15
  124. package/dist/fermi-surface/index.d.ts +0 -1
  125. package/dist/fermi-surface/index.js +0 -1
  126. package/dist/fermi-surface/parse.d.ts +1 -1
  127. package/dist/fermi-surface/parse.js +84 -97
  128. package/dist/fermi-surface/types.d.ts +2 -2
  129. package/dist/heatmap-matrix/HeatmapMatrix.svelte +161 -185
  130. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +6 -5
  131. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +12 -9
  132. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  133. package/dist/heatmap-matrix/index.d.ts +8 -2
  134. package/dist/icons.d.ts +4 -0
  135. package/dist/icons.js +4 -0
  136. package/dist/index.d.ts +1 -0
  137. package/dist/index.js +1 -0
  138. package/dist/io/ExportPane.svelte +170 -0
  139. package/dist/io/ExportPane.svelte.d.ts +17 -0
  140. package/dist/io/decompress.d.ts +2 -1
  141. package/dist/io/decompress.js +22 -36
  142. package/dist/io/export.d.ts +9 -1
  143. package/dist/io/export.js +37 -29
  144. package/dist/io/fetch.d.ts +2 -4
  145. package/dist/io/fetch.js +0 -11
  146. package/dist/io/file-drop.d.ts +7 -0
  147. package/dist/io/file-drop.js +13 -0
  148. package/dist/io/index.d.ts +1 -0
  149. package/dist/io/index.js +3 -0
  150. package/dist/io/is-binary.d.ts +9 -0
  151. package/dist/io/is-binary.js +45 -1
  152. package/dist/io/types.d.ts +13 -0
  153. package/dist/io/url-drop.js +13 -25
  154. package/dist/isosurface/Isosurface.svelte +17 -23
  155. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  156. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  157. package/dist/isosurface/parse-vaspwave.js +138 -0
  158. package/dist/isosurface/parse.js +50 -48
  159. package/dist/labels.d.ts +6 -2
  160. package/dist/labels.js +44 -14
  161. package/dist/layout/FullscreenButton.svelte +34 -0
  162. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  163. package/dist/layout/FullscreenToggle.svelte +12 -12
  164. package/dist/layout/InfoCard.svelte +7 -18
  165. package/dist/layout/InfoTag.svelte +1 -3
  166. package/dist/layout/NumberRangeInput.svelte +46 -0
  167. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  168. package/dist/layout/PropertyFilter.svelte +2 -6
  169. package/dist/layout/SettingsSection.svelte +21 -17
  170. package/dist/layout/SubpageGrid.svelte +3 -1
  171. package/dist/layout/ViewerChrome.svelte +115 -0
  172. package/dist/layout/ViewerChrome.svelte.d.ts +18 -0
  173. package/dist/layout/fullscreen.d.ts +4 -0
  174. package/dist/layout/fullscreen.js +3 -5
  175. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  176. package/dist/layout/fullscreen.svelte.js +36 -0
  177. package/dist/layout/index.d.ts +4 -0
  178. package/dist/layout/index.js +4 -0
  179. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  180. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  181. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  182. package/dist/layout/json-tree/utils.js +14 -23
  183. package/dist/math.d.ts +9 -3
  184. package/dist/math.js +37 -21
  185. package/dist/overlays/ContextMenu.svelte +4 -2
  186. package/dist/overlays/CopyButton.svelte +11 -5
  187. package/dist/overlays/DragControlTab.svelte +6 -1
  188. package/dist/overlays/DraggablePane.svelte +81 -26
  189. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  190. package/dist/overlays/GlassChip.svelte +30 -0
  191. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  192. package/dist/overlays/InfoPaneCards.svelte +11 -23
  193. package/dist/overlays/index.d.ts +11 -0
  194. package/dist/overlays/index.js +26 -0
  195. package/dist/overlays/portal.d.ts +2 -0
  196. package/dist/overlays/portal.js +14 -0
  197. package/dist/periodic-table/PeriodicTable.svelte +115 -146
  198. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  199. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  200. package/dist/periodic-table/TableInset.svelte +9 -4
  201. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  202. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  203. package/dist/phase-diagram/PhaseDiagramControls.svelte +73 -96
  204. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  205. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
  206. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  207. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +49 -134
  208. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  209. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  210. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  211. package/dist/phase-diagram/build-diagram.js +3 -3
  212. package/dist/phase-diagram/colors.js +1 -1
  213. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  214. package/dist/phase-diagram/parse.d.ts +2 -1
  215. package/dist/phase-diagram/parse.js +15 -15
  216. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  217. package/dist/phase-diagram/utils.js +2 -3
  218. package/dist/plot/bar/BarPlot.svelte +494 -692
  219. package/dist/plot/bar/BarPlot.svelte.d.ts +9 -15
  220. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  221. package/dist/plot/bar/BarPlotControls.svelte.d.ts +5 -7
  222. package/dist/plot/bar/SpacegroupBarPlot.svelte +31 -37
  223. package/dist/plot/bar/data.d.ts +5 -4
  224. package/dist/plot/bar/data.js +2 -1
  225. package/dist/plot/box/BoxPlot.svelte +361 -439
  226. package/dist/plot/box/BoxPlot.svelte.d.ts +6 -3
  227. package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
  228. package/dist/plot/box/Violin.svelte.d.ts +2 -1
  229. package/dist/plot/box/box-plot.d.ts +3 -2
  230. package/dist/plot/box/box-plot.js +6 -3
  231. package/dist/plot/box/kde.d.ts +2 -1
  232. package/dist/plot/box/kde.js +4 -4
  233. package/dist/plot/core/auto-place.d.ts +1 -1
  234. package/dist/plot/core/auto-place.js +5 -2
  235. package/dist/plot/core/axis-utils.d.ts +12 -7
  236. package/dist/plot/core/axis-utils.js +48 -48
  237. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  238. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  239. package/dist/plot/core/components/ColorBar.svelte +106 -111
  240. package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
  241. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  242. package/dist/plot/core/components/FillArea.svelte +10 -17
  243. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  244. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  245. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  246. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  247. package/dist/plot/core/components/Line.svelte +21 -11
  248. package/dist/plot/core/components/Line.svelte.d.ts +5 -2
  249. package/dist/plot/core/components/PlotAxis.svelte +42 -18
  250. package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
  251. package/dist/plot/core/components/PlotControls.svelte +65 -41
  252. package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
  253. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  254. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  255. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  256. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  257. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  258. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  259. package/dist/plot/core/components/ReferenceLine3D.svelte +56 -59
  260. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
  261. package/dist/plot/core/components/ReferencePlane.svelte +9 -10
  262. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
  263. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  264. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  265. package/dist/plot/core/components/index.d.ts +1 -0
  266. package/dist/plot/core/components/index.js +1 -0
  267. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  268. package/dist/plot/core/data-cleaning-signal.js +467 -0
  269. package/dist/plot/core/data-cleaning.d.ts +2 -42
  270. package/dist/plot/core/data-cleaning.js +29 -476
  271. package/dist/plot/core/data-transform.js +9 -5
  272. package/dist/plot/core/fill-utils.d.ts +7 -4
  273. package/dist/plot/core/fill-utils.js +34 -9
  274. package/dist/plot/core/index.d.ts +1 -0
  275. package/dist/plot/core/index.js +1 -0
  276. package/dist/plot/core/interactions.d.ts +5 -1
  277. package/dist/plot/core/interactions.js +14 -2
  278. package/dist/plot/core/layout.d.ts +3 -1
  279. package/dist/plot/core/layout.js +22 -13
  280. package/dist/plot/core/marginals.d.ts +170 -0
  281. package/dist/plot/core/marginals.js +436 -0
  282. package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
  283. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  284. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -0
  286. package/dist/plot/core/reference-line.d.ts +10 -10
  287. package/dist/plot/core/reference-line.js +7 -7
  288. package/dist/plot/core/scales.d.ts +40 -25
  289. package/dist/plot/core/scales.js +49 -21
  290. package/dist/plot/core/svg.d.ts +2 -1
  291. package/dist/plot/core/types/fills.d.ts +101 -0
  292. package/dist/plot/core/types/fills.js +15 -0
  293. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  294. package/dist/plot/core/types/plot-3d.js +4 -0
  295. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  296. package/dist/plot/core/types/reference-lines.js +9 -0
  297. package/dist/plot/core/types.d.ts +47 -331
  298. package/dist/plot/core/types.js +23 -20
  299. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  300. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  301. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  302. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  303. package/dist/plot/core/utils/label-placement.d.ts +1 -1
  304. package/dist/plot/core/utils/label-placement.js +5 -5
  305. package/dist/plot/core/utils.d.ts +2 -1
  306. package/dist/plot/histogram/Histogram.svelte +373 -631
  307. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  308. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  309. package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
  310. package/dist/plot/histogram/histogram.d.ts +31 -0
  311. package/dist/plot/histogram/histogram.js +70 -0
  312. package/dist/plot/histogram/index.d.ts +1 -0
  313. package/dist/plot/histogram/index.js +1 -0
  314. package/dist/plot/index.d.ts +1 -0
  315. package/dist/plot/index.js +1 -0
  316. package/dist/plot/sankey/Sankey.svelte +79 -73
  317. package/dist/plot/sankey/Sankey.svelte.d.ts +3 -3
  318. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  319. package/dist/plot/sankey/sankey.js +3 -1
  320. package/dist/plot/scatter/BinnedScatterPlot.svelte +264 -112
  321. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +11 -4
  322. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  323. package/dist/plot/scatter/ScatterPlot.svelte +623 -821
  324. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +9 -15
  325. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  326. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  327. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  328. package/dist/plot/scatter/binned-scatter-types.d.ts +6 -12
  329. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  330. package/dist/plot/scatter/index.d.ts +1 -1
  331. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  332. package/dist/plot/scatter/scatter-data.js +8 -7
  333. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +40 -60
  334. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
  335. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +17 -15
  336. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
  337. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +232 -234
  338. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
  339. package/dist/plot/scatter-3d/Surface3D.svelte +9 -17
  340. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
  341. package/dist/plot/sunburst/Sunburst.svelte +256 -338
  342. package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
  343. package/dist/plot/sunburst/index.d.ts +1 -1
  344. package/dist/plot/sunburst/index.js +2 -1
  345. package/dist/plot/sunburst/render.d.ts +2 -2
  346. package/dist/plot/sunburst/render.js +47 -22
  347. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  348. package/dist/plot/sunburst/sunburst.js +14 -4
  349. package/dist/plot/treemap/Treemap.svelte +907 -0
  350. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  351. package/dist/plot/treemap/index.d.ts +3 -0
  352. package/dist/plot/treemap/index.js +4 -0
  353. package/dist/plot/treemap/treemap.d.ts +26 -0
  354. package/dist/plot/treemap/treemap.js +99 -0
  355. package/dist/rdf/RdfPlot.svelte +22 -26
  356. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  357. package/dist/rdf/calc-rdf.js +4 -8
  358. package/dist/sanitize.js +14 -3
  359. package/dist/scene/SceneCamera.svelte +62 -0
  360. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  361. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  362. package/dist/scene/bind-renderer.svelte.js +22 -0
  363. package/dist/scene/index.d.ts +4 -0
  364. package/dist/scene/index.js +5 -0
  365. package/dist/scene/props.js +52 -0
  366. package/dist/scene/types.d.ts +26 -0
  367. package/dist/scene/types.js +1 -0
  368. package/dist/settings.d.ts +33 -11
  369. package/dist/settings.js +136 -51
  370. package/dist/spectral/Bands.svelte +231 -237
  371. package/dist/spectral/Bands.svelte.d.ts +3 -2
  372. package/dist/spectral/BandsAndDos.svelte +29 -29
  373. package/dist/spectral/BrillouinBandsDos.svelte +21 -29
  374. package/dist/spectral/Dos.svelte +75 -77
  375. package/dist/spectral/Dos.svelte.d.ts +2 -1
  376. package/dist/spectral/helpers.d.ts +9 -9
  377. package/dist/spectral/helpers.js +66 -70
  378. package/dist/state.svelte.d.ts +0 -7
  379. package/dist/state.svelte.js +5 -24
  380. package/dist/structure/Arrow.svelte +6 -21
  381. package/dist/structure/ArrowInstances.svelte +160 -0
  382. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  383. package/dist/structure/AtomLegend.svelte +115 -75
  384. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  385. package/dist/structure/Bond.svelte +31 -23
  386. package/dist/structure/CanvasTooltip.svelte +16 -3
  387. package/dist/structure/CellSelect.svelte +22 -29
  388. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  389. package/dist/structure/Cylinder.svelte +24 -40
  390. package/dist/structure/InstancedAtoms.svelte +114 -0
  391. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  392. package/dist/structure/Lattice.svelte +85 -149
  393. package/dist/structure/SiteLabels.svelte +122 -0
  394. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  395. package/dist/structure/Structure.svelte +725 -735
  396. package/dist/structure/Structure.svelte.d.ts +8 -16
  397. package/dist/structure/StructureCarousel.svelte +630 -0
  398. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  399. package/dist/structure/StructureControls.svelte +298 -325
  400. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  401. package/dist/structure/StructureExportPane.svelte +62 -168
  402. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  403. package/dist/structure/StructureInfoPane.svelte +77 -69
  404. package/dist/structure/StructureInfoPane.svelte.d.ts +6 -6
  405. package/dist/structure/StructureScene.svelte +758 -600
  406. package/dist/structure/StructureScene.svelte.d.ts +24 -20
  407. package/dist/structure/StructureViewport.svelte +386 -0
  408. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  409. package/dist/structure/atom-label-placement.d.ts +18 -0
  410. package/dist/structure/atom-label-placement.js +115 -0
  411. package/dist/structure/atom-properties.d.ts +3 -1
  412. package/dist/structure/atom-properties.js +115 -54
  413. package/dist/structure/bond-order-perception.js +2 -4
  414. package/dist/structure/bonding.d.ts +12 -2
  415. package/dist/structure/bonding.js +172 -73
  416. package/dist/structure/edit-history.d.ts +6 -0
  417. package/dist/structure/edit-history.js +27 -0
  418. package/dist/structure/export.d.ts +25 -4
  419. package/dist/structure/export.js +103 -153
  420. package/dist/structure/format-detect.d.ts +1 -0
  421. package/dist/structure/format-detect.js +22 -0
  422. package/dist/structure/geometry.d.ts +9 -0
  423. package/dist/structure/geometry.js +27 -0
  424. package/dist/structure/index.d.ts +18 -1
  425. package/dist/structure/index.js +15 -2
  426. package/dist/structure/measure.d.ts +1 -1
  427. package/dist/structure/measure.js +6 -12
  428. package/dist/structure/parse.d.ts +5 -3
  429. package/dist/structure/parse.js +551 -567
  430. package/dist/structure/partial-occupancy.d.ts +0 -1
  431. package/dist/structure/partial-occupancy.js +5 -3
  432. package/dist/structure/pbc.d.ts +1 -1
  433. package/dist/structure/pbc.js +204 -51
  434. package/dist/structure/polyhedra.d.ts +40 -0
  435. package/dist/structure/polyhedra.js +587 -0
  436. package/dist/structure/site.d.ts +4 -0
  437. package/dist/structure/site.js +1 -0
  438. package/dist/structure/supercell.d.ts +1 -2
  439. package/dist/structure/supercell.js +10 -15
  440. package/dist/structure/validation.js +5 -6
  441. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  442. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  443. package/dist/symmetry/SymmetryElements.svelte +350 -0
  444. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  445. package/dist/symmetry/SymmetryStats.svelte +142 -49
  446. package/dist/symmetry/WyckoffTable.svelte +58 -16
  447. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  448. package/dist/symmetry/cell-transform.js +8 -14
  449. package/dist/symmetry/index.d.ts +15 -4
  450. package/dist/symmetry/index.js +308 -81
  451. package/dist/symmetry/spacegroups.d.ts +5 -1
  452. package/dist/symmetry/spacegroups.js +18 -3
  453. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  454. package/dist/symmetry/symmetry-elements.js +521 -0
  455. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  456. package/dist/symmetry/wyckoff-db.js +87 -0
  457. package/dist/table/HeatmapTable.svelte +1104 -378
  458. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  459. package/dist/table/ToggleMenu.svelte +5 -12
  460. package/dist/table/index.d.ts +21 -6
  461. package/dist/table/index.js +34 -21
  462. package/dist/theme/ThemeControl.svelte +16 -8
  463. package/dist/theme/index.d.ts +1 -5
  464. package/dist/theme/index.js +4 -10
  465. package/dist/theme/themes.mjs +14 -7
  466. package/dist/tooltip/KCoords.svelte +4 -1
  467. package/dist/tooltip/TooltipContent.svelte +2 -5
  468. package/dist/trajectory/Trajectory.svelte +556 -352
  469. package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
  470. package/dist/trajectory/TrajectoryError.svelte +11 -8
  471. package/dist/trajectory/TrajectoryExportPane.svelte +28 -54
  472. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  473. package/dist/trajectory/TrajectoryInfoPane.svelte +88 -99
  474. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  475. package/dist/trajectory/constants.js +6 -2
  476. package/dist/trajectory/extract.js +73 -71
  477. package/dist/trajectory/format-detect.d.ts +0 -1
  478. package/dist/trajectory/format-detect.js +13 -17
  479. package/dist/trajectory/frame-reader.d.ts +2 -1
  480. package/dist/trajectory/frame-reader.js +74 -136
  481. package/dist/trajectory/helpers.d.ts +12 -2
  482. package/dist/trajectory/helpers.js +68 -37
  483. package/dist/trajectory/index.d.ts +1 -0
  484. package/dist/trajectory/index.js +3 -0
  485. package/dist/trajectory/parse/ase.d.ts +9 -1
  486. package/dist/trajectory/parse/ase.js +47 -32
  487. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  488. package/dist/trajectory/parse/diagnostics.js +14 -0
  489. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  490. package/dist/trajectory/parse/h5-utils.js +109 -0
  491. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  492. package/dist/trajectory/parse/hdf5.js +116 -106
  493. package/dist/trajectory/parse/index.d.ts +3 -4
  494. package/dist/trajectory/parse/index.js +68 -119
  495. package/dist/trajectory/parse/lammps.d.ts +0 -2
  496. package/dist/trajectory/parse/lammps.js +14 -16
  497. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  498. package/dist/trajectory/parse/pymatgen.js +74 -0
  499. package/dist/trajectory/parse/vasp.js +13 -9
  500. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  501. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  502. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  503. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  504. package/dist/trajectory/parse/xyz.d.ts +9 -21
  505. package/dist/trajectory/parse/xyz.js +38 -39
  506. package/dist/trajectory/plotting.d.ts +8 -10
  507. package/dist/trajectory/plotting.js +102 -127
  508. package/dist/utils.d.ts +4 -0
  509. package/dist/utils.js +8 -1
  510. package/dist/xrd/XrdPlot.svelte +56 -85
  511. package/dist/xrd/broadening.d.ts +2 -1
  512. package/dist/xrd/broadening.js +2 -1
  513. package/dist/xrd/calc-xrd.js +8 -15
  514. package/dist/xrd/index.d.ts +2 -2
  515. package/dist/xrd/parse.d.ts +0 -1
  516. package/dist/xrd/parse.js +56 -73
  517. package/package.json +77 -36
  518. package/dist/api/mp.d.ts +0 -6
  519. package/dist/api/mp.js +0 -22
  520. package/dist/element/data.json +0 -11864
  521. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  522. package/dist/fermi-surface/marching-cubes.js +0 -2
  523. package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
  524. package/dist/plot/core/hover-lock.svelte.js +0 -45
  525. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  526. package/dist/structure/label-placement.d.ts +0 -14
  527. package/dist/structure/label-placement.js +0 -72
@@ -1,10 +1,17 @@
1
1
  import { ATOMIC_NUMBER_TO_SYMBOL, SYMBOL_TO_ATOMIC_NUMBER } from '../composition/parse';
2
+ import * as math from '../math';
2
3
  import { DEFAULTS } from '../settings';
3
4
  import { merge_split_partial_sites } from '../structure/partial-occupancy';
4
5
  import init, { analyze_cell } from '@spglib/moyo-wasm';
5
6
  import moyo_wasm_url from '@spglib/moyo-wasm/moyo_wasm_bg.wasm?url';
7
+ import { mat3_from_flat_col_major } from './symmetry-elements';
8
+ import { wyckoff_letter } from './wyckoff-db';
6
9
  export * from './cell-transform';
7
10
  export * from './spacegroups';
11
+ export * from './symmetry-elements';
12
+ export * from './wyckoff-db';
13
+ export { default as SymmetryElementControls } from './SymmetryElementControls.svelte';
14
+ export { default as SymmetryElements } from './SymmetryElements.svelte';
8
15
  export { default as SymmetryStats } from './SymmetryStats.svelte';
9
16
  export { default as WyckoffTable } from './WyckoffTable.svelte';
10
17
  // Keys are standard crystallographic symbols (P, I, F, A, B, C, R)
@@ -27,13 +34,37 @@ const to_unit = (value) => value - Math.floor(value);
27
34
  const near_zero = (value) => Math.min(value, 1 - value);
28
35
  const near_half = (value) => Math.abs(value - 0.5);
29
36
  const symmetry_position_key = (pos) => pos.map((coord) => to_unit(coord).toFixed(8)).join(`,`);
30
- const periodic_distance = (pos1, pos2) => Math.sqrt(pos1.reduce((sum, coord, idx) => {
31
- // Wrap delta into [-0.5, 0.5) using safe modulo
32
- const delta = coord - pos2[idx];
33
- const wrapped = ((((delta + 0.5) % 1) + 1) % 1) - 0.5;
34
- const distance = Math.abs(wrapped);
35
- return sum + distance * distance;
36
- }, 0));
37
+ const is_near_integer_vec = (vec, tol) => vec.every((coord) => Math.abs(coord - Math.round(coord)) < tol);
38
+ // Wrap fractional coordinates into [0, 1), snapping values within 1e-9 of 1 back to 0.
39
+ // NOTE on epsilon: 1e-9 is deliberately looser than wrap_frac_coord @1e-10
40
+ // [[src/lib/structure/pbc.ts:26]] because inputs here passed through moyo
41
+ // standardization plus a P⁻¹(x − p) matrix transform (make_frac_coord_mapper),
42
+ // accumulating more float error than freshly parsed coords. It is tighter than
43
+ // wrap_point @1e-8 [[src/lib/symmetry/symmetry-elements.ts:214]], which must
44
+ // keep dedup keys stable for fixed points solved from linear systems. Do not
45
+ // unify: each epsilon matches the noise level of its inputs.
46
+ const wrap_frac = (pos) => pos.map((coord) => {
47
+ const wrapped = coord - Math.floor(coord);
48
+ return wrapped > 1 - 1e-9 ? 0 : wrapped;
49
+ });
50
+ // Build a mapper from input-cell to standardized-cell fractional coordinates.
51
+ // moyo's (std_linear P, std_origin_shift p) follow the ITA convention for the
52
+ // transformation from the input cell to the standardized cell: x_std = P⁻¹ (x_input − p).
53
+ // Returns null if std_linear is absent or singular.
54
+ function make_frac_coord_mapper(linear_flat, origin_shift) {
55
+ if (linear_flat?.length !== 9)
56
+ return null;
57
+ try {
58
+ const linear = mat3_from_flat_col_major(linear_flat);
59
+ const linear_inv = math.matrix_inverse_3x3(linear);
60
+ const shift = (origin_shift ?? [0, 0, 0]);
61
+ const to_std = (pos) => math.mat3x3_vec3_multiply(linear_inv, math.subtract(pos, shift));
62
+ return { to_std, linear, linear_inv, shift };
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
37
68
  export async function ensure_moyo_wasm_ready(wasm_url) {
38
69
  if (initialized)
39
70
  return;
@@ -93,23 +124,42 @@ export function to_cell_json(structure) {
93
124
  const fractional_sq_dist = (pos_1, pos_2) => (pos_1[0] - pos_2[0] - Math.round(pos_1[0] - pos_2[0])) ** 2 +
94
125
  (pos_1[1] - pos_2[1] - Math.round(pos_1[1] - pos_2[1])) ** 2 +
95
126
  (pos_1[2] - pos_2[2] - Math.round(pos_1[2] - pos_2[2])) ** 2;
96
- export const map_std_to_orig_site_indices = (std_positions, std_numbers, input_positions, input_numbers, orig_site_indices_by_input_idx) => std_positions.map((std_pos, std_idx) => {
97
- const std_number = std_numbers[std_idx];
98
- let nearest_input_idx = -1;
99
- let nearest_sq_dist = Infinity;
100
- for (let input_idx = 0; input_idx < input_positions.length; input_idx += 1) {
101
- if (input_numbers[input_idx] !== std_number)
102
- continue;
103
- const sq_dist = fractional_sq_dist(std_pos, input_positions[input_idx]);
104
- if (sq_dist < nearest_sq_dist) {
105
- nearest_sq_dist = sq_dist;
106
- nearest_input_idx = input_idx;
127
+ // Map each standardized-cell site to the input-cell site it descends from, then to
128
+ // original structure indices. When moyo's (std_linear, std_origin_shift) transform is
129
+ // provided, std positions are first mapped into the input frame via x_in = P·x_std + p
130
+ // (the std and input cells use DIFFERENT bases in general, so comparing raw fractional
131
+ // coordinates across them is meaningless). Matches account for crystal translations of
132
+ // both lattices: a difference d is a translation if d ∈ ℤ³ (input lattice) or P⁻¹d ∈ ℤ³
133
+ // (standardized lattice expressed in the input frame).
134
+ export const map_std_to_orig_site_indices = (std_positions, std_numbers, input_positions, input_numbers, orig_site_indices_by_input_idx, transform, tol = 1e-4) => {
135
+ const mapper = make_frac_coord_mapper(transform?.std_linear, transform?.std_origin_shift);
136
+ return std_positions.map((std_pos, std_idx) => {
137
+ // Predicted input-frame position of this std site: x_in = P·x_std + p
138
+ const pred = mapper
139
+ ? math.add(math.mat3x3_vec3_multiply(mapper.linear, std_pos), mapper.shift)
140
+ : std_pos;
141
+ const std_number = std_numbers[std_idx];
142
+ let nearest_input_idx = -1;
143
+ let nearest_sq_dist = Infinity;
144
+ for (let input_idx = 0; input_idx < input_positions.length; input_idx += 1) {
145
+ if (input_numbers[input_idx] !== std_number)
146
+ continue;
147
+ const delta = math.subtract(pred, input_positions[input_idx]);
148
+ // Exact match modulo a translation of the standardized lattice
149
+ const is_std_translation = mapper && is_near_integer_vec(math.mat3x3_vec3_multiply(mapper.linear_inv, delta), tol);
150
+ const sq_dist = is_std_translation
151
+ ? 0
152
+ : fractional_sq_dist(pred, input_positions[input_idx]);
153
+ if (sq_dist < nearest_sq_dist) {
154
+ nearest_sq_dist = sq_dist;
155
+ nearest_input_idx = input_idx;
156
+ }
107
157
  }
108
- }
109
- if (nearest_input_idx === -1)
110
- return [];
111
- return orig_site_indices_by_input_idx[nearest_input_idx] ?? [];
112
- });
158
+ if (nearest_input_idx === -1)
159
+ return [];
160
+ return orig_site_indices_by_input_idx[nearest_input_idx] ?? [];
161
+ });
162
+ };
113
163
  export async function analyze_structure_symmetry(struct_or_mol, settings) {
114
164
  await ensure_moyo_wasm_ready();
115
165
  if (!(`lattice` in struct_or_mol)) {
@@ -121,8 +171,16 @@ export async function analyze_structure_symmetry(struct_or_mol, settings) {
121
171
  // Map "Moyo" to "Standard" for moyo-wasm
122
172
  const moyo_algo = algo === `Moyo` ? `Standard` : algo;
123
173
  const sym_data = analyze_cell(cell_json, symprec, moyo_algo);
124
- const orig_site_indices_by_std_idx = map_std_to_orig_site_indices(sym_data.std_cell.positions, sym_data.std_cell.numbers, moyo_input_cell.positions, moyo_input_cell.numbers, moyo_input_cell.orig_site_indices_by_input_idx);
125
- return { ...sym_data, orig_site_indices_by_std_idx };
174
+ const orig_site_indices_by_std_idx = map_std_to_orig_site_indices(sym_data.std_cell.positions, sym_data.std_cell.numbers, moyo_input_cell.positions, moyo_input_cell.numbers, moyo_input_cell.orig_site_indices_by_input_idx, { std_linear: sym_data.std_linear, std_origin_shift: sym_data.std_origin_shift }, Math.max(1e-5, symprec * 10));
175
+ return {
176
+ ...sym_data,
177
+ orig_site_indices_by_std_idx,
178
+ input_cell: {
179
+ positions: moyo_input_cell.positions,
180
+ numbers: moyo_input_cell.numbers,
181
+ },
182
+ orig_site_indices_by_input_idx: moyo_input_cell.orig_site_indices_by_input_idx,
183
+ };
126
184
  }
127
185
  // Helper function to score coordinate simplicity for Wyckoff table
128
186
  export function simplicity_score(vec) {
@@ -132,59 +190,72 @@ export function simplicity_score(vec) {
132
190
  near_zero(az) +
133
191
  0.5 * (near_half(ax) + near_half(ay) + near_half(az)));
134
192
  }
135
- // Generate Wyckoff table rows from symmetry data
136
- export function wyckoff_positions_from_moyo(sym_data) {
137
- if (!sym_data)
138
- return [];
139
- const { positions, numbers } = sym_data.std_cell;
140
- const { wyckoffs, orig_indices, orig_site_indices_by_std_idx } = sym_data;
141
- // Group sites by letter-element combination and track all indices
142
- const groups = new Map();
143
- // Process all atoms in the standardized cell
144
- // Note: wyckoffs array may be shorter than std_cell when moyo combines symmetry-equivalent sites
145
- for (let idx = 0; idx < numbers.length; idx++) {
146
- // Use wyckoff letter if available, otherwise mark as non-symmetric
147
- const full = idx < wyckoffs.length ? wyckoffs[idx] : null;
148
- const letter = full?.match(/[a-z]+$/)?.[0] ?? full ?? ``;
149
- const atomic_num = numbers[idx];
150
- const elem = ATOMIC_NUMBER_TO_SYMBOL[atomic_num] ?? `?`;
151
- const position = positions[idx];
152
- const key = letter ? `${letter}|${elem}` : `nosym|${elem}|${idx}`;
153
- const group = groups.get(key) ?? { letter, elem, indices: [], positions: [] };
154
- group.indices.push(idx);
155
- group.positions.push(position);
156
- groups.set(key, group);
157
- }
158
- const rows = Array.from(groups.values()).map(({ letter, elem, indices, positions: group_positions }) => {
159
- // Find the position with the best simplicity score to display
160
- const best_pos = group_positions.reduce((best, pos) => {
161
- const score = simplicity_score(pos);
162
- return score < best.score ? { pos, score } : best;
163
- }, { pos: group_positions[0], score: simplicity_score(group_positions[0]) }).pos;
164
- // Map standardized cell indices back to original structure indices
165
- const orig_site_indices = orig_site_indices_by_std_idx
166
- ? indices.flatMap((std_idx) => orig_site_indices_by_std_idx[std_idx] ?? [])
167
- : orig_indices
168
- ? indices.map((std_idx) => orig_indices[std_idx]).filter((idx) => idx !== undefined)
169
- : indices;
170
- const wyckoff = letter ? `${indices.length}${letter}` : `1`;
193
+ // Pick the representative coordinate with the lowest simplicity score (ties keep first)
194
+ const simplest_position = (positions) => positions.reduce((best, pos) => simplicity_score(pos) < simplicity_score(best) ? pos : best);
195
+ // Build Wyckoff rows from moyo's input-cell orbits. moyo's per-site arrays (wyckoffs,
196
+ // orbits, site_symmetry_symbols) are indexed by INPUT cell sites — NOT std_cell sites —
197
+ // so rows must be derived by grouping input sites into crystallographic orbits.
198
+ // Multiplicity in the conventional cell is the orbit size scaled by the std/input cell
199
+ // size ratio (e.g. a 1-atom primitive FCC input has orbit size 1 but multiplicity 4).
200
+ function wyckoff_rows_from_input_orbits(sym_data) {
201
+ const { input_cell, orbits, wyckoffs, site_symmetry_symbols, std_cell, orig_site_indices_by_input_idx, } = sym_data;
202
+ const n_input = input_cell?.positions.length ?? 0;
203
+ if (!input_cell || n_input === 0)
204
+ return null;
205
+ if (orbits?.length !== n_input || wyckoffs?.length !== n_input)
206
+ return null;
207
+ const mapper = make_frac_coord_mapper(sym_data.std_linear, sym_data.std_origin_shift);
208
+ if (!mapper)
209
+ return null;
210
+ // Group input-cell sites by crystallographic orbit (keyed by orbit representative).
211
+ // Distinct orbits sharing the same Wyckoff letter and element stay separate rows.
212
+ const orbit_members = new Map();
213
+ orbits.forEach((rep, idx) => {
214
+ const members = orbit_members.get(rep) ?? [];
215
+ members.push(idx);
216
+ orbit_members.set(rep, members);
217
+ });
218
+ const n_std = std_cell?.positions.length ?? n_input;
219
+ return [...orbit_members.entries()].map(([rep, members]) => {
220
+ const letter = wyckoff_letter(wyckoffs[rep] ?? ``);
221
+ const elem = ATOMIC_NUMBER_TO_SYMBOL[input_cell.numbers[rep]] ?? `?`;
222
+ const multiplicity = Math.round((members.length * n_std) / n_input);
223
+ // Representative coordinate in the standardized frame, simplest first
224
+ const best_pos = simplest_position(members.map((idx) => wrap_frac(mapper.to_std(input_cell.positions[idx]))));
225
+ const orig_site_indices = members.flatMap((idx) => orig_site_indices_by_input_idx?.[idx] ?? [idx]);
226
+ const site_symmetry = site_symmetry_symbols?.[rep];
171
227
  return {
172
- wyckoff,
228
+ wyckoff: letter ? `${multiplicity}${letter}` : `${multiplicity}`,
173
229
  elem,
174
230
  abc: best_pos,
175
231
  site_indices: [...new Set(orig_site_indices)].sort((idx_a, idx_b) => idx_a - idx_b),
232
+ ...(site_symmetry ? { site_symmetry } : {}),
176
233
  };
177
234
  });
178
- rows.sort((w1, w2) => {
179
- const [w1_mult, w2_mult] = [parseInt(w1.wyckoff, 10), parseInt(w2.wyckoff, 10)];
235
+ }
236
+ // Generate Wyckoff table rows from symmetry data by grouping moyo's input-cell sites into
237
+ // crystallographic orbits. moyo's per-site arrays (wyckoffs, orbits, site_symmetry_symbols)
238
+ // always index the input cell and analyze_structure_symmetry always attaches input_cell, so
239
+ // the orbit grouping is the single source of truth for any input cell setting.
240
+ // Rows sort by ascending multiplicity, then Wyckoff label.
241
+ // Numeric multiplicity prefix of a Wyckoff label like `4a` (NaN when absent)
242
+ export const wyckoff_multiplicity = (label) => Number(/^\d+/.exec(label)?.[0] ?? NaN);
243
+ export function wyckoff_positions_from_moyo(sym_data) {
244
+ if (!sym_data)
245
+ return [];
246
+ const orbit_rows = wyckoff_rows_from_input_orbits(sym_data);
247
+ return (orbit_rows ?? []).sort((w1, w2) => {
248
+ const [w1_mult, w2_mult] = [
249
+ wyckoff_multiplicity(w1.wyckoff),
250
+ wyckoff_multiplicity(w2.wyckoff),
251
+ ];
180
252
  if (w1_mult !== w2_mult)
181
253
  return w1_mult - w2_mult;
182
254
  return w1.wyckoff.localeCompare(w2.wyckoff);
183
255
  });
184
- return rows;
185
256
  }
186
257
  // Apply symmetry operations to find all equivalent positions for a given fractional coordinate
187
- export function apply_symmetry_operations(position, operations, _tolerance = 1e-6) {
258
+ export function apply_symmetry_operations(position, operations) {
188
259
  const seen = new Set();
189
260
  return operations
190
261
  .map(({ rotation, translation }) => {
@@ -203,24 +274,180 @@ export function apply_symmetry_operations(position, operations, _tolerance = 1e-
203
274
  return true;
204
275
  });
205
276
  }
206
- // Map Wyckoff positions to all equivalent atoms in the displayed structure (including image atoms)
277
+ // Build candidate frames for the displayed structure: original, conventional (moyo
278
+ // std_cell), and primitive (moyo prim_std_cell). The displayed structure's fractional
279
+ // coordinates only match symmetry-equivalent positions when expressed in the same frame.
280
+ function candidate_display_frames(orig_structure, sym_data) {
281
+ const frames = [
282
+ {
283
+ lattice: orig_structure.lattice.matrix,
284
+ map_equiv: (pos) => pos,
285
+ input_translation_check: null,
286
+ },
287
+ ];
288
+ const cells = [
289
+ { cell: sym_data.std_cell, linear: sym_data.std_linear, shift: sym_data.std_origin_shift },
290
+ {
291
+ cell: sym_data.prim_std_cell,
292
+ linear: sym_data.prim_std_linear,
293
+ shift: sym_data.prim_std_origin_shift,
294
+ },
295
+ ];
296
+ for (const { cell, linear, shift } of cells) {
297
+ const basis = cell?.lattice?.basis;
298
+ const mapper = make_frac_coord_mapper(linear, shift);
299
+ if (basis?.length !== 9 || !mapper)
300
+ continue;
301
+ // basis is row-major (each row a lattice vector); same reshape as moyo_cell_to_structure
302
+ frames.push({
303
+ lattice: math.vec9_to_mat3x3([...basis]),
304
+ map_equiv: mapper.to_std,
305
+ input_translation_check: mapper.linear,
306
+ });
307
+ }
308
+ return frames;
309
+ }
310
+ // Spatial hash over wrapped fractional coordinates for tolerance-based, mod-1 position
311
+ // lookups. Cell size is chosen ≥ tolerance so probing the ±1 neighbor cells (with
312
+ // wraparound) covers every point within tolerance of the query.
313
+ class WrappedPositionIndex {
314
+ tolerance;
315
+ buckets = new Map();
316
+ coords;
317
+ n_cells;
318
+ constructor(positions, tolerance) {
319
+ this.tolerance = tolerance;
320
+ const inv_tolerance = Math.floor(1 / Math.max(tolerance, 1e-9));
321
+ this.n_cells = Math.min(64, Math.max(1, inv_tolerance));
322
+ this.coords = positions;
323
+ positions.forEach((pos, idx) => {
324
+ const key = this.cell_key(pos, 0, 0, 0);
325
+ const bucket = this.buckets.get(key);
326
+ if (bucket)
327
+ bucket.push(idx);
328
+ else
329
+ this.buckets.set(key, [idx]);
330
+ });
331
+ }
332
+ cell_key(pos, dx, dy, dz) {
333
+ const n_cells = this.n_cells;
334
+ const cell = (coord, offset) => {
335
+ const wrapped = coord - Math.floor(coord);
336
+ return (((Math.floor(wrapped * n_cells) + offset) % n_cells) + n_cells) % n_cells;
337
+ };
338
+ return `${cell(pos[0], dx)},${cell(pos[1], dy)},${cell(pos[2], dz)}`;
339
+ }
340
+ // Indices of stored positions within `tolerance` of `query` modulo ℤ³
341
+ query(query, out) {
342
+ const tol = this.tolerance;
343
+ for (let dx = -1; dx <= 1; dx++) {
344
+ for (let dy = -1; dy <= 1; dy++) {
345
+ for (let dz = -1; dz <= 1; dz++) {
346
+ const bucket = this.buckets.get(this.cell_key(query, dx, dy, dz));
347
+ if (!bucket)
348
+ continue;
349
+ for (const idx of bucket) {
350
+ const pos = this.coords[idx];
351
+ const d0 = pos[0] - query[0];
352
+ const d1 = pos[1] - query[1];
353
+ const d2 = pos[2] - query[2];
354
+ if (Math.abs(d0 - Math.round(d0)) < tol &&
355
+ Math.abs(d1 - Math.round(d1)) < tol &&
356
+ Math.abs(d2 - Math.round(d2)) < tol)
357
+ out.add(idx);
358
+ }
359
+ }
360
+ }
361
+ }
362
+ }
363
+ }
364
+ // Map Wyckoff positions to all equivalent atoms in the displayed structure (including
365
+ // image atoms). Handles displayed structures in the original frame as well as
366
+ // conventional/primitive cell transforms and integer supercells of any of those: the
367
+ // displayed lattice L_disp is matched against each candidate frame's lattice L_F via
368
+ // S = L_disp·L_F⁻¹ (S must be near-integer), displayed coords are converted into the
369
+ // frame via x_F = x_disp·S, and matches allow crystal translations of both the frame
370
+ // lattice (d ∈ ℤ³) and the input lattice (P·d ∈ ℤ³). Matching uses spatial hashing:
371
+ // O(N_disp + N_orig·N_ops) instead of O(N_orig·N_disp·N_ops).
207
372
  export function map_wyckoff_to_all_atoms(wyckoff_positions, displayed_structure, orig_structure, sym_data, tolerance = 1e-5) {
208
373
  if (!sym_data?.operations || !displayed_structure.sites || !orig_structure.sites) {
209
374
  return wyckoff_positions;
210
375
  }
211
- return wyckoff_positions.map((wyckoff_pos) => {
212
- const indices = (wyckoff_pos.site_indices ?? [])
213
- .filter((idx) => idx < orig_structure.sites.length)
214
- .flatMap((orig_idx) => {
215
- const { abc: orig_abc, species } = orig_structure.sites[orig_idx];
216
- const element = species[0]?.element;
217
- const equivalent_positions = apply_symmetry_operations(orig_abc, sym_data.operations, tolerance);
218
- return displayed_structure.sites
219
- .map((site, display_idx) => ({ site, display_idx }))
220
- .filter(({ site }) => site.species[0]?.element === element)
221
- .filter(({ site }) => equivalent_positions.some((equiv_pos) => periodic_distance(equiv_pos, site.abc) < tolerance))
222
- .map(({ display_idx }) => display_idx);
376
+ const map_in_frame = (frame) => {
377
+ // Supercell factor S = L_disp·L_F⁻¹ must be a near-integer matrix with |det| ≥ 1
378
+ let scaling;
379
+ try {
380
+ scaling = math.dot(displayed_structure.lattice.matrix, math.matrix_inverse_3x3(frame.lattice));
381
+ }
382
+ catch {
383
+ return null;
384
+ }
385
+ const is_integer_scaling = scaling.every((row) => row.every((val) => Math.abs(val - Math.round(val)) < tolerance));
386
+ if (!is_integer_scaling || Math.abs(math.det_3x3(scaling)) < 0.99)
387
+ return null;
388
+ // Displayed site coords expressed in frame-F fractional coordinates: x_F = x_disp·S
389
+ const scaling_transpose = math.transpose_3x3_matrix(scaling);
390
+ const displayed_frame_coords = displayed_structure.sites.map((site) => math.mat3x3_vec3_multiply(scaling_transpose, site.abc));
391
+ const displayed_elements = displayed_structure.sites.map((site) => site.species[0]?.element);
392
+ // Spatial hashes: one over the frame coords directly (matches d ∈ ℤ³), and one over
393
+ // P·x_F (matches input-lattice translations: d ∈ P⁻¹ℤ³ ⟺ P·d ∈ ℤ³)
394
+ const direct_index = new WrappedPositionIndex(displayed_frame_coords, tolerance);
395
+ const check = frame.input_translation_check;
396
+ const check_index = check
397
+ ? new WrappedPositionIndex(displayed_frame_coords.map((pos) => math.mat3x3_vec3_multiply(check, pos)), tolerance)
398
+ : null;
399
+ let any_matched = false;
400
+ const rows = wyckoff_positions.map((wyckoff_pos) => {
401
+ // Union the symmetry orbits of all original sites in this row, grouped by element.
402
+ // Sites whose (wrapped) position already appears in the accumulated orbit are
403
+ // skipped — orbit members generate identical orbits, so rows with many sites of
404
+ // one orbit (e.g. supercells) only pay for one full operation sweep
405
+ const equiv_by_element = new Map();
406
+ for (const orig_idx of wyckoff_pos.site_indices ?? []) {
407
+ if (orig_idx >= orig_structure.sites.length)
408
+ continue;
409
+ const { abc: orig_abc, species } = orig_structure.sites[orig_idx];
410
+ const element = species[0]?.element;
411
+ const equivalents = equiv_by_element.get(element) ?? new Map();
412
+ equiv_by_element.set(element, equivalents);
413
+ const member_key = symmetry_position_key(frame.map_equiv(orig_abc.map(to_unit)));
414
+ if (equivalents.has(member_key))
415
+ continue;
416
+ for (const equiv_pos of apply_symmetry_operations(orig_abc, sym_data.operations)) {
417
+ const frame_pos = frame.map_equiv(equiv_pos);
418
+ const key = symmetry_position_key(frame_pos);
419
+ if (!equivalents.has(key))
420
+ equivalents.set(key, frame_pos);
421
+ }
422
+ }
423
+ const matched = new Set();
424
+ for (const [element, equivalents] of equiv_by_element) {
425
+ const candidates = new Set();
426
+ for (const equiv_pos of equivalents.values()) {
427
+ direct_index.query(equiv_pos, candidates);
428
+ if (check && check_index) {
429
+ check_index.query(math.mat3x3_vec3_multiply(check, equiv_pos), candidates);
430
+ }
431
+ }
432
+ for (const display_idx of candidates) {
433
+ if (displayed_elements[display_idx] === element)
434
+ matched.add(display_idx);
435
+ }
436
+ }
437
+ if (matched.size > 0)
438
+ any_matched = true;
439
+ return { ...wyckoff_pos, site_indices: [...matched].sort((a, b) => a - b) };
223
440
  });
224
- return { ...wyckoff_pos, site_indices: [...new Set(indices)].sort((a, b) => a - b) };
225
- });
441
+ return any_matched || displayed_structure.sites.length === 0 ? rows : null;
442
+ };
443
+ // Try frames in order; accept the first whose lattice fits AND that matches any site
444
+ // (lattices can coincide across frames while origins differ, so a lattice match alone
445
+ // is not conclusive)
446
+ for (const frame of candidate_display_frames(orig_structure, sym_data)) {
447
+ const rows = map_in_frame(frame);
448
+ if (rows)
449
+ return rows;
450
+ }
451
+ // No frame fits — site indices into the displayed structure cannot be determined
452
+ return wyckoff_positions.map((pos) => ({ ...pos, site_indices: [] }));
226
453
  }
@@ -1,10 +1,14 @@
1
+ import type { Vec2 } from '../math';
1
2
  import type { SunburstNode } from '../plot/core/types';
2
- export declare const CRYSTAL_SYSTEM_RANGES: Record<CrystalSystem, [number, number]>;
3
+ export declare const CRYSTAL_SYSTEM_RANGES: Record<CrystalSystem, Vec2>;
3
4
  export declare const CRYSTAL_SYSTEM_COLORS: Record<CrystalSystem, string>;
4
5
  export declare const CRYSTAL_SYSTEMS: readonly ["triclinic", "monoclinic", "orthorhombic", "tetragonal", "trigonal", "hexagonal", "cubic"];
5
6
  export type CrystalSystem = (typeof CRYSTAL_SYSTEMS)[number];
6
7
  export declare function spacegroup_num_to_crystal_sys(spacegroup: number): CrystalSystem | null;
7
8
  export declare function spacegroup_to_crystal_sys(spacegroup: number | string): CrystalSystem | null;
9
+ export declare const RHOMBOHEDRAL_SPACEGROUPS: readonly number[];
10
+ export type LatticeSystem = Exclude<CrystalSystem, `trigonal`> | `rhombohedral`;
11
+ export declare function spacegroup_num_to_lattice_system(spacegroup: number): LatticeSystem | null;
8
12
  export declare function normalize_spacegroup(spacegroup: number | string): number | null;
9
13
  export declare const SPACEGROUP_SYMBOL_TO_NUM: Record<string, number>;
10
14
  export declare const SPACEGROUP_NUM_TO_SYMBOL: Record<number, string>;
@@ -43,6 +43,20 @@ export function spacegroup_to_crystal_sys(spacegroup) {
43
43
  const num = normalize_spacegroup(spacegroup);
44
44
  return num == null ? null : spacegroup_num_to_crystal_sys(num);
45
45
  }
46
+ // Trigonal space groups with rhombohedral (R-centered) Bravais lattices. All other
47
+ // trigonal groups have primitive hexagonal lattices.
48
+ export const RHOMBOHEDRAL_SPACEGROUPS = [146, 148, 155, 160, 161, 166, 167];
49
+ // Convert space group number to lattice system (classification of the Bravais lattice).
50
+ // Differs from the crystal system only for trigonal groups: R-centered ones (R3, R-3m, …)
51
+ // have rhombohedral lattices while P-trigonal ones (P3, P-3m1, …) have hexagonal lattices.
52
+ export function spacegroup_num_to_lattice_system(spacegroup) {
53
+ const crystal_sys = spacegroup_num_to_crystal_sys(spacegroup);
54
+ if (crystal_sys === null)
55
+ return null;
56
+ if (crystal_sys !== `trigonal`)
57
+ return crystal_sys;
58
+ return RHOMBOHEDRAL_SPACEGROUPS.includes(spacegroup) ? `rhombohedral` : `hexagonal`;
59
+ }
46
60
  // Normalize space group input (number, Hermann-Mauguin symbol, or numeric string
47
61
  // like "225") to a space group number in [1, 230], or null if invalid
48
62
  export function normalize_spacegroup(spacegroup) {
@@ -52,8 +66,9 @@ export function normalize_spacegroup(spacegroup) {
52
66
  const from_symbol = SPACEGROUP_SYMBOL_TO_NUM[spacegroup];
53
67
  if (from_symbol !== undefined)
54
68
  return from_symbol;
55
- const parsed = parseInt(spacegroup, 10);
56
- return isNaN(parsed) ? null : normalize_spacegroup(parsed);
69
+ // Accept trailing setting qualifiers like `146:R` by parsing the leading integer
70
+ const int_match = /^\s*(?<num>\d+)/.exec(spacegroup);
71
+ return int_match ? normalize_spacegroup(Number(int_match[1])) : null;
57
72
  }
58
73
  export const SPACEGROUP_SYMBOL_TO_NUM = {
59
74
  // Triclinic
@@ -202,13 +217,13 @@ export const SPACEGROUP_SYMBOL_TO_NUM = {
202
217
  'I4/mcm': 140,
203
218
  'I4_1/amd': 141,
204
219
  'I4_1/acd': 142,
220
+ // Trigonal
205
221
  P3: 143,
206
222
  P3_1: 144,
207
223
  P3_2: 145,
208
224
  R3: 146,
209
225
  'P-3': 147,
210
226
  'R-3': 148,
211
- // Trigonal
212
227
  P312: 149,
213
228
  P321: 150,
214
229
  P3_112: 151,
@@ -0,0 +1,33 @@
1
+ import type { Matrix3x3, Vec3 } from '../math';
2
+ import type { MoyoDataset } from '@spglib/moyo-wasm';
3
+ export type SymmetryElementKind = `rotation` | `screw` | `mirror` | `glide` | `inversion` | `rotoinversion`;
4
+ export type SymmetryElement = {
5
+ kind: SymmetryElementKind;
6
+ order: number;
7
+ label: string;
8
+ axis: Vec3 | null;
9
+ point: Vec3;
10
+ translation: Vec3 | null;
11
+ };
12
+ export declare const SYM_ELEM_KINDS: readonly ["rotation", "screw", "rotoinversion", "mirror", "glide", "inversion"];
13
+ export type ShowSymmetryKinds = Partial<Record<SymmetryElementKind, boolean>>;
14
+ export declare const DEFAULT_SHOW_SYM_KINDS: ShowSymmetryKinds;
15
+ export declare const SYM_ELEM_KIND_INFO: Record<SymmetryElementKind, {
16
+ label: string;
17
+ color: string;
18
+ }>;
19
+ export declare function count_symmetry_elements(elements: readonly SymmetryElement[]): Partial<Record<SymmetryElementKind, number>>;
20
+ export declare const has_visible_symmetry_overlay: (elements: readonly SymmetryElement[], show_kinds?: ShowSymmetryKinds) => boolean;
21
+ export declare const mat3_from_flat_col_major: (flat: readonly number[]) => Matrix3x3;
22
+ export type ClassifiedOperation = Omit<SymmetryElement, `point`> & {
23
+ point: Vec3;
24
+ };
25
+ export declare function classify_symmetry_op(rotation: readonly number[], translation: readonly number[], centerings?: readonly Vec3[]): ClassifiedOperation | null;
26
+ export declare function symmetry_elements_from_ops(operations: MoyoDataset[`operations`]): SymmetryElement[];
27
+ export declare function dash_segments(length: number, dash: number, gap: number): {
28
+ center: number;
29
+ length: number;
30
+ }[];
31
+ export declare const frac_to_cart_direction: (frac: Vec3, lattice: Matrix3x3) => Vec3;
32
+ export declare function clip_line_to_cell(point: Vec3, direction: Vec3, lattice: Matrix3x3, eps?: number): [Vec3, Vec3] | null;
33
+ export declare function clip_plane_to_cell(point: Vec3, normal_frac: Vec3, lattice: Matrix3x3): Vec3[];