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.
- package/README.md +70 -2
- package/lib/about/core/providers.d.ts +6 -0
- package/lib/about/core/providers.d.ts.map +1 -1
- package/lib/about/core/providers.js +7 -0
- package/lib/about/core/providers.js.map +1 -1
- package/lib/about/ui/AboutProvidedBy.js +34 -0
- package/lib/about/ui/AboutProvidedBy.js.map +1 -1
- package/lib/chart/ui/useChartPointer.d.ts +9 -1
- package/lib/chart/ui/useChartPointer.d.ts.map +1 -1
- package/lib/chart/ui/useChartPointer.js +11 -3
- package/lib/chart/ui/useChartPointer.js.map +1 -1
- package/lib/credits/core/credits.d.ts +41 -0
- package/lib/credits/core/credits.d.ts.map +1 -1
- package/lib/credits/core/credits.js +50 -0
- package/lib/credits/core/credits.js.map +1 -1
- package/lib/download/core/drawingMarkup.d.ts +8 -1
- package/lib/download/core/drawingMarkup.d.ts.map +1 -1
- package/lib/download/core/drawingMarkup.js +13 -1
- package/lib/download/core/drawingMarkup.js.map +1 -1
- package/lib/download/core/figurePng.d.ts +14 -0
- package/lib/download/core/figurePng.d.ts.map +1 -1
- package/lib/download/core/figurePng.js +21 -6
- package/lib/download/core/figurePng.js.map +1 -1
- package/lib/download/core/figureSvg.d.ts.map +1 -1
- package/lib/download/core/figureSvg.js +5 -3
- package/lib/download/core/figureSvg.js.map +1 -1
- package/lib/download/core/figureTarget.d.ts +13 -0
- package/lib/download/core/figureTarget.d.ts.map +1 -1
- package/lib/download/core/figureTarget.js +25 -5
- package/lib/download/core/figureTarget.js.map +1 -1
- package/lib/download/core/svgBounds.d.ts +15 -0
- package/lib/download/core/svgBounds.d.ts.map +1 -1
- package/lib/download/core/svgBounds.js +20 -0
- package/lib/download/core/svgBounds.js.map +1 -1
- package/lib/download/core/svgToPng.d.ts.map +1 -1
- package/lib/download/core/svgToPng.js +4 -2
- package/lib/download/core/svgToPng.js.map +1 -1
- package/lib/format/core/relativeTime.d.ts +8 -3
- package/lib/format/core/relativeTime.d.ts.map +1 -1
- package/lib/format/core/relativeTime.js +19 -7
- package/lib/format/core/relativeTime.js.map +1 -1
- package/lib/host/core/connectHost.d.ts +25 -34
- package/lib/host/core/connectHost.d.ts.map +1 -1
- package/lib/host/core/connectHost.js +43 -89
- package/lib/host/core/connectHost.js.map +1 -1
- package/lib/host/core/hostOutputs.d.ts +58 -0
- package/lib/host/core/hostOutputs.d.ts.map +1 -0
- package/lib/host/core/hostOutputs.js +151 -0
- package/lib/host/core/hostOutputs.js.map +1 -0
- package/lib/host/core/index.d.ts +9 -3
- package/lib/host/core/index.d.ts.map +1 -1
- package/lib/host/core/index.js +4 -1
- package/lib/host/core/index.js.map +1 -1
- package/lib/host/core/irKinds.d.ts +124 -0
- package/lib/host/core/irKinds.d.ts.map +1 -0
- package/lib/host/core/irKinds.js +46 -0
- package/lib/host/core/irKinds.js.map +1 -0
- package/lib/host/core/kinds.d.ts +13 -5
- package/lib/host/core/kinds.d.ts.map +1 -1
- package/lib/host/core/kinds.js +11 -5
- package/lib/host/core/kinds.js.map +1 -1
- package/lib/host/core/protocol.d.ts +50 -7
- package/lib/host/core/protocol.d.ts.map +1 -1
- package/lib/host/core/protocol.js +10 -6
- package/lib/host/core/protocol.js.map +1 -1
- package/lib/host/core/selectInputs.d.ts +37 -0
- package/lib/host/core/selectInputs.d.ts.map +1 -0
- package/lib/host/core/selectInputs.js +110 -0
- package/lib/host/core/selectInputs.js.map +1 -0
- package/lib/host/testing/sciPeaks.d.ts +31 -0
- package/lib/host/testing/sciPeaks.d.ts.map +1 -1
- package/lib/host/testing/sciPeaks.js +73 -0
- package/lib/host/testing/sciPeaks.js.map +1 -1
- package/lib/host/testing/standInHost.d.ts +9 -1
- package/lib/host/testing/standInHost.d.ts.map +1 -1
- package/lib/host/testing/standInHost.js +19 -1
- package/lib/host/testing/standInHost.js.map +1 -1
- package/lib/host/ui/useHostConnection.d.ts +13 -5
- package/lib/host/ui/useHostConnection.d.ts.map +1 -1
- package/lib/host/ui/useHostConnection.js +4 -3
- package/lib/host/ui/useHostConnection.js.map +1 -1
- package/lib/host-testing.d.ts +2 -2
- package/lib/host-testing.d.ts.map +1 -1
- package/lib/host-testing.js +2 -2
- package/lib/host-testing.js.map +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
- package/lib/ir/core/handPicking.d.ts +58 -0
- package/lib/ir/core/handPicking.d.ts.map +1 -0
- package/lib/ir/core/handPicking.js +130 -0
- package/lib/ir/core/handPicking.js.map +1 -0
- package/lib/ir/core/index.d.ts +3 -0
- package/lib/ir/core/index.d.ts.map +1 -1
- package/lib/ir/core/index.js +3 -0
- package/lib/ir/core/index.js.map +1 -1
- package/lib/ir/core/irBandState.d.ts +57 -0
- package/lib/ir/core/irBandState.d.ts.map +1 -0
- package/lib/ir/core/irBandState.js +119 -0
- package/lib/ir/core/irBandState.js.map +1 -0
- package/lib/ir/core/irCommands.d.ts +11 -0
- package/lib/ir/core/irCommands.d.ts.map +1 -1
- package/lib/ir/core/irCommands.js +6 -0
- package/lib/ir/core/irCommands.js.map +1 -1
- package/lib/ir/core/irPeaks.d.ts +28 -0
- package/lib/ir/core/irPeaks.d.ts.map +1 -0
- package/lib/ir/core/irPeaks.js +66 -0
- package/lib/ir/core/irPeaks.js.map +1 -0
- package/lib/ir/core/irReducer.d.ts +8 -0
- package/lib/ir/core/irReducer.d.ts.map +1 -1
- package/lib/ir/core/irReducer.js +15 -32
- package/lib/ir/core/irReducer.js.map +1 -1
- package/lib/ir/core/irSpectrum.d.ts +15 -0
- package/lib/ir/core/irSpectrum.d.ts.map +1 -1
- package/lib/ir/core/irSpectrum.js.map +1 -1
- package/lib/ir/core/irState.d.ts +9 -6
- package/lib/ir/core/irState.d.ts.map +1 -1
- package/lib/ir/core/irState.js +10 -6
- package/lib/ir/core/irState.js.map +1 -1
- package/lib/ir/core/pickBands.d.ts +14 -0
- package/lib/ir/core/pickBands.d.ts.map +1 -1
- package/lib/ir/core/pickBands.js +39 -33
- package/lib/ir/core/pickBands.js.map +1 -1
- package/lib/ir/core/ramanBands.d.ts +9 -1
- package/lib/ir/core/ramanBands.d.ts.map +1 -1
- package/lib/ir/core/ramanBands.js +2 -2
- package/lib/ir/core/ramanBands.js.map +1 -1
- package/lib/ir/core/spectrumBands.d.ts +46 -0
- package/lib/ir/core/spectrumBands.d.ts.map +1 -0
- package/lib/ir/core/spectrumBands.js +98 -0
- package/lib/ir/core/spectrumBands.js.map +1 -0
- package/lib/ir/ui/BandRow.d.ts +5 -0
- package/lib/ir/ui/BandRow.d.ts.map +1 -1
- package/lib/ir/ui/BandRow.js +4 -3
- package/lib/ir/ui/BandRow.js.map +1 -1
- package/lib/ir/ui/BandsPanel.d.ts +5 -0
- package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
- package/lib/ir/ui/BandsPanel.js +36 -16
- package/lib/ir/ui/BandsPanel.js.map +1 -1
- package/lib/ir/ui/BandsToolbar.d.ts +9 -0
- package/lib/ir/ui/BandsToolbar.d.ts.map +1 -0
- package/lib/ir/ui/BandsToolbar.js +61 -0
- package/lib/ir/ui/BandsToolbar.js.map +1 -0
- package/lib/ir/ui/IrCanvas.d.ts +2 -1
- package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
- package/lib/ir/ui/IrCanvas.js +19 -5
- package/lib/ir/ui/IrCanvas.js.map +1 -1
- package/lib/ir/ui/IrChart.d.ts.map +1 -1
- package/lib/ir/ui/IrChart.js +8 -1
- package/lib/ir/ui/IrChart.js.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
- package/lib/ir/ui/IrEditor.d.ts +4 -2
- package/lib/ir/ui/IrEditor.d.ts.map +1 -1
- package/lib/ir/ui/IrEditor.js.map +1 -1
- package/lib/ir/ui/IrShell.d.ts.map +1 -1
- package/lib/ir/ui/IrShell.js +6 -0
- package/lib/ir/ui/IrShell.js.map +1 -1
- package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
- package/lib/ir/ui/IrStatusBar.js +1 -1
- package/lib/ir/ui/IrStatusBar.js.map +1 -1
- package/lib/ir/ui/IrToolbar.d.ts +4 -3
- package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
- package/lib/ir/ui/IrToolbar.js +5 -4
- package/lib/ir/ui/IrToolbar.js.map +1 -1
- package/lib/ir/ui/VibrationalEditor.d.ts +2 -1
- package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -1
- package/lib/ir/ui/VibrationalEditor.js.map +1 -1
- package/lib/ir/ui/irActions.d.ts +5 -0
- package/lib/ir/ui/irActions.d.ts.map +1 -1
- package/lib/ir/ui/irActions.js +6 -0
- package/lib/ir/ui/irActions.js.map +1 -1
- package/lib/ir/ui/irChartProps.d.ts +4 -1
- package/lib/ir/ui/irChartProps.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.d.ts +5 -11
- package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.js +17 -18
- package/lib/ir/ui/useIrEditor.js.map +1 -1
- package/lib/locales/de.json +63 -0
- package/lib/locales/en.json +63 -0
- package/lib/locales/es.json +63 -0
- package/lib/locales/fr.json +63 -0
- package/lib/locales/it.json +63 -0
- package/lib/mass/core/analyseSpectrum.d.ts +85 -0
- package/lib/mass/core/analyseSpectrum.d.ts.map +1 -0
- package/lib/mass/core/analyseSpectrum.js +101 -0
- package/lib/mass/core/analyseSpectrum.js.map +1 -0
- package/lib/mass/core/ascendingTrace.d.ts +24 -0
- package/lib/mass/core/ascendingTrace.d.ts.map +1 -0
- package/lib/mass/core/ascendingTrace.js +57 -0
- package/lib/mass/core/ascendingTrace.js.map +1 -0
- package/lib/mass/core/centroidPeaks.d.ts +77 -0
- package/lib/mass/core/centroidPeaks.d.ts.map +1 -0
- package/lib/mass/core/centroidPeaks.js +62 -0
- package/lib/mass/core/centroidPeaks.js.map +1 -0
- package/lib/mass/core/detectMassFormat.d.ts +24 -0
- package/lib/mass/core/detectMassFormat.d.ts.map +1 -0
- package/lib/mass/core/detectMassFormat.js +105 -0
- package/lib/mass/core/detectMassFormat.js.map +1 -0
- package/lib/mass/core/downloadSpectra.d.ts +24 -0
- package/lib/mass/core/downloadSpectra.d.ts.map +1 -0
- package/lib/mass/core/downloadSpectra.js +35 -0
- package/lib/mass/core/downloadSpectra.js.map +1 -0
- package/lib/mass/core/fromJcamp.d.ts +46 -0
- package/lib/mass/core/fromJcamp.d.ts.map +1 -0
- package/lib/mass/core/fromJcamp.js +123 -0
- package/lib/mass/core/fromJcamp.js.map +1 -0
- package/lib/mass/core/fromText.d.ts +30 -0
- package/lib/mass/core/fromText.d.ts.map +1 -0
- package/lib/mass/core/fromText.js +39 -0
- package/lib/mass/core/fromText.js.map +1 -0
- package/lib/mass/core/index.d.ts +70 -0
- package/lib/mass/core/index.d.ts.map +1 -0
- package/lib/mass/core/index.js +42 -0
- package/lib/mass/core/index.js.map +1 -0
- package/lib/mass/core/jcampTechnique.d.ts +38 -0
- package/lib/mass/core/jcampTechnique.d.ts.map +1 -0
- package/lib/mass/core/jcampTechnique.js +70 -0
- package/lib/mass/core/jcampTechnique.js.map +1 -0
- package/lib/mass/core/labelStackBox.d.ts +49 -0
- package/lib/mass/core/labelStackBox.d.ts.map +1 -0
- package/lib/mass/core/labelStackBox.js +44 -0
- package/lib/mass/core/labelStackBox.js.map +1 -0
- package/lib/mass/core/labelledPeaks.d.ts +79 -0
- package/lib/mass/core/labelledPeaks.d.ts.map +1 -0
- package/lib/mass/core/labelledPeaks.js +74 -0
- package/lib/mass/core/labelledPeaks.js.map +1 -0
- package/lib/mass/core/loadMassSpectra.d.ts +57 -0
- package/lib/mass/core/loadMassSpectra.d.ts.map +1 -0
- package/lib/mass/core/loadMassSpectra.js +45 -0
- package/lib/mass/core/loadMassSpectra.js.map +1 -0
- package/lib/mass/core/loadedMassSpectrum.d.ts +42 -0
- package/lib/mass/core/loadedMassSpectrum.d.ts.map +1 -0
- package/lib/mass/core/loadedMassSpectrum.js +15 -0
- package/lib/mass/core/loadedMassSpectrum.js.map +1 -0
- package/lib/mass/core/massCommands.d.ts +170 -0
- package/lib/mass/core/massCommands.d.ts.map +1 -0
- package/lib/mass/core/massCommands.js +95 -0
- package/lib/mass/core/massCommands.js.map +1 -0
- package/lib/mass/core/massDomain.d.ts +121 -0
- package/lib/mass/core/massDomain.d.ts.map +1 -0
- package/lib/mass/core/massDomain.js +179 -0
- package/lib/mass/core/massDomain.js.map +1 -0
- package/lib/mass/core/massEditorApi.d.ts +65 -0
- package/lib/mass/core/massEditorApi.d.ts.map +1 -0
- package/lib/mass/core/massEditorApi.js +10 -0
- package/lib/mass/core/massEditorApi.js.map +1 -0
- package/lib/mass/core/massFormat.d.ts +78 -0
- package/lib/mass/core/massFormat.d.ts.map +1 -0
- package/lib/mass/core/massFormat.js +168 -0
- package/lib/mass/core/massFormat.js.map +1 -0
- package/lib/mass/core/massMeta.d.ts +85 -0
- package/lib/mass/core/massMeta.d.ts.map +1 -0
- package/lib/mass/core/massMeta.js +182 -0
- package/lib/mass/core/massMeta.js.map +1 -0
- package/lib/mass/core/massReducer.d.ts +82 -0
- package/lib/mass/core/massReducer.d.ts.map +1 -0
- package/lib/mass/core/massReducer.js +163 -0
- package/lib/mass/core/massReducer.js.map +1 -0
- package/lib/mass/core/massResolution.d.ts +92 -0
- package/lib/mass/core/massResolution.d.ts.map +1 -0
- package/lib/mass/core/massResolution.js +126 -0
- package/lib/mass/core/massResolution.js.map +1 -0
- package/lib/mass/core/massSidePanels.d.ts +28 -0
- package/lib/mass/core/massSidePanels.d.ts.map +1 -0
- package/lib/mass/core/massSidePanels.js +12 -0
- package/lib/mass/core/massSidePanels.js.map +1 -0
- package/lib/mass/core/massSpectrum.d.ts +206 -0
- package/lib/mass/core/massSpectrum.d.ts.map +1 -0
- package/lib/mass/core/massSpectrum.js +41 -0
- package/lib/mass/core/massSpectrum.js.map +1 -0
- package/lib/mass/core/massState.d.ts +145 -0
- package/lib/mass/core/massState.d.ts.map +1 -0
- package/lib/mass/core/massState.js +102 -0
- package/lib/mass/core/massState.js.map +1 -0
- package/lib/mass/core/massStateEdits.d.ts +51 -0
- package/lib/mass/core/massStateEdits.d.ts.map +1 -0
- package/lib/mass/core/massStateEdits.js +90 -0
- package/lib/mass/core/massStateEdits.js.map +1 -0
- package/lib/mass/core/massSummary.d.ts +77 -0
- package/lib/mass/core/massSummary.d.ts.map +1 -0
- package/lib/mass/core/massSummary.js +174 -0
- package/lib/mass/core/massSummary.js.map +1 -0
- package/lib/mass/core/mzDecimalsSetting.d.ts +36 -0
- package/lib/mass/core/mzDecimalsSetting.d.ts.map +1 -0
- package/lib/mass/core/mzDecimalsSetting.js +42 -0
- package/lib/mass/core/mzDecimalsSetting.js.map +1 -0
- package/lib/mass/core/nearestPeak.d.ts +75 -0
- package/lib/mass/core/nearestPeak.d.ts.map +1 -0
- package/lib/mass/core/nearestPeak.js +99 -0
- package/lib/mass/core/nearestPeak.js.map +1 -0
- package/lib/mass/core/peakLabelLines.d.ts +77 -0
- package/lib/mass/core/peakLabelLines.d.ts.map +1 -0
- package/lib/mass/core/peakLabelLines.js +54 -0
- package/lib/mass/core/peakLabelLines.js.map +1 -0
- package/lib/mass/core/peakLabelPlan.d.ts +109 -0
- package/lib/mass/core/peakLabelPlan.d.ts.map +1 -0
- package/lib/mass/core/peakLabelPlan.js +143 -0
- package/lib/mass/core/peakLabelPlan.js.map +1 -0
- package/lib/mass/core/peakTable.d.ts +54 -0
- package/lib/mass/core/peakTable.d.ts.map +1 -0
- package/lib/mass/core/peakTable.js +53 -0
- package/lib/mass/core/peakTable.js.map +1 -0
- package/lib/mass/core/resolutionOf.d.ts +60 -0
- package/lib/mass/core/resolutionOf.d.ts.map +1 -0
- package/lib/mass/core/resolutionOf.js +84 -0
- package/lib/mass/core/resolutionOf.js.map +1 -0
- package/lib/mass/core/scanFilter.d.ts +25 -0
- package/lib/mass/core/scanFilter.d.ts.map +1 -0
- package/lib/mass/core/scanFilter.js +107 -0
- package/lib/mass/core/scanFilter.js.map +1 -0
- package/lib/mass/core/spectrumJcamp.d.ts +47 -0
- package/lib/mass/core/spectrumJcamp.d.ts.map +1 -0
- package/lib/mass/core/spectrumJcamp.js +167 -0
- package/lib/mass/core/spectrumJcamp.js.map +1 -0
- package/lib/mass/core/toMassSpectrum.d.ts +67 -0
- package/lib/mass/core/toMassSpectrum.d.ts.map +1 -0
- package/lib/mass/core/toMassSpectrum.js +78 -0
- package/lib/mass/core/toMassSpectrum.js.map +1 -0
- package/lib/mass/core/traceIcon.d.ts +82 -0
- package/lib/mass/core/traceIcon.d.ts.map +1 -0
- package/lib/mass/core/traceIcon.js +66 -0
- package/lib/mass/core/traceIcon.js.map +1 -0
- package/lib/mass/core/writtenResolution.d.ts +40 -0
- package/lib/mass/core/writtenResolution.d.ts.map +1 -0
- package/lib/mass/core/writtenResolution.js +77 -0
- package/lib/mass/core/writtenResolution.js.map +1 -0
- package/lib/mass/ui/MassAboutDialog.d.ts +16 -0
- package/lib/mass/ui/MassAboutDialog.d.ts.map +1 -0
- package/lib/mass/ui/MassAboutDialog.js +44 -0
- package/lib/mass/ui/MassAboutDialog.js.map +1 -0
- package/lib/mass/ui/MassCanvas.d.ts +46 -0
- package/lib/mass/ui/MassCanvas.d.ts.map +1 -0
- package/lib/mass/ui/MassCanvas.js +84 -0
- package/lib/mass/ui/MassCanvas.js.map +1 -0
- package/lib/mass/ui/MassChart.d.ts +21 -0
- package/lib/mass/ui/MassChart.d.ts.map +1 -0
- package/lib/mass/ui/MassChart.js +139 -0
- package/lib/mass/ui/MassChart.js.map +1 -0
- package/lib/mass/ui/MassCommandProvider.d.ts +15 -0
- package/lib/mass/ui/MassCommandProvider.d.ts.map +1 -0
- package/lib/mass/ui/MassCommandProvider.js +14 -0
- package/lib/mass/ui/MassCommandProvider.js.map +1 -0
- package/lib/mass/ui/MassCommandTooltip.d.ts +16 -0
- package/lib/mass/ui/MassCommandTooltip.d.ts.map +1 -0
- package/lib/mass/ui/MassCommandTooltip.js +22 -0
- package/lib/mass/ui/MassCommandTooltip.js.map +1 -0
- package/lib/mass/ui/MassDocumentationDialog.d.ts +18 -0
- package/lib/mass/ui/MassDocumentationDialog.d.ts.map +1 -0
- package/lib/mass/ui/MassDocumentationDialog.js +70 -0
- package/lib/mass/ui/MassDocumentationDialog.js.map +1 -0
- package/lib/mass/ui/MassEditor.d.ts +78 -0
- package/lib/mass/ui/MassEditor.d.ts.map +1 -0
- package/lib/mass/ui/MassEditor.js +42 -0
- package/lib/mass/ui/MassEditor.js.map +1 -0
- package/lib/mass/ui/MassHeader.d.ts +12 -0
- package/lib/mass/ui/MassHeader.d.ts.map +1 -0
- package/lib/mass/ui/MassHeader.js +20 -0
- package/lib/mass/ui/MassHeader.js.map +1 -0
- package/lib/mass/ui/MassLogo.d.ts +21 -0
- package/lib/mass/ui/MassLogo.d.ts.map +1 -0
- package/lib/mass/ui/MassLogo.js +36 -0
- package/lib/mass/ui/MassLogo.js.map +1 -0
- package/lib/mass/ui/MassPointerTracker.d.ts +44 -0
- package/lib/mass/ui/MassPointerTracker.d.ts.map +1 -0
- package/lib/mass/ui/MassPointerTracker.js +29 -0
- package/lib/mass/ui/MassPointerTracker.js.map +1 -0
- package/lib/mass/ui/MassShell.d.ts +29 -0
- package/lib/mass/ui/MassShell.d.ts.map +1 -0
- package/lib/mass/ui/MassShell.js +133 -0
- package/lib/mass/ui/MassShell.js.map +1 -0
- package/lib/mass/ui/MassSidePanel.d.ts +32 -0
- package/lib/mass/ui/MassSidePanel.d.ts.map +1 -0
- package/lib/mass/ui/MassSidePanel.js +44 -0
- package/lib/mass/ui/MassSidePanel.js.map +1 -0
- package/lib/mass/ui/MassStateProvider.d.ts +19 -0
- package/lib/mass/ui/MassStateProvider.d.ts.map +1 -0
- package/lib/mass/ui/MassStateProvider.js +16 -0
- package/lib/mass/ui/MassStateProvider.js.map +1 -0
- package/lib/mass/ui/MassStatusBar.d.ts +15 -0
- package/lib/mass/ui/MassStatusBar.d.ts.map +1 -0
- package/lib/mass/ui/MassStatusBar.js +50 -0
- package/lib/mass/ui/MassStatusBar.js.map +1 -0
- package/lib/mass/ui/MassToolbar.d.ts +24 -0
- package/lib/mass/ui/MassToolbar.d.ts.map +1 -0
- package/lib/mass/ui/MassToolbar.js +36 -0
- package/lib/mass/ui/MassToolbar.js.map +1 -0
- package/lib/mass/ui/MetadataPanel.d.ts +35 -0
- package/lib/mass/ui/MetadataPanel.d.ts.map +1 -0
- package/lib/mass/ui/MetadataPanel.js +100 -0
- package/lib/mass/ui/MetadataPanel.js.map +1 -0
- package/lib/mass/ui/MzDecimalsMenu.d.ts +28 -0
- package/lib/mass/ui/MzDecimalsMenu.d.ts.map +1 -0
- package/lib/mass/ui/MzDecimalsMenu.js +40 -0
- package/lib/mass/ui/MzDecimalsMenu.js.map +1 -0
- package/lib/mass/ui/PeakLabels.d.ts +93 -0
- package/lib/mass/ui/PeakLabels.d.ts.map +1 -0
- package/lib/mass/ui/PeakLabels.js +91 -0
- package/lib/mass/ui/PeakLabels.js.map +1 -0
- package/lib/mass/ui/PeakTable.d.ts +34 -0
- package/lib/mass/ui/PeakTable.d.ts.map +1 -0
- package/lib/mass/ui/PeakTable.js +49 -0
- package/lib/mass/ui/PeakTable.js.map +1 -0
- package/lib/mass/ui/PeaksPanel.d.ts +31 -0
- package/lib/mass/ui/PeaksPanel.d.ts.map +1 -0
- package/lib/mass/ui/PeaksPanel.js +53 -0
- package/lib/mass/ui/PeaksPanel.js.map +1 -0
- package/lib/mass/ui/SpectraPanel.d.ts +17 -0
- package/lib/mass/ui/SpectraPanel.d.ts.map +1 -0
- package/lib/mass/ui/SpectraPanel.js +76 -0
- package/lib/mass/ui/SpectraPanel.js.map +1 -0
- package/lib/mass/ui/SpectrumRow.d.ts +26 -0
- package/lib/mass/ui/SpectrumRow.d.ts.map +1 -0
- package/lib/mass/ui/SpectrumRow.js +141 -0
- package/lib/mass/ui/SpectrumRow.js.map +1 -0
- package/lib/mass/ui/SpectrumTrace.d.ts +46 -0
- package/lib/mass/ui/SpectrumTrace.d.ts.map +1 -0
- package/lib/mass/ui/SpectrumTrace.js +68 -0
- package/lib/mass/ui/SpectrumTrace.js.map +1 -0
- package/lib/mass/ui/index.d.ts +69 -0
- package/lib/mass/ui/index.d.ts.map +1 -0
- package/lib/mass/ui/index.js +42 -0
- package/lib/mass/ui/index.js.map +1 -0
- package/lib/mass/ui/massActions.d.ts +52 -0
- package/lib/mass/ui/massActions.d.ts.map +1 -0
- package/lib/mass/ui/massActions.js +62 -0
- package/lib/mass/ui/massActions.js.map +1 -0
- package/lib/mass/ui/massChartProps.d.ts +128 -0
- package/lib/mass/ui/massChartProps.d.ts.map +1 -0
- package/lib/mass/ui/massChartProps.js +14 -0
- package/lib/mass/ui/massChartProps.js.map +1 -0
- package/lib/mass/ui/massCommandContext.d.ts +36 -0
- package/lib/mass/ui/massCommandContext.d.ts.map +1 -0
- package/lib/mass/ui/massCommandContext.js +45 -0
- package/lib/mass/ui/massCommandContext.js.map +1 -0
- package/lib/mass/ui/massHostPanels.d.ts +48 -0
- package/lib/mass/ui/massHostPanels.d.ts.map +1 -0
- package/lib/mass/ui/massHostPanels.js +41 -0
- package/lib/mass/ui/massHostPanels.js.map +1 -0
- package/lib/mass/ui/massStateContext.d.ts +26 -0
- package/lib/mass/ui/massStateContext.d.ts.map +1 -0
- package/lib/mass/ui/massStateContext.js +37 -0
- package/lib/mass/ui/massStateContext.js.map +1 -0
- package/lib/mass/ui/useIntensityZoom.d.ts +20 -0
- package/lib/mass/ui/useIntensityZoom.d.ts.map +1 -0
- package/lib/mass/ui/useIntensityZoom.js +42 -0
- package/lib/mass/ui/useIntensityZoom.js.map +1 -0
- package/lib/mass/ui/useMassEditor.d.ts +52 -0
- package/lib/mass/ui/useMassEditor.d.ts.map +1 -0
- package/lib/mass/ui/useMassEditor.js +93 -0
- package/lib/mass/ui/useMassEditor.js.map +1 -0
- package/lib/mass/ui/useMassFiles.d.ts +22 -0
- package/lib/mass/ui/useMassFiles.d.ts.map +1 -0
- package/lib/mass/ui/useMassFiles.js +71 -0
- package/lib/mass/ui/useMassFiles.js.map +1 -0
- package/lib/mass/ui/useMassHandle.d.ts +15 -0
- package/lib/mass/ui/useMassHandle.d.ts.map +1 -0
- package/lib/mass/ui/useMassHandle.js +35 -0
- package/lib/mass/ui/useMassHandle.js.map +1 -0
- package/lib/mass/ui/useMassPointer.d.ts +70 -0
- package/lib/mass/ui/useMassPointer.d.ts.map +1 -0
- package/lib/mass/ui/useMassPointer.js +57 -0
- package/lib/mass/ui/useMassPointer.js.map +1 -0
- package/lib/mass/ui/useMassShortcuts.d.ts +21 -0
- package/lib/mass/ui/useMassShortcuts.d.ts.map +1 -0
- package/lib/mass/ui/useMassShortcuts.js +66 -0
- package/lib/mass/ui/useMassShortcuts.js.map +1 -0
- package/lib/mass/ui/useMassSide.d.ts +27 -0
- package/lib/mass/ui/useMassSide.d.ts.map +1 -0
- package/lib/mass/ui/useMassSide.js +45 -0
- package/lib/mass/ui/useMassSide.js.map +1 -0
- package/lib/mass/ui/useMassZoom.d.ts +92 -0
- package/lib/mass/ui/useMassZoom.d.ts.map +1 -0
- package/lib/mass/ui/useMassZoom.js +65 -0
- package/lib/mass/ui/useMassZoom.js.map +1 -0
- package/lib/mass.d.ts +16 -0
- package/lib/mass.d.ts.map +1 -0
- package/lib/mass.js +16 -0
- package/lib/mass.js.map +1 -0
- package/lib/panel/ui/PanelRail.d.ts.map +1 -1
- package/lib/panel/ui/PanelRail.js +6 -1
- package/lib/panel/ui/PanelRail.js.map +1 -1
- package/lib/slides/ui/slideSanitizeSchema.d.ts +3 -2
- package/lib/slides/ui/slideSanitizeSchema.d.ts.map +1 -1
- package/lib/slides/ui/slideSanitizeSchema.js +82 -2
- package/lib/slides/ui/slideSanitizeSchema.js.map +1 -1
- package/package.json +6 -1
- package/src/about/core/providers.ts +7 -0
- package/src/about/ui/AboutProvidedBy.tsx +49 -0
- package/src/chart/ui/useChartPointer.ts +18 -4
- package/src/credits/core/credits.ts +53 -0
- package/src/download/core/drawingMarkup.ts +18 -1
- package/src/download/core/figurePng.ts +21 -8
- package/src/download/core/figureSvg.ts +5 -2
- package/src/download/core/figureTarget.ts +28 -3
- package/src/download/core/svgBounds.ts +21 -0
- package/src/download/core/svgToPng.ts +3 -4
- package/src/format/core/relativeTime.ts +29 -7
- package/src/host/core/connectHost.ts +77 -120
- package/src/host/core/hostOutputs.ts +197 -0
- package/src/host/core/index.ts +13 -7
- package/src/host/core/irKinds.ts +92 -0
- package/src/host/core/kinds.ts +16 -6
- package/src/host/core/protocol.ts +50 -8
- package/src/host/core/selectInputs.ts +145 -0
- package/src/host/testing/sciPeaks.ts +140 -0
- package/src/host/testing/standInHost.ts +30 -5
- package/src/host/ui/useHostConnection.ts +17 -8
- package/src/host-testing.ts +4 -0
- package/src/ir/core/handPicking.ts +154 -0
- package/src/ir/core/index.ts +14 -0
- package/src/ir/core/irBandState.ts +155 -0
- package/src/ir/core/irCommands.ts +7 -0
- package/src/ir/core/irPeaks.ts +79 -0
- package/src/ir/core/irReducer.ts +27 -34
- package/src/ir/core/irSpectrum.ts +16 -0
- package/src/ir/core/irState.ts +15 -8
- package/src/ir/core/pickBands.ts +46 -39
- package/src/ir/core/ramanBands.ts +2 -2
- package/src/ir/core/spectrumBands.ts +113 -0
- package/src/ir/ui/BandRow.tsx +20 -2
- package/src/ir/ui/BandsPanel.tsx +46 -88
- package/src/ir/ui/BandsToolbar.tsx +152 -0
- package/src/ir/ui/IrCanvas.tsx +22 -11
- package/src/ir/ui/IrChart.tsx +10 -1
- package/src/ir/ui/IrDocumentationDialog.tsx +7 -0
- package/src/ir/ui/IrEditor.tsx +4 -2
- package/src/ir/ui/IrShell.tsx +5 -0
- package/src/ir/ui/IrStatusBar.tsx +4 -1
- package/src/ir/ui/IrToolbar.tsx +14 -5
- package/src/ir/ui/VibrationalEditor.tsx +2 -1
- package/src/ir/ui/irActions.ts +11 -0
- package/src/ir/ui/irChartProps.ts +4 -1
- package/src/ir/ui/useIrEditor.ts +21 -21
- package/src/locales/de.json +63 -0
- package/src/locales/en.json +63 -0
- package/src/locales/es.json +63 -0
- package/src/locales/fr.json +63 -0
- package/src/locales/it.json +63 -0
- package/src/mass/core/analyseSpectrum.ts +191 -0
- package/src/mass/core/ascendingTrace.ts +62 -0
- package/src/mass/core/centroidPeaks.ts +114 -0
- package/src/mass/core/detectMassFormat.ts +113 -0
- package/src/mass/core/downloadSpectra.ts +52 -0
- package/src/mass/core/fromJcamp.ts +151 -0
- package/src/mass/core/fromText.ts +58 -0
- package/src/mass/core/index.ts +194 -0
- package/src/mass/core/jcampTechnique.ts +87 -0
- package/src/mass/core/labelStackBox.ts +75 -0
- package/src/mass/core/labelledPeaks.ts +135 -0
- package/src/mass/core/loadMassSpectra.ts +86 -0
- package/src/mass/core/loadedMassSpectrum.ts +43 -0
- package/src/mass/core/massCommands.ts +156 -0
- package/src/mass/core/massDomain.ts +229 -0
- package/src/mass/core/massEditorApi.ts +68 -0
- package/src/mass/core/massFormat.ts +187 -0
- package/src/mass/core/massMeta.ts +239 -0
- package/src/mass/core/massReducer.ts +232 -0
- package/src/mass/core/massResolution.ts +169 -0
- package/src/mass/core/massSidePanels.ts +27 -0
- package/src/mass/core/massSpectrum.ts +220 -0
- package/src/mass/core/massState.ts +206 -0
- package/src/mass/core/massStateEdits.ts +104 -0
- package/src/mass/core/massSummary.ts +213 -0
- package/src/mass/core/mzDecimalsSetting.ts +52 -0
- package/src/mass/core/nearestPeak.ts +130 -0
- package/src/mass/core/peakLabelLines.ts +112 -0
- package/src/mass/core/peakLabelPlan.ts +246 -0
- package/src/mass/core/peakTable.ts +82 -0
- package/src/mass/core/resolutionOf.ts +100 -0
- package/src/mass/core/scanFilter.ts +119 -0
- package/src/mass/core/spectrumJcamp.ts +186 -0
- package/src/mass/core/toMassSpectrum.ts +126 -0
- package/src/mass/core/traceIcon.ts +105 -0
- package/src/mass/core/writtenResolution.ts +81 -0
- package/src/mass/ui/MassAboutDialog.tsx +89 -0
- package/src/mass/ui/MassCanvas.tsx +170 -0
- package/src/mass/ui/MassChart.tsx +266 -0
- package/src/mass/ui/MassCommandProvider.tsx +34 -0
- package/src/mass/ui/MassCommandTooltip.tsx +36 -0
- package/src/mass/ui/MassDocumentationDialog.tsx +136 -0
- package/src/mass/ui/MassEditor.tsx +130 -0
- package/src/mass/ui/MassHeader.tsx +38 -0
- package/src/mass/ui/MassLogo.tsx +84 -0
- package/src/mass/ui/MassPointerTracker.tsx +72 -0
- package/src/mass/ui/MassShell.tsx +237 -0
- package/src/mass/ui/MassSidePanel.tsx +107 -0
- package/src/mass/ui/MassStateProvider.tsx +32 -0
- package/src/mass/ui/MassStatusBar.tsx +108 -0
- package/src/mass/ui/MassToolbar.tsx +120 -0
- package/src/mass/ui/MetadataPanel.tsx +201 -0
- package/src/mass/ui/MzDecimalsMenu.tsx +86 -0
- package/src/mass/ui/PeakLabels.tsx +242 -0
- package/src/mass/ui/PeakTable.tsx +199 -0
- package/src/mass/ui/PeaksPanel.tsx +182 -0
- package/src/mass/ui/SpectraPanel.tsx +153 -0
- package/src/mass/ui/SpectrumRow.tsx +246 -0
- package/src/mass/ui/SpectrumTrace.tsx +119 -0
- package/src/mass/ui/index.ts +69 -0
- package/src/mass/ui/massActions.ts +109 -0
- package/src/mass/ui/massChartProps.ts +130 -0
- package/src/mass/ui/massCommandContext.tsx +65 -0
- package/src/mass/ui/massHostPanels.ts +71 -0
- package/src/mass/ui/massStateContext.ts +48 -0
- package/src/mass/ui/useIntensityZoom.ts +55 -0
- package/src/mass/ui/useMassEditor.ts +156 -0
- package/src/mass/ui/useMassFiles.ts +91 -0
- package/src/mass/ui/useMassHandle.ts +58 -0
- package/src/mass/ui/useMassPointer.ts +120 -0
- package/src/mass/ui/useMassShortcuts.ts +85 -0
- package/src/mass/ui/useMassSide.ts +63 -0
- package/src/mass/ui/useMassZoom.ts +157 -0
- package/src/mass.ts +16 -0
- package/src/panel/ui/PanelRail.tsx +5 -1
- package/src/slides/ui/slideSanitizeSchema.ts +86 -2
- package/styles/chrome.css +7 -0
- package/styles/slides.css +47 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Writing spectra back out as JCAMP-DX, so what was loaded can be taken away.
|
|
3
|
+
*
|
|
4
|
+
* JCAMP is the format to write rather than two columns of text because it
|
|
5
|
+
* carries the acquisition records beside the points, so a spectrum that came in
|
|
6
|
+
* knowing it was an MS2 scan at 3.2 minutes goes out still knowing it — and
|
|
7
|
+
* comes back into this viewer, or into any other reader of the format, with its
|
|
8
|
+
* acquisition table intact.
|
|
9
|
+
*
|
|
10
|
+
* The points are written as an `##PEAK TABLE=` of explicit `x y` pairs rather
|
|
11
|
+
* than as a compressed `##XYDATA=` record, and that is a correctness choice. An
|
|
12
|
+
* XYDATA record states a first x and an increment and lets the reader rebuild
|
|
13
|
+
* the axis, which is exact only for an evenly sampled trace; a TOF or an FT scan
|
|
14
|
+
* is not evenly sampled, and writing one that way moves every m/z. Explicit
|
|
15
|
+
* pairs round trip bit for bit, at about 16 bytes a point.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { fromJSON } from 'convert-to-jcamp';
|
|
19
|
+
|
|
20
|
+
import { metaRecord } from './massMeta.ts';
|
|
21
|
+
import type { MassSpectrum } from './massSpectrum.ts';
|
|
22
|
+
|
|
23
|
+
/** The extension a written spectrum is saved under. */
|
|
24
|
+
export const JCAMP_EXTENSION = '.jdx';
|
|
25
|
+
|
|
26
|
+
/** What a JCAMP-DX file is served as. */
|
|
27
|
+
export const JCAMP_MIME_TYPE = 'chemical/x-jcamp-dx';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Write one spectrum as a JCAMP-DX block.
|
|
31
|
+
*
|
|
32
|
+
* The trace written is the one the spectrum is the record of: the continuous
|
|
33
|
+
* profile where the file held one, and the centroid otherwise. Both are never
|
|
34
|
+
* written, because a reader — this one included — picks the peaks of a profile
|
|
35
|
+
* as it loads it, so a file carrying the sticks as well would come back as two
|
|
36
|
+
* spectra of the same acquisition.
|
|
37
|
+
* @param spectrum - The spectrum.
|
|
38
|
+
* @returns The block, `##TITLE=` through `##END=`.
|
|
39
|
+
*/
|
|
40
|
+
export function massSpectrumToJcamp(spectrum: MassSpectrum): string {
|
|
41
|
+
const trace = spectrum.profile ?? spectrum.centroid;
|
|
42
|
+
return fromJSON(
|
|
43
|
+
{ x: trace.x, y: trace.y },
|
|
44
|
+
{ info: infoRecords(spectrum), meta: metaRecords(spectrum) },
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Write every spectrum of a list as one JCAMP-DX file.
|
|
50
|
+
*
|
|
51
|
+
* One file rather than one download per spectrum: a browser asked for eleven
|
|
52
|
+
* files in a row blocks all but the first. The blocks go inside a `LINK` block,
|
|
53
|
+
* which is what JCAMP has for a container, so dropping the file back on the
|
|
54
|
+
* chart brings the whole list back. A list of one is written as that block
|
|
55
|
+
* alone: wrapping a single spectrum in a container gains nothing.
|
|
56
|
+
* @param spectra - The spectra, in the order the list holds them.
|
|
57
|
+
* @param title - What to call the file's own outer block.
|
|
58
|
+
* @returns The file.
|
|
59
|
+
*/
|
|
60
|
+
export function massSpectraToJcamp(
|
|
61
|
+
spectra: readonly MassSpectrum[],
|
|
62
|
+
title = `${spectra.length} mass spectra`,
|
|
63
|
+
): string {
|
|
64
|
+
const only = spectra.length === 1 ? spectra[0] : undefined;
|
|
65
|
+
if (only !== undefined) return massSpectrumToJcamp(only);
|
|
66
|
+
|
|
67
|
+
const blocks: string[] = [];
|
|
68
|
+
for (const spectrum of spectra) blocks.push(massSpectrumToJcamp(spectrum));
|
|
69
|
+
return `##TITLE=${recordValue(title)}
|
|
70
|
+
##JCAMP-DX=4.24
|
|
71
|
+
##DATA TYPE=LINK
|
|
72
|
+
##BLOCKS=${blocks.length}
|
|
73
|
+
${blocks.join('\n')}
|
|
74
|
+
##END=
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The standard records of a block: what it is called, and what its axes are.
|
|
80
|
+
* @param spectrum - The spectrum.
|
|
81
|
+
* @returns The records, as `convert-to-jcamp` takes them.
|
|
82
|
+
*/
|
|
83
|
+
function infoRecords(spectrum: MassSpectrum): Record<string, string> {
|
|
84
|
+
const info: Record<string, string> = {
|
|
85
|
+
title: recordValue(spectrum.name),
|
|
86
|
+
dataType: 'MASS SPECTRUM',
|
|
87
|
+
xUnits: 'M/Z',
|
|
88
|
+
yUnits: 'RELATIVE ABUNDANCE',
|
|
89
|
+
};
|
|
90
|
+
const { meta } = spectrum;
|
|
91
|
+
if (meta === null) return info;
|
|
92
|
+
|
|
93
|
+
for (const field of meta.fields) {
|
|
94
|
+
const record = metaRecord(field.label);
|
|
95
|
+
if (record?.info === true) info[record.key] = recordValue(field.value);
|
|
96
|
+
}
|
|
97
|
+
if (meta.molecularFormula !== null) {
|
|
98
|
+
info.MOLFORM = recordValue(meta.molecularFormula);
|
|
99
|
+
}
|
|
100
|
+
// `origin` is the one standard record `fromJSON` writes from a lowercase key,
|
|
101
|
+
// and the reader shows it as the source, so it goes through that key or not at
|
|
102
|
+
// all: an `##ORIGIN=` written twice is a file two readers disagree about.
|
|
103
|
+
const source = info.ORIGIN;
|
|
104
|
+
if (source !== undefined) {
|
|
105
|
+
info.origin = source;
|
|
106
|
+
delete info.ORIGIN;
|
|
107
|
+
}
|
|
108
|
+
return info;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The `$`-prefixed records of a block: the acquisition, as far as it is known.
|
|
113
|
+
*
|
|
114
|
+
* Everything the acquisition table holds, plus whatever the origin knows that
|
|
115
|
+
* the table does not — an mzML or a netCDF states the MS level and the polarity
|
|
116
|
+
* in its own structures rather than in a record, and those facts would otherwise
|
|
117
|
+
* be the one thing a round trip through JCAMP lost.
|
|
118
|
+
*
|
|
119
|
+
* The formula is written here as well as into the standard `##MOLFORM=`, which
|
|
120
|
+
* looks like the same fact stated twice and is: a reader that keeps only the
|
|
121
|
+
* `$` records — `common-spectrum` is one — would otherwise lose it, and it
|
|
122
|
+
* drives which masses an annotator looks for.
|
|
123
|
+
* @param spectrum - The spectrum.
|
|
124
|
+
* @returns The records, keyed without their `##$`.
|
|
125
|
+
*/
|
|
126
|
+
function metaRecords(spectrum: MassSpectrum): Record<string, string> {
|
|
127
|
+
const records: Record<string, string> = {};
|
|
128
|
+
const { meta, origin } = spectrum;
|
|
129
|
+
|
|
130
|
+
if (meta !== null) {
|
|
131
|
+
for (const field of meta.fields) {
|
|
132
|
+
const record = metaRecord(field.label);
|
|
133
|
+
if (record !== null && !record.info) {
|
|
134
|
+
records[record.key] = recordValue(field.value);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (meta.conditions !== null) {
|
|
138
|
+
records.CONDITIONS = recordValue(meta.conditions);
|
|
139
|
+
}
|
|
140
|
+
if (meta.molecularFormula !== null) {
|
|
141
|
+
records.ACCURATE_MF = recordValue(meta.molecularFormula);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fill(records, 'MSLEVEL', origin.msLevel);
|
|
146
|
+
fill(records, 'MODE', origin.polarity);
|
|
147
|
+
fill(records, 'ISOLATION', origin.precursorMz);
|
|
148
|
+
if (origin.retentionTime !== undefined) {
|
|
149
|
+
fill(records, 'RETENTIONTIME', `${origin.retentionTime} min`);
|
|
150
|
+
}
|
|
151
|
+
return records;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Write a fact the origin knows, unless the table already stated it.
|
|
156
|
+
*
|
|
157
|
+
* The table wins because it is what the file itself said, whereas the origin is
|
|
158
|
+
* what was derived from it — and a value shown in the panel that changed on the
|
|
159
|
+
* way out is worse than a value written in a slightly different spelling.
|
|
160
|
+
* @param records - The records being built.
|
|
161
|
+
* @param key - The record to write.
|
|
162
|
+
* @param value - What it says, absent when nothing is known.
|
|
163
|
+
*/
|
|
164
|
+
function fill(
|
|
165
|
+
records: Record<string, string>,
|
|
166
|
+
key: string,
|
|
167
|
+
value: string | number | undefined,
|
|
168
|
+
): void {
|
|
169
|
+
if (value === undefined || records[key] !== undefined) return;
|
|
170
|
+
records[key] = recordValue(String(value));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* A value put where a JCAMP record's value goes.
|
|
175
|
+
*
|
|
176
|
+
* A record is one line and `$$` opens a comment that runs to the end of it, so
|
|
177
|
+
* an instrument's scan description — which arrives with newlines in it as often
|
|
178
|
+
* as not — would otherwise either break the file in two or lose its tail. Both
|
|
179
|
+
* failures are silent on the way back in, which is why this is done to every
|
|
180
|
+
* value rather than to the ones known to be long.
|
|
181
|
+
* @param value - The value as it is held.
|
|
182
|
+
* @returns The value as one line, with no comment marker in it.
|
|
183
|
+
*/
|
|
184
|
+
function recordValue(value: string): string {
|
|
185
|
+
return value.replaceAll(/\s+/g, ' ').replaceAll('$$', '$').trim();
|
|
186
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning what a reader produced into what the viewer holds.
|
|
3
|
+
*
|
|
4
|
+
* A reader answers about a file and knows nothing about the session it is being
|
|
5
|
+
* read into — which spectra are already open, what colours they took, what this
|
|
6
|
+
* one should be called. That is the gap this closes: the peaks are picked here,
|
|
7
|
+
* the resolution decided, and it is the only place an identity or a colour is
|
|
8
|
+
* invented.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { nextSpectrumColor } from '../../chart/core/spectrumColor.ts';
|
|
12
|
+
|
|
13
|
+
import type { AnalyseSpectrumOptions } from './analyseSpectrum.ts';
|
|
14
|
+
import { analyseSpectrum } from './analyseSpectrum.ts';
|
|
15
|
+
import type { LoadedMassSpectrum } from './loadedMassSpectrum.ts';
|
|
16
|
+
import type { MassSpectrum } from './massSpectrum.ts';
|
|
17
|
+
import { decideResolution } from './resolutionOf.ts';
|
|
18
|
+
|
|
19
|
+
/** What has to be decided for a loaded spectrum to become a held one. */
|
|
20
|
+
export interface ToMassSpectrumOptions {
|
|
21
|
+
/**
|
|
22
|
+
* Identity, which every later edit and selection is keyed on.
|
|
23
|
+
* @default a fresh UUID
|
|
24
|
+
*/
|
|
25
|
+
id?: string;
|
|
26
|
+
/**
|
|
27
|
+
* The colour to draw it in.
|
|
28
|
+
* @default the lowest hue not in `taken`
|
|
29
|
+
*/
|
|
30
|
+
color?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The colours the spectra already open have taken, so a new one is told apart
|
|
33
|
+
* from them. Ignored when `color` says outright.
|
|
34
|
+
* @default no colours taken
|
|
35
|
+
*/
|
|
36
|
+
taken?: readonly string[];
|
|
37
|
+
/**
|
|
38
|
+
* What to call it, overriding the file's own title.
|
|
39
|
+
* @default the file's title, then its name, then `Spectrum`
|
|
40
|
+
*/
|
|
41
|
+
name?: string;
|
|
42
|
+
/**
|
|
43
|
+
* How the peaks are picked, beyond what the file itself said.
|
|
44
|
+
* @default the analysis's own defaults
|
|
45
|
+
*/
|
|
46
|
+
analysis?: Omit<AnalyseSpectrumOptions, 'continuous'>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Make a held spectrum out of a read one.
|
|
51
|
+
*
|
|
52
|
+
* The resolution is the strongest verdict there is evidence for, as
|
|
53
|
+
* `decideResolution` weighs it: measured on the peak widths when the trace is a
|
|
54
|
+
* profile, otherwise what the file says the instrument was, and only failing
|
|
55
|
+
* both what the decimals of the masses imply.
|
|
56
|
+
* @param loaded - What the reader produced.
|
|
57
|
+
* @param options - The identity, colour and name to give it.
|
|
58
|
+
* @returns The spectrum as the viewer holds it, its peaks picked.
|
|
59
|
+
* @throws {Error} Whatever the peak picking refuses the trace with.
|
|
60
|
+
*/
|
|
61
|
+
export function toMassSpectrum(
|
|
62
|
+
loaded: LoadedMassSpectrum,
|
|
63
|
+
options: ToMassSpectrumOptions = {},
|
|
64
|
+
): MassSpectrum {
|
|
65
|
+
const {
|
|
66
|
+
id = crypto.randomUUID(),
|
|
67
|
+
color,
|
|
68
|
+
taken = [],
|
|
69
|
+
name,
|
|
70
|
+
analysis,
|
|
71
|
+
} = options;
|
|
72
|
+
const analysed = analyseSpectrum(loaded.trace, {
|
|
73
|
+
...analysis,
|
|
74
|
+
...(loaded.continuous === undefined
|
|
75
|
+
? {}
|
|
76
|
+
: { continuous: loaded.continuous }),
|
|
77
|
+
});
|
|
78
|
+
const resolution = decideResolution({
|
|
79
|
+
measured: analysed.resolution,
|
|
80
|
+
meta: loaded.meta,
|
|
81
|
+
masses: analysed.centroid.x,
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
id,
|
|
85
|
+
name: name ?? loaded.name ?? loaded.origin.fileName ?? 'Spectrum',
|
|
86
|
+
color: color ?? nextSpectrumColor(taken),
|
|
87
|
+
profile: analysed.profile,
|
|
88
|
+
centroid: analysed.centroid,
|
|
89
|
+
meta: loaded.meta,
|
|
90
|
+
origin: loaded.origin,
|
|
91
|
+
// One trace or the other, never both: sticks standing inside the peak
|
|
92
|
+
// shapes they were picked from read as a second spectrum over the first.
|
|
93
|
+
showProfile: analysed.profile !== null,
|
|
94
|
+
showCentroid: analysed.profile === null,
|
|
95
|
+
resolution,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Make held spectra out of everything one file held.
|
|
101
|
+
*
|
|
102
|
+
* The colours are handed out one at a time against a growing list, so a file
|
|
103
|
+
* carrying three scans gives three spectra of three colours rather than three
|
|
104
|
+
* of the same — `nextSpectrumColor` can only answer that if it is told what the
|
|
105
|
+
* previous call took.
|
|
106
|
+
* @param loaded - What the reader produced, in file order.
|
|
107
|
+
* @param options - The colours already taken, and how the peaks are picked.
|
|
108
|
+
* @returns The spectra, in the same order.
|
|
109
|
+
*/
|
|
110
|
+
export function toMassSpectra(
|
|
111
|
+
loaded: readonly LoadedMassSpectrum[],
|
|
112
|
+
options: Pick<ToMassSpectrumOptions, 'taken' | 'analysis'> = {},
|
|
113
|
+
): MassSpectrum[] {
|
|
114
|
+
const { taken = [], analysis } = options;
|
|
115
|
+
const colors = [...taken];
|
|
116
|
+
const spectra: MassSpectrum[] = [];
|
|
117
|
+
for (const entry of loaded) {
|
|
118
|
+
const spectrum = toMassSpectrum(entry, {
|
|
119
|
+
taken: colors,
|
|
120
|
+
...(analysis === undefined ? {} : { analysis }),
|
|
121
|
+
});
|
|
122
|
+
colors.push(spectrum.color);
|
|
123
|
+
spectra.push(spectrum);
|
|
124
|
+
}
|
|
125
|
+
return spectra;
|
|
126
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three things one trace icon has to say, and what a click on it asks for.
|
|
3
|
+
*
|
|
4
|
+
* A spectrum row carries two of these icons, one for the continuous trace and
|
|
5
|
+
* one for the centroid sticks, and each of them answers two questions at once:
|
|
6
|
+
* is this trace on the chart, and is this the spectrum everything else is
|
|
7
|
+
* about. The second is not decoration — the selected spectrum is the one the
|
|
8
|
+
* peak labels are written on, the one the acquisition table describes and the
|
|
9
|
+
* one the peak list holds — so a plain visibility checkbox would either lose it
|
|
10
|
+
* or need a second control beside it in a row that has no room for one.
|
|
11
|
+
*
|
|
12
|
+
* The two icons are an **either/or**, not two checkboxes: a spectrum is drawn as
|
|
13
|
+
* its profile or as its sticks and never as both. Drawn together, the sticks
|
|
14
|
+
* stand inside the very peak shapes they were picked from, and the pair reads as
|
|
15
|
+
* two spectra laid over each other — a peak top that says one thing in the
|
|
16
|
+
* outline and another in the stick beside it. Which peaks the picking found is
|
|
17
|
+
* asked of the label toggle instead, which marks their tops over whichever trace
|
|
18
|
+
* is on screen.
|
|
19
|
+
*
|
|
20
|
+
* Hence the cycle: a hidden trace comes back drawn *and* selected and takes the
|
|
21
|
+
* other trace off, a trace drawn beside somebody else's selection takes the
|
|
22
|
+
* selection over, and only a click on a trace that already has both takes the
|
|
23
|
+
* spectrum off the chart. The rule lives here rather than in the row so it can
|
|
24
|
+
* be read in one place and tested without mounting anything.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import type { SpectrumVisibility } from './massReducer.ts';
|
|
28
|
+
|
|
29
|
+
/** Which of a spectrum's two traces an icon stands for. */
|
|
30
|
+
export type MassTraceKind = 'profile' | 'centroid';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* What one trace icon currently says.
|
|
34
|
+
*
|
|
35
|
+
* `drawn` is the state a plain checkbox cannot tell from `selected`: the trace
|
|
36
|
+
* is on the chart, but the labels, the acquisition table and the peak list are
|
|
37
|
+
* about some other spectrum.
|
|
38
|
+
*/
|
|
39
|
+
export type TraceIconState = 'hidden' | 'drawn' | 'selected';
|
|
40
|
+
|
|
41
|
+
/** What a click on a trace icon asks the viewer for. */
|
|
42
|
+
export interface TraceIconClick {
|
|
43
|
+
/**
|
|
44
|
+
* The visibility to ask of the spectrum. It names **both** traces every time,
|
|
45
|
+
* because they are an either/or: picking one is also the gesture that puts the
|
|
46
|
+
* other away, and a change that mentioned only the trace clicked would leave
|
|
47
|
+
* the two drawn together for exactly as long as nobody clicked the other.
|
|
48
|
+
*/
|
|
49
|
+
visibility: SpectrumVisibility;
|
|
50
|
+
/**
|
|
51
|
+
* Whether the spectrum becomes the one the panels act on. `false` means the
|
|
52
|
+
* selection is left exactly as it is rather than cleared: a spectrum whose
|
|
53
|
+
* last trace has just been hidden is still the one being worked on, and its
|
|
54
|
+
* acquisition table has no business emptying itself because of a click on an
|
|
55
|
+
* eye.
|
|
56
|
+
*/
|
|
57
|
+
select: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* What a click on a trace icon asks for, given what the icon was saying.
|
|
62
|
+
*
|
|
63
|
+
* The click that hides a trace is the same click that would otherwise select
|
|
64
|
+
* it, which is why `select` and the visibility asked for always agree: any
|
|
65
|
+
* click leaving the spectrum on the chart also makes it the one being looked at,
|
|
66
|
+
* and the only click that takes it off is one on a trace that already had the
|
|
67
|
+
* selection.
|
|
68
|
+
* @param kind - The trace the icon stands for.
|
|
69
|
+
* @param state - What the icon was saying before the click.
|
|
70
|
+
* @returns The visibility to ask for, and whether to take the selection.
|
|
71
|
+
* @example
|
|
72
|
+
* nextTraceIconClick('centroid', 'drawn'); // { visibility: { showProfile: false, showCentroid: true }, select: true }
|
|
73
|
+
*/
|
|
74
|
+
export function nextTraceIconClick(
|
|
75
|
+
kind: MassTraceKind,
|
|
76
|
+
state: TraceIconState,
|
|
77
|
+
): TraceIconClick {
|
|
78
|
+
const show = state !== 'selected';
|
|
79
|
+
return {
|
|
80
|
+
visibility: {
|
|
81
|
+
showProfile: show && kind === 'profile',
|
|
82
|
+
showCentroid: show && kind === 'centroid',
|
|
83
|
+
},
|
|
84
|
+
select: show,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* What a trace icon says about a spectrum as it stands.
|
|
90
|
+
*
|
|
91
|
+
* Selection belongs to the spectrum rather than to either trace, so the icon of
|
|
92
|
+
* the drawn trace of the selected spectrum says `selected` while the other says
|
|
93
|
+
* `hidden` — which is the honest picture: it is that spectrum, not one of its
|
|
94
|
+
* traces, that the rest of the viewer is about.
|
|
95
|
+
* @param shown - Whether that trace is drawn.
|
|
96
|
+
* @param isSelected - Whether the spectrum is the one the panels act on.
|
|
97
|
+
* @returns The state the icon draws itself in.
|
|
98
|
+
*/
|
|
99
|
+
export function traceIconState(
|
|
100
|
+
shown: boolean,
|
|
101
|
+
isSelected: boolean,
|
|
102
|
+
): TraceIconState {
|
|
103
|
+
if (!shown) return 'hidden';
|
|
104
|
+
return isSelected ? 'selected' : 'drawn';
|
|
105
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The weakest evidence of resolution, and the only one a bare peak table has:
|
|
3
|
+
* how many decimals its masses were written with.
|
|
4
|
+
*
|
|
5
|
+
* Weak because the decimals say what the exporter wrote rather than what the
|
|
6
|
+
* instrument resolved — an ion trap that exports four decimals is read as high
|
|
7
|
+
* resolution by it, and nothing in the numbers can tell that apart. Whole
|
|
8
|
+
* numbers are the case it is sure of: a table of them is a nominal-mass table
|
|
9
|
+
* whatever wrote it.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { MassResolution } from './massResolution.ts';
|
|
13
|
+
import { MZ_DECIMALS } from './massResolution.ts';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The most decimals a written mass is looked at for.
|
|
17
|
+
*
|
|
18
|
+
* Beyond six the digits are the noise of a binary fraction rather than anything
|
|
19
|
+
* an exporter wrote, and every mass computed rather than typed reaches it.
|
|
20
|
+
*/
|
|
21
|
+
export const MAXIMUM_WRITTEN_DECIMALS = 6;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The resolution the written masses imply.
|
|
25
|
+
*
|
|
26
|
+
* Whole numbers are a nominal-mass table; one or two decimals are a coarse
|
|
27
|
+
* measurement; three or more are taken for a resolved one. The decimals the
|
|
28
|
+
* masses were written with are also how many they are shown with, up to four.
|
|
29
|
+
* @param masses - The m/z of every peak, as they were read.
|
|
30
|
+
* @returns The verdict, `nominal` for a spectrum holding no peak at all.
|
|
31
|
+
*/
|
|
32
|
+
export function writtenResolution(masses: Float64Array): MassResolution {
|
|
33
|
+
const written = writtenDecimals(masses);
|
|
34
|
+
const kind = written === 0 ? 'nominal' : written < 3 ? 'low' : 'high';
|
|
35
|
+
return {
|
|
36
|
+
kind,
|
|
37
|
+
resolvingPower: null,
|
|
38
|
+
basis: 'decimals',
|
|
39
|
+
decimals: Math.min(written, MZ_DECIMALS.high),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* How many decimals the masses were written with, the most any of them needs.
|
|
45
|
+
*
|
|
46
|
+
* Tested against a tolerance rather than for equality, because a JCAMP scales
|
|
47
|
+
* every value by its `##XFACTOR=` on the way in and `1631 × 0.1` is
|
|
48
|
+
* `163.10000000000002` — one decimal written, sixteen in the double. The count
|
|
49
|
+
* only ever grows, so each mass is tested from the decimals already found.
|
|
50
|
+
* @param masses - The m/z of every peak.
|
|
51
|
+
* @returns The decimals, from 0 to `MAXIMUM_WRITTEN_DECIMALS`.
|
|
52
|
+
*/
|
|
53
|
+
export function writtenDecimals(masses: Float64Array): number {
|
|
54
|
+
let most = 0;
|
|
55
|
+
for (const mass of masses) {
|
|
56
|
+
if (!Number.isFinite(mass)) continue;
|
|
57
|
+
while (most < MAXIMUM_WRITTEN_DECIMALS && !isWrittenWith(mass, most)) {
|
|
58
|
+
most++;
|
|
59
|
+
}
|
|
60
|
+
if (most === MAXIMUM_WRITTEN_DECIMALS) break;
|
|
61
|
+
}
|
|
62
|
+
return most;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Whether a mass was written with no more than so many decimals.
|
|
67
|
+
* @param mass - The mass.
|
|
68
|
+
* @param decimals - How many decimals.
|
|
69
|
+
* @returns Whether rounding it there changes nothing an exporter wrote.
|
|
70
|
+
*/
|
|
71
|
+
function isWrittenWith(mass: number, decimals: number): boolean {
|
|
72
|
+
return Math.abs(mass - Number(mass.toFixed(decimals))) <= DECIMAL_EPSILON;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* How far a mass may sit from its rounding and still be written that way.
|
|
77
|
+
*
|
|
78
|
+
* Far below the smallest step tested, a millionth, and far above the error a
|
|
79
|
+
* scaling by `##XFACTOR=` leaves in a double, which is around 1e-13 at m/z 1000.
|
|
80
|
+
*/
|
|
81
|
+
const DECIMAL_EPSILON = 1e-8;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Dialog, DialogBody } from '@blueprintjs/core';
|
|
2
|
+
|
|
3
|
+
import { credits } from '../../credits/core/credits.ts';
|
|
4
|
+
import { CreditsList } from '../../credits/ui/CreditsList.tsx';
|
|
5
|
+
import { massCommands } from '../core/massCommands.ts';
|
|
6
|
+
|
|
7
|
+
import { MassLogo } from './MassLogo.tsx';
|
|
8
|
+
|
|
9
|
+
export interface MassAboutDialogProps {
|
|
10
|
+
/** Whether the dialog is open. */
|
|
11
|
+
isOpen: boolean;
|
|
12
|
+
/** Close it. */
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* What the viewer is, what it stands on, and who is owed for it.
|
|
18
|
+
*
|
|
19
|
+
* The credits are read from the shared registry rather than written here, so
|
|
20
|
+
* every page of the family names each work the same way, licence included.
|
|
21
|
+
* @param props - Component props.
|
|
22
|
+
* @returns The dialog.
|
|
23
|
+
*/
|
|
24
|
+
export function MassAboutDialog(props: MassAboutDialogProps) {
|
|
25
|
+
const { isOpen, onClose } = props;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Dialog
|
|
29
|
+
isOpen={isOpen}
|
|
30
|
+
onClose={onClose}
|
|
31
|
+
title={massCommands.about.title}
|
|
32
|
+
icon={<MassLogo size={20} />}
|
|
33
|
+
style={dialogStyle}
|
|
34
|
+
>
|
|
35
|
+
<DialogBody>
|
|
36
|
+
<div style={brandStyle}>
|
|
37
|
+
<MassLogo size={64} />
|
|
38
|
+
<div>
|
|
39
|
+
<p style={leadStyle}>react-cheminfo/mass</p>
|
|
40
|
+
<p style={paragraphStyle}>
|
|
41
|
+
Draws mass spectra read from JCAMP-DX and text files, picks the
|
|
42
|
+
peaks of a profile, labels them as you zoom, and says whether each
|
|
43
|
+
spectrum is high resolution.
|
|
44
|
+
</p>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<h4 style={headingStyle}>Built on</h4>
|
|
49
|
+
<CreditsList entries={MASS_CREDITS} />
|
|
50
|
+
<p style={paragraphStyle}>
|
|
51
|
+
The <strong>colours</strong> are Okabe and Ito's colour-universal
|
|
52
|
+
palette, so two traces stay distinguishable for a reader with a colour
|
|
53
|
+
vision deficiency.
|
|
54
|
+
</p>
|
|
55
|
+
</DialogBody>
|
|
56
|
+
</Dialog>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Every work the viewer borrows, in the order it reads a file through them. */
|
|
61
|
+
const MASS_CREDITS = credits([
|
|
62
|
+
'jcampconverter',
|
|
63
|
+
'xy-parser',
|
|
64
|
+
'ms-spectrum',
|
|
65
|
+
'ml-gsd',
|
|
66
|
+
'ml-spectra-processing',
|
|
67
|
+
'convert-to-jcamp',
|
|
68
|
+
'react-mf',
|
|
69
|
+
'react-science',
|
|
70
|
+
'blueprint',
|
|
71
|
+
]);
|
|
72
|
+
|
|
73
|
+
const dialogStyle = { width: 'min(680px, 92vw)' } as const;
|
|
74
|
+
|
|
75
|
+
const brandStyle = {
|
|
76
|
+
display: 'flex',
|
|
77
|
+
alignItems: 'flex-start',
|
|
78
|
+
gap: 16,
|
|
79
|
+
} as const;
|
|
80
|
+
|
|
81
|
+
const leadStyle = {
|
|
82
|
+
margin: '0 0 4px',
|
|
83
|
+
fontWeight: 600,
|
|
84
|
+
fontSize: 16,
|
|
85
|
+
} as const;
|
|
86
|
+
|
|
87
|
+
const paragraphStyle = { margin: '0 0 6px' } as const;
|
|
88
|
+
|
|
89
|
+
const headingStyle = { margin: '14px 0 4px' } as const;
|