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,246 @@
1
+ /**
2
+ * Where every labelled peak's numbers go, worked out before anything is drawn.
3
+ *
4
+ * Which peaks are labelled is `selectLabelledPeaks`, and the slots it makes that
5
+ * choice with are cut from the *window*: ten of them, whatever the chart is. A
6
+ * label is not — it is a number set at a fixed size, and `527.1607` is fifty
7
+ * pixels wide on a plot of any width. So a chart narrow enough for its slots to
8
+ * be thinner than that hands back two peaks whose stacks are written one across
9
+ * the other, and the two masses that result are neither.
10
+ *
11
+ * What settles it: **the taller peak keeps the room, and the fainter one goes
12
+ * without**. Never a nudge sideways — on a chart, distance from a stick is the
13
+ * only thing saying which stick a number belongs to, and a mass slid clear of
14
+ * its neighbour is a mass now hanging over somebody else's peak. The peak that
15
+ * loses its numbers keeps the mark on its tip, so it is not read as a peak the
16
+ * spectrum lacks, and a zoom widens the room and brings its stack straight back.
17
+ *
18
+ * Kept out of the component so that which peak was labelled, and at what pixel,
19
+ * is worth a test that no browser has to stand by for.
20
+ */
21
+
22
+ import type { PlotRect } from '../../chart/core/chartGeometry.ts';
23
+ import type { ChartScale } from '../../chart/core/chartScale.ts';
24
+ import { chartPixel, chartValue } from '../../chart/core/chartScale.ts';
25
+ import { PEAK_LABEL } from '../../chart/core/chartTheme.ts';
26
+ import { labelStackBaselines } from '../../chart/core/labelStack.ts';
27
+
28
+ import type { StackBox } from './labelStackBox.ts';
29
+ import { labelStackBox } from './labelStackBox.ts';
30
+ import type { LabelledPeak } from './labelledPeaks.ts';
31
+ import { selectLabelledPeaks } from './labelledPeaks.ts';
32
+ import type { MassSpectrum } from './massSpectrum.ts';
33
+ import type { PeakLabelLine } from './peakLabelLines.ts';
34
+ import { peakKey, peakLabelLines } from './peakLabelLines.ts';
35
+
36
+ /** The clear space kept between two stacks standing side by side. */
37
+ export const LABEL_SPACING = 4;
38
+
39
+ /** One labelled peak: its stick, its numbers, and where both are drawn. */
40
+ export interface PeakLabelPlan {
41
+ /** The peak being labelled. */
42
+ peak: LabelledPeak;
43
+ /** `${spectrumId}:${index}`, which is how anything said about it is found. */
44
+ key: string;
45
+ /** Where its stick stands, in pixels across the SVG. */
46
+ tipX: number;
47
+ /** Where the tip of that stick is, in pixels down the SVG. */
48
+ tipY: number;
49
+ /**
50
+ * Where the stack is centred, which is over the tip unless the peak stands so
51
+ * near the edge of the plot that its numbers would be written half outside it.
52
+ * `NaN` for a peak crowded out of its numbers by a taller neighbour, which is
53
+ * still marked — it simply is not written.
54
+ */
55
+ labelX: number;
56
+ /** What the stack says, farthest line from the peak first. */
57
+ lines: PeakLabelLine[];
58
+ /** Where each of those lines is written, in the order the lines are in. */
59
+ baselines: Float64Array;
60
+ /** The room the stack takes, which is what answers the pointer. */
61
+ box: StackBox;
62
+ }
63
+
64
+ /** What a set of stacks is planned against. */
65
+ export interface PlanPeakLabelsOptions {
66
+ /** The spectrum whose peaks are labelled, as it is drawn. */
67
+ spectrum: MassSpectrum;
68
+ /** Where the plot sits, which is what a stack may not be written outside of. */
69
+ plot: PlotRect;
70
+ /** The m/z axis as it is currently zoomed. */
71
+ xScale: ChartScale;
72
+ /** The intensity axis as it is currently zoomed. */
73
+ yScale: ChartScale;
74
+ /**
75
+ * How many peaks are labelled at most, the most intense first.
76
+ * @default the selection's own default
77
+ */
78
+ limit?: number;
79
+ /**
80
+ * Whether a peak whose charge was established says so.
81
+ * @default false
82
+ */
83
+ showCharges?: boolean;
84
+ /**
85
+ * How many decimals the masses on screen are written with.
86
+ * @default 4
87
+ */
88
+ mzDecimals?: number;
89
+ /**
90
+ * What explains each peak, keyed as `peakKey` keys it.
91
+ * @default undefined
92
+ */
93
+ annotationLabels?: ReadonlyMap<string, string>;
94
+ /**
95
+ * Whether the stacks hang under the sticks rather than standing over them,
96
+ * which is what the lower half of a mirrored pair wants.
97
+ * @default false
98
+ */
99
+ below?: boolean;
100
+ /**
101
+ * What one unit of the measured intensity is written as.
102
+ * @default 1
103
+ */
104
+ intensityScale?: number;
105
+ }
106
+
107
+ /**
108
+ * Plan the stacks for the window on screen.
109
+ *
110
+ * The crowding is settled before a single line is composed, and settled in
111
+ * descending intensity: the tallest peak of the window asks for its stretch of
112
+ * the axis first and keeps it, and every fainter peak standing closer than a
113
+ * label is wide loses its `labelX`. What comes back is in ascending m/z, so the
114
+ * drawing order is the axis order and a stack keeps its key from one render to
115
+ * the next.
116
+ * @param options - The spectrum, the axes, and what the stacks may say.
117
+ * @returns One plan per peak that earned a label, in ascending m/z, those
118
+ * crowded out among them.
119
+ */
120
+ export function planPeakLabels(
121
+ options: PlanPeakLabelsOptions,
122
+ ): PeakLabelPlan[] {
123
+ const {
124
+ spectrum,
125
+ plot,
126
+ xScale,
127
+ yScale,
128
+ limit,
129
+ showCharges = false,
130
+ mzDecimals,
131
+ annotationLabels,
132
+ below = false,
133
+ intensityScale = 1,
134
+ } = options;
135
+
136
+ const peaks = selectLabelledPeaks(spectrum, {
137
+ from: chartValue(xScale, plot.left),
138
+ to: chartValue(xScale, plot.right),
139
+ // The far edge of the half this spectrum is drawn in: the top of the plot
140
+ // for an ordinary chart, its bottom for a half drawn through a reflected
141
+ // scale.
142
+ maxValue: chartValue(yScale, below ? plot.bottom : plot.top),
143
+ ...(limit === undefined ? {} : { limit }),
144
+ });
145
+ if (peaks.length === 0) return [];
146
+
147
+ const centres = placeStacks(peaks, plot, xScale);
148
+ const bounds: [number, number] = [plot.top, plot.bottom];
149
+ const plans: PeakLabelPlan[] = [];
150
+ for (let index = 0; index < peaks.length; index++) {
151
+ const peak = peaks[index] as LabelledPeak;
152
+ const key = peakKey(spectrum.id, peak.index);
153
+ const lines = peakLabelLines(peak, {
154
+ ...(mzDecimals === undefined ? {} : { mzDecimals }),
155
+ showCharges,
156
+ intensityScale,
157
+ ...(annotationLabels === undefined
158
+ ? {}
159
+ : { annotationLabel: annotationLabels.get(key) }),
160
+ });
161
+ const tipY = chartPixel(yScale, peak.y);
162
+ const labelX = centres[index] as number;
163
+ const baselines = labelStackBaselines(tipY, lines.length, bounds, below);
164
+ plans.push({
165
+ peak,
166
+ key,
167
+ tipX: chartPixel(xScale, peak.x),
168
+ tipY,
169
+ labelX,
170
+ lines,
171
+ baselines,
172
+ box: labelStackBox(labelX, baselines),
173
+ });
174
+ }
175
+ return plans;
176
+ }
177
+
178
+ /**
179
+ * Where each stack may stand, `NaN` for one crowded out by a taller peak.
180
+ *
181
+ * A stack whose peak stands at the very edge of the plot is slid back inside it
182
+ * and never further, which is a different thing from clearing a neighbour: the
183
+ * mark stays on the stick, the number moves by a few pixels rather than by its
184
+ * own width, and what it avoids is being written half over the axis.
185
+ * @param peaks - The peaks that earned a label, in ascending m/z.
186
+ * @param plot - Where the plot sits inside the SVG.
187
+ * @param xScale - The m/z axis as it is currently zoomed.
188
+ * @returns The centre each stack was given, indexed as the peaks are.
189
+ */
190
+ function placeStacks(
191
+ peaks: readonly LabelledPeak[],
192
+ plot: PlotRect,
193
+ xScale: ChartScale,
194
+ ): Float64Array {
195
+ const half = PEAK_LABEL.hoverHalfWidth;
196
+ const step = half * 2 + LABEL_SPACING;
197
+ // A plot too narrow to hold one whole label has no inside to slide anything
198
+ // back into, and the clamp would put every stack in the same place.
199
+ const roomy = plot.width >= half * 2;
200
+ const centres = new Float64Array(peaks.length).fill(Number.NaN);
201
+ const placed: number[] = [];
202
+
203
+ for (const index of tallestFirst(peaks)) {
204
+ const wanted = chartPixel(xScale, (peaks[index] as LabelledPeak).x);
205
+ const centre = roomy
206
+ ? Math.min(Math.max(wanted, plot.left + half), plot.right - half)
207
+ : wanted;
208
+ if (!clearOfPlaced(placed, centre, step)) continue;
209
+ placed.push(centre);
210
+ centres[index] = centre;
211
+ }
212
+ return centres;
213
+ }
214
+
215
+ /**
216
+ * The indices of the peaks, the tallest first — the order the room is handed
217
+ * out in, so that a base peak is labelled on every chart it appears on.
218
+ * @param peaks - The peaks that earned a label.
219
+ * @returns Their indices, descending by intensity.
220
+ */
221
+ function tallestFirst(peaks: readonly LabelledPeak[]): Uint32Array {
222
+ const order = new Uint32Array(peaks.length);
223
+ for (let index = 0; index < peaks.length; index++) order[index] = index;
224
+ return order.toSorted(
225
+ (first, second) =>
226
+ (peaks[second] as LabelledPeak).y - (peaks[first] as LabelledPeak).y,
227
+ );
228
+ }
229
+
230
+ /**
231
+ * Whether a stack may stand where it wants to, given the ones already placed.
232
+ * @param placed - The centres already given out, in pixels.
233
+ * @param centre - The centre being asked for.
234
+ * @param step - How far apart two centres have to be for both to be readable.
235
+ * @returns Whether it clears every one of them.
236
+ */
237
+ function clearOfPlaced(
238
+ placed: readonly number[],
239
+ centre: number,
240
+ step: number,
241
+ ): boolean {
242
+ for (const taken of placed) {
243
+ if (Math.abs(taken - centre) < step) return false;
244
+ }
245
+ return true;
246
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * The rows the peak table lists, and the text they are copied out as.
3
+ *
4
+ * The rows are the centroid's own peaks, read through `selectCentroidPeaks` —
5
+ * the same windowing the chart is read through — so the table and the chart
6
+ * can never disagree about which peaks exist.
7
+ */
8
+
9
+ import type { MassPeakObject } from './centroidPeaks.ts';
10
+ import { selectCentroidPeaks } from './centroidPeaks.ts';
11
+ import { formatIntensity, formatMz } from './massFormat.ts';
12
+ import type { MassDomain, MassSpectrum } from './massSpectrum.ts';
13
+
14
+ /**
15
+ * How many rows the table lists at most, the most intense kept.
16
+ *
17
+ * Far more than anybody reads, and few enough that a centroid of fifty
18
+ * thousand peaks does not lay out fifty thousand rows under a pointer move.
19
+ */
20
+ export const PEAK_TABLE_LIMIT = 1000;
21
+
22
+ /**
23
+ * The floor the table starts at, as a fraction of the base peak: where a
24
+ * chemist's own peak list starts, and where everything under it is the
25
+ * baseline the compound sits on.
26
+ */
27
+ export const PEAK_TABLE_THRESHOLD = 0.01;
28
+
29
+ /** Which peaks the table lists. */
30
+ export interface PeakTableOptions {
31
+ /**
32
+ * The window the chart shows, when the table is to follow it; `null` for the
33
+ * whole spectrum.
34
+ * @default null
35
+ */
36
+ domain?: MassDomain | null;
37
+ /**
38
+ * The floor, as a fraction of the base peak; `0` lists every peak.
39
+ * @default PEAK_TABLE_THRESHOLD
40
+ */
41
+ threshold?: number;
42
+ }
43
+
44
+ /**
45
+ * The peaks the table lists for one spectrum, in increasing m/z.
46
+ * @param spectrum - The spectrum the table is about.
47
+ * @param options - The window, and the floor.
48
+ * @returns The peaks, shared with the centroid's cache — read, never written.
49
+ */
50
+ export function peakTableRows(
51
+ spectrum: MassSpectrum,
52
+ options: PeakTableOptions = {},
53
+ ): MassPeakObject[] {
54
+ const { domain = null, threshold = PEAK_TABLE_THRESHOLD } = options;
55
+ return selectCentroidPeaks(spectrum.centroid, {
56
+ ...(domain === null ? {} : { from: domain.x[0], to: domain.x[1] }),
57
+ threshold,
58
+ limit: PEAK_TABLE_LIMIT,
59
+ });
60
+ }
61
+
62
+ /**
63
+ * The rows as tab-separated text, the way a spreadsheet takes a paste.
64
+ *
65
+ * Written to the decimals the table shows rather than as the doubles are held,
66
+ * so what is pasted is what was read on screen.
67
+ * @param peaks - The rows, in the order they are listed.
68
+ * @param mzDecimals - How many decimals the masses are written with.
69
+ * @returns A header line and one line per peak.
70
+ */
71
+ export function peakTableToTsv(
72
+ peaks: readonly MassPeakObject[],
73
+ mzDecimals: number,
74
+ ): string {
75
+ const lines = ['m/z\tintensity\tcharge'];
76
+ for (const peak of peaks) {
77
+ lines.push(
78
+ `${formatMz(peak.x, mzDecimals)}\t${formatIntensity(peak.y, mzDecimals)}\t${peak.charge === 0 ? '' : peak.charge}`,
79
+ );
80
+ }
81
+ return `${lines.join('\n')}\n`;
82
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The resolution of a spectrum as everything downstream asks for it, and the
3
+ * decimals every number on screen is written with.
4
+ */
5
+
6
+ import type { MassResolution } from './massResolution.ts';
7
+ import { MZ_DECIMALS, statedResolution } from './massResolution.ts';
8
+ import type { MassMeta, MassSpectrum } from './massSpectrum.ts';
9
+ import { writtenResolution } from './writtenResolution.ts';
10
+
11
+ /** The evidence a verdict is decided on. */
12
+ export interface DecideResolutionOptions {
13
+ /** What the peak widths measured, `null` for a peak table. */
14
+ measured: MassResolution | null;
15
+ /** What the file said about the acquisition. */
16
+ meta: MassMeta | null;
17
+ /** The m/z of every picked peak. */
18
+ masses: Float64Array;
19
+ }
20
+
21
+ /**
22
+ * The strongest verdict there is evidence for.
23
+ *
24
+ * A measurement wins outright. Otherwise the instrument the file names decides
25
+ * the kind, but never the decimals beyond what the masses were written with:
26
+ * an ion trap exporting four decimals resolves one, and a table of whole
27
+ * numbers stays whole whatever instrument it came off — writing `330.0` claims
28
+ * a decimal nobody wrote.
29
+ * @param options - The measurement, the file's records and the masses.
30
+ * @returns The verdict.
31
+ */
32
+ export function decideResolution(
33
+ options: DecideResolutionOptions,
34
+ ): MassResolution {
35
+ const { measured, meta, masses } = options;
36
+ if (measured !== null) return measured;
37
+ const written = writtenResolution(masses);
38
+ const stated = statedResolution(meta);
39
+ if (stated === null || written.kind === 'nominal') return written;
40
+ return { ...stated, decimals: Math.min(stated.decimals, written.decimals) };
41
+ }
42
+
43
+ /**
44
+ * The verdict on a spectrum: the one it was read with, or else the one its file
45
+ * and its masses imply.
46
+ *
47
+ * A spectrum a host built itself carries no verdict, and has no peak widths to
48
+ * measure one from either, so what the file named and what the masses were
49
+ * written with are all there is. Cached per centroid, since the verdict is
50
+ * asked of every drawn spectrum on every change of what is drawn, and a
51
+ * centroid is replaced rather than written into.
52
+ * @param spectrum - The spectrum.
53
+ * @returns How finely it resolves masses.
54
+ */
55
+ export function resolutionOf(spectrum: MassSpectrum): MassResolution {
56
+ if (spectrum.resolution !== undefined) return spectrum.resolution;
57
+ const cached = decidedCache.get(spectrum.centroid.x);
58
+ if (cached !== undefined) return cached;
59
+ const resolution = decideResolution({
60
+ measured: null,
61
+ meta: spectrum.meta,
62
+ masses: spectrum.centroid.x,
63
+ });
64
+ decidedCache.set(spectrum.centroid.x, resolution);
65
+ return resolution;
66
+ }
67
+
68
+ /**
69
+ * How many decimals the masses of spectra drawn together are written with when
70
+ * nobody chose: high-resolution masses or nominal ones, nothing in between.
71
+ *
72
+ * A high-resolution spectrum is written to the decimals its verdict allows —
73
+ * four, or fewer where the file wrote fewer, since padding `330.12` out to
74
+ * `330.1200` claims digits nobody measured. Anything else is written as the
75
+ * nominal mass: a low-resolution instrument's decimals are where its noise
76
+ * lives, and a reader who wants them chooses a number of decimals instead.
77
+ *
78
+ * Asked of all of them at once rather than of each, so one table and one axis
79
+ * never disagree about how wide a number is — and the most precise spectrum
80
+ * wins: put a calculated isotopic pattern beside a nominal peak table and the
81
+ * masses go back to four decimals, because rounding the pattern to match would
82
+ * hide the very difference the comparison was made to show.
83
+ * @param spectra - The spectra being shown together.
84
+ * @returns The decimals; four when none of them holds a peak.
85
+ */
86
+ export function mzDecimalsOf(spectra: readonly MassSpectrum[]): number {
87
+ let decimals = -1;
88
+ for (const spectrum of spectra) {
89
+ if (spectrum.centroid.x.length === 0) continue;
90
+ const resolution = resolutionOf(spectrum);
91
+ decimals = Math.max(
92
+ decimals,
93
+ resolution.kind === 'high' ? resolution.decimals : MZ_DECIMALS.nominal,
94
+ );
95
+ }
96
+ return decimals === -1 ? MZ_DECIMALS.high : decimals;
97
+ }
98
+
99
+ /** The verdicts already decided, keyed by the masses they were decided on. */
100
+ const decidedCache = new WeakMap<Float64Array, MassResolution>();
@@ -0,0 +1,119 @@
1
+ /**
2
+ * What a Thermo scan filter states, mined for the fields the records left blank.
3
+ *
4
+ * The structured `##$` records are the polite answer and the scan filter is the
5
+ * honest one: a real Exploris export writes `##$IONISATION=` with nothing after
6
+ * the equals sign and then names `NSI` in the middle of the conditions block
7
+ * two lines later. So every field falls back to this, per field and never
8
+ * wholesale — an explicit record always wins, because the exporter that wrote
9
+ * it knew something the filter line does not say.
10
+ *
11
+ * A filter reads like
12
+ * `FTMS + p NSI Full ms2 194.5000@hcd50.00 [44.0860-220.4300]`, preceded by the
13
+ * raw file name and followed by `Scan #:` and `RT:` lines.
14
+ */
15
+
16
+ /**
17
+ * Read every field a conditions block states.
18
+ *
19
+ * Keyed by the same labels the metadata table uses, so a caller only has to
20
+ * look up the label it failed to fill — nothing here has to know which fields
21
+ * exist or what order they are shown in.
22
+ * @param conditions - The instrument's own scan description, verbatim.
23
+ * @returns The fields it states, by label; empty when it states none.
24
+ */
25
+ export function parseScanFilter(conditions: string): Record<string, string> {
26
+ if (!conditions) return {};
27
+ const derived: Record<string, string> = {};
28
+
29
+ const analyser = group(/^(?<value>FTMS|ITMS|TOFMS)\b/m, conditions);
30
+ if (analyser) derived.Analyser = analyser;
31
+
32
+ const ionisation = group(/\b(?<value>ESI|NSI|APCI|MALDI)\b/, conditions);
33
+ if (ionisation) derived.Ionization = ionisation;
34
+
35
+ // The sign is read between the analyser and the ion source rather than on its
36
+ // own, because a bare `-` also separates the two ends of the scan range.
37
+ if (/(?:FTMS|ITMS|TOFMS) \+ /.test(conditions)) {
38
+ derived.Polarity = 'positive';
39
+ } else if (/(?:FTMS|ITMS|TOFMS) - /.test(conditions)) {
40
+ derived.Polarity = 'negative';
41
+ }
42
+
43
+ readFragmentation(conditions, derived);
44
+
45
+ const range = /\[(?<from>[\d.]+)-(?<to>[\d.]+)\]/.exec(conditions);
46
+ const from = range?.groups?.from;
47
+ const to = range?.groups?.to;
48
+ if (from !== undefined && to !== undefined) {
49
+ derived['Scan range'] = `${Number(from)}–${Number(to)} m/z`;
50
+ }
51
+
52
+ const retentionTime = group(/^RT:\s*(?<value>.+)$/m, conditions);
53
+ if (retentionTime) derived['Retention time'] = `${retentionTime} min`;
54
+
55
+ const scans = group(/^Scan #:\s*(?<value>.+)$/m, conditions);
56
+ if (scans) derived.Scans = scans;
57
+
58
+ const rawFile = group(/^(?<value>\S+\.raw)$/m, conditions);
59
+ if (rawFile) derived['Raw file'] = rawFile;
60
+
61
+ return derived;
62
+ }
63
+
64
+ /**
65
+ * Read the level a scan was taken at, and what it isolated to get there.
66
+ *
67
+ * The level is read first and everything else only under it, because the
68
+ * isolation and the energy are the level's own clause: a survey scan that
69
+ * happens to be described one line below a product scan states no level of its
70
+ * own, and reading its `@hcd50.00` anyway would report a collision energy for a
71
+ * spectrum nothing was ever fragmented into.
72
+ *
73
+ * The level is not tied to the shape of that clause, though — `Full ms2
74
+ * 194.5000@etd` and `SIM ms [190.0000-200.0000]` are both real filters, and an
75
+ * MS2 that loses its level because the activation was spelled unusually loses
76
+ * the precursor the annotator would have searched for.
77
+ * @param conditions - The instrument's own scan description.
78
+ * @param derived - The fields read so far, added to in place.
79
+ */
80
+ function readFragmentation(
81
+ conditions: string,
82
+ derived: Record<string, string>,
83
+ ): void {
84
+ const level = /\b(?:Full|SIM|SRM) ms(?<level>\d*)\b/.exec(conditions)?.groups
85
+ ?.level;
86
+ if (level === undefined) return;
87
+ if (level === '') {
88
+ derived['MS level'] = 'MS1';
89
+ return;
90
+ }
91
+ derived['MS level'] = `MS${level}`;
92
+
93
+ // The isolation is anchored to the level the filter just stated, so an MS3
94
+ // reports the window it was isolated at rather than the one before it.
95
+ const isolation = group(
96
+ new RegExp(String.raw` ms${level} (?<value>\d+(?:\.\d+)?)`),
97
+ conditions,
98
+ );
99
+ if (isolation) derived['Isolation m/z'] = isolation;
100
+
101
+ const clause = /@(?<activation>[a-z]+)(?<energy>\d+(?:\.\d+)?)/.exec(
102
+ conditions,
103
+ );
104
+ const activation = clause?.groups?.activation;
105
+ const energy = clause?.groups?.energy;
106
+ if (activation !== undefined && energy !== undefined) {
107
+ derived['Collision energy'] = `${activation.toUpperCase()} ${energy}`;
108
+ }
109
+ }
110
+
111
+ /**
112
+ * The `value` capture of a pattern, trimmed.
113
+ * @param pattern - A regular expression carrying a `value` named group.
114
+ * @param conditions - The text to read it out of.
115
+ * @returns The capture, or `''` when the pattern does not match.
116
+ */
117
+ function group(pattern: RegExp, conditions: string): string {
118
+ return pattern.exec(conditions)?.groups?.value?.trim() ?? '';
119
+ }