react-cheminfo 0.69.0 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (616) hide show
  1. package/README.md +70 -2
  2. package/lib/about/core/providers.d.ts +6 -0
  3. package/lib/about/core/providers.d.ts.map +1 -1
  4. package/lib/about/core/providers.js +7 -0
  5. package/lib/about/core/providers.js.map +1 -1
  6. package/lib/about/ui/AboutProvidedBy.js +34 -0
  7. package/lib/about/ui/AboutProvidedBy.js.map +1 -1
  8. package/lib/chart/ui/useChartPointer.d.ts +9 -1
  9. package/lib/chart/ui/useChartPointer.d.ts.map +1 -1
  10. package/lib/chart/ui/useChartPointer.js +11 -3
  11. package/lib/chart/ui/useChartPointer.js.map +1 -1
  12. package/lib/credits/core/credits.d.ts +41 -0
  13. package/lib/credits/core/credits.d.ts.map +1 -1
  14. package/lib/credits/core/credits.js +50 -0
  15. package/lib/credits/core/credits.js.map +1 -1
  16. package/lib/download/core/drawingMarkup.d.ts +8 -1
  17. package/lib/download/core/drawingMarkup.d.ts.map +1 -1
  18. package/lib/download/core/drawingMarkup.js +13 -1
  19. package/lib/download/core/drawingMarkup.js.map +1 -1
  20. package/lib/download/core/figurePng.d.ts +14 -0
  21. package/lib/download/core/figurePng.d.ts.map +1 -1
  22. package/lib/download/core/figurePng.js +21 -6
  23. package/lib/download/core/figurePng.js.map +1 -1
  24. package/lib/download/core/figureSvg.d.ts.map +1 -1
  25. package/lib/download/core/figureSvg.js +5 -3
  26. package/lib/download/core/figureSvg.js.map +1 -1
  27. package/lib/download/core/figureTarget.d.ts +13 -0
  28. package/lib/download/core/figureTarget.d.ts.map +1 -1
  29. package/lib/download/core/figureTarget.js +25 -5
  30. package/lib/download/core/figureTarget.js.map +1 -1
  31. package/lib/download/core/svgBounds.d.ts +15 -0
  32. package/lib/download/core/svgBounds.d.ts.map +1 -1
  33. package/lib/download/core/svgBounds.js +20 -0
  34. package/lib/download/core/svgBounds.js.map +1 -1
  35. package/lib/download/core/svgToPng.d.ts.map +1 -1
  36. package/lib/download/core/svgToPng.js +4 -2
  37. package/lib/download/core/svgToPng.js.map +1 -1
  38. package/lib/format/core/relativeTime.d.ts +8 -3
  39. package/lib/format/core/relativeTime.d.ts.map +1 -1
  40. package/lib/format/core/relativeTime.js +19 -7
  41. package/lib/format/core/relativeTime.js.map +1 -1
  42. package/lib/host/core/connectHost.d.ts +25 -34
  43. package/lib/host/core/connectHost.d.ts.map +1 -1
  44. package/lib/host/core/connectHost.js +43 -89
  45. package/lib/host/core/connectHost.js.map +1 -1
  46. package/lib/host/core/hostOutputs.d.ts +58 -0
  47. package/lib/host/core/hostOutputs.d.ts.map +1 -0
  48. package/lib/host/core/hostOutputs.js +151 -0
  49. package/lib/host/core/hostOutputs.js.map +1 -0
  50. package/lib/host/core/index.d.ts +9 -3
  51. package/lib/host/core/index.d.ts.map +1 -1
  52. package/lib/host/core/index.js +4 -1
  53. package/lib/host/core/index.js.map +1 -1
  54. package/lib/host/core/irKinds.d.ts +124 -0
  55. package/lib/host/core/irKinds.d.ts.map +1 -0
  56. package/lib/host/core/irKinds.js +46 -0
  57. package/lib/host/core/irKinds.js.map +1 -0
  58. package/lib/host/core/kinds.d.ts +13 -5
  59. package/lib/host/core/kinds.d.ts.map +1 -1
  60. package/lib/host/core/kinds.js +11 -5
  61. package/lib/host/core/kinds.js.map +1 -1
  62. package/lib/host/core/protocol.d.ts +50 -7
  63. package/lib/host/core/protocol.d.ts.map +1 -1
  64. package/lib/host/core/protocol.js +10 -6
  65. package/lib/host/core/protocol.js.map +1 -1
  66. package/lib/host/core/selectInputs.d.ts +37 -0
  67. package/lib/host/core/selectInputs.d.ts.map +1 -0
  68. package/lib/host/core/selectInputs.js +110 -0
  69. package/lib/host/core/selectInputs.js.map +1 -0
  70. package/lib/host/testing/sciPeaks.d.ts +31 -0
  71. package/lib/host/testing/sciPeaks.d.ts.map +1 -1
  72. package/lib/host/testing/sciPeaks.js +73 -0
  73. package/lib/host/testing/sciPeaks.js.map +1 -1
  74. package/lib/host/testing/standInHost.d.ts +9 -1
  75. package/lib/host/testing/standInHost.d.ts.map +1 -1
  76. package/lib/host/testing/standInHost.js +19 -1
  77. package/lib/host/testing/standInHost.js.map +1 -1
  78. package/lib/host/ui/useHostConnection.d.ts +13 -5
  79. package/lib/host/ui/useHostConnection.d.ts.map +1 -1
  80. package/lib/host/ui/useHostConnection.js +4 -3
  81. package/lib/host/ui/useHostConnection.js.map +1 -1
  82. package/lib/host-testing.d.ts +2 -2
  83. package/lib/host-testing.d.ts.map +1 -1
  84. package/lib/host-testing.js +2 -2
  85. package/lib/host-testing.js.map +1 -1
  86. package/lib/i18n/core/chromeCatalog.d.ts +1 -1
  87. package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
  88. package/lib/ir/core/handPicking.d.ts +58 -0
  89. package/lib/ir/core/handPicking.d.ts.map +1 -0
  90. package/lib/ir/core/handPicking.js +130 -0
  91. package/lib/ir/core/handPicking.js.map +1 -0
  92. package/lib/ir/core/index.d.ts +3 -0
  93. package/lib/ir/core/index.d.ts.map +1 -1
  94. package/lib/ir/core/index.js +3 -0
  95. package/lib/ir/core/index.js.map +1 -1
  96. package/lib/ir/core/irBandState.d.ts +57 -0
  97. package/lib/ir/core/irBandState.d.ts.map +1 -0
  98. package/lib/ir/core/irBandState.js +119 -0
  99. package/lib/ir/core/irBandState.js.map +1 -0
  100. package/lib/ir/core/irCommands.d.ts +11 -0
  101. package/lib/ir/core/irCommands.d.ts.map +1 -1
  102. package/lib/ir/core/irCommands.js +6 -0
  103. package/lib/ir/core/irCommands.js.map +1 -1
  104. package/lib/ir/core/irPeaks.d.ts +28 -0
  105. package/lib/ir/core/irPeaks.d.ts.map +1 -0
  106. package/lib/ir/core/irPeaks.js +66 -0
  107. package/lib/ir/core/irPeaks.js.map +1 -0
  108. package/lib/ir/core/irReducer.d.ts +8 -0
  109. package/lib/ir/core/irReducer.d.ts.map +1 -1
  110. package/lib/ir/core/irReducer.js +15 -32
  111. package/lib/ir/core/irReducer.js.map +1 -1
  112. package/lib/ir/core/irSpectrum.d.ts +15 -0
  113. package/lib/ir/core/irSpectrum.d.ts.map +1 -1
  114. package/lib/ir/core/irSpectrum.js.map +1 -1
  115. package/lib/ir/core/irState.d.ts +9 -6
  116. package/lib/ir/core/irState.d.ts.map +1 -1
  117. package/lib/ir/core/irState.js +10 -6
  118. package/lib/ir/core/irState.js.map +1 -1
  119. package/lib/ir/core/pickBands.d.ts +14 -0
  120. package/lib/ir/core/pickBands.d.ts.map +1 -1
  121. package/lib/ir/core/pickBands.js +39 -33
  122. package/lib/ir/core/pickBands.js.map +1 -1
  123. package/lib/ir/core/ramanBands.d.ts +9 -1
  124. package/lib/ir/core/ramanBands.d.ts.map +1 -1
  125. package/lib/ir/core/ramanBands.js +2 -2
  126. package/lib/ir/core/ramanBands.js.map +1 -1
  127. package/lib/ir/core/spectrumBands.d.ts +46 -0
  128. package/lib/ir/core/spectrumBands.d.ts.map +1 -0
  129. package/lib/ir/core/spectrumBands.js +98 -0
  130. package/lib/ir/core/spectrumBands.js.map +1 -0
  131. package/lib/ir/ui/BandRow.d.ts +5 -0
  132. package/lib/ir/ui/BandRow.d.ts.map +1 -1
  133. package/lib/ir/ui/BandRow.js +4 -3
  134. package/lib/ir/ui/BandRow.js.map +1 -1
  135. package/lib/ir/ui/BandsPanel.d.ts +5 -0
  136. package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
  137. package/lib/ir/ui/BandsPanel.js +36 -16
  138. package/lib/ir/ui/BandsPanel.js.map +1 -1
  139. package/lib/ir/ui/BandsToolbar.d.ts +9 -0
  140. package/lib/ir/ui/BandsToolbar.d.ts.map +1 -0
  141. package/lib/ir/ui/BandsToolbar.js +61 -0
  142. package/lib/ir/ui/BandsToolbar.js.map +1 -0
  143. package/lib/ir/ui/IrCanvas.d.ts +2 -1
  144. package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
  145. package/lib/ir/ui/IrCanvas.js +19 -5
  146. package/lib/ir/ui/IrCanvas.js.map +1 -1
  147. package/lib/ir/ui/IrChart.d.ts.map +1 -1
  148. package/lib/ir/ui/IrChart.js +8 -1
  149. package/lib/ir/ui/IrChart.js.map +1 -1
  150. package/lib/ir/ui/IrDocumentationDialog.js +1 -1
  151. package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
  152. package/lib/ir/ui/IrEditor.d.ts +4 -2
  153. package/lib/ir/ui/IrEditor.d.ts.map +1 -1
  154. package/lib/ir/ui/IrEditor.js.map +1 -1
  155. package/lib/ir/ui/IrShell.d.ts.map +1 -1
  156. package/lib/ir/ui/IrShell.js +6 -0
  157. package/lib/ir/ui/IrShell.js.map +1 -1
  158. package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
  159. package/lib/ir/ui/IrStatusBar.js +1 -1
  160. package/lib/ir/ui/IrStatusBar.js.map +1 -1
  161. package/lib/ir/ui/IrToolbar.d.ts +4 -3
  162. package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
  163. package/lib/ir/ui/IrToolbar.js +5 -4
  164. package/lib/ir/ui/IrToolbar.js.map +1 -1
  165. package/lib/ir/ui/VibrationalEditor.d.ts +2 -1
  166. package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -1
  167. package/lib/ir/ui/VibrationalEditor.js.map +1 -1
  168. package/lib/ir/ui/irActions.d.ts +5 -0
  169. package/lib/ir/ui/irActions.d.ts.map +1 -1
  170. package/lib/ir/ui/irActions.js +6 -0
  171. package/lib/ir/ui/irActions.js.map +1 -1
  172. package/lib/ir/ui/irChartProps.d.ts +4 -1
  173. package/lib/ir/ui/irChartProps.d.ts.map +1 -1
  174. package/lib/ir/ui/useIrEditor.d.ts +5 -11
  175. package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
  176. package/lib/ir/ui/useIrEditor.js +17 -18
  177. package/lib/ir/ui/useIrEditor.js.map +1 -1
  178. package/lib/locales/de.json +63 -0
  179. package/lib/locales/en.json +63 -0
  180. package/lib/locales/es.json +63 -0
  181. package/lib/locales/fr.json +63 -0
  182. package/lib/locales/it.json +63 -0
  183. package/lib/mass/core/analyseSpectrum.d.ts +85 -0
  184. package/lib/mass/core/analyseSpectrum.d.ts.map +1 -0
  185. package/lib/mass/core/analyseSpectrum.js +101 -0
  186. package/lib/mass/core/analyseSpectrum.js.map +1 -0
  187. package/lib/mass/core/ascendingTrace.d.ts +24 -0
  188. package/lib/mass/core/ascendingTrace.d.ts.map +1 -0
  189. package/lib/mass/core/ascendingTrace.js +57 -0
  190. package/lib/mass/core/ascendingTrace.js.map +1 -0
  191. package/lib/mass/core/centroidPeaks.d.ts +77 -0
  192. package/lib/mass/core/centroidPeaks.d.ts.map +1 -0
  193. package/lib/mass/core/centroidPeaks.js +62 -0
  194. package/lib/mass/core/centroidPeaks.js.map +1 -0
  195. package/lib/mass/core/detectMassFormat.d.ts +24 -0
  196. package/lib/mass/core/detectMassFormat.d.ts.map +1 -0
  197. package/lib/mass/core/detectMassFormat.js +105 -0
  198. package/lib/mass/core/detectMassFormat.js.map +1 -0
  199. package/lib/mass/core/downloadSpectra.d.ts +24 -0
  200. package/lib/mass/core/downloadSpectra.d.ts.map +1 -0
  201. package/lib/mass/core/downloadSpectra.js +35 -0
  202. package/lib/mass/core/downloadSpectra.js.map +1 -0
  203. package/lib/mass/core/fromJcamp.d.ts +46 -0
  204. package/lib/mass/core/fromJcamp.d.ts.map +1 -0
  205. package/lib/mass/core/fromJcamp.js +123 -0
  206. package/lib/mass/core/fromJcamp.js.map +1 -0
  207. package/lib/mass/core/fromText.d.ts +30 -0
  208. package/lib/mass/core/fromText.d.ts.map +1 -0
  209. package/lib/mass/core/fromText.js +39 -0
  210. package/lib/mass/core/fromText.js.map +1 -0
  211. package/lib/mass/core/index.d.ts +70 -0
  212. package/lib/mass/core/index.d.ts.map +1 -0
  213. package/lib/mass/core/index.js +42 -0
  214. package/lib/mass/core/index.js.map +1 -0
  215. package/lib/mass/core/jcampTechnique.d.ts +38 -0
  216. package/lib/mass/core/jcampTechnique.d.ts.map +1 -0
  217. package/lib/mass/core/jcampTechnique.js +70 -0
  218. package/lib/mass/core/jcampTechnique.js.map +1 -0
  219. package/lib/mass/core/labelStackBox.d.ts +49 -0
  220. package/lib/mass/core/labelStackBox.d.ts.map +1 -0
  221. package/lib/mass/core/labelStackBox.js +44 -0
  222. package/lib/mass/core/labelStackBox.js.map +1 -0
  223. package/lib/mass/core/labelledPeaks.d.ts +79 -0
  224. package/lib/mass/core/labelledPeaks.d.ts.map +1 -0
  225. package/lib/mass/core/labelledPeaks.js +74 -0
  226. package/lib/mass/core/labelledPeaks.js.map +1 -0
  227. package/lib/mass/core/loadMassSpectra.d.ts +57 -0
  228. package/lib/mass/core/loadMassSpectra.d.ts.map +1 -0
  229. package/lib/mass/core/loadMassSpectra.js +45 -0
  230. package/lib/mass/core/loadMassSpectra.js.map +1 -0
  231. package/lib/mass/core/loadedMassSpectrum.d.ts +42 -0
  232. package/lib/mass/core/loadedMassSpectrum.d.ts.map +1 -0
  233. package/lib/mass/core/loadedMassSpectrum.js +15 -0
  234. package/lib/mass/core/loadedMassSpectrum.js.map +1 -0
  235. package/lib/mass/core/massCommands.d.ts +170 -0
  236. package/lib/mass/core/massCommands.d.ts.map +1 -0
  237. package/lib/mass/core/massCommands.js +95 -0
  238. package/lib/mass/core/massCommands.js.map +1 -0
  239. package/lib/mass/core/massDomain.d.ts +121 -0
  240. package/lib/mass/core/massDomain.d.ts.map +1 -0
  241. package/lib/mass/core/massDomain.js +179 -0
  242. package/lib/mass/core/massDomain.js.map +1 -0
  243. package/lib/mass/core/massEditorApi.d.ts +65 -0
  244. package/lib/mass/core/massEditorApi.d.ts.map +1 -0
  245. package/lib/mass/core/massEditorApi.js +10 -0
  246. package/lib/mass/core/massEditorApi.js.map +1 -0
  247. package/lib/mass/core/massFormat.d.ts +78 -0
  248. package/lib/mass/core/massFormat.d.ts.map +1 -0
  249. package/lib/mass/core/massFormat.js +168 -0
  250. package/lib/mass/core/massFormat.js.map +1 -0
  251. package/lib/mass/core/massMeta.d.ts +85 -0
  252. package/lib/mass/core/massMeta.d.ts.map +1 -0
  253. package/lib/mass/core/massMeta.js +182 -0
  254. package/lib/mass/core/massMeta.js.map +1 -0
  255. package/lib/mass/core/massReducer.d.ts +82 -0
  256. package/lib/mass/core/massReducer.d.ts.map +1 -0
  257. package/lib/mass/core/massReducer.js +163 -0
  258. package/lib/mass/core/massReducer.js.map +1 -0
  259. package/lib/mass/core/massResolution.d.ts +92 -0
  260. package/lib/mass/core/massResolution.d.ts.map +1 -0
  261. package/lib/mass/core/massResolution.js +126 -0
  262. package/lib/mass/core/massResolution.js.map +1 -0
  263. package/lib/mass/core/massSidePanels.d.ts +28 -0
  264. package/lib/mass/core/massSidePanels.d.ts.map +1 -0
  265. package/lib/mass/core/massSidePanels.js +12 -0
  266. package/lib/mass/core/massSidePanels.js.map +1 -0
  267. package/lib/mass/core/massSpectrum.d.ts +206 -0
  268. package/lib/mass/core/massSpectrum.d.ts.map +1 -0
  269. package/lib/mass/core/massSpectrum.js +41 -0
  270. package/lib/mass/core/massSpectrum.js.map +1 -0
  271. package/lib/mass/core/massState.d.ts +145 -0
  272. package/lib/mass/core/massState.d.ts.map +1 -0
  273. package/lib/mass/core/massState.js +102 -0
  274. package/lib/mass/core/massState.js.map +1 -0
  275. package/lib/mass/core/massStateEdits.d.ts +51 -0
  276. package/lib/mass/core/massStateEdits.d.ts.map +1 -0
  277. package/lib/mass/core/massStateEdits.js +90 -0
  278. package/lib/mass/core/massStateEdits.js.map +1 -0
  279. package/lib/mass/core/massSummary.d.ts +77 -0
  280. package/lib/mass/core/massSummary.d.ts.map +1 -0
  281. package/lib/mass/core/massSummary.js +174 -0
  282. package/lib/mass/core/massSummary.js.map +1 -0
  283. package/lib/mass/core/mzDecimalsSetting.d.ts +36 -0
  284. package/lib/mass/core/mzDecimalsSetting.d.ts.map +1 -0
  285. package/lib/mass/core/mzDecimalsSetting.js +42 -0
  286. package/lib/mass/core/mzDecimalsSetting.js.map +1 -0
  287. package/lib/mass/core/nearestPeak.d.ts +75 -0
  288. package/lib/mass/core/nearestPeak.d.ts.map +1 -0
  289. package/lib/mass/core/nearestPeak.js +99 -0
  290. package/lib/mass/core/nearestPeak.js.map +1 -0
  291. package/lib/mass/core/peakLabelLines.d.ts +77 -0
  292. package/lib/mass/core/peakLabelLines.d.ts.map +1 -0
  293. package/lib/mass/core/peakLabelLines.js +54 -0
  294. package/lib/mass/core/peakLabelLines.js.map +1 -0
  295. package/lib/mass/core/peakLabelPlan.d.ts +109 -0
  296. package/lib/mass/core/peakLabelPlan.d.ts.map +1 -0
  297. package/lib/mass/core/peakLabelPlan.js +143 -0
  298. package/lib/mass/core/peakLabelPlan.js.map +1 -0
  299. package/lib/mass/core/peakTable.d.ts +54 -0
  300. package/lib/mass/core/peakTable.d.ts.map +1 -0
  301. package/lib/mass/core/peakTable.js +53 -0
  302. package/lib/mass/core/peakTable.js.map +1 -0
  303. package/lib/mass/core/resolutionOf.d.ts +60 -0
  304. package/lib/mass/core/resolutionOf.d.ts.map +1 -0
  305. package/lib/mass/core/resolutionOf.js +84 -0
  306. package/lib/mass/core/resolutionOf.js.map +1 -0
  307. package/lib/mass/core/scanFilter.d.ts +25 -0
  308. package/lib/mass/core/scanFilter.d.ts.map +1 -0
  309. package/lib/mass/core/scanFilter.js +107 -0
  310. package/lib/mass/core/scanFilter.js.map +1 -0
  311. package/lib/mass/core/spectrumJcamp.d.ts +47 -0
  312. package/lib/mass/core/spectrumJcamp.d.ts.map +1 -0
  313. package/lib/mass/core/spectrumJcamp.js +167 -0
  314. package/lib/mass/core/spectrumJcamp.js.map +1 -0
  315. package/lib/mass/core/toMassSpectrum.d.ts +67 -0
  316. package/lib/mass/core/toMassSpectrum.d.ts.map +1 -0
  317. package/lib/mass/core/toMassSpectrum.js +78 -0
  318. package/lib/mass/core/toMassSpectrum.js.map +1 -0
  319. package/lib/mass/core/traceIcon.d.ts +82 -0
  320. package/lib/mass/core/traceIcon.d.ts.map +1 -0
  321. package/lib/mass/core/traceIcon.js +66 -0
  322. package/lib/mass/core/traceIcon.js.map +1 -0
  323. package/lib/mass/core/writtenResolution.d.ts +40 -0
  324. package/lib/mass/core/writtenResolution.d.ts.map +1 -0
  325. package/lib/mass/core/writtenResolution.js +77 -0
  326. package/lib/mass/core/writtenResolution.js.map +1 -0
  327. package/lib/mass/ui/MassAboutDialog.d.ts +16 -0
  328. package/lib/mass/ui/MassAboutDialog.d.ts.map +1 -0
  329. package/lib/mass/ui/MassAboutDialog.js +44 -0
  330. package/lib/mass/ui/MassAboutDialog.js.map +1 -0
  331. package/lib/mass/ui/MassCanvas.d.ts +46 -0
  332. package/lib/mass/ui/MassCanvas.d.ts.map +1 -0
  333. package/lib/mass/ui/MassCanvas.js +84 -0
  334. package/lib/mass/ui/MassCanvas.js.map +1 -0
  335. package/lib/mass/ui/MassChart.d.ts +21 -0
  336. package/lib/mass/ui/MassChart.d.ts.map +1 -0
  337. package/lib/mass/ui/MassChart.js +139 -0
  338. package/lib/mass/ui/MassChart.js.map +1 -0
  339. package/lib/mass/ui/MassCommandProvider.d.ts +15 -0
  340. package/lib/mass/ui/MassCommandProvider.d.ts.map +1 -0
  341. package/lib/mass/ui/MassCommandProvider.js +14 -0
  342. package/lib/mass/ui/MassCommandProvider.js.map +1 -0
  343. package/lib/mass/ui/MassCommandTooltip.d.ts +16 -0
  344. package/lib/mass/ui/MassCommandTooltip.d.ts.map +1 -0
  345. package/lib/mass/ui/MassCommandTooltip.js +22 -0
  346. package/lib/mass/ui/MassCommandTooltip.js.map +1 -0
  347. package/lib/mass/ui/MassDocumentationDialog.d.ts +18 -0
  348. package/lib/mass/ui/MassDocumentationDialog.d.ts.map +1 -0
  349. package/lib/mass/ui/MassDocumentationDialog.js +70 -0
  350. package/lib/mass/ui/MassDocumentationDialog.js.map +1 -0
  351. package/lib/mass/ui/MassEditor.d.ts +78 -0
  352. package/lib/mass/ui/MassEditor.d.ts.map +1 -0
  353. package/lib/mass/ui/MassEditor.js +42 -0
  354. package/lib/mass/ui/MassEditor.js.map +1 -0
  355. package/lib/mass/ui/MassHeader.d.ts +12 -0
  356. package/lib/mass/ui/MassHeader.d.ts.map +1 -0
  357. package/lib/mass/ui/MassHeader.js +20 -0
  358. package/lib/mass/ui/MassHeader.js.map +1 -0
  359. package/lib/mass/ui/MassLogo.d.ts +21 -0
  360. package/lib/mass/ui/MassLogo.d.ts.map +1 -0
  361. package/lib/mass/ui/MassLogo.js +36 -0
  362. package/lib/mass/ui/MassLogo.js.map +1 -0
  363. package/lib/mass/ui/MassPointerTracker.d.ts +44 -0
  364. package/lib/mass/ui/MassPointerTracker.d.ts.map +1 -0
  365. package/lib/mass/ui/MassPointerTracker.js +29 -0
  366. package/lib/mass/ui/MassPointerTracker.js.map +1 -0
  367. package/lib/mass/ui/MassShell.d.ts +29 -0
  368. package/lib/mass/ui/MassShell.d.ts.map +1 -0
  369. package/lib/mass/ui/MassShell.js +133 -0
  370. package/lib/mass/ui/MassShell.js.map +1 -0
  371. package/lib/mass/ui/MassSidePanel.d.ts +32 -0
  372. package/lib/mass/ui/MassSidePanel.d.ts.map +1 -0
  373. package/lib/mass/ui/MassSidePanel.js +44 -0
  374. package/lib/mass/ui/MassSidePanel.js.map +1 -0
  375. package/lib/mass/ui/MassStateProvider.d.ts +19 -0
  376. package/lib/mass/ui/MassStateProvider.d.ts.map +1 -0
  377. package/lib/mass/ui/MassStateProvider.js +16 -0
  378. package/lib/mass/ui/MassStateProvider.js.map +1 -0
  379. package/lib/mass/ui/MassStatusBar.d.ts +15 -0
  380. package/lib/mass/ui/MassStatusBar.d.ts.map +1 -0
  381. package/lib/mass/ui/MassStatusBar.js +50 -0
  382. package/lib/mass/ui/MassStatusBar.js.map +1 -0
  383. package/lib/mass/ui/MassToolbar.d.ts +24 -0
  384. package/lib/mass/ui/MassToolbar.d.ts.map +1 -0
  385. package/lib/mass/ui/MassToolbar.js +36 -0
  386. package/lib/mass/ui/MassToolbar.js.map +1 -0
  387. package/lib/mass/ui/MetadataPanel.d.ts +35 -0
  388. package/lib/mass/ui/MetadataPanel.d.ts.map +1 -0
  389. package/lib/mass/ui/MetadataPanel.js +100 -0
  390. package/lib/mass/ui/MetadataPanel.js.map +1 -0
  391. package/lib/mass/ui/MzDecimalsMenu.d.ts +28 -0
  392. package/lib/mass/ui/MzDecimalsMenu.d.ts.map +1 -0
  393. package/lib/mass/ui/MzDecimalsMenu.js +40 -0
  394. package/lib/mass/ui/MzDecimalsMenu.js.map +1 -0
  395. package/lib/mass/ui/PeakLabels.d.ts +93 -0
  396. package/lib/mass/ui/PeakLabels.d.ts.map +1 -0
  397. package/lib/mass/ui/PeakLabels.js +91 -0
  398. package/lib/mass/ui/PeakLabels.js.map +1 -0
  399. package/lib/mass/ui/PeakTable.d.ts +34 -0
  400. package/lib/mass/ui/PeakTable.d.ts.map +1 -0
  401. package/lib/mass/ui/PeakTable.js +49 -0
  402. package/lib/mass/ui/PeakTable.js.map +1 -0
  403. package/lib/mass/ui/PeaksPanel.d.ts +31 -0
  404. package/lib/mass/ui/PeaksPanel.d.ts.map +1 -0
  405. package/lib/mass/ui/PeaksPanel.js +53 -0
  406. package/lib/mass/ui/PeaksPanel.js.map +1 -0
  407. package/lib/mass/ui/SpectraPanel.d.ts +17 -0
  408. package/lib/mass/ui/SpectraPanel.d.ts.map +1 -0
  409. package/lib/mass/ui/SpectraPanel.js +76 -0
  410. package/lib/mass/ui/SpectraPanel.js.map +1 -0
  411. package/lib/mass/ui/SpectrumRow.d.ts +26 -0
  412. package/lib/mass/ui/SpectrumRow.d.ts.map +1 -0
  413. package/lib/mass/ui/SpectrumRow.js +141 -0
  414. package/lib/mass/ui/SpectrumRow.js.map +1 -0
  415. package/lib/mass/ui/SpectrumTrace.d.ts +46 -0
  416. package/lib/mass/ui/SpectrumTrace.d.ts.map +1 -0
  417. package/lib/mass/ui/SpectrumTrace.js +68 -0
  418. package/lib/mass/ui/SpectrumTrace.js.map +1 -0
  419. package/lib/mass/ui/index.d.ts +69 -0
  420. package/lib/mass/ui/index.d.ts.map +1 -0
  421. package/lib/mass/ui/index.js +42 -0
  422. package/lib/mass/ui/index.js.map +1 -0
  423. package/lib/mass/ui/massActions.d.ts +52 -0
  424. package/lib/mass/ui/massActions.d.ts.map +1 -0
  425. package/lib/mass/ui/massActions.js +62 -0
  426. package/lib/mass/ui/massActions.js.map +1 -0
  427. package/lib/mass/ui/massChartProps.d.ts +128 -0
  428. package/lib/mass/ui/massChartProps.d.ts.map +1 -0
  429. package/lib/mass/ui/massChartProps.js +14 -0
  430. package/lib/mass/ui/massChartProps.js.map +1 -0
  431. package/lib/mass/ui/massCommandContext.d.ts +36 -0
  432. package/lib/mass/ui/massCommandContext.d.ts.map +1 -0
  433. package/lib/mass/ui/massCommandContext.js +45 -0
  434. package/lib/mass/ui/massCommandContext.js.map +1 -0
  435. package/lib/mass/ui/massHostPanels.d.ts +48 -0
  436. package/lib/mass/ui/massHostPanels.d.ts.map +1 -0
  437. package/lib/mass/ui/massHostPanels.js +41 -0
  438. package/lib/mass/ui/massHostPanels.js.map +1 -0
  439. package/lib/mass/ui/massStateContext.d.ts +26 -0
  440. package/lib/mass/ui/massStateContext.d.ts.map +1 -0
  441. package/lib/mass/ui/massStateContext.js +37 -0
  442. package/lib/mass/ui/massStateContext.js.map +1 -0
  443. package/lib/mass/ui/useIntensityZoom.d.ts +20 -0
  444. package/lib/mass/ui/useIntensityZoom.d.ts.map +1 -0
  445. package/lib/mass/ui/useIntensityZoom.js +42 -0
  446. package/lib/mass/ui/useIntensityZoom.js.map +1 -0
  447. package/lib/mass/ui/useMassEditor.d.ts +52 -0
  448. package/lib/mass/ui/useMassEditor.d.ts.map +1 -0
  449. package/lib/mass/ui/useMassEditor.js +93 -0
  450. package/lib/mass/ui/useMassEditor.js.map +1 -0
  451. package/lib/mass/ui/useMassFiles.d.ts +22 -0
  452. package/lib/mass/ui/useMassFiles.d.ts.map +1 -0
  453. package/lib/mass/ui/useMassFiles.js +71 -0
  454. package/lib/mass/ui/useMassFiles.js.map +1 -0
  455. package/lib/mass/ui/useMassHandle.d.ts +15 -0
  456. package/lib/mass/ui/useMassHandle.d.ts.map +1 -0
  457. package/lib/mass/ui/useMassHandle.js +35 -0
  458. package/lib/mass/ui/useMassHandle.js.map +1 -0
  459. package/lib/mass/ui/useMassPointer.d.ts +70 -0
  460. package/lib/mass/ui/useMassPointer.d.ts.map +1 -0
  461. package/lib/mass/ui/useMassPointer.js +57 -0
  462. package/lib/mass/ui/useMassPointer.js.map +1 -0
  463. package/lib/mass/ui/useMassShortcuts.d.ts +21 -0
  464. package/lib/mass/ui/useMassShortcuts.d.ts.map +1 -0
  465. package/lib/mass/ui/useMassShortcuts.js +66 -0
  466. package/lib/mass/ui/useMassShortcuts.js.map +1 -0
  467. package/lib/mass/ui/useMassSide.d.ts +27 -0
  468. package/lib/mass/ui/useMassSide.d.ts.map +1 -0
  469. package/lib/mass/ui/useMassSide.js +45 -0
  470. package/lib/mass/ui/useMassSide.js.map +1 -0
  471. package/lib/mass/ui/useMassZoom.d.ts +92 -0
  472. package/lib/mass/ui/useMassZoom.d.ts.map +1 -0
  473. package/lib/mass/ui/useMassZoom.js +65 -0
  474. package/lib/mass/ui/useMassZoom.js.map +1 -0
  475. package/lib/mass.d.ts +16 -0
  476. package/lib/mass.d.ts.map +1 -0
  477. package/lib/mass.js +16 -0
  478. package/lib/mass.js.map +1 -0
  479. package/lib/panel/ui/PanelRail.d.ts.map +1 -1
  480. package/lib/panel/ui/PanelRail.js +6 -1
  481. package/lib/panel/ui/PanelRail.js.map +1 -1
  482. package/lib/slides/ui/slideSanitizeSchema.d.ts +3 -2
  483. package/lib/slides/ui/slideSanitizeSchema.d.ts.map +1 -1
  484. package/lib/slides/ui/slideSanitizeSchema.js +82 -2
  485. package/lib/slides/ui/slideSanitizeSchema.js.map +1 -1
  486. package/package.json +6 -1
  487. package/src/about/core/providers.ts +7 -0
  488. package/src/about/ui/AboutProvidedBy.tsx +49 -0
  489. package/src/chart/ui/useChartPointer.ts +18 -4
  490. package/src/credits/core/credits.ts +53 -0
  491. package/src/download/core/drawingMarkup.ts +18 -1
  492. package/src/download/core/figurePng.ts +21 -8
  493. package/src/download/core/figureSvg.ts +5 -2
  494. package/src/download/core/figureTarget.ts +28 -3
  495. package/src/download/core/svgBounds.ts +21 -0
  496. package/src/download/core/svgToPng.ts +3 -4
  497. package/src/format/core/relativeTime.ts +29 -7
  498. package/src/host/core/connectHost.ts +77 -120
  499. package/src/host/core/hostOutputs.ts +197 -0
  500. package/src/host/core/index.ts +13 -7
  501. package/src/host/core/irKinds.ts +92 -0
  502. package/src/host/core/kinds.ts +16 -6
  503. package/src/host/core/protocol.ts +50 -8
  504. package/src/host/core/selectInputs.ts +145 -0
  505. package/src/host/testing/sciPeaks.ts +140 -0
  506. package/src/host/testing/standInHost.ts +30 -5
  507. package/src/host/ui/useHostConnection.ts +17 -8
  508. package/src/host-testing.ts +4 -0
  509. package/src/ir/core/handPicking.ts +154 -0
  510. package/src/ir/core/index.ts +14 -0
  511. package/src/ir/core/irBandState.ts +155 -0
  512. package/src/ir/core/irCommands.ts +7 -0
  513. package/src/ir/core/irPeaks.ts +79 -0
  514. package/src/ir/core/irReducer.ts +27 -34
  515. package/src/ir/core/irSpectrum.ts +16 -0
  516. package/src/ir/core/irState.ts +15 -8
  517. package/src/ir/core/pickBands.ts +46 -39
  518. package/src/ir/core/ramanBands.ts +2 -2
  519. package/src/ir/core/spectrumBands.ts +113 -0
  520. package/src/ir/ui/BandRow.tsx +20 -2
  521. package/src/ir/ui/BandsPanel.tsx +46 -88
  522. package/src/ir/ui/BandsToolbar.tsx +152 -0
  523. package/src/ir/ui/IrCanvas.tsx +22 -11
  524. package/src/ir/ui/IrChart.tsx +10 -1
  525. package/src/ir/ui/IrDocumentationDialog.tsx +7 -0
  526. package/src/ir/ui/IrEditor.tsx +4 -2
  527. package/src/ir/ui/IrShell.tsx +5 -0
  528. package/src/ir/ui/IrStatusBar.tsx +4 -1
  529. package/src/ir/ui/IrToolbar.tsx +14 -5
  530. package/src/ir/ui/VibrationalEditor.tsx +2 -1
  531. package/src/ir/ui/irActions.ts +11 -0
  532. package/src/ir/ui/irChartProps.ts +4 -1
  533. package/src/ir/ui/useIrEditor.ts +21 -21
  534. package/src/locales/de.json +63 -0
  535. package/src/locales/en.json +63 -0
  536. package/src/locales/es.json +63 -0
  537. package/src/locales/fr.json +63 -0
  538. package/src/locales/it.json +63 -0
  539. package/src/mass/core/analyseSpectrum.ts +191 -0
  540. package/src/mass/core/ascendingTrace.ts +62 -0
  541. package/src/mass/core/centroidPeaks.ts +114 -0
  542. package/src/mass/core/detectMassFormat.ts +113 -0
  543. package/src/mass/core/downloadSpectra.ts +52 -0
  544. package/src/mass/core/fromJcamp.ts +151 -0
  545. package/src/mass/core/fromText.ts +58 -0
  546. package/src/mass/core/index.ts +194 -0
  547. package/src/mass/core/jcampTechnique.ts +87 -0
  548. package/src/mass/core/labelStackBox.ts +75 -0
  549. package/src/mass/core/labelledPeaks.ts +135 -0
  550. package/src/mass/core/loadMassSpectra.ts +86 -0
  551. package/src/mass/core/loadedMassSpectrum.ts +43 -0
  552. package/src/mass/core/massCommands.ts +156 -0
  553. package/src/mass/core/massDomain.ts +229 -0
  554. package/src/mass/core/massEditorApi.ts +68 -0
  555. package/src/mass/core/massFormat.ts +187 -0
  556. package/src/mass/core/massMeta.ts +239 -0
  557. package/src/mass/core/massReducer.ts +232 -0
  558. package/src/mass/core/massResolution.ts +169 -0
  559. package/src/mass/core/massSidePanels.ts +27 -0
  560. package/src/mass/core/massSpectrum.ts +220 -0
  561. package/src/mass/core/massState.ts +206 -0
  562. package/src/mass/core/massStateEdits.ts +104 -0
  563. package/src/mass/core/massSummary.ts +213 -0
  564. package/src/mass/core/mzDecimalsSetting.ts +52 -0
  565. package/src/mass/core/nearestPeak.ts +130 -0
  566. package/src/mass/core/peakLabelLines.ts +112 -0
  567. package/src/mass/core/peakLabelPlan.ts +246 -0
  568. package/src/mass/core/peakTable.ts +82 -0
  569. package/src/mass/core/resolutionOf.ts +100 -0
  570. package/src/mass/core/scanFilter.ts +119 -0
  571. package/src/mass/core/spectrumJcamp.ts +186 -0
  572. package/src/mass/core/toMassSpectrum.ts +126 -0
  573. package/src/mass/core/traceIcon.ts +105 -0
  574. package/src/mass/core/writtenResolution.ts +81 -0
  575. package/src/mass/ui/MassAboutDialog.tsx +89 -0
  576. package/src/mass/ui/MassCanvas.tsx +170 -0
  577. package/src/mass/ui/MassChart.tsx +266 -0
  578. package/src/mass/ui/MassCommandProvider.tsx +34 -0
  579. package/src/mass/ui/MassCommandTooltip.tsx +36 -0
  580. package/src/mass/ui/MassDocumentationDialog.tsx +136 -0
  581. package/src/mass/ui/MassEditor.tsx +130 -0
  582. package/src/mass/ui/MassHeader.tsx +38 -0
  583. package/src/mass/ui/MassLogo.tsx +84 -0
  584. package/src/mass/ui/MassPointerTracker.tsx +72 -0
  585. package/src/mass/ui/MassShell.tsx +237 -0
  586. package/src/mass/ui/MassSidePanel.tsx +107 -0
  587. package/src/mass/ui/MassStateProvider.tsx +32 -0
  588. package/src/mass/ui/MassStatusBar.tsx +108 -0
  589. package/src/mass/ui/MassToolbar.tsx +120 -0
  590. package/src/mass/ui/MetadataPanel.tsx +201 -0
  591. package/src/mass/ui/MzDecimalsMenu.tsx +86 -0
  592. package/src/mass/ui/PeakLabels.tsx +242 -0
  593. package/src/mass/ui/PeakTable.tsx +199 -0
  594. package/src/mass/ui/PeaksPanel.tsx +182 -0
  595. package/src/mass/ui/SpectraPanel.tsx +153 -0
  596. package/src/mass/ui/SpectrumRow.tsx +246 -0
  597. package/src/mass/ui/SpectrumTrace.tsx +119 -0
  598. package/src/mass/ui/index.ts +69 -0
  599. package/src/mass/ui/massActions.ts +109 -0
  600. package/src/mass/ui/massChartProps.ts +130 -0
  601. package/src/mass/ui/massCommandContext.tsx +65 -0
  602. package/src/mass/ui/massHostPanels.ts +71 -0
  603. package/src/mass/ui/massStateContext.ts +48 -0
  604. package/src/mass/ui/useIntensityZoom.ts +55 -0
  605. package/src/mass/ui/useMassEditor.ts +156 -0
  606. package/src/mass/ui/useMassFiles.ts +91 -0
  607. package/src/mass/ui/useMassHandle.ts +58 -0
  608. package/src/mass/ui/useMassPointer.ts +120 -0
  609. package/src/mass/ui/useMassShortcuts.ts +85 -0
  610. package/src/mass/ui/useMassSide.ts +63 -0
  611. package/src/mass/ui/useMassZoom.ts +157 -0
  612. package/src/mass.ts +16 -0
  613. package/src/panel/ui/PanelRail.tsx +5 -1
  614. package/src/slides/ui/slideSanitizeSchema.ts +86 -2
  615. package/styles/chrome.css +7 -0
  616. package/styles/slides.css +47 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * The bands of an infrared spectrum as a notebook writes them, and back: the
