matterviz 0.3.5 → 0.3.6

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 (855) hide show
  1. package/.vscode/launch.json +13 -0
  2. package/.vscodeignore +7 -0
  3. package/dist/assets/STLExporter-BpTH3YHE.js +8 -0
  4. package/dist/assets/browser-DdDecX_W.js +1 -0
  5. package/dist/assets/export-qgn-H9y6.js +2 -0
  6. package/dist/assets/main-DiKYzti2.css +1 -0
  7. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  8. package/dist/extension.js +31293 -0
  9. package/dist/src/lib/FilePicker.svelte +360 -0
  10. package/dist/src/lib/MillerIndexInput.svelte +66 -0
  11. package/dist/src/lib/api/mp.ts +26 -0
  12. package/dist/src/lib/api/optimade.ts +204 -0
  13. package/dist/src/lib/brillouin/BrillouinZone.svelte +549 -0
  14. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +144 -0
  15. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +146 -0
  16. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  17. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +476 -0
  18. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +92 -0
  19. package/dist/src/lib/brillouin/compute.ts +529 -0
  20. package/dist/src/lib/brillouin/index.ts +8 -0
  21. package/dist/src/lib/brillouin/types.ts +51 -0
  22. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +327 -0
  23. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +846 -0
  24. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +3193 -0
  25. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +94 -0
  26. package/dist/src/lib/chempot-diagram/chempot-worker.ts +11 -0
  27. package/dist/src/lib/chempot-diagram/color.ts +42 -0
  28. package/dist/src/lib/chempot-diagram/compute.ts +1014 -0
  29. package/dist/src/lib/chempot-diagram/index.ts +6 -0
  30. package/dist/src/lib/chempot-diagram/pointer.ts +56 -0
  31. package/dist/src/lib/chempot-diagram/temperature.ts +77 -0
  32. package/dist/src/lib/chempot-diagram/types.ts +130 -0
  33. package/dist/src/lib/colors/index.ts +249 -0
  34. package/dist/src/lib/composition/BarChart.svelte +297 -0
  35. package/dist/src/lib/composition/BubbleChart.svelte +218 -0
  36. package/dist/src/lib/composition/Composition.svelte +165 -0
  37. package/dist/src/lib/composition/Formula.svelte +268 -0
  38. package/dist/src/lib/composition/FormulaFilter.svelte +1257 -0
  39. package/dist/src/lib/composition/PieChart.svelte +323 -0
  40. package/dist/src/lib/composition/format.ts +155 -0
  41. package/dist/src/lib/composition/index.ts +37 -0
  42. package/dist/src/lib/composition/parse.ts +605 -0
  43. package/dist/src/lib/constants.ts +134 -0
  44. package/dist/src/lib/controls.ts +42 -0
  45. package/dist/src/lib/convex-hull/ConvexHull.svelte +157 -0
  46. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +825 -0
  47. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +1801 -0
  48. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +1398 -0
  49. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +535 -0
  50. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +125 -0
  51. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +929 -0
  52. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +131 -0
  53. package/dist/src/lib/convex-hull/GasPressureControls.svelte +247 -0
  54. package/dist/src/lib/convex-hull/StructurePopup.svelte +151 -0
  55. package/dist/src/lib/convex-hull/TemperatureSlider.svelte +140 -0
  56. package/dist/src/lib/convex-hull/barycentric-coords.ts +246 -0
  57. package/dist/src/lib/convex-hull/demo-temperature.ts +63 -0
  58. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +405 -0
  59. package/dist/src/lib/convex-hull/helpers.ts +932 -0
  60. package/dist/src/lib/convex-hull/index.ts +202 -0
  61. package/dist/src/lib/convex-hull/thermodynamics.ts +2192 -0
  62. package/dist/src/lib/convex-hull/types.ts +267 -0
  63. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +311 -0
  64. package/dist/src/lib/coordination/calc-coordination.ts +93 -0
  65. package/dist/src/lib/coordination/index.ts +9 -0
  66. package/dist/src/lib/effects.svelte.ts +48 -0
  67. package/dist/src/lib/element/BohrAtom.svelte +147 -0
  68. package/dist/src/lib/element/ElementHeading.svelte +26 -0
  69. package/dist/src/lib/element/ElementPhoto.svelte +57 -0
  70. package/dist/src/lib/element/ElementStats.svelte +80 -0
  71. package/dist/src/lib/element/ElementTile.svelte +484 -0
  72. package/dist/src/lib/element/data.json.gz.d.ts +4 -0
  73. package/dist/src/lib/element/data.ts +14 -0
  74. package/dist/src/lib/element/index.ts +8 -0
  75. package/dist/src/lib/element/types.ts +62 -0
  76. package/dist/src/lib/feedback/ClickFeedback.svelte +58 -0
  77. package/dist/src/lib/feedback/DragOverlay.svelte +42 -0
  78. package/dist/src/lib/feedback/index.ts +4 -0
  79. package/dist/src/lib/fermi-surface/FermiSlice.svelte +189 -0
  80. package/dist/src/lib/fermi-surface/FermiSurface.svelte +600 -0
  81. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +448 -0
  82. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +794 -0
  83. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +111 -0
  84. package/dist/src/lib/fermi-surface/compute.ts +728 -0
  85. package/dist/src/lib/fermi-surface/constants.ts +32 -0
  86. package/dist/src/lib/fermi-surface/export.ts +64 -0
  87. package/dist/src/lib/fermi-surface/index.ts +14 -0
  88. package/dist/src/lib/fermi-surface/marching-cubes.ts +3 -0
  89. package/dist/src/lib/fermi-surface/parse.ts +574 -0
  90. package/dist/src/lib/fermi-surface/symmetry.ts +56 -0
  91. package/dist/src/lib/fermi-surface/types.ts +159 -0
  92. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +1545 -0
  93. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  94. package/dist/src/lib/heatmap-matrix/index.ts +167 -0
  95. package/dist/src/lib/heatmap-matrix/shared.ts +7 -0
  96. package/dist/src/lib/icons.ts +650 -0
  97. package/dist/src/lib/index.ts +61 -0
  98. package/dist/src/lib/io/decompress.ts +92 -0
  99. package/dist/src/lib/io/export.ts +385 -0
  100. package/dist/src/lib/io/fetch.ts +46 -0
  101. package/dist/src/lib/io/file-drop.ts +51 -0
  102. package/dist/src/lib/io/index.ts +7 -0
  103. package/dist/src/lib/io/is-binary.ts +24 -0
  104. package/dist/src/lib/io/types.ts +8 -0
  105. package/dist/src/lib/io/url-drop.ts +141 -0
  106. package/dist/src/lib/isosurface/Isosurface.svelte +285 -0
  107. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +277 -0
  108. package/dist/src/lib/isosurface/index.ts +7 -0
  109. package/dist/src/lib/isosurface/parse.ts +656 -0
  110. package/dist/src/lib/isosurface/slice.ts +175 -0
  111. package/dist/src/lib/isosurface/types.ts +309 -0
  112. package/dist/src/lib/labels.ts +320 -0
  113. package/dist/src/lib/layout/FullscreenToggle.svelte +50 -0
  114. package/dist/src/lib/layout/InfoCard.svelte +120 -0
  115. package/dist/src/lib/layout/InfoTag.svelte +185 -0
  116. package/dist/src/lib/layout/PropertyFilter.svelte +246 -0
  117. package/dist/src/lib/layout/SettingsSection.svelte +148 -0
  118. package/dist/src/lib/layout/SubpageGrid.svelte +82 -0
  119. package/dist/src/lib/layout/fullscreen.ts +65 -0
  120. package/dist/src/lib/layout/index.ts +11 -0
  121. package/dist/src/lib/layout/json-tree/JsonNode.svelte +548 -0
  122. package/dist/src/lib/layout/json-tree/JsonTree.svelte +1230 -0
  123. package/dist/src/lib/layout/json-tree/JsonValue.svelte +334 -0
  124. package/dist/src/lib/layout/json-tree/index.ts +3 -0
  125. package/dist/src/lib/layout/json-tree/types.ts +126 -0
  126. package/dist/src/lib/layout/json-tree/utils.ts +682 -0
  127. package/dist/src/lib/marching-cubes.ts +614 -0
  128. package/dist/src/lib/math.ts +1081 -0
  129. package/dist/src/lib/overlays/ContextMenu.svelte +162 -0
  130. package/dist/src/lib/overlays/CopyButton.svelte +45 -0
  131. package/dist/src/lib/overlays/DragControlTab.svelte +98 -0
  132. package/dist/src/lib/overlays/DraggablePane.svelte +487 -0
  133. package/dist/src/lib/overlays/InfoPaneCards.svelte +149 -0
  134. package/dist/src/lib/overlays/index.ts +3 -0
  135. package/dist/src/lib/periodic-table/PeriodicTable.svelte +469 -0
  136. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +557 -0
  137. package/dist/src/lib/periodic-table/PropertySelect.svelte +37 -0
  138. package/dist/src/lib/periodic-table/index.ts +12 -0
  139. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1086 -0
  140. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +444 -0
  141. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  142. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  143. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  144. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +203 -0
  145. package/dist/src/lib/phase-diagram/build-diagram.ts +186 -0
  146. package/dist/src/lib/phase-diagram/colors.ts +58 -0
  147. package/dist/src/lib/phase-diagram/diagram-input.ts +40 -0
  148. package/dist/src/lib/phase-diagram/index.ts +13 -0
  149. package/dist/src/lib/phase-diagram/parse.ts +348 -0
  150. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +1023 -0
  151. package/dist/src/lib/phase-diagram/types.ts +144 -0
  152. package/dist/src/lib/phase-diagram/utils.ts +775 -0
  153. package/dist/src/lib/plot/AxisLabel.svelte +51 -0
  154. package/dist/src/lib/plot/BarPlot.svelte +2113 -0
  155. package/dist/src/lib/plot/BarPlotControls.svelte +66 -0
  156. package/dist/src/lib/plot/BinnedScatterPlot.svelte +1114 -0
  157. package/dist/src/lib/plot/ColorBar.svelte +721 -0
  158. package/dist/src/lib/plot/ColorScaleSelect.svelte +54 -0
  159. package/dist/src/lib/plot/ElementScatter.svelte +63 -0
  160. package/dist/src/lib/plot/FillArea.svelte +223 -0
  161. package/dist/src/lib/plot/Histogram.svelte +1558 -0
  162. package/dist/src/lib/plot/HistogramControls.svelte +212 -0
  163. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +96 -0
  164. package/dist/src/lib/plot/Line.svelte +84 -0
  165. package/dist/src/lib/plot/PlotAxis.svelte +169 -0
  166. package/dist/src/lib/plot/PlotControls.svelte +537 -0
  167. package/dist/src/lib/plot/PlotLegend.svelte +569 -0
  168. package/dist/src/lib/plot/PlotTooltip.svelte +67 -0
  169. package/dist/src/lib/plot/PortalSelect.svelte +253 -0
  170. package/dist/src/lib/plot/ReferenceLine3D.svelte +156 -0
  171. package/dist/src/lib/plot/ReferencePlane.svelte +175 -0
  172. package/dist/src/lib/plot/ScatterPlot.svelte +2778 -0
  173. package/dist/src/lib/plot/ScatterPlot3D.svelte +529 -0
  174. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +437 -0
  175. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +912 -0
  176. package/dist/src/lib/plot/ScatterPlotControls.svelte +306 -0
  177. package/dist/src/lib/plot/ScatterPoint.svelte +182 -0
  178. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +293 -0
  179. package/dist/src/lib/plot/Surface3D.svelte +197 -0
  180. package/dist/src/lib/plot/ZeroLines.svelte +97 -0
  181. package/dist/src/lib/plot/ZoomRect.svelte +23 -0
  182. package/dist/src/lib/plot/adaptive-density.ts +316 -0
  183. package/dist/src/lib/plot/auto-place.ts +184 -0
  184. package/dist/src/lib/plot/axis-utils.ts +122 -0
  185. package/dist/src/lib/plot/binned-scatter-types.ts +83 -0
  186. package/dist/src/lib/plot/data-cleaning.ts +1069 -0
  187. package/dist/src/lib/plot/data-transform.ts +69 -0
  188. package/dist/src/lib/plot/defaults.ts +9 -0
  189. package/dist/src/lib/plot/fill-utils.ts +494 -0
  190. package/dist/src/lib/plot/hover-lock.svelte.ts +60 -0
  191. package/dist/src/lib/plot/index.ts +53 -0
  192. package/dist/src/lib/plot/interactions.ts +119 -0
  193. package/dist/src/lib/plot/layout.ts +425 -0
  194. package/dist/src/lib/plot/reference-line.ts +426 -0
  195. package/dist/src/lib/plot/scales.ts +654 -0
  196. package/dist/src/lib/plot/svg.ts +23 -0
  197. package/dist/src/lib/plot/types.ts +1144 -0
  198. package/dist/src/lib/plot/utils/label-placement.ts +541 -0
  199. package/dist/src/lib/plot/utils/series-visibility.ts +140 -0
  200. package/dist/src/lib/plot/utils.ts +11 -0
  201. package/dist/src/lib/rdf/RdfPlot.svelte +247 -0
  202. package/dist/src/lib/rdf/calc-rdf.ts +167 -0
  203. package/dist/src/lib/rdf/index.ts +27 -0
  204. package/dist/src/lib/sanitize.ts +126 -0
  205. package/dist/src/lib/settings.ts +1479 -0
  206. package/dist/src/lib/spectral/Bands.svelte +1040 -0
  207. package/dist/src/lib/spectral/BandsAndDos.svelte +134 -0
  208. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +252 -0
  209. package/dist/src/lib/spectral/Dos.svelte +697 -0
  210. package/dist/src/lib/spectral/helpers.ts +1381 -0
  211. package/dist/src/lib/spectral/index.ts +8 -0
  212. package/dist/src/lib/spectral/types.ts +112 -0
  213. package/dist/src/lib/state.svelte.ts +64 -0
  214. package/dist/src/lib/structure/Arrow.svelte +72 -0
  215. package/dist/src/lib/structure/AtomLegend.svelte +815 -0
  216. package/dist/src/lib/structure/Bond.svelte +140 -0
  217. package/dist/src/lib/structure/CanvasTooltip.svelte +33 -0
  218. package/dist/src/lib/structure/CellSelect.svelte +349 -0
  219. package/dist/src/lib/structure/Cylinder.svelte +45 -0
  220. package/dist/src/lib/structure/Lattice.svelte +196 -0
  221. package/dist/src/lib/structure/Structure.svelte +2248 -0
  222. package/dist/src/lib/structure/StructureControls.svelte +1273 -0
  223. package/dist/src/lib/structure/StructureExportPane.svelte +252 -0
  224. package/dist/src/lib/structure/StructureInfoPane.svelte +737 -0
  225. package/dist/src/lib/structure/StructureScene.svelte +2255 -0
  226. package/dist/src/lib/structure/atom-properties.ts +316 -0
  227. package/dist/src/lib/structure/bond-order-perception.ts +447 -0
  228. package/dist/src/lib/structure/bonding.ts +944 -0
  229. package/dist/src/lib/structure/export.ts +861 -0
  230. package/dist/src/lib/structure/index.ts +291 -0
  231. package/dist/src/lib/structure/label-placement.ts +130 -0
  232. package/dist/src/lib/structure/measure.ts +45 -0
  233. package/dist/src/lib/structure/parse.ts +1705 -0
  234. package/dist/src/lib/structure/partial-occupancy.ts +183 -0
  235. package/dist/src/lib/structure/pbc.ts +164 -0
  236. package/dist/src/lib/structure/supercell.ts +226 -0
  237. package/dist/src/lib/structure/validation.ts +11 -0
  238. package/dist/src/lib/symmetry/SymmetryStats.svelte +226 -0
  239. package/dist/src/lib/symmetry/WyckoffTable.svelte +120 -0
  240. package/dist/src/lib/symmetry/cell-transform.ts +118 -0
  241. package/dist/src/lib/symmetry/index.ts +348 -0
  242. package/dist/src/lib/symmetry/spacegroups.ts +404 -0
  243. package/dist/src/lib/table/HeatmapTable.svelte +1833 -0
  244. package/dist/src/lib/table/ToggleMenu.svelte +385 -0
  245. package/dist/src/lib/table/index.ts +139 -0
  246. package/dist/src/lib/theme/ThemeControl.svelte +53 -0
  247. package/dist/src/lib/theme/index.ts +107 -0
  248. package/dist/src/lib/theme/themes.mjs +297 -0
  249. package/dist/src/lib/time.ts +71 -0
  250. package/dist/src/lib/tooltip/TooltipContent.svelte +58 -0
  251. package/dist/src/lib/tooltip/index.ts +2 -0
  252. package/dist/src/lib/tooltip/types.ts +13 -0
  253. package/dist/src/lib/trajectory/Trajectory.svelte +1545 -0
  254. package/dist/src/lib/trajectory/TrajectoryError.svelte +128 -0
  255. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +357 -0
  256. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +313 -0
  257. package/dist/src/lib/trajectory/constants.ts +7 -0
  258. package/dist/src/lib/trajectory/extract.ts +196 -0
  259. package/dist/src/lib/trajectory/format-detect.ts +96 -0
  260. package/dist/src/lib/trajectory/frame-reader.ts +456 -0
  261. package/dist/src/lib/trajectory/helpers.ts +217 -0
  262. package/dist/src/lib/trajectory/index.ts +218 -0
  263. package/dist/src/lib/trajectory/parse/ase.ts +109 -0
  264. package/dist/src/lib/trajectory/parse/hdf5.ts +173 -0
  265. package/dist/src/lib/trajectory/parse/index.ts +411 -0
  266. package/dist/src/lib/trajectory/parse/lammps.ts +215 -0
  267. package/dist/src/lib/trajectory/parse/vasp.ts +102 -0
  268. package/dist/src/lib/trajectory/parse/xyz.ts +143 -0
  269. package/dist/src/lib/trajectory/plotting.ts +599 -0
  270. package/dist/src/lib/trajectory/types.ts +13 -0
  271. package/dist/src/lib/utils.ts +56 -0
  272. package/dist/src/lib/xrd/XrdPlot.svelte +615 -0
  273. package/dist/src/lib/xrd/broadening.ts +130 -0
  274. package/dist/src/lib/xrd/calc-xrd.ts +397 -0
  275. package/dist/src/lib/xrd/index.ts +38 -0
  276. package/dist/src/lib/xrd/parse.ts +858 -0
  277. package/dist/webview.js +29421 -0
  278. package/icon.png +0 -0
  279. package/license +1 -1
  280. package/matterviz-0.3.2.vsix +0 -0
  281. package/matterviz-0.3.4.vsix +0 -0
  282. package/matterviz-0.3.5.vsix +0 -0
  283. package/package.json +1460 -215
  284. package/readme.md +171 -98
  285. package/scripts/sync-config.ts +101 -0
  286. package/src/declarations.d.ts +2 -0
  287. package/src/extension.ts +972 -0
  288. package/src/node-io.ts +65 -0
  289. package/src/types.ts +17 -0
  290. package/src/webview/JsonBrowser.svelte +1079 -0
  291. package/src/webview/PlotPanel.svelte +346 -0
  292. package/src/webview/detect.ts +444 -0
  293. package/src/webview/main.ts +764 -0
  294. package/src/webview/plot-utils.ts +250 -0
  295. package/test-fixtures/all-viz-types.json.gz +0 -0
  296. package/test-fixtures/plot-demo-data.json.gz +0 -0
  297. package/tests/detect.test.ts +604 -0
  298. package/tests/extension.test.ts +2041 -0
  299. package/tests/node-io.test.ts +39 -0
  300. package/tests/plot-utils.test.ts +302 -0
  301. package/tests/vite-plugin-json-gz.test.ts +114 -0
  302. package/tests/vscode-mock.ts +18 -0
  303. package/tests/webview.test.ts +231 -0
  304. package/tsconfig.json +20 -0
  305. package/vite-plugin-json-gz.ts +29 -0
  306. package/vite.config.ts +34 -0
  307. package/vite.extension.config.ts +34 -0
  308. package/dist/EmptyState.svelte.d.ts +0 -9
  309. package/dist/FilePicker.svelte +0 -360
  310. package/dist/FilePicker.svelte.d.ts +0 -17
  311. package/dist/Icon.svelte.d.ts +0 -13
  312. package/dist/MillerIndexInput.svelte +0 -66
  313. package/dist/MillerIndexInput.svelte.d.ts +0 -7
  314. package/dist/api/mp.d.ts +0 -6
  315. package/dist/api/mp.js +0 -22
  316. package/dist/api/optimade.d.ts +0 -45
  317. package/dist/api/optimade.js +0 -135
  318. package/dist/brillouin/BrillouinZone.svelte +0 -546
  319. package/dist/brillouin/BrillouinZone.svelte.d.ts +0 -83
  320. package/dist/brillouin/BrillouinZoneControls.svelte +0 -144
  321. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +0 -17
  322. package/dist/brillouin/BrillouinZoneExportPane.svelte +0 -148
  323. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +0 -15
  324. package/dist/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  325. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +0 -13
  326. package/dist/brillouin/BrillouinZoneScene.svelte +0 -476
  327. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +0 -48
  328. package/dist/brillouin/BrillouinZoneTooltip.svelte +0 -92
  329. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +0 -8
  330. package/dist/brillouin/compute.d.ts +0 -17
  331. package/dist/brillouin/compute.js +0 -426
  332. package/dist/brillouin/index.d.ts +0 -8
  333. package/dist/brillouin/index.js +0 -8
  334. package/dist/brillouin/types.d.ts +0 -48
  335. package/dist/brillouin/types.js +0 -1
  336. package/dist/chempot-diagram/ChemPotDiagram.svelte +0 -327
  337. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +0 -13
  338. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +0 -847
  339. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +0 -16
  340. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +0 -3194
  341. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +0 -16
  342. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +0 -7
  343. package/dist/chempot-diagram/async-compute.svelte.d.ts +0 -3
  344. package/dist/chempot-diagram/async-compute.svelte.js +0 -78
  345. package/dist/chempot-diagram/chempot-worker.d.ts +0 -1
  346. package/dist/chempot-diagram/chempot-worker.js +0 -11
  347. package/dist/chempot-diagram/color.d.ts +0 -10
  348. package/dist/chempot-diagram/color.js +0 -32
  349. package/dist/chempot-diagram/compute.d.ts +0 -48
  350. package/dist/chempot-diagram/compute.js +0 -812
  351. package/dist/chempot-diagram/index.d.ts +0 -6
  352. package/dist/chempot-diagram/index.js +0 -6
  353. package/dist/chempot-diagram/pointer.d.ts +0 -16
  354. package/dist/chempot-diagram/pointer.js +0 -40
  355. package/dist/chempot-diagram/temperature.d.ts +0 -15
  356. package/dist/chempot-diagram/temperature.js +0 -36
  357. package/dist/chempot-diagram/types.d.ts +0 -86
  358. package/dist/chempot-diagram/types.js +0 -28
  359. package/dist/colors/index.d.ts +0 -47
  360. package/dist/colors/index.js +0 -203
  361. package/dist/composition/BarChart.svelte +0 -297
  362. package/dist/composition/BarChart.svelte.d.ts +0 -39
  363. package/dist/composition/BubbleChart.svelte +0 -218
  364. package/dist/composition/BubbleChart.svelte.d.ts +0 -28
  365. package/dist/composition/Composition.svelte +0 -164
  366. package/dist/composition/Composition.svelte.d.ts +0 -15
  367. package/dist/composition/Formula.svelte +0 -265
  368. package/dist/composition/Formula.svelte.d.ts +0 -19
  369. package/dist/composition/FormulaFilter.svelte +0 -1259
  370. package/dist/composition/FormulaFilter.svelte.d.ts +0 -51
  371. package/dist/composition/PieChart.svelte +0 -323
  372. package/dist/composition/PieChart.svelte.d.ts +0 -37
  373. package/dist/composition/format.d.ts +0 -15
  374. package/dist/composition/format.js +0 -109
  375. package/dist/composition/index.d.ts +0 -20
  376. package/dist/composition/index.js +0 -14
  377. package/dist/composition/parse.d.ts +0 -55
  378. package/dist/composition/parse.js +0 -459
  379. package/dist/constants.d.ts +0 -29
  380. package/dist/constants.js +0 -99
  381. package/dist/controls.d.ts +0 -14
  382. package/dist/controls.js +0 -30
  383. package/dist/convex-hull/ConvexHull.svelte +0 -157
  384. package/dist/convex-hull/ConvexHull.svelte.d.ts +0 -13
  385. package/dist/convex-hull/ConvexHull2D.svelte +0 -814
  386. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +0 -11
  387. package/dist/convex-hull/ConvexHull3D.svelte +0 -1790
  388. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +0 -8
  389. package/dist/convex-hull/ConvexHull4D.svelte +0 -1386
  390. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +0 -8
  391. package/dist/convex-hull/ConvexHullControls.svelte +0 -546
  392. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +0 -48
  393. package/dist/convex-hull/ConvexHullInfoPane.svelte +0 -122
  394. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +0 -18
  395. package/dist/convex-hull/ConvexHullStats.svelte +0 -922
  396. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +0 -15
  397. package/dist/convex-hull/ConvexHullTooltip.svelte +0 -131
  398. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +0 -33
  399. package/dist/convex-hull/GasPressureControls.svelte +0 -247
  400. package/dist/convex-hull/GasPressureControls.svelte.d.ts +0 -11
  401. package/dist/convex-hull/StructurePopup.svelte +0 -116
  402. package/dist/convex-hull/StructurePopup.svelte.d.ts +0 -18
  403. package/dist/convex-hull/TemperatureSlider.svelte +0 -137
  404. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +0 -8
  405. package/dist/convex-hull/barycentric-coords.d.ts +0 -18
  406. package/dist/convex-hull/barycentric-coords.js +0 -182
  407. package/dist/convex-hull/demo-temperature.d.ts +0 -6
  408. package/dist/convex-hull/demo-temperature.js +0 -40
  409. package/dist/convex-hull/gas-thermodynamics.d.ts +0 -16
  410. package/dist/convex-hull/gas-thermodynamics.js +0 -316
  411. package/dist/convex-hull/helpers.d.ts +0 -103
  412. package/dist/convex-hull/helpers.js +0 -689
  413. package/dist/convex-hull/index.d.ts +0 -118
  414. package/dist/convex-hull/index.js +0 -57
  415. package/dist/convex-hull/thermodynamics.d.ts +0 -66
  416. package/dist/convex-hull/thermodynamics.js +0 -1752
  417. package/dist/convex-hull/types.d.ts +0 -162
  418. package/dist/convex-hull/types.js +0 -36
  419. package/dist/coordination/CoordinationBarPlot.svelte +0 -311
  420. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +0 -30
  421. package/dist/coordination/calc-coordination.d.ts +0 -15
  422. package/dist/coordination/calc-coordination.js +0 -63
  423. package/dist/coordination/index.d.ts +0 -8
  424. package/dist/coordination/index.js +0 -7
  425. package/dist/element/BohrAtom.svelte +0 -147
  426. package/dist/element/BohrAtom.svelte.d.ts +0 -20
  427. package/dist/element/ElementHeading.svelte +0 -26
  428. package/dist/element/ElementHeading.svelte.d.ts +0 -8
  429. package/dist/element/ElementPhoto.svelte +0 -57
  430. package/dist/element/ElementPhoto.svelte.d.ts +0 -9
  431. package/dist/element/ElementStats.svelte +0 -80
  432. package/dist/element/ElementStats.svelte.d.ts +0 -8
  433. package/dist/element/ElementTile.svelte +0 -484
  434. package/dist/element/ElementTile.svelte.d.ts +0 -29
  435. package/dist/element/Nucleus.svelte.d.ts +0 -17
  436. package/dist/element/data.d.ts +0 -2
  437. package/dist/element/data.js +0 -2
  438. package/dist/element/data.json.gz.d.ts +0 -2
  439. package/dist/element/index.d.ts +0 -8
  440. package/dist/element/index.js +0 -8
  441. package/dist/element/types.d.ts +0 -57
  442. package/dist/element/types.js +0 -1
  443. package/dist/feedback/ClickFeedback.svelte +0 -58
  444. package/dist/feedback/ClickFeedback.svelte.d.ts +0 -12
  445. package/dist/feedback/DragOverlay.svelte +0 -42
  446. package/dist/feedback/DragOverlay.svelte.d.ts +0 -7
  447. package/dist/feedback/Spinner.svelte.d.ts +0 -7
  448. package/dist/feedback/StatusMessage.svelte.d.ts +0 -9
  449. package/dist/feedback/index.d.ts +0 -4
  450. package/dist/feedback/index.js +0 -4
  451. package/dist/fermi-surface/FermiSlice.svelte +0 -189
  452. package/dist/fermi-surface/FermiSlice.svelte.d.ts +0 -24
  453. package/dist/fermi-surface/FermiSurface.svelte +0 -600
  454. package/dist/fermi-surface/FermiSurface.svelte.d.ts +0 -83
  455. package/dist/fermi-surface/FermiSurfaceControls.svelte +0 -452
  456. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +0 -35
  457. package/dist/fermi-surface/FermiSurfaceScene.svelte +0 -792
  458. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +0 -50
  459. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  460. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +0 -8
  461. package/dist/fermi-surface/compute.d.ts +0 -5
  462. package/dist/fermi-surface/compute.js +0 -538
  463. package/dist/fermi-surface/constants.d.ts +0 -9
  464. package/dist/fermi-surface/constants.js +0 -27
  465. package/dist/fermi-surface/export.d.ts +0 -5
  466. package/dist/fermi-surface/export.js +0 -63
  467. package/dist/fermi-surface/index.d.ts +0 -12
  468. package/dist/fermi-surface/index.js +0 -13
  469. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  470. package/dist/fermi-surface/marching-cubes.js +0 -2
  471. package/dist/fermi-surface/parse.d.ts +0 -2
  472. package/dist/fermi-surface/parse.js +0 -495
  473. package/dist/fermi-surface/symmetry.d.ts +0 -3
  474. package/dist/fermi-surface/symmetry.js +0 -46
  475. package/dist/fermi-surface/types.d.ts +0 -113
  476. package/dist/fermi-surface/types.js +0 -4
  477. package/dist/heatmap-matrix/HeatmapMatrix.svelte +0 -1527
  478. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +0 -110
  479. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  480. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +0 -30
  481. package/dist/heatmap-matrix/index.d.ts +0 -53
  482. package/dist/heatmap-matrix/index.js +0 -100
  483. package/dist/heatmap-matrix/shared.d.ts +0 -2
  484. package/dist/heatmap-matrix/shared.js +0 -4
  485. package/dist/icons.d.ts +0 -569
  486. package/dist/icons.js +0 -648
  487. package/dist/index.d.ts +0 -39
  488. package/dist/index.js +0 -39
  489. package/dist/io/decompress.d.ts +0 -10
  490. package/dist/io/decompress.js +0 -74
  491. package/dist/io/export.d.ts +0 -16
  492. package/dist/io/export.js +0 -316
  493. package/dist/io/fetch.d.ts +0 -5
  494. package/dist/io/fetch.js +0 -39
  495. package/dist/io/file-drop.d.ts +0 -7
  496. package/dist/io/file-drop.js +0 -43
  497. package/dist/io/index.d.ts +0 -7
  498. package/dist/io/index.js +0 -7
  499. package/dist/io/is-binary.d.ts +0 -1
  500. package/dist/io/is-binary.js +0 -20
  501. package/dist/io/types.d.ts +0 -8
  502. package/dist/io/types.js +0 -1
  503. package/dist/io/url-drop.d.ts +0 -2
  504. package/dist/io/url-drop.js +0 -117
  505. package/dist/isosurface/Isosurface.svelte +0 -285
  506. package/dist/isosurface/Isosurface.svelte.d.ts +0 -8
  507. package/dist/isosurface/IsosurfaceControls.svelte +0 -291
  508. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +0 -9
  509. package/dist/isosurface/index.d.ts +0 -5
  510. package/dist/isosurface/index.js +0 -6
  511. package/dist/isosurface/parse.d.ts +0 -6
  512. package/dist/isosurface/parse.js +0 -553
  513. package/dist/isosurface/slice.d.ts +0 -11
  514. package/dist/isosurface/slice.js +0 -140
  515. package/dist/isosurface/types.d.ts +0 -56
  516. package/dist/isosurface/types.js +0 -227
  517. package/dist/labels.d.ts +0 -53
  518. package/dist/labels.js +0 -274
  519. package/dist/layout/FullscreenToggle.svelte +0 -50
  520. package/dist/layout/FullscreenToggle.svelte.d.ts +0 -7
  521. package/dist/layout/InfoCard.svelte +0 -120
  522. package/dist/layout/InfoCard.svelte.d.ts +0 -21
  523. package/dist/layout/InfoTag.svelte +0 -183
  524. package/dist/layout/InfoTag.svelte.d.ts +0 -19
  525. package/dist/layout/PropertyFilter.svelte +0 -244
  526. package/dist/layout/PropertyFilter.svelte.d.ts +0 -24
  527. package/dist/layout/SettingsSection.svelte +0 -148
  528. package/dist/layout/SettingsSection.svelte.d.ts +0 -17
  529. package/dist/layout/SubpageGrid.svelte +0 -82
  530. package/dist/layout/SubpageGrid.svelte.d.ts +0 -14
  531. package/dist/layout/fullscreen.d.ts +0 -9
  532. package/dist/layout/fullscreen.js +0 -53
  533. package/dist/layout/index.d.ts +0 -10
  534. package/dist/layout/index.js +0 -8
  535. package/dist/layout/json-tree/JsonNode.svelte +0 -548
  536. package/dist/layout/json-tree/JsonNode.svelte.d.ts +0 -11
  537. package/dist/layout/json-tree/JsonTree.svelte +0 -1222
  538. package/dist/layout/json-tree/JsonTree.svelte.d.ts +0 -6
  539. package/dist/layout/json-tree/JsonValue.svelte +0 -334
  540. package/dist/layout/json-tree/JsonValue.svelte.d.ts +0 -9
  541. package/dist/layout/json-tree/index.d.ts +0 -3
  542. package/dist/layout/json-tree/index.js +0 -3
  543. package/dist/layout/json-tree/types.d.ts +0 -73
  544. package/dist/layout/json-tree/types.js +0 -3
  545. package/dist/layout/json-tree/utils.d.ts +0 -29
  546. package/dist/layout/json-tree/utils.js +0 -649
  547. package/dist/marching-cubes.d.ts +0 -14
  548. package/dist/marching-cubes.js +0 -542
  549. package/dist/math.d.ts +0 -91
  550. package/dist/math.js +0 -896
  551. package/dist/overlays/ContextMenu.svelte +0 -162
  552. package/dist/overlays/ContextMenu.svelte.d.ts +0 -25
  553. package/dist/overlays/CopyButton.svelte +0 -45
  554. package/dist/overlays/CopyButton.svelte.d.ts +0 -8
  555. package/dist/overlays/DraggablePane.svelte +0 -564
  556. package/dist/overlays/DraggablePane.svelte.d.ts +0 -36
  557. package/dist/overlays/InfoPaneCards.svelte +0 -149
  558. package/dist/overlays/InfoPaneCards.svelte.d.ts +0 -22
  559. package/dist/overlays/index.d.ts +0 -2
  560. package/dist/overlays/index.js +0 -2
  561. package/dist/periodic-table/PeriodicTable.svelte +0 -469
  562. package/dist/periodic-table/PeriodicTable.svelte.d.ts +0 -55
  563. package/dist/periodic-table/PeriodicTableControls.svelte +0 -557
  564. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +0 -24
  565. package/dist/periodic-table/PropertySelect.svelte +0 -37
  566. package/dist/periodic-table/PropertySelect.svelte.d.ts +0 -13
  567. package/dist/periodic-table/TableInset.svelte.d.ts +0 -9
  568. package/dist/periodic-table/index.d.ts +0 -10
  569. package/dist/periodic-table/index.js +0 -4
  570. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1084
  571. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +0 -44
  572. package/dist/phase-diagram/PhaseDiagramControls.svelte +0 -449
  573. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +0 -30
  574. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  575. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +0 -15
  576. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +0 -192
  577. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +0 -19
  578. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +0 -392
  579. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +0 -16
  580. package/dist/phase-diagram/TdbInfoPanel.svelte +0 -203
  581. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +0 -12
  582. package/dist/phase-diagram/build-diagram.d.ts +0 -11
  583. package/dist/phase-diagram/build-diagram.js +0 -167
  584. package/dist/phase-diagram/colors.d.ts +0 -35
  585. package/dist/phase-diagram/colors.js +0 -51
  586. package/dist/phase-diagram/diagram-input.d.ts +0 -33
  587. package/dist/phase-diagram/diagram-input.js +0 -3
  588. package/dist/phase-diagram/index.d.ts +0 -13
  589. package/dist/phase-diagram/index.js +0 -13
  590. package/dist/phase-diagram/parse.d.ts +0 -55
  591. package/dist/phase-diagram/parse.js +0 -276
  592. package/dist/phase-diagram/svg-to-diagram.d.ts +0 -2
  593. package/dist/phase-diagram/svg-to-diagram.js +0 -867
  594. package/dist/phase-diagram/types.d.ts +0 -99
  595. package/dist/phase-diagram/types.js +0 -1
  596. package/dist/phase-diagram/utils.d.ts +0 -118
  597. package/dist/phase-diagram/utils.js +0 -606
  598. package/dist/plot/AxisLabel.svelte +0 -51
  599. package/dist/plot/AxisLabel.svelte.d.ts +0 -16
  600. package/dist/plot/BarPlot.svelte +0 -2265
  601. package/dist/plot/BarPlot.svelte.d.ts +0 -83
  602. package/dist/plot/BarPlotControls.svelte +0 -66
  603. package/dist/plot/BarPlotControls.svelte.d.ts +0 -18
  604. package/dist/plot/ColorBar.svelte +0 -719
  605. package/dist/plot/ColorBar.svelte.d.ts +0 -31
  606. package/dist/plot/ColorScaleSelect.svelte +0 -54
  607. package/dist/plot/ColorScaleSelect.svelte.d.ts +0 -15
  608. package/dist/plot/ElementScatter.svelte +0 -63
  609. package/dist/plot/ElementScatter.svelte.d.ts +0 -14
  610. package/dist/plot/FillArea.svelte +0 -225
  611. package/dist/plot/FillArea.svelte.d.ts +0 -21
  612. package/dist/plot/Histogram.svelte +0 -1672
  613. package/dist/plot/Histogram.svelte.d.ts +0 -50
  614. package/dist/plot/HistogramControls.svelte +0 -212
  615. package/dist/plot/HistogramControls.svelte.d.ts +0 -22
  616. package/dist/plot/InteractiveAxisLabel.svelte +0 -94
  617. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +0 -14
  618. package/dist/plot/Line.svelte +0 -84
  619. package/dist/plot/Line.svelte.d.ts +0 -15
  620. package/dist/plot/PlotControls.svelte +0 -537
  621. package/dist/plot/PlotControls.svelte.d.ts +0 -4
  622. package/dist/plot/PlotLegend.svelte +0 -569
  623. package/dist/plot/PlotLegend.svelte.d.ts +0 -29
  624. package/dist/plot/PlotTooltip.svelte +0 -67
  625. package/dist/plot/PlotTooltip.svelte.d.ts +0 -17
  626. package/dist/plot/PortalSelect.svelte +0 -253
  627. package/dist/plot/PortalSelect.svelte.d.ts +0 -16
  628. package/dist/plot/ReferenceLine.svelte.d.ts +0 -20
  629. package/dist/plot/ReferenceLine3D.svelte +0 -154
  630. package/dist/plot/ReferenceLine3D.svelte.d.ts +0 -14
  631. package/dist/plot/ReferencePlane.svelte +0 -178
  632. package/dist/plot/ReferencePlane.svelte.d.ts +0 -14
  633. package/dist/plot/ScatterPlot.svelte +0 -2845
  634. package/dist/plot/ScatterPlot.svelte.d.ts +0 -93
  635. package/dist/plot/ScatterPlot3D.svelte +0 -502
  636. package/dist/plot/ScatterPlot3D.svelte.d.ts +0 -94
  637. package/dist/plot/ScatterPlot3DControls.svelte +0 -437
  638. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +0 -20
  639. package/dist/plot/ScatterPlot3DScene.svelte +0 -912
  640. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +0 -74
  641. package/dist/plot/ScatterPlotControls.svelte +0 -307
  642. package/dist/plot/ScatterPlotControls.svelte.d.ts +0 -17
  643. package/dist/plot/ScatterPoint.svelte +0 -191
  644. package/dist/plot/ScatterPoint.svelte.d.ts +0 -21
  645. package/dist/plot/SpacegroupBarPlot.svelte +0 -293
  646. package/dist/plot/SpacegroupBarPlot.svelte.d.ts +0 -9
  647. package/dist/plot/Surface3D.svelte +0 -200
  648. package/dist/plot/Surface3D.svelte.d.ts +0 -13
  649. package/dist/plot/ZeroLines.svelte +0 -96
  650. package/dist/plot/ZeroLines.svelte.d.ts +0 -32
  651. package/dist/plot/ZoomRect.svelte +0 -23
  652. package/dist/plot/ZoomRect.svelte.d.ts +0 -8
  653. package/dist/plot/axis-utils.d.ts +0 -19
  654. package/dist/plot/axis-utils.js +0 -80
  655. package/dist/plot/data-cleaning.d.ts +0 -37
  656. package/dist/plot/data-cleaning.js +0 -855
  657. package/dist/plot/data-transform.d.ts +0 -16
  658. package/dist/plot/data-transform.js +0 -45
  659. package/dist/plot/defaults.d.ts +0 -19
  660. package/dist/plot/defaults.js +0 -9
  661. package/dist/plot/fill-utils.d.ts +0 -51
  662. package/dist/plot/fill-utils.js +0 -337
  663. package/dist/plot/hover-lock.svelte.d.ts +0 -14
  664. package/dist/plot/hover-lock.svelte.js +0 -46
  665. package/dist/plot/index.d.ts +0 -37
  666. package/dist/plot/index.js +0 -37
  667. package/dist/plot/interactions.d.ts +0 -12
  668. package/dist/plot/interactions.js +0 -100
  669. package/dist/plot/layout.d.ts +0 -60
  670. package/dist/plot/layout.js +0 -230
  671. package/dist/plot/reference-line.d.ts +0 -60
  672. package/dist/plot/reference-line.js +0 -316
  673. package/dist/plot/scales.d.ts +0 -48
  674. package/dist/plot/scales.js +0 -484
  675. package/dist/plot/svg.d.ts +0 -1
  676. package/dist/plot/svg.js +0 -11
  677. package/dist/plot/types.d.ts +0 -859
  678. package/dist/plot/types.js +0 -103
  679. package/dist/plot/utils/label-placement.d.ts +0 -47
  680. package/dist/plot/utils/label-placement.js +0 -256
  681. package/dist/plot/utils/series-visibility.d.ts +0 -9
  682. package/dist/plot/utils/series-visibility.js +0 -67
  683. package/dist/plot/utils.d.ts +0 -1
  684. package/dist/plot/utils.js +0 -14
  685. package/dist/rdf/RdfPlot.svelte +0 -247
  686. package/dist/rdf/RdfPlot.svelte.d.ts +0 -27
  687. package/dist/rdf/calc-rdf.d.ts +0 -4
  688. package/dist/rdf/calc-rdf.js +0 -111
  689. package/dist/rdf/index.d.ts +0 -23
  690. package/dist/rdf/index.js +0 -2
  691. package/dist/sanitize.d.ts +0 -4
  692. package/dist/sanitize.js +0 -114
  693. package/dist/settings.d.ts +0 -255
  694. package/dist/settings.js +0 -1132
  695. package/dist/spectral/Bands.svelte +0 -1040
  696. package/dist/spectral/Bands.svelte.d.ts +0 -40
  697. package/dist/spectral/BandsAndDos.svelte +0 -128
  698. package/dist/spectral/BandsAndDos.svelte.d.ts +0 -18
  699. package/dist/spectral/BrillouinBandsDos.svelte +0 -248
  700. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +0 -20
  701. package/dist/spectral/Dos.svelte +0 -697
  702. package/dist/spectral/Dos.svelte.d.ts +0 -29
  703. package/dist/spectral/helpers.d.ts +0 -117
  704. package/dist/spectral/helpers.js +0 -1023
  705. package/dist/spectral/index.d.ts +0 -6
  706. package/dist/spectral/index.js +0 -7
  707. package/dist/spectral/types.d.ts +0 -84
  708. package/dist/spectral/types.js +0 -2
  709. package/dist/state.svelte.d.ts +0 -25
  710. package/dist/state.svelte.js +0 -45
  711. package/dist/structure/Arrow.svelte +0 -72
  712. package/dist/structure/Arrow.svelte.d.ts +0 -15
  713. package/dist/structure/AtomLegend.svelte +0 -798
  714. package/dist/structure/AtomLegend.svelte.d.ts +0 -34
  715. package/dist/structure/Bond.svelte +0 -140
  716. package/dist/structure/Bond.svelte.d.ts +0 -9
  717. package/dist/structure/CanvasTooltip.svelte +0 -33
  718. package/dist/structure/CanvasTooltip.svelte.d.ts +0 -12
  719. package/dist/structure/CellSelect.svelte +0 -351
  720. package/dist/structure/CellSelect.svelte.d.ts +0 -13
  721. package/dist/structure/Cylinder.svelte +0 -45
  722. package/dist/structure/Cylinder.svelte.d.ts +0 -10
  723. package/dist/structure/Lattice.svelte +0 -196
  724. package/dist/structure/Lattice.svelte.d.ts +0 -17
  725. package/dist/structure/Structure.svelte +0 -1999
  726. package/dist/structure/Structure.svelte.d.ts +0 -87
  727. package/dist/structure/StructureControls.svelte +0 -1298
  728. package/dist/structure/StructureControls.svelte.d.ts +0 -31
  729. package/dist/structure/StructureExportPane.svelte +0 -251
  730. package/dist/structure/StructureExportPane.svelte.d.ts +0 -17
  731. package/dist/structure/StructureInfoPane.svelte +0 -735
  732. package/dist/structure/StructureInfoPane.svelte.d.ts +0 -19
  733. package/dist/structure/StructureScene.svelte +0 -1905
  734. package/dist/structure/StructureScene.svelte.d.ts +0 -108
  735. package/dist/structure/atom-properties.d.ts +0 -37
  736. package/dist/structure/atom-properties.js +0 -200
  737. package/dist/structure/bond-order-perception.d.ts +0 -13
  738. package/dist/structure/bond-order-perception.js +0 -367
  739. package/dist/structure/bonding.d.ts +0 -42
  740. package/dist/structure/bonding.js +0 -525
  741. package/dist/structure/export.d.ts +0 -20
  742. package/dist/structure/export.js +0 -727
  743. package/dist/structure/index.d.ts +0 -125
  744. package/dist/structure/index.js +0 -171
  745. package/dist/structure/label-placement.d.ts +0 -14
  746. package/dist/structure/label-placement.js +0 -72
  747. package/dist/structure/measure.d.ts +0 -6
  748. package/dist/structure/measure.js +0 -29
  749. package/dist/structure/parse.d.ts +0 -66
  750. package/dist/structure/parse.js +0 -1363
  751. package/dist/structure/partial-occupancy.d.ts +0 -25
  752. package/dist/structure/partial-occupancy.js +0 -99
  753. package/dist/structure/pbc.d.ts +0 -9
  754. package/dist/structure/pbc.js +0 -123
  755. package/dist/structure/supercell.d.ts +0 -8
  756. package/dist/structure/supercell.js +0 -170
  757. package/dist/structure/validation.d.ts +0 -2
  758. package/dist/structure/validation.js +0 -10
  759. package/dist/symmetry/SymmetryStats.svelte +0 -226
  760. package/dist/symmetry/SymmetryStats.svelte.d.ts +0 -21
  761. package/dist/symmetry/WyckoffTable.svelte +0 -113
  762. package/dist/symmetry/WyckoffTable.svelte.d.ts +0 -11
  763. package/dist/symmetry/cell-transform.d.ts +0 -12
  764. package/dist/symmetry/cell-transform.js +0 -91
  765. package/dist/symmetry/index.d.ts +0 -43
  766. package/dist/symmetry/index.js +0 -229
  767. package/dist/symmetry/spacegroups.d.ts +0 -9
  768. package/dist/symmetry/spacegroups.js +0 -394
  769. package/dist/table/HeatmapTable.svelte +0 -1854
  770. package/dist/table/HeatmapTable.svelte.d.ts +0 -49
  771. package/dist/table/ToggleMenu.svelte +0 -376
  772. package/dist/table/ToggleMenu.svelte.d.ts +0 -11
  773. package/dist/table/index.d.ts +0 -74
  774. package/dist/table/index.js +0 -38
  775. package/dist/theme/ThemeControl.svelte +0 -53
  776. package/dist/theme/ThemeControl.svelte.d.ts +0 -9
  777. package/dist/theme/index.d.ts +0 -29
  778. package/dist/theme/index.js +0 -79
  779. package/dist/theme/themes.mjs +0 -285
  780. package/dist/time.d.ts +0 -4
  781. package/dist/time.js +0 -70
  782. package/dist/tooltip/TooltipContent.svelte +0 -58
  783. package/dist/tooltip/TooltipContent.svelte.d.ts +0 -31
  784. package/dist/tooltip/index.d.ts +0 -2
  785. package/dist/tooltip/index.js +0 -2
  786. package/dist/tooltip/types.d.ts +0 -8
  787. package/dist/tooltip/types.js +0 -1
  788. package/dist/trajectory/Trajectory.svelte +0 -1517
  789. package/dist/trajectory/Trajectory.svelte.d.ts +0 -77
  790. package/dist/trajectory/TrajectoryError.svelte +0 -128
  791. package/dist/trajectory/TrajectoryError.svelte.d.ts +0 -13
  792. package/dist/trajectory/TrajectoryExportPane.svelte +0 -357
  793. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +0 -17
  794. package/dist/trajectory/TrajectoryInfoPane.svelte +0 -313
  795. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +0 -17
  796. package/dist/trajectory/constants.d.ts +0 -6
  797. package/dist/trajectory/constants.js +0 -7
  798. package/dist/trajectory/extract.d.ts +0 -5
  799. package/dist/trajectory/extract.js +0 -162
  800. package/dist/trajectory/format-detect.d.ts +0 -9
  801. package/dist/trajectory/format-detect.js +0 -76
  802. package/dist/trajectory/frame-reader.d.ts +0 -17
  803. package/dist/trajectory/frame-reader.js +0 -332
  804. package/dist/trajectory/helpers.d.ts +0 -14
  805. package/dist/trajectory/helpers.js +0 -172
  806. package/dist/trajectory/index.d.ts +0 -63
  807. package/dist/trajectory/index.js +0 -126
  808. package/dist/trajectory/parse/ase.d.ts +0 -2
  809. package/dist/trajectory/parse/ase.js +0 -73
  810. package/dist/trajectory/parse/hdf5.d.ts +0 -2
  811. package/dist/trajectory/parse/hdf5.js +0 -127
  812. package/dist/trajectory/parse/index.d.ts +0 -12
  813. package/dist/trajectory/parse/index.js +0 -299
  814. package/dist/trajectory/parse/lammps.d.ts +0 -5
  815. package/dist/trajectory/parse/lammps.js +0 -179
  816. package/dist/trajectory/parse/vasp.d.ts +0 -2
  817. package/dist/trajectory/parse/vasp.js +0 -68
  818. package/dist/trajectory/parse/xyz.d.ts +0 -2
  819. package/dist/trajectory/parse/xyz.js +0 -110
  820. package/dist/trajectory/plotting.d.ts +0 -28
  821. package/dist/trajectory/plotting.js +0 -423
  822. package/dist/trajectory/types.d.ts +0 -11
  823. package/dist/trajectory/types.js +0 -1
  824. package/dist/utils.d.ts +0 -5
  825. package/dist/utils.js +0 -36
  826. package/dist/xrd/XrdPlot.svelte +0 -615
  827. package/dist/xrd/XrdPlot.svelte.d.ts +0 -28
  828. package/dist/xrd/broadening.d.ts +0 -20
  829. package/dist/xrd/broadening.js +0 -97
  830. package/dist/xrd/calc-xrd.d.ts +0 -37
  831. package/dist/xrd/calc-xrd.js +0 -337
  832. package/dist/xrd/index.d.ts +0 -37
  833. package/dist/xrd/index.js +0 -4
  834. package/dist/xrd/parse.d.ts +0 -13
  835. package/dist/xrd/parse.js +0 -749
  836. /package/dist/{EmptyState.svelte → src/lib/EmptyState.svelte} +0 -0
  837. /package/dist/{Icon.svelte → src/lib/Icon.svelte} +0 -0
  838. /package/dist/{app.css → src/lib/app.css} +0 -0
  839. /package/dist/{chempot-diagram → src/lib/chempot-diagram}/ChemPotScene3D.svelte +0 -0
  840. /package/dist/{colors → src/lib/colors}/alloy-colors.json +0 -0
  841. /package/dist/{colors → src/lib/colors}/dark-mode-colors.json +0 -0
  842. /package/dist/{colors → src/lib/colors}/jmol-colors.json +0 -0
  843. /package/dist/{colors → src/lib/colors}/muted-colors.json +0 -0
  844. /package/dist/{colors → src/lib/colors}/pastel-colors.json +0 -0
  845. /package/dist/{colors → src/lib/colors}/vesta-colors.json +0 -0
  846. /package/dist/{element → src/lib/element}/Nucleus.svelte +0 -0
  847. /package/dist/{element → src/lib/element}/data.json +0 -0
  848. /package/dist/{element → src/lib/element}/data.json.gz +0 -0
  849. /package/dist/{element → src/lib/element}/data.schema.json +0 -0
  850. /package/dist/{element-image-urls.json → src/lib/element-image-urls.json} +0 -0
  851. /package/dist/{feedback → src/lib/feedback}/Spinner.svelte +0 -0
  852. /package/dist/{feedback → src/lib/feedback}/StatusMessage.svelte +0 -0
  853. /package/dist/{periodic-table → src/lib/periodic-table}/TableInset.svelte +0 -0
  854. /package/dist/{plot → src/lib/plot}/ReferenceLine.svelte +0 -0
  855. /package/dist/{xrd → src/lib/xrd}/atomic_scattering_params.json +0 -0