3
+ * peaks of the host protocol's `spectra.ir.jdx` and `spectra.ir.peaks`.
4
+ *
5
+ * The two differ in two ways only: a notebook's transmittance is a fraction
6
+ * where the viewer holds a percentage, and it calls a band's strength `kind`.
7
+ */
8
+
9
+ import { xFindClosestIndex } from 'ml-spectra-processing';
10
+
11
+ import type { IrPeakValue } from '../../host/core/irKinds.ts';
12
+
13
+ import { bandAtIndex } from './handPicking.ts';
14
+ import type { IrBand, IrBandStrength } from './irBand.ts';
15
+ import type { IrSpectrum } from './irSpectrum.ts';
16
+ import { orderedBands } from './spectrumBands.ts';
17
+
18
+ /**
19
+ * The bands a notebook handed over with a spectrum.
20
+ *
21
+ * Each stays where the notebook put it, with the values it gave; a value it
22
+ * left out is read off the spectrum at the nearest sample, and a strength
23
+ * letter that is not one of `w`, `m` and `S` is worked out again.
24
+ * @param spectrum - The spectrum they were picked on.
25
+ * @param peaks - The peaks, in any order.
26
+ * @returns The bands, ascending, one per wavenumber.
27
+ */
28
+ export function bandsFromPeaks(
29
+ spectrum: IrSpectrum,
30
+ peaks: readonly IrPeakValue[],
31
+ ): IrBand[] {
32
+ const bands: IrBand[] = [];
33
+ for (const peak of peaks) {
34
+ const { wavenumber, absorbance, transmittance, kind } = peak;
35
+ if (!Number.isFinite(wavenumber)) continue;
36
+ const read = bandAtIndex(
37
+ spectrum,
38
+ xFindClosestIndex(spectrum.wavenumber, wavenumber),
39
+ );
40
+ if (read === null) continue;
41
+ bands.push({
42
+ ...read,
43
+ wavenumber,
44
+ ...(absorbance === undefined ? {} : { absorbance }),
45
+ ...(transmittance === undefined
46
+ ? {}
47
+ : { transmittance: transmittance * 100 }),
48
+ strength: isStrength(kind) ? kind : read.strength,
49
+ });
50
+ }
51
+ return orderedBands(spectrum.id, bands);
52
+ }
53
+
54
+ /**
55
+ * Bands as a notebook keeps them.
56
+ * @param bands - The bands, as the viewer holds them.
57
+ * @returns The peaks, in the same order.
58
+ */
59
+ export function peaksFromBands(bands: readonly IrBand[]): IrPeakValue[] {
60
+ const peaks: IrPeakValue[] = [];
61
+ for (const band of bands) {
62
+ const { wavenumber, absorbance, transmittance, strength } = band;
63
+ peaks.push({
64
+ wavenumber,
65
+ ...(absorbance === undefined ? {} : { absorbance }),
66
+ ...(transmittance === undefined
67
+ ? {}
68
+ : { transmittance: transmittance / 100 }),
69
+ kind: strength,
70
+ });
71
+ }
72
+ return peaks;
73
+ }
74
+
75
+ function isStrength(kind: string | undefined): kind is IrBandStrength {
76
+ return kind !== undefined && STRENGTHS.includes(kind);
77
+ }
78
+
79
+ const STRENGTHS: readonly string[] = ['w', 'm', 'S'] satisfies IrBandStrength[];
@@ -13,10 +13,19 @@
13
13
  * closed.
14
14
  */
15
15
 
16
+ import type { IrBand } from './irBand.ts';
17
+ import {
18
+ arriving,
19
+ changeSettings,
20
+ mapSpectrum,
21
+ resetSpectrumBands,
22
+ restoreState,
23
+ setSpectrumBands,
24
+ } from './irBandState.ts';
16
25
  import type { IrPanelId } from './irSidePanels.ts';
17
26
  import type { IrDomain, IrSpectrum } from './irSpectrum.ts';
18
27
  import type { IrSettings, IrState, IrTool, PartialIrState } from './irState.ts';
19
- import { isIrWindow, mergeIrSettings } from './irState.ts';
28
+ import { isIrWindow } from './irState.ts';
20
29
 
21
30
  /** Everything that can be asked of the viewer. */
22
31
  export type IrAction =
@@ -26,6 +35,8 @@ export type IrAction =
26
35
  | { type: 'renameSpectrum'; id: string; name: string }
27
36
  | { type: 'setSpectrumColor'; id: string; color: string }
28
37
  | { type: 'setSpectrumVisible'; id: string; visible: boolean }
38
+ | { type: 'setBands'; id: string; bands: IrBand[] }
39
+ | { type: 'resetBands'; id: string }
29
40
  | { type: 'selectSpectrum'; id: string | null }