@@ -0,0 +1,1023 @@
1
+ // SVG-to-DiagramInput converter
2
+ // Parses phase diagram SVGs (matplotlib or simple/Gemini format) into DiagramInput JSON
3
+ // for immediate rendering by IsobaricBinaryPhaseDiagram
4
+
5
+ import type { DiagramInput, DiagramPoint, RegionInput } from './diagram-input'
6
+
7
+ // Two-phase color keys to cycle through for region assignment
8
+ const TWO_PHASE_COLORS = [
9
+ `two_phase`,
10
+ `two_phase_intermetallic`,
11
+ `two_phase_fcc_liquid`,
12
+ `two_phase_intermetallic_alt`,
13
+ `two_phase_alt`,
14
+ `two_phase_gamma`,
15
+ `two_phase_mixed`,
16
+ `two_phase_si`,
17
+ `two_phase_bcc_liquid`,
18
+ `two_phase_hcp_liquid`,
19
+ `two_phase_theta_liquid`,
20
+ `two_phase_eta`,
21
+ ]
22
+
23
+ // Round to 6 decimal places for clean floating-point output
24
+ const round = (val: number): number => Math.round(val * 1e6) / 1e6
25
+
26
+ // === Types ===
27
+
28
+ type SvgFormat = `matplotlib` | `simple` | `mpds`
29
+
30
+ interface LinearScale {
31
+ to_data: (px: number) => number
32
+ domain: [number, number] // [min_data, max_data]
33
+ }
34
+
35
+ interface Boundary {
36
+ x1: number // data coordinates
37
+ y1: number
38
+ x2: number
39
+ y2: number
40
+ orientation: `horizontal` | `vertical`
41
+ }
42
+
43
+ interface Label {
44
+ text: string // plain text, e.g. "La2NiO4 + NiO"
45
+ px_x: number // pixel position
46
+ px_y: number
47
+ }
48
+
49
+ // === Format Detection ===
50
+
51
+ // Detect whether the SVG is matplotlib, MPDS, or simple format
52
+ function detect_format(doc: Document): SvgFormat {
53
+ // Matplotlib SVGs have xtick/ytick group IDs
54
+ if (doc.querySelector(`[id^="xtick_"]`) || doc.querySelector(`[id^="ytick_"]`)) {
55
+ return `matplotlib`
56
+ }
57
+ // MPDS SVGs (from CorelDRAW/Inkscape) have sodipodi namespace or inkscape attributes
58
+ const svg_el = doc.querySelector(`svg`)
59
+ if (
60
+ svg_el?.getAttribute(`sodipodi:docname`) ||
61
+ svg_el?.getAttribute(`inkscape:version`) ||
62
+ svg_el?.getAttributeNS(`http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd`, `docname`)
63
+ ) {
64
+ return `mpds`
65
+ }
66
+ return `simple`
67
+ }
68
+
69
+ // === Axis Scale Extraction ===
70
+
71
+ // Extract x and y axis scales from tick marks
72
+ function extract_axis_scales(
73
+ doc: Document,
74
+ format: SvgFormat,
75
+ ): { x_scale: LinearScale; y_scale: LinearScale } {
76
+ const x_ticks: { px: number; value: number }[] = []
77
+ const y_ticks: { px: number; value: number }[] = []
78
+
79
+ if (format === `matplotlib`) {
80
+ extract_matplotlib_ticks(doc, x_ticks, y_ticks)
81
+ } else if (format === `mpds`) {
82
+ return extract_mpds_scales(doc)
83
+ } else {
84
+ extract_simple_ticks(doc, x_ticks, y_ticks)
85
+ }
86
+
87
+ if (x_ticks.length < 2) {
88
+ throw new Error(`Need at least 2 x-axis ticks, found ${x_ticks.length}`)
89
+ }
90
+ if (y_ticks.length < 2) {
91
+ throw new Error(`Need at least 2 y-axis ticks, found ${y_ticks.length}`)
92
+ }
93
+
94
+ return {
95
+ x_scale: build_scale(x_ticks),
96
+ y_scale: build_scale(y_ticks), // y-axis inverted (SVG y down, temp up)
97
+ }
98
+ }
99
+
100
+ // Extract ticks from matplotlib SVG (id="xtick_N", comment-based values)
101
+ function extract_matplotlib_ticks(
102
+ doc: Document,
103
+ x_ticks: { px: number; value: number }[],
104
+ y_ticks: { px: number; value: number }[],
105
+ ): void {
106
+ const axes: [string, string, { px: number; value: number }[]][] = [
107
+ [`xtick_`, `x`, x_ticks],
108
+ [`ytick_`, `y`, y_ticks],
109
+ ]
110
+ for (const [prefix, attr, ticks] of axes) {
111
+ for (const group of Array.from(doc.querySelectorAll(`[id^="${prefix}"]`))) {
112
+ const value = extract_comment_number(group)
113
+ const use_el = group.querySelector(`use`)
114
+ if (value !== null && use_el) {
115
+ const px = parse_float_attr(use_el, attr)
116
+ if (px !== null) ticks.push({ px, value })
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ // Extract ticks from simple SVG (class-based text elements)
123
+ function extract_simple_ticks(
124
+ doc: Document,
125
+ x_ticks: { px: number; value: number }[],
126
+ y_ticks: { px: number; value: number }[],
127
+ ): void {
128
+ // Y-axis ticks: class="tick-text" with text-anchor: end
129
+ for (const text_el of Array.from(doc.querySelectorAll(`.tick-text`))) {
130
+ const value = parseFloat(text_el.textContent?.trim() ?? ``)
131
+ if (isNaN(value)) continue
132
+
133
+ // Find the immediately preceding sibling tick line (not just any line in parent)
134
+ const tick_line = text_el.previousElementSibling
135
+ if (!tick_line || !tick_line.matches(`.tick-line, line`)) continue
136
+ const py = parse_float_attr(tick_line, `y1`)
137
+ // Apply parent group transform if present
138
+ const parent = text_el.parentElement
139
+ const transform_y = get_group_translate(parent, `y`)
140
+ if (py !== null) y_ticks.push({ px: py + transform_y, value })
141
+ }
142
+
143
+ // X-axis ticks: class="tick-text-x"
144
+ for (const text_el of Array.from(doc.querySelectorAll(`.tick-text-x`))) {
145
+ const value = parseFloat(text_el.textContent?.trim() ?? ``)
146
+ if (isNaN(value)) continue
147
+
148
+ const px_x = parse_float_attr(text_el, `x`)
149
+ // Apply parent group transform if present
150
+ const parent = text_el.parentElement
151
+ const transform_x = get_group_translate(parent, `x`)
152
+ if (px_x !== null) x_ticks.push({ px: px_x + transform_x, value })
153
+ }
154
+ }
155
+
156
+ // Extract scales from MPDS SVGs using tick mark paths and text values
157
+ // MPDS SVGs store tick marks as multi-segment paths with major ticks (longer)
158
+ // and minor ticks (shorter). Text values are not positionally useful but
159
+ // tell us the data range.
160
+ function extract_mpds_scales(doc: Document): {
161
+ x_scale: LinearScale
162
+ y_scale: LinearScale
163
+ } {
164
+ // Extract all numeric text values to infer axis ranges
165
+ const numbers: number[] = []
166
+ for (const text_el of Array.from(doc.querySelectorAll(`text`))) {
167
+ const val = parseFloat(text_el.textContent?.trim() ?? ``)
168
+ if (!isNaN(val)) numbers.push(val)
169
+ }
170
+
171
+ // Separate composition (0-100 at%) from temperature (typically 100-3000)
172
+ // Note: value 100 appears in both filters (valid as 100 at% and 100°C).
173
+ // This is intentional — only endpoints are used for scale mapping.
174
+ const comp_vals = [
175
+ ...new Set(numbers.filter((value) => value >= 0 && value <= 100 && value % 10 === 0)),
176
+ ].toSorted((a, b) => a - b)
177
+ const temp_vals = [
178
+ ...new Set(numbers.filter((value) => value >= 100 && value % 100 === 0 && value <= 3000)),
179
+ ].toSorted((a, b) => a - b)
180
+
181
+ if (comp_vals.length < 2 || temp_vals.length < 2) {
182
+ throw new Error(
183
+ `MPDS SVG: could not infer axis ranges (found ${comp_vals.length} composition, ${temp_vals.length} temperature values)`,
184
+ )
185
+ }
186
+
187
+ // Find tick mark paths — multi-segment paths with stroke-width ~0.5
188
+ // containing both major (longer) and minor (shorter) tick marks
189
+ const x_major_ticks: number[] = []
190
+ const y_major_ticks: number[] = []
191
+
192
+ for (const path of Array.from(doc.querySelectorAll(`path`))) {
193
+ const path_data = path.getAttribute(`d`) ?? ``
194
+ const stroke_width = parse_stroke_width(path)
195
+
196
+ // Tick mark paths have stroke-width ~0.5
197
+ if (stroke_width < 0.3 || stroke_width > 1.0) continue
198
+
199
+ // Parse path into absolute line segments (handles both absolute & relative commands)
200
+ const segments = parse_path_segments(path_data)
201
+ if (segments.length < 3) continue
202
+
203
+ for (const [sx1, sy1, sx2, sy2] of segments) {
204
+ const seg_dx = Math.abs(sx2 - sx1)
205
+ const seg_dy = Math.abs(sy2 - sy1)
206
+
207
+ // Major ticks are longer (~3.9 px), minor are shorter (~1.7 px)
208
+ if (Math.hypot(seg_dx, seg_dy) < 3) continue
209
+
210
+ // Horizontal tick segments → y-axis tick (x changes, y constant)
211
+ if (seg_dy < 0.1 && seg_dx > 2) {
212
+ y_major_ticks.push(Math.round(sy1 * 100) / 100)
213
+ }
214
+ // Vertical tick segments → x-axis tick (y changes, x constant)
215
+ if (seg_dx < 0.1 && seg_dy > 2) {
216
+ x_major_ticks.push(Math.round(sx1 * 100) / 100)
217
+ }
218
+ }
219
+ }
220
+
221
+ // Deduplicate and sort
222
+ const x_ticks_sorted = [
223
+ ...new Set(x_major_ticks.map((value) => Math.round(value * 10) / 10)),
224
+ ].toSorted((a, b) => a - b)
225
+ const y_ticks_sorted = [
226
+ ...new Set(y_major_ticks.map((value) => Math.round(value * 10) / 10)),
227
+ ].toSorted((a, b) => a - b)
228
+
229
+ if (x_ticks_sorted.length < 2 || y_ticks_sorted.length < 2) {
230
+ throw new Error(
231
+ `MPDS SVG: could not find tick marks (found ${x_ticks_sorted.length} x-ticks, ${y_ticks_sorted.length} y-ticks)`,
232
+ )
233
+ }
234
+
235
+ // Map tick positions to data values using endpoints
236
+ // Only the first and last tick+value need to match for a linear scale
237
+ // x-axis: composition in at% → fraction; y-axis: temperature (SVG y inverted)
238
+ const x_ticks = [
239
+ { px: x_ticks_sorted[0], value: comp_vals[0] / 100 },
240
+ {
241
+ px: x_ticks_sorted[x_ticks_sorted.length - 1],
242
+ value: comp_vals[comp_vals.length - 1] / 100,
243
+ },
244
+ ]
245
+ const y_ticks = [
246
+ { px: y_ticks_sorted[0], value: temp_vals[temp_vals.length - 1] }, // top = highest temp
247
+ { px: y_ticks_sorted[y_ticks_sorted.length - 1], value: temp_vals[0] }, // bottom = lowest temp
248
+ ]
249
+
250
+ return {
251
+ x_scale: build_scale(x_ticks),
252
+ y_scale: build_scale(y_ticks),
253
+ }
254
+ }
255
+
256
+ // Build a linear scale from tick data points
257
+ function build_scale(ticks: { px: number; value: number }[]): LinearScale {
258
+ ticks.sort((a, b) => a.value - b.value)
259
+ const first = ticks[0]
260
+ const last = ticks[ticks.length - 1]
261
+
262
+ const range = last.value - first.value
263
+ if (range === 0) {
264
+ return { to_data: () => first.value, domain: [first.value, last.value] }
265
+ }
266
+ const px_per_unit = (last.px - first.px) / range
267
+
268
+ return {
269
+ to_data: (px: number) => first.value + (px - first.px) / px_per_unit,
270
+ domain: [first.value, last.value],
271
+ }
272
+ }
273
+
274
+ // === Boundary Extraction ===
275
+
276
+ // Extract phase boundary lines from SVG and convert to data coordinates
277
+ function extract_boundaries(
278
+ doc: Document,
279
+ format: SvgFormat,
280
+ x_scale: LinearScale,
281
+ y_scale: LinearScale,
282
+ ): Boundary[] {
283
+ const boundaries: Boundary[] = []
284
+ const epsilon = 0.5 // pixel tolerance for classifying horizontal/vertical
285
+
286
+ if (format === `mpds`) {
287
+ extract_mpds_boundaries(doc, boundaries, x_scale, y_scale, epsilon)
288
+ } else if (format === `matplotlib`) {
289
+ // Matplotlib: look for line2d_N groups with path elements (skip tick marks at line2d_1..12ish)
290
+ for (const group of Array.from(doc.querySelectorAll(`[id^="line2d_"]`))) {
291
+ const path_el = group.querySelector(`path`)
292
+ if (!path_el) continue
293
+
294
+ const d_attr = path_el.getAttribute(`d`)
295
+ if (!d_attr) continue
296
+
297
+ // Parse "M x1 y1 L x2 y2" path data
298
+ const coords = parse_ml_path(d_attr)
299
+ if (!coords) continue
300
+
301
+ // Skip tick mark lines (short lines, typically < 10px)
302
+ const dx = Math.abs(coords.x2 - coords.x1)
303
+ const dy = Math.abs(coords.y2 - coords.y1)
304
+ if (dx < 15 && dy < 15) continue
305
+
306
+ // Check stroke-width to distinguish boundaries from axis lines
307
+ const stroke_width = parse_stroke_width(path_el) || 1
308
+
309
+ // Axis patches (id="patch_*") are axis borders, not phase boundaries
310
+ const parent_id = group.getAttribute(`id`) ?? ``
311
+ if (parent_id.startsWith(`patch_`)) continue
312
+
313
+ // Only include lines with meaningful stroke
314
+ if (stroke_width < 1) continue
315
+
316
+ add_boundary(boundaries, coords, x_scale, y_scale, epsilon)
317
+ }
318
+ } else {
319
+ // Simple: <line class="phase-boundary">
320
+ for (const line_el of Array.from(
321
+ doc.querySelectorAll(`.phase-boundary, line[class*="phase-boundary"]`),
322
+ )) {
323
+ const x1 = parse_float_attr(line_el, `x1`)
324
+ const y1 = parse_float_attr(line_el, `y1`)
325
+ const x2 = parse_float_attr(line_el, `x2`)
326
+ const y2 = parse_float_attr(line_el, `y2`)
327
+ if (x1 === null || y1 === null || x2 === null || y2 === null) continue
328
+
329
+ add_boundary(boundaries, { x1, y1, x2, y2 }, x_scale, y_scale, epsilon)
330
+ }
331
+ }
332
+
333
+ return boundaries
334
+ }
335
+
336
+ // Extract boundaries from MPDS SVGs — simple M x1,y1 L x2,y2 path elements
337
+ // inside the plot area with thin stroke (0.216) and dark color
338
+ function extract_mpds_boundaries(
339
+ doc: Document,
340
+ boundaries: Boundary[],
341
+ x_scale: LinearScale,
342
+ y_scale: LinearScale,
343
+ epsilon: number,
344
+ ): void {
345
+ // Find the plot border to filter boundaries inside it
346
+ const plot_rect = find_mpds_plot_rect(doc)
347
+ if (!plot_rect) return
348
+
349
+ const { left, right, top, bottom } = plot_rect
350
+
351
+ for (const path of Array.from(doc.querySelectorAll(`path`))) {
352
+ const path_data = path.getAttribute(`d`) ?? ``
353
+ const style = path.getAttribute(`style`) ?? ``
354
+
355
+ // Skip tick mark paths (stroke-width > 0.3)
356
+ const stroke_width = parse_stroke_width(path)
357
+ if (stroke_width > 0.3 || stroke_width === 0) continue
358
+
359
+ // Skip filled regions (phase region fills)
360
+ if (
361
+ (style.includes(`fill-rule`) || style.includes(`fill: #`) || style.includes(`fill:#`)) &&
362
+ !style.includes(`fill: none`) &&
363
+ !style.includes(`fill:none`)
364
+ ) {
365
+ continue
366
+ }
367
+
368
+ // Skip red annotation lines
369
+ if (style.includes(`#e30016`) || style.includes(`#E30016`)) continue
370
+
371
+ // Parse as simple M...L line
372
+ const coords = parse_ml_path(path_data)
373
+ if (!coords) continue
374
+
375
+ // Must be inside the plot area
376
+ const inside =
377
+ coords.x1 >= left - 1 &&
378
+ coords.x1 <= right + 1 &&
379
+ coords.x2 >= left - 1 &&
380
+ coords.x2 <= right + 1 &&
381
+ coords.y1 >= top - 1 &&
382
+ coords.y1 <= bottom + 1 &&
383
+ coords.y2 >= top - 1 &&
384
+ coords.y2 <= bottom + 1
385
+ if (!inside) continue
386
+
387
+ // Skip very short segments (< 10px)
388
+ const dx = Math.abs(coords.x2 - coords.x1)
389
+ const dy = Math.abs(coords.y2 - coords.y1)
390
+ if (dx < 10 && dy < 10) continue
391
+
392
+ // Skip the plot border itself (connects all 4 edges)
393
+ const touches_left = Math.abs(coords.x1 - left) < 2 || Math.abs(coords.x2 - left) < 2
394
+ const touches_right = Math.abs(coords.x1 - right) < 2 || Math.abs(coords.x2 - right) < 2
395
+ if (touches_left && touches_right) continue // spans full width = likely axis
396
+
397
+ add_boundary(boundaries, coords, x_scale, y_scale, epsilon)
398
+ }
399
+ }
400
+
401
+ // Find the plot area rectangle in an MPDS SVG
402
+ // Handles both M...L...L...L...Z and M...V...H...V...Z formats
403
+ function find_mpds_plot_rect(
404
+ doc: Document,
405
+ ): { left: number; right: number; top: number; bottom: number } | null {
406
+ for (const path of Array.from(doc.querySelectorAll(`path`))) {
407
+ const path_data = path.getAttribute(`d`) ?? ``
408
+ const style = path.getAttribute(`style`) ?? ``
409
+ if (!style.includes(`fill: none`) && !style.includes(`fill:none`)) continue
410
+ if (!path_data.includes(`Z`) && !path_data.includes(`z`)) continue
411
+
412
+ // Parse path into absolute segments and extract corner points
413
+ const segments = parse_path_segments(path_data)
414
+ if (segments.length < 3) continue // rectangle needs at least 3 segments (4th is Z)
415
+
416
+ // Collect all x and y coordinates from segment endpoints
417
+ const xs: number[] = []
418
+ const ys: number[] = []
419
+ for (const [x1, y1, x2, y2] of segments) {
420
+ xs.push(Math.round(x1 * 10) / 10, Math.round(x2 * 10) / 10)
421
+ ys.push(Math.round(y1 * 10) / 10, Math.round(y2 * 10) / 10)
422
+ }
423
+
424
+ const unique_x = [...new Set(xs)]
425
+ const unique_y = [...new Set(ys)]
426
+
427
+ // Rectangle has exactly 2 unique x and 2 unique y values
428
+ if (unique_x.length === 2 && unique_y.length === 2) {
429
+ return {
430
+ left: Math.min(...unique_x),
431
+ right: Math.max(...unique_x),
432
+ top: Math.min(...unique_y),
433
+ bottom: Math.max(...unique_y),
434
+ }
435
+ }
436
+ }
437
+ return null
438
+ }
439
+
440
+ // Add a boundary line, classifying as horizontal or vertical
441
+ function add_boundary(
442
+ boundaries: Boundary[],
443
+ px: { x1: number; y1: number; x2: number; y2: number },
444
+ x_scale: LinearScale,
445
+ y_scale: LinearScale,
446
+ epsilon: number,
447
+ ): void {
448
+ const is_vertical = Math.abs(px.x1 - px.x2) < epsilon
449
+ const is_horizontal = Math.abs(px.y1 - px.y2) < epsilon
450
+
451
+ if (!is_vertical && !is_horizontal) return // skip diagonal lines
452
+
453
+ const data_x1 = x_scale.to_data(px.x1)
454
+ const data_y1 = y_scale.to_data(px.y1)
455
+ const data_x2 = x_scale.to_data(px.x2)
456
+ const data_y2 = y_scale.to_data(px.y2)
457
+
458
+ boundaries.push({
459
+ x1: Math.min(data_x1, data_x2),
460
+ y1: Math.min(data_y1, data_y2),
461
+ x2: Math.max(data_x1, data_x2),
462
+ y2: Math.max(data_y1, data_y2),
463
+ orientation: is_vertical ? `vertical` : `horizontal`,
464
+ })
465
+ }
466
+
467
+ // === Label Extraction ===
468
+
469
+ // Extract phase region labels with their pixel positions
470
+ function extract_labels(doc: Document, format: SvgFormat): Label[] {
471
+ const labels: Label[] = []
472
+
473
+ if (format === `matplotlib`) {
474
+ extract_matplotlib_labels(doc, labels)
475
+ } else if (format === `mpds`) {
476
+ // MPDS labels use garbled encoding; skip label extraction
477
+ // Regions will get auto-generated names from infer_regions
478
+ } else {
479
+ extract_simple_labels(doc, labels)
480
+ }
481
+
482
+ return labels
483
+ }
484
+
485
+ // Extract labels from matplotlib SVG using XML comments
486
+ function extract_matplotlib_labels(doc: Document, labels: Label[]): void {
487
+ // Find text groups with comments containing phase names
488
+ // Matplotlib may split multi-line labels (especially rotated ones) into
489
+ // separate <g> groups: text_N has "La$_2$NiO$_4$", followed by a sibling
490
+ // with "+ La$_3$Ni$_2$O$_7$". We concatenate these continuation groups.
491
+ for (const group of Array.from(doc.querySelectorAll(`[id^="text_"]`))) {
492
+ let comment = find_comment_text(group)
493
+ if (!comment) continue
494
+
495
+ // Check following sibling groups for continuation comments starting with "+"
496
+ let sibling = group.nextElementSibling
497
+ while (sibling) {
498
+ // Stop at the next text_N group (that's a separate label)
499
+ if (sibling.id?.startsWith(`text_`)) break
500
+ const continuation = find_comment_text(sibling)
501
+ if (continuation?.trimStart().startsWith(`+`)) {
502
+ comment += ` ${continuation.trim()}`
503
+ sibling = sibling.nextElementSibling
504
+ } else {
505
+ break
506
+ }
507
+ }
508
+
509
+ if (!comment.includes(`+`)) continue // skip axis labels (no "+")
510
+
511
+ // Clean LaTeX: "La$_2$NiO$_4$ + NiO" -> "La2NiO4 + NiO"
512
+ const text = clean_latex(comment.trim())
513
+
514
+ // Get position from transform="translate(x, y)"
515
+ const pos = parse_translate(group.querySelector(`g[transform]`)) ?? parse_translate(group)
516
+ if (!pos) continue
517
+
518
+ labels.push({ text, px_x: pos[0], px_y: pos[1] })
519
+ }
520
+ }
521
+
522
+ // Extract labels from simple SVG using class="label-main"
523
+ function extract_simple_labels(doc: Document, labels: Label[]): void {
524
+ for (const text_el of Array.from(doc.querySelectorAll(`.label-main`))) {
525
+ // Get plain text content (strips tspan tags)
526
+ const text = (text_el.textContent ?? ``).replaceAll(/\s+/g, ` `).trim()
527
+ if (!text.includes(`+`)) continue // skip non-phase labels
528
+
529
+ // Get position from transform or x/y attributes
530
+ const pos = parse_translate(text_el)
531
+ const px_x = pos?.[0] ?? parse_float_attr(text_el, `x`)
532
+ const px_y = pos?.[1] ?? parse_float_attr(text_el, `y`)
533
+
534
+ if (px_x !== null && px_y !== null) {
535
+ labels.push({ text, px_x, px_y })
536
+ }
537
+ }
538
+ }
539
+
540
+ // === Component Inference ===
541
+
542
+ const split_phase_label = (label: Label) => label.text.split(/\s*\+\s*/)
543
+
544
+ // Infer binary components from region labels
545
+ function infer_components(labels: Label[]): [string, string] {
546
+ // Sort labels by x position, split each into phases
547
+ const sorted = labels.toSorted((a, b) => a.px_x - b.px_x)
548
+ if (sorted.length < 2) return [`A`, `B`]
549
+
550
+ const leftmost = split_phase_label(sorted[0])
551
+ const rightmost = split_phase_label(sorted[sorted.length - 1])
552
+
553
+ // Component A: the unique phase in the leftmost region that doesn't appear on the right
554
+ // For "La2NiO4 + La2O3", La2O3 is the pure A endpoint
555
+ let comp_a = `A`
556
+ if (leftmost.length === 2) {
557
+ const right_phases = new Set(sorted.slice(-3).flatMap(split_phase_label))
558
+ comp_a = leftmost.find((phase) => !right_phases.has(phase)) ?? leftmost[1] ?? `A`
559
+ }
560
+
561
+ // Component B: the unique phase in the rightmost region that doesn't appear on the left
562
+ let comp_b = `B`
563
+ if (rightmost.length === 2) {
564
+ const left_phases = new Set(sorted.slice(0, 3).flatMap(split_phase_label))
565
+ comp_b = rightmost.find((phase) => !left_phases.has(phase)) ?? rightmost[1] ?? `B`
566
+ }
567
+
568
+ return [comp_a, comp_b]
569
+ }
570
+
571
+ // === Region Inference ===
572
+
573
+ // Infer phase regions from orthogonal boundaries using flood-fill on a cell grid
574
+ function infer_regions(
575
+ boundaries: Boundary[],
576
+ labels: Label[],
577
+ x_scale: LinearScale,
578
+ y_scale: LinearScale,
579
+ ): RegionInput[] {
580
+ const verticals = boundaries.filter((boundary) => boundary.orientation === `vertical`)
581
+ const horizontals = boundaries.filter((boundary) => boundary.orientation === `horizontal`)
582
+
583
+ // Collect all unique x and y coordinates (boundaries + domain edges)
584
+ const x_coords = collect_unique_sorted([
585
+ x_scale.domain[0],
586
+ x_scale.domain[1],
587
+ ...verticals.map((boundary) => boundary.x1), // x1 === x2 for vertical
588
+ ])
589
+
590
+ const y_coords = collect_unique_sorted([
591
+ y_scale.domain[0],
592
+ y_scale.domain[1],
593
+ ...horizontals.map((boundary) => boundary.y1), // y1 === y2 for horizontal
594
+ ])
595
+
596
+ // Build cell grid: cells[col][row]
597
+ const n_cols = x_coords.length - 1
598
+ const n_rows = y_coords.length - 1
599
+ const cell_ids = Array.from({ length: n_cols }, () => Array(n_rows).fill(-1))
600
+
601
+ // Check which cell edges have boundaries
602
+ const h_walls = Array.from({ length: n_cols }, () => Array(n_rows + 1).fill(false))
603
+ const v_walls = Array.from({ length: n_cols + 1 }, () => Array(n_rows).fill(false))
604
+
605
+ // Mark horizontal walls (bottom/top of cells)
606
+ for (const hb of horizontals) {
607
+ const row = find_coord_index(y_coords, hb.y1)
608
+ if (row === -1) continue
609
+ for (let col = 0; col < n_cols; col++) {
610
+ const cell_x_min = x_coords[col]
611
+ const cell_x_max = x_coords[col + 1]
612
+ // Check if the boundary spans this cell's x range
613
+ if (hb.x1 <= cell_x_min + 1e-6 && hb.x2 >= cell_x_max - 1e-6) {
614
+ h_walls[col][row] = true
615
+ }
616
+ }
617
+ }
618
+
619
+ // Mark vertical walls (left/right of cells)
620
+ for (const vb of verticals) {
621
+ const col = find_coord_index(x_coords, vb.x1)
622
+ if (col === -1) continue
623
+ for (let row = 0; row < n_rows; row++) {
624
+ const cell_y_min = y_coords[row]
625
+ const cell_y_max = y_coords[row + 1]
626
+ // Check if the boundary spans this cell's y range
627
+ if (vb.y1 <= cell_y_min + 1e-6 && vb.y2 >= cell_y_max - 1e-6) {
628
+ v_walls[col][row] = true
629
+ }
630
+ }
631
+ }
632
+
633
+ // Plot edges are always walls
634
+ for (let col = 0; col < n_cols; col++) {
635
+ h_walls[col][0] = true // bottom edge
636
+ h_walls[col][n_rows] = true // top edge
637
+ }
638
+ for (let row = 0; row < n_rows; row++) {
639
+ v_walls[0][row] = true // left edge
640
+ v_walls[n_cols][row] = true // right edge
641
+ }
642
+
643
+ // Flood-fill to assign region IDs
644
+ let next_region_id = 0
645
+ for (let col = 0; col < n_cols; col++) {
646
+ for (let row = 0; row < n_rows; row++) {
647
+ if (cell_ids[col][row] !== -1) continue
648
+ flood_fill(cell_ids, h_walls, v_walls, col, row, n_cols, n_rows, next_region_id)
649
+ next_region_id++
650
+ }
651
+ }
652
+
653
+ // Assign labels to regions by checking which region contains each label's position
654
+ const region_labels = new Map<number, string>()
655
+ for (const label of labels) {
656
+ const data_x = x_scale.to_data(label.px_x)
657
+ const data_y = y_scale.to_data(label.px_y)
658
+
659
+ const col = find_cell_index(x_coords, data_x)
660
+ const row = find_cell_index(y_coords, data_y)
661
+ if (col >= 0 && col < n_cols && row >= 0 && row < n_rows) {
662
+ const region_id = cell_ids[col][row]
663
+ if (region_id !== -1) {
664
+ region_labels.set(region_id, label.text)
665
+ }
666
+ }
667
+ }
668
+
669
+ // Build region polygons from merged cells
670
+ const regions: RegionInput[] = []
671
+ for (let region_id = 0; region_id < next_region_id; region_id++) {
672
+ const name = region_labels.get(region_id) ?? `Region ${region_id + 1}`
673
+ // Slug can be empty for non-ASCII labels like "α + β" — fall back to region_N
674
+ const slug =
675
+ name
676
+ .toLowerCase()
677
+ .replaceAll(/[^a-z0-9]+/g, `_`)
678
+ .replaceAll(/^_|_$/g, ``) || `region_${region_id + 1}`
679
+
680
+ // Find bounding box of all cells in this region
681
+ let [min_x, max_x] = [Infinity, -Infinity]
682
+ let [min_y, max_y] = [Infinity, -Infinity]
683
+ for (let col = 0; col < n_cols; col++) {
684
+ for (let row = 0; row < n_rows; row++) {
685
+ if (cell_ids[col][row] !== region_id) continue
686
+ min_x = Math.min(min_x, x_coords[col])
687
+ max_x = Math.max(max_x, x_coords[col + 1])
688
+ min_y = Math.min(min_y, y_coords[row])
689
+ max_y = Math.max(max_y, y_coords[row + 1])
690
+ }
691
+ }
692
+
693
+ if (min_x === Infinity) continue
694
+
695
+ const bounds: DiagramPoint[] = [
696
+ [round(min_x), round(min_y)],
697
+ [round(max_x), round(min_y)],
698
+ [round(max_x), round(max_y)],
699
+ [round(min_x), round(max_y)],
700
+ ]
701
+
702
+ regions.push({
703
+ id: slug,
704
+ name,
705
+ color: TWO_PHASE_COLORS[region_id % TWO_PHASE_COLORS.length],
706
+ bounds,
707
+ })
708
+ }
709
+
710
+ return regions
711
+ }
712
+
713
+ // Flood-fill connected cells that share an open edge
714
+ function flood_fill(
715
+ cell_ids: number[][],
716
+ h_walls: boolean[][],
717
+ v_walls: boolean[][],
718
+ start_col: number,
719
+ start_row: number,
720
+ n_cols: number,
721
+ n_rows: number,
722
+ region_id: number,
723
+ ): void {
724
+ const stack: [number, number][] = [[start_col, start_row]]
725
+
726
+ for (let item = stack.pop(); item; item = stack.pop()) {
727
+ const [col, row] = item
728
+ if (col < 0 || col >= n_cols || row < 0 || row >= n_rows) continue
729
+ if (cell_ids[col][row] !== -1) continue
730
+
731
+ cell_ids[col][row] = region_id
732
+
733
+ // Check neighbors (no wall between them)
734
+ // Left neighbor: check v_walls[col][row]
735
+ if (col > 0 && !v_walls[col][row]) stack.push([col - 1, row])
736
+ // Right neighbor: check v_walls[col+1][row]
737
+ if (col < n_cols - 1 && !v_walls[col + 1][row]) stack.push([col + 1, row])
738
+ // Bottom neighbor: check h_walls[col][row]
739
+ if (row > 0 && !h_walls[col][row]) stack.push([col, row - 1])
740
+ // Top neighbor: check h_walls[col][row+1]
741
+ if (row < n_rows - 1 && !h_walls[col][row + 1]) stack.push([col, row + 1])
742
+ }
743
+ }
744
+
745
+ // === Curve Generation ===
746
+
747
+ // Generate named curves from boundaries for the DiagramInput format
748
+ function generate_curves(boundaries: Boundary[]): Record<string, DiagramPoint[]> {
749
+ const curves: Record<string, DiagramPoint[]> = {}
750
+ const counts = { vertical: 0, horizontal: 0 }
751
+
752
+ for (const bnd of boundaries) {
753
+ const is_vert = bnd.orientation === `vertical`
754
+ const name = `${bnd.orientation}_${counts[bnd.orientation]++}`
755
+ curves[name] = [
756
+ [round(bnd.x1), round(bnd.y1)],
757
+ [round(is_vert ? bnd.x1 : bnd.x2), round(is_vert ? bnd.y2 : bnd.y1)],
758
+ ]
759
+ }
760
+
761
+ return curves
762
+ }
763
+
764
+ // === Main Entry Point ===
765
+
766
+ // Parse a phase diagram SVG string and return a DiagramInput
767
+ export function parse_phase_diagram_svg(svg_string: string): DiagramInput {
768
+ const parser = new DOMParser()
769
+ const doc = parser.parseFromString(svg_string, `image/svg+xml`)
770
+
771
+ // Check for parse errors
772
+ const parse_error = doc.querySelector(`parsererror`)
773
+ if (parse_error) {
774
+ throw new Error(`Invalid SVG: ${parse_error.textContent}`)
775
+ }
776
+
777
+ const format = detect_format(doc)
778
+ const { x_scale, y_scale } = extract_axis_scales(doc, format)
779
+ const boundaries = extract_boundaries(doc, format, x_scale, y_scale)
780
+ const labels = extract_labels(doc, format)
781
+ const components = format === `mpds` ? infer_mpds_components(doc) : infer_components(labels)
782
+
783
+ if (boundaries.length === 0) {
784
+ throw new Error(`No phase boundaries found in SVG`)
785
+ }
786
+
787
+ const regions = infer_regions(boundaries, labels, x_scale, y_scale)
788
+ const curves = generate_curves(boundaries)
789
+
790
+ // MPDS SVGs use °C for temperature
791
+ const temp_unit = format === `mpds` ? `°C` : `K`
792
+
793
+ return {
794
+ meta: {
795
+ components,
796
+ temp_range: y_scale.domain,
797
+ temp_unit,
798
+ comp_unit: `fraction`,
799
+ title: `Imported Phase Diagram`,
800
+ },
801
+ curves,
802
+ regions,
803
+ }
804
+ }
805
+
806
+ // Infer components from MPDS SVGs by finding element-like text content
807
+ // MPDS SVGs have readable element names as text (e.g., "Cu", "Si")
808
+ function infer_mpds_components(doc: Document): [string, string] {
809
+ const elements = new Set<string>()
810
+ for (const text_el of Array.from(doc.querySelectorAll(`text`))) {
811
+ const content = text_el.textContent?.trim() ?? ``
812
+ // Match single/two-letter element symbols, exclude common non-element text
813
+ if (/^[A-Z][a-z]?$/.test(content) && content !== `L` && content !== `M`) {
814
+ elements.add(content)
815
+ }
816
+ }
817
+ const unique = [...elements]
818
+ return [unique[0] ?? `A`, unique[1] ?? `B`]
819
+ }
820
+
821
+ // === Utility Functions ===
822
+
823
+ // Parse stroke-width from style attribute or direct attribute (returns 0 if not found)
824
+ function parse_stroke_width(el: Element): number {
825
+ const style_match = /stroke-width:\s*([\d.]+)/.exec(el.getAttribute(`style`) ?? ``)
826
+ if (style_match) return parseFloat(style_match[1])
827
+ const attr = el.getAttribute(`stroke-width`)
828
+ return attr ? parseFloat(attr) || 0 : 0
829
+ }
830
+
831
+ // Parse a float attribute from an SVG element
832
+ function parse_float_attr(el: Element, attr: string): number | null {
833
+ const val = el.getAttribute(attr)
834
+ if (val === null) return null
835
+ const parsed = parseFloat(val)
836
+ return isNaN(parsed) ? null : parsed
837
+ }
838
+
839
+ // Extract a number from XML comment nodes inside a group element
840
+ function extract_comment_number(group: Element): number | null {
841
+ const walker = group.ownerDocument.createTreeWalker(group, NodeFilter.SHOW_COMMENT)
842
+ let node: Comment | null
843
+ while ((node = walker.nextNode() as Comment | null)) {
844
+ const value = parseFloat(node.textContent?.trim() ?? ``)
845
+ if (!isNaN(value)) return value
846
+ }
847
+ return null
848
+ }
849
+
850
+ // Find the first XML comment text inside or preceding a group
851
+ function find_comment_text(group: Element): string | null {
852
+ // Check comment nodes inside the group
853
+ const walker = group.ownerDocument.createTreeWalker(group, NodeFilter.SHOW_COMMENT)
854
+ let node: Comment | null
855
+ while ((node = walker.nextNode() as Comment | null)) {
856
+ const text = node.textContent?.trim()
857
+ if (text && text.length > 1) return text
858
+ }
859
+
860
+ // Check preceding sibling comments
861
+ let sibling = group.previousSibling
862
+ while (sibling) {
863
+ if (sibling.nodeType === Node.COMMENT_NODE) {
864
+ const text = sibling.textContent?.trim()
865
+ if (text && text.length > 1) return text
866
+ }
867
+ if (sibling.nodeType === Node.ELEMENT_NODE) break // stop at previous element
868
+ sibling = sibling.previousSibling
869
+ }
870
+
871
+ return null
872
+ }
873
+
874
+ // Clean LaTeX subscript notation: "La$_2$NiO$_4$" -> "La2NiO4"
875
+ const clean_latex = (text: string): string =>
876
+ text
877
+ .replaceAll(/\$_\{([^}]*)\}\$/g, `$1`) // $_{10}$ -> 10
878
+ .replaceAll(/\$_(\d)\$/g, `$1`) // $_2$ -> 2
879
+ .replaceAll(`$`, ``) // remove any remaining $
880
+ .replaceAll(/\s+/g, ` `)
881
+ .trim()
882
+
883
+ // Parse SVG path data into absolute line segments [x1,y1,x2,y2]
884
+ // Handles all SVG path commands (M/L/H/V/C/S/Q/T/A/Z, both absolute and relative)
885
+ // Curves (C/S/Q/T/A) are approximated as straight lines from start to endpoint
886
+ // After M/m, implicit coordinates are treated as L/l per SVG spec
887
+ function parse_path_segments(path_str: string): [number, number, number, number][] {
888
+ const segments: [number, number, number, number][] = []
889
+ let [cursor_x, cursor_y] = [0, 0]
890
+ let [start_x, start_y] = [0, 0]
891
+ let last_cmd = ``
892
+
893
+ // Numbers to skip before the endpoint x,y for each curve command
894
+ const curve_skip: Record<string, number> = { C: 4, S: 2, Q: 2, T: 0, A: 5 }
895
+ const tokens = path_str.match(/[MmLlHhVvCcSsQqTtAaZz]|[-+]?[\d]*\.?[\d]+(?:[eE][-+]?\d+)?/g)
896
+ if (!tokens) return segments
897
+
898
+ let idx = 0
899
+ const peek = () => tokens[idx]
900
+ const next_num = () => parseFloat(tokens[idx++] ?? `0`)
901
+
902
+ while (idx < tokens.length) {
903
+ let cmd = peek() ?? ``
904
+
905
+ if (cmd.length === 1 && /[A-Za-z]/.test(cmd)) {
906
+ idx++
907
+ last_cmd = cmd
908
+ } else {
909
+ // Implicit repeat: after M→L, after m→l, others repeat themselves
910
+ cmd = last_cmd === `M` ? `L` : last_cmd === `m` ? `l` : last_cmd
911
+ }
912
+
913
+ if (cmd === `M` || cmd === `m`) {
914
+ const next_x = next_num()
915
+ const next_y = next_num()
916
+ cursor_x = cmd === `M` ? next_x : cursor_x + next_x
917
+ cursor_y = cmd === `M` ? next_y : cursor_y + next_y
918
+ start_x = cursor_x
919
+ start_y = cursor_y
920
+ last_cmd = cmd
921
+ } else if (cmd === `L` || cmd === `l`) {
922
+ const next_x = next_num()
923
+ const next_y = next_num()
924
+ const x2 = cmd === `L` ? next_x : cursor_x + next_x
925
+ const y2 = cmd === `L` ? next_y : cursor_y + next_y
926
+ segments.push([cursor_x, cursor_y, x2, y2])
927
+ cursor_x = x2
928
+ cursor_y = y2
929
+ } else if (cmd === `H` || cmd === `h`) {
930
+ const next_x = next_num()
931
+ const x2 = cmd === `H` ? next_x : cursor_x + next_x
932
+ segments.push([cursor_x, cursor_y, x2, cursor_y])
933
+ cursor_x = x2
934
+ } else if (cmd === `V` || cmd === `v`) {
935
+ const next_y = next_num()
936
+ const y2 = cmd === `V` ? next_y : cursor_y + next_y
937
+ segments.push([cursor_x, cursor_y, cursor_x, y2])
938
+ cursor_y = y2
939
+ } else if (cmd === `Z` || cmd === `z`) {
940
+ if (cursor_x !== start_x || cursor_y !== start_y) {
941
+ segments.push([cursor_x, cursor_y, start_x, start_y])
942
+ }
943
+ cursor_x = start_x
944
+ cursor_y = start_y
945
+ } else {
946
+ // Curve commands: skip control/arc params, use endpoint as straight line
947
+ // C=4 skip, S=2, Q=2, T=0, A=5 (numbers before the final x,y endpoint)
948
+ const upper = cmd.toUpperCase()
949
+ const skip = curve_skip[upper]
950
+ if (skip !== undefined) {
951
+ for (let skip_idx = 0; skip_idx < skip; skip_idx++) next_num()
952
+ const end_x = next_num()
953
+ const end_y = next_num()
954
+ const x2 = cmd === upper ? end_x : cursor_x + end_x
955
+ const y2 = cmd === upper ? end_y : cursor_y + end_y
956
+ segments.push([cursor_x, cursor_y, x2, y2])
957
+ cursor_x = x2
958
+ cursor_y = y2
959
+ } else {
960
+ idx++ // skip unknown tokens
961
+ }
962
+ }
963
+ }
964
+ return segments
965
+ }
966
+
967
+ // Parse a simple 2-point line path (M...L only). Returns null for multi-segment paths
968
+ // to enforce the single-line contract expected by boundary extraction.
969
+ function parse_ml_path(
970
+ path_str: string,
971
+ ): { x1: number; y1: number; x2: number; y2: number } | null {
972
+ const segments = parse_path_segments(path_str)
973
+ if (segments.length !== 1) return null
974
+ const [x1, y1, x2, y2] = segments[0]
975
+ return { x1, y1, x2, y2 }
976
+ }
977
+
978
+ // Parse translate(x, y) or translate(x) from a transform attribute
979
+ // Single-arg translate uses implicit y=0 per SVG spec
980
+ function parse_translate(el: Element | null): [number, number] | null {
981
+ const match = /translate\(\s*([\d.eE+-]+)(?:\s*[,\s]\s*([\d.eE+-]+))?\s*\)/.exec(
982
+ el?.getAttribute(`transform`) ?? ``,
983
+ )
984
+ if (!match) return null
985
+ return [parseFloat(match[1]), match[2] ? parseFloat(match[2]) : 0]
986
+ }
987
+
988
+ // Get translate X or Y from a group's transform attribute
989
+ function get_group_translate(el: Element | null, axis: `x` | `y`): number {
990
+ const coords = parse_translate(el)
991
+ return coords ? coords[axis === `x` ? 0 : 1] : 0
992
+ }
993
+
994
+ // Collect unique sorted values from an array (with epsilon deduplication)
995
+ function collect_unique_sorted(values: number[]): number[] {
996
+ if (values.length === 0) return []
997
+ const sorted = values.toSorted((a, b) => a - b)
998
+ const unique: number[] = [sorted[0]]
999
+ for (let idx = 1; idx < sorted.length; idx++) {
1000
+ if (Math.abs(sorted[idx] - unique[unique.length - 1]) > 1e-4) {
1001
+ unique.push(sorted[idx])
1002
+ }
1003
+ }
1004
+ return unique
1005
+ }
1006
+
1007
+ // Find the index of a coordinate in a sorted array (with epsilon tolerance)
1008
+ function find_coord_index(coords: number[], value: number): number {
1009
+ for (let idx = 0; idx < coords.length; idx++) {
1010
+ if (Math.abs(coords[idx] - value) < 1e-4) return idx
1011
+ }
1012
+ return -1
1013
+ }
1014
+
1015
+ // Find which cell interval a value falls into
1016
+ function find_cell_index(coords: number[], value: number): number {
1017
+ for (let idx = 0; idx < coords.length - 1; idx++) {
1018
+ if (value >= coords[idx] - 1e-4 && value <= coords[idx + 1] + 1e-4) {
1019
+ return idx
1020
+ }
1021
+ }
1022
+ return -1
1023
+ }