30
41
  | { type: 'setDomain'; domain: IrDomain }
31
42
  | { type: 'resetDomain' }
@@ -46,7 +57,10 @@ export function irReducer(state: IrState, action: IrAction): IrState {
46
57
  switch (action.type) {
47
58
  case 'addSpectra': {
48
59
  if (action.spectra.length === 0) return state;
49
- const spectra = [...state.data.spectra, ...action.spectra];
60
+ const spectra = [
61
+ ...state.data.spectra,
62
+ ...arriving(state, action.spectra),
63
+ ];
50
64
  return {
51
65
  ...state,
52
66
  data: { spectra },
@@ -65,7 +79,7 @@ export function irReducer(state: IrState, action: IrAction): IrState {
65
79
  case 'setSpectra': {
66
80
  return {
67
81
  ...state,
68
- data: { spectra: [...action.spectra] },
82
+ data: { spectra: arriving(state, action.spectra) },
69
83
  view: {
70
84
  ...state.view,
71
85
  selectedId: action.spectra[0]?.id ?? null,
@@ -122,6 +136,14 @@ export function irReducer(state: IrState, action: IrAction): IrState {
122
136
  );
123
137
  }
124
138
 
139
+ case 'setBands': {
140
+ return setSpectrumBands(state, action.id, action.bands);
141
+ }
142
+
143
+ case 'resetBands': {
144
+ return resetSpectrumBands(state, action.id);
145
+ }
146
+
125
147
  case 'selectSpectrum': {
126
148
  if (state.view.selectedId === action.id) return state;
127
149
  return { ...state, view: { ...state.view, selectedId: action.id } };
@@ -162,17 +184,11 @@ export function irReducer(state: IrState, action: IrAction): IrState {
162
184
  }
163
185
 
164
186
  case 'setSettings': {
165
- const settings = mergeIrSettings(state.settings, action.settings);
166
- return { ...state, settings };
187
+ return changeSettings(state, action.settings);
167
188
  }
168
189
 
169
190
  case 'loadState': {
170
- const { data, view, settings } = action.state;
171
- return {
172
- data: data === undefined ? state.data : { spectra: [...data.spectra] },
173
- view: { ...state.view, ...view },
174
- settings: mergeIrSettings(state.settings, settings),
175
- };
191
+ return restoreState(state, action.state);
176
192
  }
177
193
 
178
194
  case 'clear': {
@@ -191,29 +207,6 @@ export function irReducer(state: IrState, action: IrAction): IrState {
191
207
  }
192
208
  }
193
209
 
194
- /**
195
- * Change one spectrum, leaving the state alone when it did not change.
196
- * @param state - The state in force.
197
- * @param id - Which spectrum.
198
- * @param change - What to make of it; return it unchanged for no change.
199
- * @returns The new state, or the old one.
200
- */
201
- function mapSpectrum(
202
- state: IrState,
203
- id: string,
204
- change: (spectrum: IrSpectrum) => IrSpectrum,
205
- ): IrState {
206
- let changed = false;
207
- const spectra = state.data.spectra.map((spectrum) => {
208
- if (spectrum.id !== id) return spectrum;
209
- const next = change(spectrum);
210
- if (next !== spectrum) changed = true;
211
- return next;
212
- });
213
- if (!changed) return state;
214
- return { ...state, data: { spectra }, view: { ...state.view, error: null } };
215
- }
216
-
217
210
  /**
218
211
  * Refuse an action, saying why.
219
212
  * @param state - The state in force.
@@ -25,6 +25,8 @@ import type { DataXY } from 'cheminfo-types';
25
25
 
26
26
  import type { ChartDomain } from '../../chart/core/chartDomain.ts';
27
27
 
28
+ import type { IrBand } from './irBand.ts';
29
+
28
30
  /**
29
31
  * One trace of a measurement: wavenumber against whichever value axis is drawn.
30
32
  *
@@ -150,6 +152,20 @@ export interface IrSpectrum {
150
152
  * @default false
151
153
  */
152
154
  excludeFromDomain?: boolean;
155
+ /**
156
+ * The bands picked on it, ascending by wavenumber. The viewer picks them
157
+ * when a spectrum arrives without any; a host may hand them over with it, as
158
+ * a notebook that keeps them does.
159
+ * @default undefined
160
+ */
161
+ bands?: IrBand[];
162
+ /**
163
+ * Whether `bands` were picked by hand — edited in the viewer, or handed over
164
+ * — rather than found with the picking settings, which re-pick only a list
165
+ * that was not.
166
+ * @default false
167
+ */
168
+ bandsByHand?: boolean;
153
169
  }
154
170
 
155
171
  /**
@@ -7,10 +7,10 @@
7
7
  * `settings` is the workspace, which is how every spectrum is drawn whichever
8
8
  * ones happen to be open.
9
9
  *
10
- * The bands are **not** in here. They are derived from the spectra and the
11
- * picking settings, so holding them would mean holding an answer that has to be
12
- * kept in step with its own inputs — `useIrEditor` recomputes them instead, and
13
- * a stale band is then impossible rather than merely unlikely.
10
+ * The bands are in `data`, each spectrum carrying its own: picked when it
11
+ * arrives, picked again by the reducer when the settings change while they were
12
+ * found automatically, and left alone once picked by hand. That is what lets a
13
+ * band be added or taken away, and a list be handed to a host and back.
14
14
  */
15
15
 
16
16
  import type { IrPanelId, IrSidePanelId } from './irSidePanels.ts';
@@ -18,6 +18,7 @@ import type { IrDomain, IrMode, IrSpectrum } from './irSpectrum.ts';
18
18
  import type { IrTechnique } from './irTechnique.ts';
19
19
  import { defaultIrMode, irModeFor, offersIrMode } from './irTechnique.ts';
20
20
  import type { PickBandsOptions } from './pickBands.ts';
21
+ import { withBands } from './spectrumBands.ts';
21
22
 
22
23
  /** The document: what a file holds. */
23
24
  export interface IrData {
@@ -25,8 +26,11 @@ export interface IrData {
25
26
  spectra: IrSpectrum[];
26
27
  }
27
28
 
28
- /** What a drag across the chart is for while it is chosen. */
29
- export type IrTool = 'read' | 'box';
29
+ /**
30
+ * What a drag across the chart is for while it is chosen, and for `pick`, what
31
+ * a click is: a band added where it lands, or taken away.
32
+ */
33
+ export type IrTool = 'read' | 'box' | 'pick';
30
34
 
31
35
  /** Where you are in the viewer. */
32
36
  export interface IrView {
@@ -165,8 +169,11 @@ export function createIrState(options: CreateIrStateOptions = {}): IrState {
165
169
  technique,
166
170
  mode: defaultIrMode(technique),
167
171
  };
172
+ const merged = mergeIrSettings(opened, settings);
168
173
  return {
169
- data: { spectra: [...spectra] },
174
+ data: {
175
+ spectra: spectra.map((spectrum) => withBands(spectrum, merged.picking)),
176
+ },
170
177
  view: {
171
178
  selectedId: spectra[0]?.id ?? null,
172
179
  domain: null,
@@ -174,7 +181,7 @@ export function createIrState(options: CreateIrStateOptions = {}): IrState {
174
181
  openPanelIds: [...(panelIds ?? DEFAULT_SIDE_PANELS)],
175
182
  error: null,
176
183
  },
177
- settings: mergeIrSettings(opened, settings),
184
+ settings: merged,
178
185
  };
179
186
  }
180
187
 
@@ -21,6 +21,13 @@ import type { IrSpectrum } from './irSpectrum.ts';
21
21
  import type { PeakPickingOptions } from './ramanBands.ts';
22
22
  import { ramanBands } from './ramanBands.ts';
23
23
 
24
+ /**
25
+ * How many points the picker smooths over before it looks for a band. `ml-gsd`
26
+ * refuses a trace shorter than that — a few points typed in by hand — rather
27
+ * than finding no band in it.
28
+ */
29
+ const SMOOTHING_WINDOW = 9;
30
+
24
31
  /** How the bands are picked. */
25
32
  export interface PickBandsOptions {
26
33
  /**
@@ -88,7 +95,7 @@ export function pickBands(
88
95
  minPeakWidth = 4,
89
96
  limit,
90
97
  } = options;
91
- if (spectrum.wavenumber.length < 2) return [];
98
+ if (spectrum.wavenumber.length < SMOOTHING_WINDOW) return [];
92
99
 
93
100
  const picking: PeakPickingOptions = {
94
101
  minMaxRatio: minRelativeHeight,
@@ -109,43 +116,6 @@ export function pickBands(
109
116
  return kept.toSorted(byAscendingWavenumber);
110
117
  }
111
118
 
112
- /**
113
- * The bands of an infrared spectrum, picked on its absorbance.
114
- * @param spectrum - The spectrum to pick from.
115
- * @param picking - Where to pick, and how finely.
116
- * @returns The bands, in the order they were found; none when the spectrum
117
- * carries only one of its two axes, since the strength is read off the other.
118
- */
119
- function infraredBands(
120
- spectrum: IrSpectrum,
121
- picking: PeakPickingOptions,
122
- ): IrBand[] {
123
- const { id, wavenumber, absorbance, transmittance } = spectrum;
124
- if (absorbance === undefined || transmittance === undefined) return [];
125
-
126
- const picked = autoPeakPicking(
127
- measurementOf(wavenumber, absorbance, transmittance),
128
- // Absorbance, because a band is a maximum there and a minimum in the other.
129
- { yVariable: 'a', ...picking },
130
- );
131
-
132
- const bands: IrBand[] = [];
133
- for (const peak of picked) {
134
- if (!Number.isFinite(peak.wavenumber)) continue;
135
- bands.push({
136
- spectrumId: id,
137
- wavenumber: peak.wavenumber,
138
- absorbance: peak.absorbance,
139
- // `ConvertedPeak.transmittance` is a fraction where the spectrum's own
140
- // transmittance is a percentage; brought onto the one scale here so that
141
- // nothing downstream has to remember which of the two it is holding.
142
- transmittance: peak.transmittance * 100,
143
- strength: peak.kind as IrBandStrength,
144
- });
145
- }
146
- return bands;
147
- }
148
-
149
119
  /**
150
120
  * The spectrum as `ir-spectrum` wants it.
151
121
  *
@@ -158,7 +128,7 @@ function infraredBands(
158
128
  * @param transmittance - Percent transmittance at each.
159
129
  * @returns A measurement carrying all three variables.
160
130
  */
161
- function measurementOf(
131
+ export function infraredMeasurement(
162
132
  wavenumber: Float64Array,
163
133
  absorbance: Float64Array,
164
134
  transmittance: Float64Array,
@@ -195,6 +165,43 @@ function measurementOf(
195
165
  };
196
166
  }
197
167
 
168
+ /**
169
+ * The bands of an infrared spectrum, picked on its absorbance.
170
+ * @param spectrum - The spectrum to pick from.
171
+ * @param picking - Where to pick, and how finely.
172
+ * @returns The bands, in the order they were found; none when the spectrum
173
+ * carries only one of its two axes, since the strength is read off the other.
174
+ */
175
+ function infraredBands(
176
+ spectrum: IrSpectrum,
177
+ picking: PeakPickingOptions,
178
+ ): IrBand[] {
179
+ const { id, wavenumber, absorbance, transmittance } = spectrum;
180
+ if (absorbance === undefined || transmittance === undefined) return [];
181
+
182
+ const picked = autoPeakPicking(
183
+ infraredMeasurement(wavenumber, absorbance, transmittance),
184
+ // Absorbance, because a band is a maximum there and a minimum in the other.
185
+ { yVariable: 'a', ...picking },
186
+ );
187
+
188
+ const bands: IrBand[] = [];
189
+ for (const peak of picked) {
190
+ if (!Number.isFinite(peak.wavenumber)) continue;
191
+ bands.push({
192
+ spectrumId: id,
193
+ wavenumber: peak.wavenumber,
194
+ absorbance: peak.absorbance,
195
+ // `ConvertedPeak.transmittance` is a fraction where the spectrum's own
196
+ // transmittance is a percentage; brought onto the one scale here so that
197
+ // nothing downstream has to remember which of the two it is holding.
198
+ transmittance: peak.transmittance * 100,
199
+ strength: peak.kind as IrBandStrength,
200
+ });
201
+ }
202
+ return bands;
203
+ }
204
+
198
205
  /**
199
206
  * Order two bands by height, tallest first.
200
207
  * @param first - One band.
@@ -56,7 +56,7 @@ export function ramanBands(
56
56
  spectrumId: id,
57
57
  wavenumber: peak.wavenumber,
58
58
  intensity: value,
59
- strength: strengthOf(value, min, max),
59
+ strength: intensityStrength(value, min, max),
60
60
  });
61
61
  }
62
62
  return bands;
@@ -69,7 +69,7 @@ export function ramanBands(
69
69
  * @param highest - Its highest.
70
70
  * @returns The letter a correlation table would use.
71
71
  */
72
- function strengthOf(
72
+ export function intensityStrength(
73
73
  value: number,
74
74
  lowest: number,
75
75
  highest: number,
@@ -0,0 +1,113 @@
1
+ /**
2
+ * The bands a spectrum carries.
3
+ *
4
+ * A spectrum arriving without bands is picked once, with the picking settings
5
+ * in force, and from then on its bands are part of it: they travel to a host
6
+ * with it, and a host's own reach the chart. Bands found automatically follow
7
+ * the settings — moving the threshold picks them again — while bands picked by
8
+ * hand, or handed over, are left as they are.
9
+ */
10
+
11
+ import type { IrBand } from './irBand.ts';
12
+ import type { IrSpectrum } from './irSpectrum.ts';
13
+ import type { PickBandsOptions } from './pickBands.ts';
14
+ import { pickBands } from './pickBands.ts';
15
+
16
+ /**
17
+ * A spectrum carrying its bands: picked now when it has none, its own kept and
18
+ * put in order otherwise.
19
+ * @param spectrum - The spectrum, as it arrived.
20
+ * @param picking - How to pick it, if it has to be.
21
+ * @returns The spectrum with its bands; the same object when it had them, in
22
+ * order.
23
+ */
24
+ export function withBands(
25
+ spectrum: IrSpectrum,
26
+ picking: PickBandsOptions,
27
+ ): IrSpectrum {
28
+ const { id, bands } = spectrum;
29
+ if (bands === undefined) {
30
+ return {
31
+ ...spectrum,
32
+ bands: pickBands(spectrum, picking),
33
+ bandsByHand: false,
34
+ };
35
+ }
36
+ const ordered = orderedBands(id, bands);
37
+ return ordered === bands ? spectrum : { ...spectrum, bands: ordered };
38
+ }
39
+
40
+ /**
41
+ * A spectrum's bands picked again with other settings, unless they were picked
42
+ * by hand.
43
+ * @param spectrum - The spectrum.
44
+ * @param picking - The settings now in force.
45
+ * @returns The spectrum re-picked, or the same object when its bands are its
46
+ * own.
47
+ */
48
+ export function repickBands(
49
+ spectrum: IrSpectrum,
50
+ picking: PickBandsOptions,
51
+ ): IrSpectrum {
52
+ if (spectrum.bandsByHand) return spectrum;
53
+ return {
54
+ ...spectrum,
55
+ bands: pickBands(spectrum, picking),
56
+ bandsByHand: false,
57
+ };
58
+ }
59
+
60
+ /**
61
+ * Bands as a spectrum holds them: ascending, one per wavenumber, each naming
62
+ * the spectrum, and none at a wavenumber that is not a number.
63
+ * @param spectrumId - The spectrum they belong to.
64
+ * @param bands - The bands, in any order.
65
+ * @returns The bands in order; the same array when they already were.
66
+ */
67
+ export function orderedBands(spectrumId: string, bands: IrBand[]): IrBand[] {
68
+ if (isOrdered(spectrumId, bands)) return bands;
69
+ const kept: IrBand[] = [];
70
+ for (const band of bands.toSorted(byWavenumber)) {
71
+ if (!Number.isFinite(band.wavenumber)) continue;
72
+ if (kept.at(-1)?.wavenumber === band.wavenumber) continue;
73
+ kept.push(band.spectrumId === spectrumId ? band : { ...band, spectrumId });
74
+ }
75
+ return kept;
76
+ }
77
+
78
+ /**
79
+ * Whether two picking settings pick the same bands.
80
+ * @param first - One.
81
+ * @param second - The other.
82
+ * @returns Whether every option agrees.
83
+ */
84
+ export function samePicking(
85
+ first: PickBandsOptions,
86
+ second: PickBandsOptions,
87
+ ): boolean {
88
+ return (
89
+ first === second ||
90
+ (first.from === second.from &&
91
+ first.to === second.to &&
92
+ first.minRelativeHeight === second.minRelativeHeight &&
93
+ first.minPeakWidth === second.minPeakWidth &&
94
+ first.limit === second.limit)
95
+ );
96
+ }
97
+
98
+ function isOrdered(spectrumId: string, bands: readonly IrBand[]): boolean {
99
+ let previous = Number.NEGATIVE_INFINITY;
100
+ for (const band of bands) {
101
+ const { wavenumber } = band;
102
+ if (band.spectrumId !== spectrumId || !Number.isFinite(wavenumber)) {
103
+ return false;
104
+ }
105
+ if (wavenumber <= previous) return false;
106
+ previous = wavenumber;
107
+ }
108
+ return true;
109
+ }
110
+
111
+ function byWavenumber(first: IrBand, second: IrBand): number {
112
+ return first.wavenumber - second.wavenumber;
113
+ }
@@ -1,4 +1,4 @@
1
- import { Icon } from '@blueprintjs/core';
1
+ import { Button, Icon } from '@blueprintjs/core';
2
2
 
3
3
  import {
4
4
  panelCellStyle,
@@ -24,6 +24,11 @@ export interface BandRowProps {
24
24
  * @default undefined
25
25
  */
26
26
  onHighlight?: (band: IrBand | null) => void;
27
+ /**
28
+ * Takes the band away; the row ends with the button that calls it.
29
+ * @default undefined — no button
30
+ */
31
+ onRemove?: (band: IrBand) => void;
27
32
  }
28
33
 
29
34
  /**
@@ -37,7 +42,7 @@ export interface BandRowProps {
37
42
  * @returns The row.
38
43
  */
39
44
  export function BandRow(props: BandRowProps) {
40
- const { entry, mode, assignments, lit, onHighlight } = props;
45
+ const { entry, mode, assignments, lit, onHighlight, onRemove } = props;
41
46
  const { band } = entry;
42
47
 
43
48
  return (
@@ -54,6 +59,17 @@ export function BandRow(props: BandRowProps) {
54
59
  {formatIrValue(bandValue(band, mode) ?? Number.NaN, mode)}
55
60
  </td>
56
61
  {assignments ? <CandidatesCell entry={entry} /> : null}
62
+ {onRemove === undefined ? null : (
63
+ <td style={removeCellStyle}>
64
+ <Button
65
+ variant="minimal"
66
+ size="small"
67
+ icon="small-cross"
68
+ aria-label={`Take away the band at ${formatWavenumber(band.wavenumber)} cm⁻¹`}
69
+ onClick={() => onRemove(band)}
70
+ />
71
+ </td>
72
+ )}
57
73
  </tr>
58
74
  );
59
75
  }
@@ -105,3 +121,5 @@ const STRENGTH_TITLES = {
105
121
  } as const;
106
122
 
107
123
  const litRowStyle = { background: '#fff3e0' } as const;
124
+
125
+ const removeCellStyle = { ...panelCellStyle, padding: 0, width: 1 } as const;