react-cheminfo 0.64.1 → 0.66.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 +293 -6
- package/lib/card/core/cardAddress.d.ts +70 -0
- package/lib/card/core/cardAddress.d.ts.map +1 -0
- package/lib/card/core/cardAddress.js +59 -0
- package/lib/card/core/cardAddress.js.map +1 -0
- package/lib/card/core/cardPageUrl.d.ts +49 -0
- package/lib/card/core/cardPageUrl.d.ts.map +1 -0
- package/lib/card/core/cardPageUrl.js +59 -0
- package/lib/card/core/cardPageUrl.js.map +1 -0
- package/lib/card/core/index.d.ts +7 -0
- package/lib/card/core/index.d.ts.map +1 -0
- package/lib/card/core/index.js +4 -0
- package/lib/card/core/index.js.map +1 -0
- package/lib/card/core/panelRoom.d.ts +40 -0
- package/lib/card/core/panelRoom.d.ts.map +1 -0
- package/lib/card/core/panelRoom.js +40 -0
- package/lib/card/core/panelRoom.js.map +1 -0
- package/lib/card/ui/CardDetailsButton.d.ts +38 -0
- package/lib/card/ui/CardDetailsButton.d.ts.map +1 -0
- package/lib/card/ui/CardDetailsButton.js +50 -0
- package/lib/card/ui/CardDetailsButton.js.map +1 -0
- package/lib/card/ui/CardFigure.d.ts +51 -0
- package/lib/card/ui/CardFigure.d.ts.map +1 -0
- package/lib/card/ui/CardFigure.js +27 -0
- package/lib/card/ui/CardFigure.js.map +1 -0
- package/lib/card/ui/CardFrame.d.ts +30 -0
- package/lib/card/ui/CardFrame.d.ts.map +1 -0
- package/lib/card/ui/CardFrame.js +20 -0
- package/lib/card/ui/CardFrame.js.map +1 -0
- package/lib/card/ui/CopyTableButton.d.ts +37 -0
- package/lib/card/ui/CopyTableButton.d.ts.map +1 -0
- package/lib/card/ui/CopyTableButton.js +19 -0
- package/lib/card/ui/CopyTableButton.js.map +1 -0
- package/lib/card/ui/cardTooltip.d.ts +14 -0
- package/lib/card/ui/cardTooltip.d.ts.map +1 -0
- package/lib/card/ui/cardTooltip.js +15 -0
- package/lib/card/ui/cardTooltip.js.map +1 -0
- package/lib/card/ui/embed.d.ts +15 -0
- package/lib/card/ui/embed.d.ts.map +1 -0
- package/lib/card/ui/embed.js +24 -0
- package/lib/card/ui/embed.js.map +1 -0
- package/lib/card/ui/fitCardToFrame.d.ts +31 -0
- package/lib/card/ui/fitCardToFrame.d.ts.map +1 -0
- package/lib/card/ui/fitCardToFrame.js +66 -0
- package/lib/card/ui/fitCardToFrame.js.map +1 -0
- package/lib/card/ui/holdRoomForPanels.d.ts +16 -0
- package/lib/card/ui/holdRoomForPanels.d.ts.map +1 -0
- package/lib/card/ui/holdRoomForPanels.js +76 -0
- package/lib/card/ui/holdRoomForPanels.js.map +1 -0
- package/lib/card/ui/index.d.ts +11 -0
- package/lib/card/ui/index.d.ts.map +1 -0
- package/lib/card/ui/index.js +7 -0
- package/lib/card/ui/index.js.map +1 -0
- package/lib/card/ui/openPanels.d.ts +25 -0
- package/lib/card/ui/openPanels.d.ts.map +1 -0
- package/lib/card/ui/openPanels.js +85 -0
- package/lib/card/ui/openPanels.js.map +1 -0
- package/lib/card.d.ts +13 -0
- package/lib/card.d.ts.map +1 -0
- package/lib/card.js +13 -0
- package/lib/card.js.map +1 -0
- package/lib/conformers.d.ts +1 -0
- package/lib/conformers.d.ts.map +1 -1
- package/lib/conformers.js +1 -0
- package/lib/conformers.js.map +1 -1
- package/lib/core.d.ts +4 -0
- package/lib/core.d.ts.map +1 -1
- package/lib/core.js +5 -0
- package/lib/core.js.map +1 -1
- package/lib/fetch/core/apiError.d.ts +56 -0
- package/lib/fetch/core/apiError.d.ts.map +1 -0
- package/lib/fetch/core/apiError.js +43 -0
- package/lib/fetch/core/apiError.js.map +1 -0
- package/lib/fetch/core/fetchJson.d.ts +47 -0
- package/lib/fetch/core/fetchJson.d.ts.map +1 -0
- package/lib/fetch/core/fetchJson.js +109 -0
- package/lib/fetch/core/fetchJson.js.map +1 -0
- package/lib/fetch/core/index.d.ts +5 -0
- package/lib/fetch/core/index.d.ts.map +1 -0
- package/lib/fetch/core/index.js +3 -0
- package/lib/fetch/core/index.js.map +1 -0
- package/lib/formula/core/formulaText.d.ts +46 -0
- package/lib/formula/core/formulaText.d.ts.map +1 -0
- package/lib/formula/core/formulaText.js +74 -0
- package/lib/formula/core/formulaText.js.map +1 -0
- package/lib/formula/core/index.d.ts +6 -0
- package/lib/formula/core/index.d.ts.map +1 -0
- package/lib/formula/core/index.js +4 -0
- package/lib/formula/core/index.js.map +1 -0
- package/lib/formula/core/normalizeFormula.d.ts +22 -0
- package/lib/formula/core/normalizeFormula.d.ts.map +1 -0
- package/lib/formula/core/normalizeFormula.js +46 -0
- package/lib/formula/core/normalizeFormula.js.map +1 -0
- package/lib/formula/core/readFormula.d.ts +73 -0
- package/lib/formula/core/readFormula.d.ts.map +1 -0
- package/lib/formula/core/readFormula.js +132 -0
- package/lib/formula/core/readFormula.js.map +1 -0
- package/lib/formula/ui/CopyableFormula.d.ts +31 -0
- package/lib/formula/ui/CopyableFormula.d.ts.map +1 -0
- package/lib/formula/ui/CopyableFormula.js +19 -0
- package/lib/formula/ui/CopyableFormula.js.map +1 -0
- package/lib/formula/ui/FormulaInput.d.ts +29 -0
- package/lib/formula/ui/FormulaInput.d.ts.map +1 -0
- package/lib/formula/ui/FormulaInput.js +16 -0
- package/lib/formula/ui/FormulaInput.js.map +1 -0
- package/lib/formula/ui/QuestionFormula.d.ts +14 -0
- package/lib/formula/ui/QuestionFormula.d.ts.map +1 -0
- package/lib/formula/ui/QuestionFormula.js +13 -0
- package/lib/formula/ui/QuestionFormula.js.map +1 -0
- package/lib/formula/ui/index.d.ts +7 -0
- package/lib/formula/ui/index.d.ts.map +1 -0
- package/lib/formula/ui/index.js +4 -0
- package/lib/formula/ui/index.js.map +1 -0
- package/lib/formula.d.ts +11 -0
- package/lib/formula.d.ts.map +1 -0
- package/lib/formula.js +11 -0
- package/lib/formula.js.map +1 -0
- package/lib/hooks/ui/index.d.ts +1 -0
- package/lib/hooks/ui/index.d.ts.map +1 -1
- package/lib/hooks/ui/index.js.map +1 -1
- package/lib/hooks/ui/keyTargets.d.ts +4 -2
- package/lib/hooks/ui/keyTargets.d.ts.map +1 -1
- package/lib/hooks/ui/keyTargets.js +5 -3
- package/lib/hooks/ui/keyTargets.js.map +1 -1
- package/lib/hooks/ui/useAsync.d.ts +20 -5
- package/lib/hooks/ui/useAsync.d.ts.map +1 -1
- package/lib/hooks/ui/useAsync.js +29 -14
- package/lib/hooks/ui/useAsync.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/analysisSpectra.d.ts +23 -6
- package/lib/ir/core/analysisSpectra.d.ts.map +1 -1
- package/lib/ir/core/analysisSpectra.js.map +1 -1
- package/lib/ir/core/bandLabelPlan.d.ts.map +1 -1
- package/lib/ir/core/bandLabelPlan.js +11 -6
- package/lib/ir/core/bandLabelPlan.js.map +1 -1
- package/lib/ir/core/index.d.ts +13 -9
- package/lib/ir/core/index.d.ts.map +1 -1
- package/lib/ir/core/index.js +9 -6
- package/lib/ir/core/index.js.map +1 -1
- package/lib/ir/core/irBand.d.ts +45 -14
- package/lib/ir/core/irBand.d.ts.map +1 -1
- package/lib/ir/core/irBand.js +28 -6
- package/lib/ir/core/irBand.js.map +1 -1
- 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 +11 -1
- package/lib/ir/core/irCommands.js.map +1 -1
- package/lib/ir/core/irDomain.d.ts +4 -3
- package/lib/ir/core/irDomain.d.ts.map +1 -1
- package/lib/ir/core/irDomain.js +10 -7
- package/lib/ir/core/irDomain.js.map +1 -1
- package/lib/ir/core/irFormat.d.ts +14 -2
- package/lib/ir/core/irFormat.d.ts.map +1 -1
- package/lib/ir/core/irFormat.js +33 -4
- package/lib/ir/core/irFormat.js.map +1 -1
- package/lib/ir/core/irMode.d.ts +35 -8
- package/lib/ir/core/irMode.d.ts.map +1 -1
- package/lib/ir/core/irMode.js +38 -10
- package/lib/ir/core/irMode.js.map +1 -1
- package/lib/ir/core/irReducer.d.ts +0 -28
- package/lib/ir/core/irReducer.d.ts.map +1 -1
- package/lib/ir/core/irReducer.js +1 -24
- package/lib/ir/core/irReducer.js.map +1 -1
- package/lib/ir/core/irSpectrum.d.ts +52 -26
- package/lib/ir/core/irSpectrum.d.ts.map +1 -1
- package/lib/ir/core/irSpectrum.js +21 -15
- package/lib/ir/core/irSpectrum.js.map +1 -1
- package/lib/ir/core/irState.d.ts +40 -2
- package/lib/ir/core/irState.d.ts.map +1 -1
- package/lib/ir/core/irState.js +38 -1
- package/lib/ir/core/irState.js.map +1 -1
- package/lib/ir/core/irTechnique.d.ts +94 -0
- package/lib/ir/core/irTechnique.d.ts.map +1 -0
- package/lib/ir/core/irTechnique.js +87 -0
- package/lib/ir/core/irTechnique.js.map +1 -0
- package/lib/ir/core/irTechniqueCommands.d.ts +26 -0
- package/lib/ir/core/irTechniqueCommands.d.ts.map +1 -0
- package/lib/ir/core/irTechniqueCommands.js +68 -0
- package/lib/ir/core/irTechniqueCommands.js.map +1 -0
- package/lib/ir/core/pickBands.d.ts +6 -5
- package/lib/ir/core/pickBands.d.ts.map +1 -1
- package/lib/ir/core/pickBands.js +49 -26
- package/lib/ir/core/pickBands.js.map +1 -1
- package/lib/ir/core/ramanBands.d.ts +30 -0
- package/lib/ir/core/ramanBands.d.ts.map +1 -0
- package/lib/ir/core/ramanBands.js +83 -0
- package/lib/ir/core/ramanBands.js.map +1 -0
- package/lib/ir/core/spectrumJcamp.d.ts +10 -5
- package/lib/ir/core/spectrumJcamp.d.ts.map +1 -1
- package/lib/ir/core/spectrumJcamp.js +63 -15
- package/lib/ir/core/spectrumJcamp.js.map +1 -1
- package/lib/ir/core/toIrSpectrum.d.ts.map +1 -1
- package/lib/ir/core/toIrSpectrum.js +17 -2
- package/lib/ir/core/toIrSpectrum.js.map +1 -1
- package/lib/ir/ui/BandRow.d.ts +30 -0
- package/lib/ir/ui/BandRow.d.ts.map +1 -0
- package/lib/ir/ui/BandRow.js +42 -0
- package/lib/ir/ui/BandRow.js.map +1 -0
- package/lib/ir/ui/BandsPanel.d.ts +4 -0
- package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
- package/lib/ir/ui/BandsPanel.js +14 -59
- package/lib/ir/ui/BandsPanel.js.map +1 -1
- package/lib/ir/ui/IrAboutDialog.d.ts +7 -0
- package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -1
- package/lib/ir/ui/IrAboutDialog.js +16 -3
- package/lib/ir/ui/IrAboutDialog.js.map +1 -1
- package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
- package/lib/ir/ui/IrCanvas.js +2 -2
- package/lib/ir/ui/IrCanvas.js.map +1 -1
- package/lib/ir/ui/IrChart.d.ts +2 -1
- package/lib/ir/ui/IrChart.d.ts.map +1 -1
- package/lib/ir/ui/IrChart.js +18 -21
- package/lib/ir/ui/IrChart.js.map +1 -1
- package/lib/ir/ui/IrCommandProvider.d.ts +7 -0
- package/lib/ir/ui/IrCommandProvider.d.ts.map +1 -1
- package/lib/ir/ui/IrCommandProvider.js +2 -2
- package/lib/ir/ui/IrCommandProvider.js.map +1 -1
- package/lib/ir/ui/IrCommandTooltip.d.ts +7 -0
- package/lib/ir/ui/IrCommandTooltip.d.ts.map +1 -1
- package/lib/ir/ui/IrCommandTooltip.js +3 -2
- package/lib/ir/ui/IrCommandTooltip.js.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.d.ts +8 -1
- package/lib/ir/ui/IrDocumentationDialog.d.ts.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js +30 -7
- package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
- package/lib/ir/ui/IrEditor.d.ts +3 -1
- package/lib/ir/ui/IrEditor.d.ts.map +1 -1
- package/lib/ir/ui/IrEditor.js +3 -20
- package/lib/ir/ui/IrEditor.js.map +1 -1
- package/lib/ir/ui/IrHeader.d.ts.map +1 -1
- package/lib/ir/ui/IrHeader.js +5 -1
- package/lib/ir/ui/IrHeader.js.map +1 -1
- package/lib/ir/ui/IrLogo.d.ts +11 -3
- package/lib/ir/ui/IrLogo.d.ts.map +1 -1
- package/lib/ir/ui/IrLogo.js +14 -5
- package/lib/ir/ui/IrLogo.js.map +1 -1
- package/lib/ir/ui/IrShell.d.ts.map +1 -1
- package/lib/ir/ui/IrShell.js +23 -56
- package/lib/ir/ui/IrShell.js.map +1 -1
- package/lib/ir/ui/IrStatusBar.d.ts +3 -2
- package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
- package/lib/ir/ui/IrStatusBar.js +14 -9
- package/lib/ir/ui/IrStatusBar.js.map +1 -1
- package/lib/ir/ui/IrToolbar.d.ts +3 -0
- package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
- package/lib/ir/ui/IrToolbar.js +10 -3
- package/lib/ir/ui/IrToolbar.js.map +1 -1
- package/lib/ir/ui/IrTraces.d.ts +4 -1
- package/lib/ir/ui/IrTraces.d.ts.map +1 -1
- package/lib/ir/ui/IrTraces.js +2 -0
- package/lib/ir/ui/IrTraces.js.map +1 -1
- package/lib/ir/ui/RamanEditor.d.ts +46 -0
- package/lib/ir/ui/RamanEditor.d.ts.map +1 -0
- package/lib/ir/ui/RamanEditor.js +17 -0
- package/lib/ir/ui/RamanEditor.js.map +1 -0
- package/lib/ir/ui/SpectraPanel.d.ts.map +1 -1
- package/lib/ir/ui/SpectraPanel.js +2 -2
- package/lib/ir/ui/SpectraPanel.js.map +1 -1
- package/lib/ir/ui/SpectrumRow.d.ts +7 -0
- package/lib/ir/ui/SpectrumRow.d.ts.map +1 -1
- package/lib/ir/ui/SpectrumRow.js +4 -5
- package/lib/ir/ui/SpectrumRow.js.map +1 -1
- package/lib/ir/ui/VibrationalEditor.d.ts +48 -0
- package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -0
- package/lib/ir/ui/VibrationalEditor.js +31 -0
- package/lib/ir/ui/VibrationalEditor.js.map +1 -0
- package/lib/ir/ui/bandsTsv.d.ts +19 -0
- package/lib/ir/ui/bandsTsv.d.ts.map +1 -0
- package/lib/ir/ui/bandsTsv.js +38 -0
- package/lib/ir/ui/bandsTsv.js.map +1 -0
- package/lib/ir/ui/irChartProps.d.ts +14 -4
- package/lib/ir/ui/irChartProps.d.ts.map +1 -1
- package/lib/ir/ui/irChartProps.js +3 -2
- package/lib/ir/ui/irChartProps.js.map +1 -1
- package/lib/ir/ui/irCommandContext.d.ts +8 -0
- package/lib/ir/ui/irCommandContext.d.ts.map +1 -1
- package/lib/ir/ui/irCommandContext.js +14 -3
- package/lib/ir/ui/irCommandContext.js.map +1 -1
- package/lib/ir/ui/useIrEditor.d.ts +3 -3
- package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.js +13 -4
- package/lib/ir/ui/useIrEditor.js.map +1 -1
- package/lib/ir/ui/useIrHandle.d.ts +14 -0
- package/lib/ir/ui/useIrHandle.d.ts.map +1 -0
- package/lib/ir/ui/useIrHandle.js +39 -0
- package/lib/ir/ui/useIrHandle.js.map +1 -0
- package/lib/ir/ui/useIrText.d.ts +40 -0
- package/lib/ir/ui/useIrText.d.ts.map +1 -0
- package/lib/ir/ui/useIrText.js +118 -0
- package/lib/ir/ui/useIrText.js.map +1 -0
- package/lib/ir/ui/useIrZoom.d.ts +7 -0
- package/lib/ir/ui/useIrZoom.d.ts.map +1 -1
- package/lib/ir/ui/useIrZoom.js +5 -4
- package/lib/ir/ui/useIrZoom.js.map +1 -1
- package/lib/ir/ui/useValueAxisZoom.d.ts +20 -0
- package/lib/ir/ui/useValueAxisZoom.d.ts.map +1 -0
- package/lib/ir/ui/useValueAxisZoom.js +54 -0
- package/lib/ir/ui/useValueAxisZoom.js.map +1 -0
- package/lib/ir.d.ts +3 -0
- package/lib/ir.d.ts.map +1 -1
- package/lib/ir.js +3 -0
- package/lib/ir.js.map +1 -1
- package/lib/locales/de.json +57 -1
- package/lib/locales/en.json +57 -1
- package/lib/locales/es.json +57 -1
- package/lib/locales/fr.json +57 -1
- package/lib/locales/it.json +57 -1
- package/lib/moleculesClient/core/index.d.ts +5 -0
- package/lib/moleculesClient/core/index.d.ts.map +1 -0
- package/lib/moleculesClient/core/index.js +3 -0
- package/lib/moleculesClient/core/index.js.map +1 -0
- package/lib/moleculesClient/core/moleculesClient.d.ts +12 -0
- package/lib/moleculesClient/core/moleculesClient.d.ts.map +1 -0
- package/lib/moleculesClient/core/moleculesClient.js +105 -0
- package/lib/moleculesClient/core/moleculesClient.js.map +1 -0
- package/lib/moleculesClient/core/moleculesClientApi.d.ts +100 -0
- package/lib/moleculesClient/core/moleculesClientApi.d.ts.map +1 -0
- package/lib/moleculesClient/core/moleculesClientApi.js +20 -0
- package/lib/moleculesClient/core/moleculesClientApi.js.map +1 -0
- package/lib/moleculesClient/core/moleculesTypes.d.ts +154 -0
- package/lib/moleculesClient/core/moleculesTypes.d.ts.map +1 -0
- package/lib/moleculesClient/core/moleculesTypes.js +2 -0
- package/lib/moleculesClient/core/moleculesTypes.js.map +1 -0
- package/lib/moleculesClient/core/requestRetry.d.ts +50 -0
- package/lib/moleculesClient/core/requestRetry.d.ts.map +1 -0
- package/lib/moleculesClient/core/requestRetry.js +108 -0
- package/lib/moleculesClient/core/requestRetry.js.map +1 -0
- package/lib/molstar/core/camera.d.ts +2 -1
- package/lib/molstar/core/camera.d.ts.map +1 -1
- package/lib/molstar/core/camera.js +3 -2
- package/lib/molstar/core/camera.js.map +1 -1
- package/lib/molstar/core/framing.d.ts +102 -0
- package/lib/molstar/core/framing.d.ts.map +1 -0
- package/lib/molstar/core/framing.js +120 -0
- package/lib/molstar/core/framing.js.map +1 -0
- package/lib/molstar/core/hover.d.ts +16 -0
- package/lib/molstar/core/hover.d.ts.map +1 -1
- package/lib/molstar/core/hover.js +14 -0
- package/lib/molstar/core/hover.js.map +1 -1
- package/lib/molstar/core/index.d.ts +4 -1
- package/lib/molstar/core/index.d.ts.map +1 -1
- package/lib/molstar/core/index.js +2 -1
- package/lib/molstar/core/index.js.map +1 -1
- package/lib/pedagogy/core/answers.d.ts +46 -0
- package/lib/pedagogy/core/answers.d.ts.map +1 -0
- package/lib/pedagogy/core/answers.js +77 -0
- package/lib/pedagogy/core/answers.js.map +1 -0
- package/lib/pedagogy/core/attempts.d.ts +86 -0
- package/lib/pedagogy/core/attempts.d.ts.map +1 -0
- package/lib/pedagogy/core/attempts.js +117 -0
- package/lib/pedagogy/core/attempts.js.map +1 -0
- package/lib/pedagogy/core/index.d.ts +8 -0
- package/lib/pedagogy/core/index.d.ts.map +1 -1
- package/lib/pedagogy/core/index.js +4 -0
- package/lib/pedagogy/core/index.js.map +1 -1
- package/lib/pedagogy/core/progressController.d.ts +64 -0
- package/lib/pedagogy/core/progressController.d.ts.map +1 -0
- package/lib/pedagogy/core/progressController.js +56 -0
- package/lib/pedagogy/core/progressController.js.map +1 -0
- package/lib/pedagogy/core/seed.d.ts +96 -0
- package/lib/pedagogy/core/seed.d.ts.map +1 -0
- package/lib/pedagogy/core/seed.js +128 -0
- package/lib/pedagogy/core/seed.js.map +1 -0
- package/lib/pedagogy/core/series.d.ts +77 -0
- package/lib/pedagogy/core/series.d.ts.map +1 -0
- package/lib/pedagogy/core/series.js +10 -0
- package/lib/pedagogy/core/series.js.map +1 -0
- package/lib/pedagogy/ui/AnswerFields.d.ts +21 -0
- package/lib/pedagogy/ui/AnswerFields.d.ts.map +1 -0
- package/lib/pedagogy/ui/AnswerFields.js +24 -0
- package/lib/pedagogy/ui/AnswerFields.js.map +1 -0
- package/lib/pedagogy/ui/ExerciseList.d.ts +82 -0
- package/lib/pedagogy/ui/ExerciseList.d.ts.map +1 -0
- package/lib/pedagogy/ui/ExerciseList.js +53 -0
- package/lib/pedagogy/ui/ExerciseList.js.map +1 -0
- package/lib/pedagogy/ui/ExerciseSeries.d.ts +95 -0
- package/lib/pedagogy/ui/ExerciseSeries.d.ts.map +1 -0
- package/lib/pedagogy/ui/ExerciseSeries.js +74 -0
- package/lib/pedagogy/ui/ExerciseSeries.js.map +1 -0
- package/lib/pedagogy/ui/QuestionCard.d.ts +64 -0
- package/lib/pedagogy/ui/QuestionCard.d.ts.map +1 -0
- package/lib/pedagogy/ui/QuestionCard.js +73 -0
- package/lib/pedagogy/ui/QuestionCard.js.map +1 -0
- package/lib/pedagogy/ui/index.d.ts +10 -0
- package/lib/pedagogy/ui/index.d.ts.map +1 -1
- package/lib/pedagogy/ui/index.js +6 -0
- package/lib/pedagogy/ui/index.js.map +1 -1
- package/lib/pedagogy/ui/seriesCounts.d.ts +17 -0
- package/lib/pedagogy/ui/seriesCounts.d.ts.map +1 -0
- package/lib/pedagogy/ui/seriesCounts.js +27 -0
- package/lib/pedagogy/ui/seriesCounts.js.map +1 -0
- package/lib/pedagogy/ui/seriesParts.d.ts +55 -0
- package/lib/pedagogy/ui/seriesParts.d.ts.map +1 -0
- package/lib/pedagogy/ui/seriesParts.js +38 -0
- package/lib/pedagogy/ui/seriesParts.js.map +1 -0
- package/lib/pedagogy/ui/useAttemptRecords.d.ts +10 -0
- package/lib/pedagogy/ui/useAttemptRecords.d.ts.map +1 -0
- package/lib/pedagogy/ui/useAttemptRecords.js +11 -0
- package/lib/pedagogy/ui/useAttemptRecords.js.map +1 -0
- package/lib/periodic/ui/PeriodicTable.d.ts.map +1 -1
- package/lib/periodic/ui/PeriodicTable.js +6 -3
- package/lib/periodic/ui/PeriodicTable.js.map +1 -1
- package/lib/property/core/copyableText.d.ts +14 -0
- package/lib/property/core/copyableText.d.ts.map +1 -0
- package/lib/property/core/copyableText.js +21 -0
- package/lib/property/core/copyableText.js.map +1 -0
- package/lib/property/core/index.d.ts +2 -0
- package/lib/property/core/index.d.ts.map +1 -0
- package/lib/property/core/index.js +2 -0
- package/lib/property/core/index.js.map +1 -0
- package/lib/property/ui/PropertyTable.d.ts +43 -0
- package/lib/property/ui/PropertyTable.d.ts.map +1 -0
- package/lib/property/ui/PropertyTable.js +19 -0
- package/lib/property/ui/PropertyTable.js.map +1 -0
- package/lib/property/ui/index.d.ts +3 -0
- package/lib/property/ui/index.d.ts.map +1 -0
- package/lib/property/ui/index.js +2 -0
- package/lib/property/ui/index.js.map +1 -0
- package/lib/raman.d.ts +16 -0
- package/lib/raman.d.ts.map +1 -0
- package/lib/raman.js +12 -0
- package/lib/raman.js.map +1 -0
- package/lib/router/core/history.d.ts +24 -3
- package/lib/router/core/history.d.ts.map +1 -1
- package/lib/router/core/history.js +55 -7
- package/lib/router/core/history.js.map +1 -1
- package/lib/router/core/index.d.ts +3 -3
- package/lib/router/core/index.d.ts.map +1 -1
- package/lib/router/core/index.js +2 -2
- package/lib/router/core/index.js.map +1 -1
- package/lib/router/core/languageRoute.d.ts +61 -0
- package/lib/router/core/languageRoute.d.ts.map +1 -0
- package/lib/router/core/languageRoute.js +96 -0
- package/lib/router/core/languageRoute.js.map +1 -0
- package/lib/router/core/siteAddresses.d.ts +23 -0
- package/lib/router/core/siteAddresses.d.ts.map +1 -1
- package/lib/router/core/siteAddresses.js +26 -0
- package/lib/router/core/siteAddresses.js.map +1 -1
- package/lib/router/core/tabRouter.d.ts +2 -108
- package/lib/router/core/tabRouter.d.ts.map +1 -1
- package/lib/router/core/tabRouter.js +38 -5
- package/lib/router/core/tabRouter.js.map +1 -1
- package/lib/router/core/tabRouterTypes.d.ts +154 -0
- package/lib/router/core/tabRouterTypes.d.ts.map +1 -0
- package/lib/router/core/tabRouterTypes.js +2 -0
- package/lib/router/core/tabRouterTypes.js.map +1 -0
- package/lib/seo/core/fitDescription.d.ts +40 -0
- package/lib/seo/core/fitDescription.d.ts.map +1 -0
- package/lib/seo/core/fitDescription.js +45 -0
- package/lib/seo/core/fitDescription.js.map +1 -0
- package/lib/seo/core/index.d.ts +7 -0
- package/lib/seo/core/index.d.ts.map +1 -1
- package/lib/seo/core/index.js +4 -0
- package/lib/seo/core/index.js.map +1 -1
- package/lib/seo/core/limits.d.ts +24 -0
- package/lib/seo/core/limits.d.ts.map +1 -0
- package/lib/seo/core/limits.js +24 -0
- package/lib/seo/core/limits.js.map +1 -0
- package/lib/seo/core/pageContent.d.ts +25 -0
- package/lib/seo/core/pageContent.d.ts.map +1 -0
- package/lib/seo/core/pageContent.js +25 -0
- package/lib/seo/core/pageContent.js.map +1 -0
- package/lib/seo/core/plainDescription.d.ts.map +1 -1
- package/lib/seo/core/plainDescription.js +3 -2
- package/lib/seo/core/plainDescription.js.map +1 -1
- package/lib/seo/core/routeProblems.d.ts.map +1 -1
- package/lib/seo/core/routeProblems.js +1 -6
- package/lib/seo/core/routeProblems.js.map +1 -1
- package/lib/seo/core/routeTable.d.ts +31 -0
- package/lib/seo/core/routeTable.d.ts.map +1 -0
- package/lib/seo/core/routeTable.js +96 -0
- package/lib/seo/core/routeTable.js.map +1 -0
- package/lib/seo/vite/index.d.ts +2 -0
- package/lib/seo/vite/index.d.ts.map +1 -1
- package/lib/seo/vite/index.js +1 -0
- package/lib/seo/vite/index.js.map +1 -1
- package/lib/seo/vite/prerender.d.ts +10 -0
- package/lib/seo/vite/prerender.d.ts.map +1 -1
- package/lib/seo/vite/prerender.js +12 -1
- package/lib/seo/vite/prerender.js.map +1 -1
- package/lib/seo/vite/routeTable.d.ts +40 -0
- package/lib/seo/vite/routeTable.d.ts.map +1 -0
- package/lib/seo/vite/routeTable.js +44 -0
- package/lib/seo/vite/routeTable.js.map +1 -0
- package/lib/server/answerAddresses.d.ts +51 -0
- package/lib/server/answerAddresses.d.ts.map +1 -0
- package/lib/server/answerAddresses.js +72 -0
- package/lib/server/answerAddresses.js.map +1 -0
- package/lib/server/cardMeta.d.ts +57 -0
- package/lib/server/cardMeta.d.ts.map +1 -0
- package/lib/server/cardMeta.js +52 -0
- package/lib/server/cardMeta.js.map +1 -0
- package/lib/server/config.d.ts +72 -0
- package/lib/server/config.d.ts.map +1 -0
- package/lib/server/config.js +67 -0
- package/lib/server/config.js.map +1 -0
- package/lib/server/envNumber.d.ts +35 -0
- package/lib/server/envNumber.d.ts.map +1 -0
- package/lib/server/envNumber.js +42 -0
- package/lib/server/envNumber.js.map +1 -0
- package/lib/server/healthRoute.d.ts +26 -0
- package/lib/server/healthRoute.d.ts.map +1 -0
- package/lib/server/healthRoute.js +22 -0
- package/lib/server/healthRoute.js.map +1 -0
- package/lib/server/listenSite.d.ts +38 -0
- package/lib/server/listenSite.d.ts.map +1 -0
- package/lib/server/listenSite.js +60 -0
- package/lib/server/listenSite.js.map +1 -0
- package/lib/server/mcpServer.d.ts +8 -0
- package/lib/server/mcpServer.d.ts.map +1 -0
- package/lib/server/mcpServer.js +11 -0
- package/lib/server/mcpServer.js.map +1 -0
- package/lib/server/repositoryVersion.d.ts +16 -0
- package/lib/server/repositoryVersion.d.ts.map +1 -0
- package/lib/server/repositoryVersion.js +33 -0
- package/lib/server/repositoryVersion.js.map +1 -0
- package/lib/server/routeOptions.d.ts +23 -0
- package/lib/server/routeOptions.d.ts.map +1 -0
- package/lib/server/routeOptions.js +20 -0
- package/lib/server/routeOptions.js.map +1 -0
- package/lib/server/routeTable.d.ts +14 -0
- package/lib/server/routeTable.d.ts.map +1 -0
- package/lib/server/routeTable.js +32 -0
- package/lib/server/routeTable.js.map +1 -0
- package/lib/server/siteView.d.ts +29 -0
- package/lib/server/siteView.d.ts.map +1 -0
- package/lib/server/siteView.js +21 -0
- package/lib/server/siteView.js.map +1 -0
- package/lib/server/spaPages.d.ts +32 -0
- package/lib/server/spaPages.d.ts.map +1 -0
- package/lib/server/spaPages.js +126 -0
- package/lib/server/spaPages.js.map +1 -0
- package/lib/server/spaSite.d.ts +30 -0
- package/lib/server/spaSite.d.ts.map +1 -0
- package/lib/server/spaSite.js +170 -0
- package/lib/server/spaSite.js.map +1 -0
- package/lib/server/spaSiteOptions.d.ts +126 -0
- package/lib/server/spaSiteOptions.d.ts.map +1 -0
- package/lib/server/spaSiteOptions.js +2 -0
- package/lib/server/spaSiteOptions.js.map +1 -0
- package/lib/server/staticSite.d.ts +9 -0
- package/lib/server/staticSite.d.ts.map +1 -1
- package/lib/server/staticSite.js +41 -19
- package/lib/server/staticSite.js.map +1 -1
- package/lib/server/toolSiteServer.d.ts +77 -0
- package/lib/server/toolSiteServer.d.ts.map +1 -0
- package/lib/server/toolSiteServer.js +58 -0
- package/lib/server/toolSiteServer.js.map +1 -0
- package/lib/server/trustProxy.d.ts +20 -0
- package/lib/server/trustProxy.d.ts.map +1 -0
- package/lib/server/trustProxy.js +32 -0
- package/lib/server/trustProxy.js.map +1 -0
- package/lib/server/types.d.ts +13 -0
- package/lib/server/types.d.ts.map +1 -0
- package/lib/server/types.js +2 -0
- package/lib/server/types.js.map +1 -0
- package/lib/server.d.ts +22 -0
- package/lib/server.d.ts.map +1 -1
- package/lib/server.js +12 -0
- package/lib/server.js.map +1 -1
- package/lib/share/core/config.d.ts +18 -0
- package/lib/share/core/config.d.ts.map +1 -1
- package/lib/share/core/config.js +33 -2
- package/lib/share/core/config.js.map +1 -1
- package/lib/share/core/index.d.ts +3 -1
- package/lib/share/core/index.d.ts.map +1 -1
- package/lib/share/core/index.js +2 -1
- package/lib/share/core/index.js.map +1 -1
- package/lib/share/core/keySetParam.d.ts +40 -0
- package/lib/share/core/keySetParam.d.ts.map +1 -0
- package/lib/share/core/keySetParam.js +60 -0
- package/lib/share/core/keySetParam.js.map +1 -0
- package/lib/share/core/vocabulary.d.ts +8 -0
- package/lib/share/core/vocabulary.d.ts.map +1 -1
- package/lib/shell/ui/ShareControl.d.ts +75 -0
- package/lib/shell/ui/ShareControl.d.ts.map +1 -0
- package/lib/shell/ui/ShareControl.js +40 -0
- package/lib/shell/ui/ShareControl.js.map +1 -0
- package/lib/shell/ui/ShellFrame.d.ts +14 -0
- package/lib/shell/ui/ShellFrame.d.ts.map +1 -0
- package/lib/shell/ui/ShellFrame.js +45 -0
- package/lib/shell/ui/ShellFrame.js.map +1 -0
- package/lib/shell/ui/SiteShell.d.ts +251 -0
- package/lib/shell/ui/SiteShell.d.ts.map +1 -0
- package/lib/shell/ui/SiteShell.js +39 -0
- package/lib/shell/ui/SiteShell.js.map +1 -0
- package/lib/shell/ui/index.d.ts +5 -0
- package/lib/shell/ui/index.d.ts.map +1 -0
- package/lib/shell/ui/index.js +3 -0
- package/lib/shell/ui/index.js.map +1 -0
- package/lib/state/core/index.d.ts +1 -0
- package/lib/state/core/index.d.ts.map +1 -1
- package/lib/state/core/index.js.map +1 -1
- package/lib/state/core/legacyEntries.d.ts +30 -0
- package/lib/state/core/legacyEntries.d.ts.map +1 -0
- package/lib/state/core/legacyEntries.js +51 -0
- package/lib/state/core/legacyEntries.js.map +1 -0
- package/lib/state/core/persistBucket.d.ts +26 -2
- package/lib/state/core/persistBucket.d.ts.map +1 -1
- package/lib/state/core/persistBucket.js +26 -9
- package/lib/state/core/persistBucket.js.map +1 -1
- package/lib/state/core/persistSignalBucket.d.ts +26 -0
- package/lib/state/core/persistSignalBucket.d.ts.map +1 -1
- package/lib/state/core/persistSignalBucket.js +31 -0
- package/lib/state/core/persistSignalBucket.js.map +1 -1
- package/lib/state/core/storageEntry.d.ts +15 -0
- package/lib/state/core/storageEntry.d.ts.map +1 -1
- package/lib/state/core/storageEntry.js +33 -0
- package/lib/state/core/storageEntry.js.map +1 -1
- package/lib/structure/ui/StructureExportButton.d.ts +27 -0
- package/lib/structure/ui/StructureExportButton.d.ts.map +1 -0
- package/lib/structure/ui/StructureExportButton.js +21 -0
- package/lib/structure/ui/StructureExportButton.js.map +1 -0
- package/lib/structure/ui/index.d.ts +4 -0
- package/lib/structure/ui/index.d.ts.map +1 -1
- package/lib/structure/ui/index.js +2 -0
- package/lib/structure/ui/index.js.map +1 -1
- package/lib/structure/ui/useStructureDraft.d.ts +32 -0
- package/lib/structure/ui/useStructureDraft.d.ts.map +1 -0
- package/lib/structure/ui/useStructureDraft.js +20 -0
- package/lib/structure/ui/useStructureDraft.js.map +1 -0
- package/lib/ui.d.ts +2 -0
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +2 -0
- package/lib/ui.js.map +1 -1
- package/lib/worker/core/index.d.ts +1 -1
- package/lib/worker/core/index.d.ts.map +1 -1
- package/lib/worker/core/messages.d.ts +4 -2
- package/lib/worker/core/messages.d.ts.map +1 -1
- package/lib/worker/core/messages.js.map +1 -1
- package/lib/worker/core/oclResourcesUrl.d.ts +16 -0
- package/lib/worker/core/oclResourcesUrl.d.ts.map +1 -0
- package/lib/worker/core/oclResourcesUrl.js +19 -0
- package/lib/worker/core/oclResourcesUrl.js.map +1 -0
- package/lib/worker/core/serveWorkerRequests.d.ts +8 -0
- package/lib/worker/core/serveWorkerRequests.d.ts.map +1 -1
- package/lib/worker/core/serveWorkerRequests.js +15 -2
- package/lib/worker/core/serveWorkerRequests.js.map +1 -1
- package/lib/worker/core/workerChannel.d.ts +3 -4
- package/lib/worker/core/workerChannel.d.ts.map +1 -1
- package/lib/worker/core/workerChannel.js +72 -67
- package/lib/worker/core/workerChannel.js.map +1 -1
- package/lib/worker/core/workerChannelParts.d.ts +17 -6
- package/lib/worker/core/workerChannelParts.d.ts.map +1 -1
- package/lib/worker/core/workerChannelParts.js +20 -4
- package/lib/worker/core/workerChannelParts.js.map +1 -1
- package/lib/worker/core/workerChannelTypes.d.ts +46 -2
- package/lib/worker/core/workerChannelTypes.d.ts.map +1 -1
- package/lib/worker/core/workerSlot.d.ts +66 -0
- package/lib/worker/core/workerSlot.d.ts.map +1 -0
- package/lib/worker/core/workerSlot.js +107 -0
- package/lib/worker/core/workerSlot.js.map +1 -0
- package/package.json +17 -1
- package/src/card/core/cardAddress.ts +100 -0
- package/src/card/core/cardPageUrl.ts +97 -0
- package/src/card/core/index.ts +6 -0
- package/src/card/core/panelRoom.ts +66 -0
- package/src/card/ui/CardDetailsButton.tsx +104 -0
- package/src/card/ui/CardFigure.tsx +86 -0
- package/src/card/ui/CardFrame.tsx +46 -0
- package/src/card/ui/CopyTableButton.tsx +81 -0
- package/src/card/ui/cardTooltip.ts +18 -0
- package/src/card/ui/embed.ts +27 -0
- package/src/card/ui/fitCardToFrame.ts +76 -0
- package/src/card/ui/holdRoomForPanels.ts +83 -0
- package/src/card/ui/index.ts +14 -0
- package/src/card/ui/openPanels.ts +106 -0
- package/src/card.ts +13 -0
- package/src/conformers.ts +4 -0
- package/src/core.ts +5 -0
- package/src/fetch/core/apiError.ts +65 -0
- package/src/fetch/core/fetchJson.ts +129 -0
- package/src/fetch/core/index.ts +4 -0
- package/src/formula/core/formulaText.ts +96 -0
- package/src/formula/core/index.ts +20 -0
- package/src/formula/core/normalizeFormula.ts +50 -0
- package/src/formula/core/readFormula.ts +211 -0
- package/src/formula/ui/CopyableFormula.tsx +51 -0
- package/src/formula/ui/FormulaInput.tsx +50 -0
- package/src/formula/ui/QuestionFormula.tsx +20 -0
- package/src/formula/ui/index.ts +6 -0
- package/src/formula.ts +11 -0
- package/src/hooks/ui/index.ts +1 -0
- package/src/hooks/ui/keyTargets.ts +5 -3
- package/src/hooks/ui/useAsync.ts +50 -14
- package/src/ir/core/analysisSpectra.ts +26 -10
- package/src/ir/core/bandLabelPlan.ts +21 -10
- package/src/ir/core/index.ts +25 -5
- package/src/ir/core/irBand.ts +52 -14
- package/src/ir/core/irCommands.ts +15 -1
- package/src/ir/core/irDomain.ts +9 -7
- package/src/ir/core/irFormat.ts +39 -6
- package/src/ir/core/irMode.ts +42 -10
- package/src/ir/core/irReducer.ts +1 -49
- package/src/ir/core/irSpectrum.ts +59 -30
- package/src/ir/core/irState.ts +67 -2
- package/src/ir/core/irTechnique.ts +115 -0
- package/src/ir/core/irTechniqueCommands.ts +82 -0
- package/src/ir/core/pickBands.ts +63 -28
- package/src/ir/core/ramanBands.ts +105 -0
- package/src/ir/core/spectrumJcamp.ts +65 -16
- package/src/ir/core/toIrSpectrum.ts +20 -2
- package/src/ir/ui/BandRow.tsx +107 -0
- package/src/ir/ui/BandsPanel.tsx +32 -125
- package/src/ir/ui/IrAboutDialog.tsx +69 -28
- package/src/ir/ui/IrCanvas.tsx +2 -1
- package/src/ir/ui/IrChart.tsx +20 -24
- package/src/ir/ui/IrCommandProvider.tsx +10 -3
- package/src/ir/ui/IrCommandTooltip.tsx +11 -2
- package/src/ir/ui/IrDocumentationDialog.tsx +99 -55
- package/src/ir/ui/IrEditor.tsx +5 -36
- package/src/ir/ui/IrHeader.tsx +10 -3
- package/src/ir/ui/IrLogo.tsx +28 -9
- package/src/ir/ui/IrShell.tsx +27 -75
- package/src/ir/ui/IrStatusBar.tsx +17 -12
- package/src/ir/ui/IrToolbar.tsx +26 -15
- package/src/ir/ui/IrTraces.tsx +5 -1
- package/src/ir/ui/RamanEditor.tsx +53 -0
- package/src/ir/ui/SpectraPanel.tsx +2 -1
- package/src/ir/ui/SpectrumRow.tsx +14 -5
- package/src/ir/ui/VibrationalEditor.tsx +94 -0
- package/src/ir/ui/bandsTsv.ts +46 -0
- package/src/ir/ui/irChartProps.ts +14 -4
- package/src/ir/ui/irCommandContext.tsx +18 -3
- package/src/ir/ui/useIrEditor.ts +20 -8
- package/src/ir/ui/useIrHandle.ts +51 -0
- package/src/ir/ui/useIrText.ts +170 -0
- package/src/ir/ui/useIrZoom.ts +12 -3
- package/src/ir/ui/useValueAxisZoom.ts +67 -0
- package/src/ir.ts +3 -0
- package/src/locales/de.json +57 -1
- package/src/locales/en.json +57 -1
- package/src/locales/es.json +57 -1
- package/src/locales/fr.json +57 -1
- package/src/locales/it.json +57 -1
- package/src/moleculesClient/core/index.ts +19 -0
- package/src/moleculesClient/core/moleculesClient.ts +175 -0
- package/src/moleculesClient/core/moleculesClientApi.ts +120 -0
- package/src/moleculesClient/core/moleculesTypes.ts +163 -0
- package/src/moleculesClient/core/requestRetry.ts +118 -0
- package/src/molstar/core/camera.ts +3 -2
- package/src/molstar/core/framing.ts +200 -0
- package/src/molstar/core/hover.ts +26 -0
- package/src/molstar/core/index.ts +21 -1
- package/src/pedagogy/core/answers.ts +94 -0
- package/src/pedagogy/core/attempts.ts +205 -0
- package/src/pedagogy/core/index.ts +36 -0
- package/src/pedagogy/core/progressController.ts +116 -0
- package/src/pedagogy/core/seed.ts +177 -0
- package/src/pedagogy/core/series.ts +82 -0
- package/src/pedagogy/ui/AnswerFields.tsx +63 -0
- package/src/pedagogy/ui/ExerciseList.tsx +202 -0
- package/src/pedagogy/ui/ExerciseSeries.tsx +250 -0
- package/src/pedagogy/ui/QuestionCard.tsx +231 -0
- package/src/pedagogy/ui/index.ts +18 -0
- package/src/pedagogy/ui/seriesCounts.ts +34 -0
- package/src/pedagogy/ui/seriesParts.tsx +127 -0
- package/src/pedagogy/ui/useAttemptRecords.ts +16 -0
- package/src/periodic/ui/PeriodicTable.tsx +6 -3
- package/src/property/core/copyableText.ts +20 -0
- package/src/property/core/index.ts +1 -0
- package/src/property/ui/PropertyTable.tsx +83 -0
- package/src/property/ui/index.ts +2 -0
- package/src/raman.ts +19 -0
- package/src/router/core/history.ts +61 -7
- package/src/router/core/index.ts +3 -2
- package/src/router/core/languageRoute.ts +136 -0
- package/src/router/core/siteAddresses.ts +38 -0
- package/src/router/core/tabRouter.ts +59 -117
- package/src/router/core/tabRouterTypes.ts +158 -0
- package/src/seo/core/fitDescription.ts +74 -0
- package/src/seo/core/index.ts +17 -0
- package/src/seo/core/limits.ts +27 -0
- package/src/seo/core/pageContent.ts +42 -0
- package/src/seo/core/plainDescription.ts +4 -2
- package/src/seo/core/routeProblems.ts +1 -7
- package/src/seo/core/routeTable.ts +103 -0
- package/src/seo/vite/index.ts +2 -0
- package/src/seo/vite/prerender.ts +26 -1
- package/src/seo/vite/routeTable.ts +79 -0
- package/src/server/answerAddresses.ts +92 -0
- package/src/server/cardMeta.ts +88 -0
- package/src/server/config.ts +125 -0
- package/src/server/envNumber.ts +65 -0
- package/src/server/healthRoute.ts +42 -0
- package/src/server/listenSite.ts +90 -0
- package/src/server/mcpServer.ts +14 -0
- package/src/server/repositoryVersion.ts +33 -0
- package/src/server/routeOptions.ts +26 -0
- package/src/server/routeTable.ts +35 -0
- package/src/server/siteView.ts +42 -0
- package/src/server/spaPages.ts +179 -0
- package/src/server/spaSite.ts +216 -0
- package/src/server/spaSiteOptions.ts +133 -0
- package/src/server/staticSite.ts +65 -35
- package/src/server/toolSiteServer.ts +127 -0
- package/src/server/trustProxy.ts +32 -0
- package/src/server/types.ts +25 -0
- package/src/server.ts +40 -0
- package/src/share/core/config.ts +45 -2
- package/src/share/core/index.ts +4 -0
- package/src/share/core/keySetParam.ts +92 -0
- package/src/share/core/vocabulary.ts +8 -0
- package/src/shell/ui/ShareControl.tsx +150 -0
- package/src/shell/ui/ShellFrame.tsx +180 -0
- package/src/shell/ui/SiteShell.tsx +297 -0
- package/src/shell/ui/index.ts +9 -0
- package/src/state/core/index.ts +1 -0
- package/src/state/core/legacyEntries.ts +76 -0
- package/src/state/core/persistBucket.ts +50 -10
- package/src/state/core/persistSignalBucket.ts +52 -0
- package/src/state/core/storageEntry.ts +32 -0
- package/src/structure/ui/StructureExportButton.tsx +57 -0
- package/src/structure/ui/index.ts +4 -0
- package/src/structure/ui/useStructureDraft.ts +47 -0
- package/src/ui.ts +2 -0
- package/src/worker/core/index.ts +1 -0
- package/src/worker/core/messages.ts +4 -3
- package/src/worker/core/oclResourcesUrl.ts +21 -0
- package/src/worker/core/serveWorkerRequests.ts +30 -2
- package/src/worker/core/workerChannel.ts +74 -74
- package/src/worker/core/workerChannelParts.ts +33 -13
- package/src/worker/core/workerChannelTypes.ts +47 -2
- package/src/worker/core/workerSlot.ts +181 -0
- package/styles/card.css +145 -0
- package/styles/chrome.css +248 -0
package/README.md
CHANGED
|
@@ -33,10 +33,12 @@ only when it drags a heavy dependency behind it.
|
|
|
33
33
|
| Import | Holds | Costs |
|
|
34
34
|
| ---------------------------------- | ----------------------------------------------------- | ------------------------------------------------ |
|
|
35
35
|
| `react-cheminfo/core` | every framework-free helper — 140 value exports | nothing |
|
|
36
|
+
| `react-cheminfo/formula` | formulas: read, compared, drawn and copied | mf-parser, react-mf; React on the components |
|
|
36
37
|
| `react-cheminfo/ui` | every React component and hook — 60 value exports | React |
|
|
37
38
|
| `react-cheminfo/vite` | the prerender plugin and the OG card | nothing; React on the card |
|
|
38
39
|
| `react-cheminfo/pages` | the Cloudflare Pages analytics middleware | nothing |
|
|
39
40
|
| `react-cheminfo/server` | the prerendered build, served from Node | fastify, @fastify/static; Node only |
|
|
41
|
+
| `react-cheminfo/card` | the card an answer is shown as in a chat | React; cheminfo-mcp-server, an optional peer |
|
|
40
42
|
| `react-cheminfo/orbital` | the 3D atomic-orbital viewer | React, molstar |
|
|
41
43
|
| `react-cheminfo/molecule3d` | the 3D molecule viewer and its toolbar | React, molstar |
|
|
42
44
|
| `react-cheminfo/structure` | the structure editor and renderer | React, react-ocl, OCL |
|
|
@@ -44,11 +46,13 @@ only when it drags a heavy dependency behind it.
|
|
|
44
46
|
| `react-cheminfo/slides` | the deck format and the slideshow player | React, react-markdown |
|
|
45
47
|
| `react-cheminfo/spectra` | the spectra processing settings editors | React; types only from spectra-processor, ml-pca |
|
|
46
48
|
| `react-cheminfo/ir` | the infrared chart, band table and editor | React, ir-spectrum, convert-to-jcamp |
|
|
49
|
+
| `react-cheminfo/raman` | the Raman editor: the infrared one, read for Raman | the same as `react-cheminfo/ir` |
|
|
47
50
|
| `react-cheminfo/xtb` | GFN2-xTB as a geometry relaxer | nothing on import; xtb-wasm on the first call |
|
|
48
51
|
| `react-cheminfo/host` | data handed over by a page that frames the tool | nothing on import; ajv once the page is framed |
|
|
49
52
|
| `react-cheminfo/host-testing` | a stand-in host and SciPeaks' messages, for e2e tests | nothing; Node only |
|
|
50
53
|
| `react-cheminfo/styles/chrome.css` | the shared tokens and site-header stylesheet | nothing |
|
|
51
54
|
| `react-cheminfo/styles/slides.css` | the deck stylesheet, themed on the site's colours | nothing |
|
|
55
|
+
| `react-cheminfo/styles/card.css` | the card’s stylesheet, on the family’s tokens | nothing |
|
|
52
56
|
|
|
53
57
|
A backend serving an RIS endpoint, a prerender script writing a sitemap, and
|
|
54
58
|
every unit test of that logic therefore load no React at all — and a worker
|
|
@@ -65,11 +69,15 @@ module scope: a site that never imports that door bundles none of it.
|
|
|
65
69
|
usual reason: reading a spectrum drags the formats one may arrive in —
|
|
66
70
|
`ir-spectrum` for the band correlations and the absorbance/transmittance pair,
|
|
67
71
|
`convert-to-jcamp` for writing them back out, and a JCAMP or SPC reader fetched
|
|
68
|
-
only once the bytes turn out to need it.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
only once the bytes turn out to need it. `react-cheminfo/raman` opens the same
|
|
73
|
+
viewer for Raman spectra — one value axis, the Raman shift running left to
|
|
74
|
+
right, the bands picked on intensity and no correlation table — so a page
|
|
75
|
+
imports each technique's viewer by name while both share one shell. The chart
|
|
76
|
+
it is drawn with is **not** behind that door: scales, ticks, plot geometry, the
|
|
77
|
+
zoom gestures, the label placement and the panel chrome are in `core` and `ui`,
|
|
78
|
+
because a spectrum of any kind is drawn with them and the next viewer built on
|
|
79
|
+
them should find them already there rather than reach through an infrared
|
|
80
|
+
package for them.
|
|
73
81
|
|
|
74
82
|
`react-cheminfo/xtb` is the door a page opens only when a visitor asks for a
|
|
75
83
|
better number. `refineConformers` in
|
|
@@ -100,16 +108,21 @@ through a wildcard subpath exactly as `react-science` serves its own.
|
|
|
100
108
|
| **Routing & head** | `createTabRouter`, `readRoute`, `writeRoute`, `subscribeToRoute`, `adoptLegacyHashAddress`, `writeDocumentMeta`, `pageLocation`, `pageHistory` | `useTabRoute` |
|
|
101
109
|
| **Indexing** | `injectPageMeta`, `pageHeadTags`, `pageDocumentMeta`, `fill`, `PAGE_HEAD_MARKER`, `PAGE_BODY_MARKER`, `robotsTxt`, `sitemapXml`, `noscriptIndex`, `structuredDataScript`, `assertRoutes`, `routeFor`, `homeRoute` | `cheminfoPrerender`, `ogCardHtml`, `OG_WIDTH`, `OG_HEIGHT` (all `/vite`) |
|
|
102
110
|
| **Pedagogy** | `parseGlossaryMarkers`, `localStorageProgressStore`, `progressSummary`, `finishValidation` | `GlossaryText`, `SyntaxTooltip`, `HintLadder`, `ExerciseActions`, `ExerciseProgressHeader`, `TutorialStepStrip`, `ReferenceGrid`, `TestCaseList` |
|
|
111
|
+
| **Graded series** | `pickSeeded`, `freshSeed`, `parseSeed`, `seedParam`, `createAttemptStore`, `createProgressController`, `readAnswerNumber`, `emptyCase`, `unreadableCase` | `ExerciseSeries`, `QuestionCard`, `AnswerFields`, `ExerciseList`, `useAttemptRecords` |
|
|
112
|
+
| **Formulas** | `readFormula`, `normalizeFormula`, `canonicalFormula`, `atomCounts`, `formulaHtml`, `formulaText` (all `/formula`) | `CopyableFormula`, `QuestionFormula`, `FormulaInput` (all `/formula`) |
|
|
113
|
+
| **Site shell** | `pageContentOf`; the `pages` option of `cheminfoPrerender` (`/vite`) | `SiteShell`, `ShareControl` |
|
|
114
|
+
| **Properties** | `copyableText` | `PropertyTable` |
|
|
103
115
|
| **Clipboard & files** | `writeToClipboard`, `downloadBlob`, `downloadText`, `sanitizeFileName`, `toDelimited`, `readDelimited`, `downloadFigure`, `figureSvg`, `figurePng`, `figureSize` | `ClickToCopy`, `CopyButton`, `CopyableValue`, `CodeBlock`, `DelimitedTextDialog`, `FigureDownload` |
|
|
104
116
|
| **Formatting & colour** | `formatInteger`, `formatDecimal`, `formatBytes`, `pluralize`, `readableInk`, `contrastRatio`, `COLOR_SCALES`, `resolveColorScale`, `formatColorScale`, `colorAt`, `swatchAt`, `sampleScale`, `colorScaleGradient`, `rgbToHsv` | `ColorScaleLegend`, `ColorScaleSelect`, `ColorScaleEditor`, `ColorScaleBar` |
|
|
105
117
|
| **Number entry** | `readNumber`, `numberText`, `isPartialNumber`, `stepNumber`, `snapToStep` | `NumberInput` |
|
|
106
118
|
| **Range filter** | `isRangeBounded`, `isRangeDomain`, `rangeHandles`, `movedRange`, `settleHandles`, `sameRange`, `rangeHistogramPath`, `OPEN_RANGE` | `RangeSlider` |
|
|
107
119
|
| **Widgets** | `CREDITS`, `credits` | `ErrorBoundary`, `CollapsibleSection`, `CapsuleFilter`, `HelpTooltip`, `CreditsList` |
|
|
108
120
|
| **Hooks & state** | `createWorkerChannel`, `persistBucket`, `persistSignalBucket` | `useDebouncedValue`, `useContainerSize`, `useListKeyboardNavigation`, `useDisclosure` |
|
|
121
|
+
| **Requests** | `fetchJson`, `ApiError`, `readApiError`, `keySetParam`, `readHiddenParts`, `formatHiddenParts`, `fitDescription`, `DESCRIPTION_MIN`, `DESCRIPTION_MAX`, `openingRoute`, `anchorHref` | `useAsync` (signal, `pending`) |
|
|
109
122
|
| **Chemistry** | `atomicOrbitalsOf`, `configurationOf`, `classifyMolfile`, `readStructure`, `toMolfileExport` | `AtomicOrbitalViewer` (`/orbital`), `StructureEditor`, `Structure` (`/structure`) |
|
|
110
123
|
| **Conformers** | `generateConformers`, `continueConformers`, `refineConformers`, `conformerShape`, `isSameMinimum`, `rankByEnergy`, `minimiseConformer`, `DEFAULT_CONFORMER_OPTIONS`, `CONFORMER_STRATEGIES` (all `/conformers`); `GeometryRelaxer`, `readRelaxableGeometry`, `centredRmsd` | — |
|
|
111
124
|
| **Spectrum charts** | `chartScale`, `chartAxisScale`, `plotRect`, `zoomDomain`, `zoomSelection`, `labelStackBaselines`, `layoutAnnotationBoxes`, `profilePath`, `stickPath`, `guidePlacement`, `readoutPlacement`, `stackCapacity`, `nextSpectrumColor`, `panelStyles`, `statusBar` | `Axes`, `AxisGuide`, `ChartTracker`, `ChartStack`, `SelectionRect`, `TraceLegend`, `PlotCaption`, `useChartZoom`, `useChartPointer`, `useChartSize`, `SidePanelStack`, `PanelRail`, `Section`, `FilterInput`, `AboutDialogFrame`, `DocumentationDialogFrame`, `FigureDownload`, `useFigureDownload` |
|
|
112
|
-
| **Infrared**
|
|
125
|
+
| **Infrared and Raman** | `loadIrSpectra`, `toIrSpectrum`, `pickBands`, `assignBands`, `BAND_ASSIGNMENTS`, `irSpectrumToJcamp`, `IR_MODE_RULES`, `IR_TECHNIQUE_RULES`, `nearestBandAt`, `planBandLabels`, `irReducer` (all `/ir`) | `IrEditor`, `IrChart`, `BandsPanel`, `SpectraPanel`, `MetadataPanel`, `useIrEditor` (all `/ir`); `RamanEditor` (`/raman`) |
|
|
113
126
|
| **Spectra** | `FILTER_CATALOG`, `filterMenu`, `settingsProblems`, `normalizationFilters`, `addFilter`, `moveFilter`, `setFilterOption`, `principalComponentChoices`, `clampPrincipalComponents`, `EMPTY_SETTINGS` (all `/spectra`) | `SpectraSettingsEditor`, `FilterChainEditor`, `PrincipalComponentSelect` (all `/spectra`) |
|
|
114
127
|
| **About** | `resolveAbout`, `aboutProblems` | `AboutPage` |
|
|
115
128
|
| **Which build is running** | `formatBuiltAt`, `shortCommit`, `BuildInfo` | `AboutVersion`, `cheminfoBuildInfo` (`/vite`) |
|
|
@@ -121,6 +134,7 @@ through a wildcard subpath exactly as `react-science` serves its own.
|
|
|
121
134
|
| **Periodic table** | `PERIODIC_ELEMENTS`, `elementBySymbol`, `elementByAtomicNumber`, `cellOf`, `placedElements`, `elementByArrowKey`, `EMPTY_BLOCK`, `categorySwatch`, `CATEGORY_LABELS` | `PeriodicTable`, `ElementCell`, `CategoryLegend` |
|
|
122
135
|
| **Taxonomy** | `TAXON_RANKS`, `PRINCIPAL_RANKS`, `rankOrder`, `isPrincipalRank`, `isGenusOrBelow`, `isAboveGenus`, `principalLineage`, `lineageFromNodes`, `lineageFromRanks`, `genusOrBelow`, `ncbiTaxonomyUrl`, `splitOrganismName` | `TaxonLineage`, `OrganismName`, `useRankLabel` |
|
|
123
136
|
| **Framed by a host** | `hostStructureLoader`, `readHostMolecule`, `STRUCTURE_KINDS`, `connectHost`, `selectInputs`, `checkValue`, `kindAccepts`, `parseRequest` (all `/host`); `startStandInHost`, `SCIPEAKS_ETHYLBENZENE_LOAD` (`/host-testing`) | `useHostConnection` (`/host`) |
|
|
137
|
+
| **Answer cards** | `CARD_PARAM`, `isCardAddress`, `sitePageUrl`, `cardPageUrl`, `framedPageUrl`, `roomForPanels`; `answerAddresses`, `joinAddress`, `viewOrigins`, `cardMeta`, `pageAnswer`, `siteView` (all `/server`) | `CardFrame`, `CardDetailsButton`, `CardFigure`, `CopyTableButton`, `fitCardToFrame`, `useFitCardToFrame`, `useOverlayRoom`, `holdRoomForPanels` (all `/card`); `StructureExportButton`, `useStructureDraft` (`/structure`) |
|
|
124
138
|
|
|
125
139
|
Everything in that table is exported from `./core`, `./ui`, `./slides`,
|
|
126
140
|
`./vite` or `./structure` and nothing else is: the sub-components a component is built
|
|
@@ -854,6 +868,60 @@ const included = useMemo(
|
|
|
854
868
|
subject — a formula through `react-mf`, a structure, a name — and a readout of
|
|
855
869
|
strings cannot hold any of that.
|
|
856
870
|
|
|
871
|
+
## A graded series, and the shell around it
|
|
872
|
+
|
|
873
|
+
A pedagogic site that asks a series of questions writes its pool and its
|
|
874
|
+
grader, and nothing else. `SeriesTool` describes them; `ExerciseSeries` draws
|
|
875
|
+
the list beside the open question, the progress over the series, the length
|
|
876
|
+
picker and the new-series button. It reads no address: the page hands it the
|
|
877
|
+
seed, the length and the share of the row, and is told when one changes.
|
|
878
|
+
|
|
879
|
+
```tsx
|
|
880
|
+
import { createAttemptStore, parseSeed } from 'react-cheminfo/core';
|
|
881
|
+
import { ExerciseSeries } from 'react-cheminfo/ui';
|
|
882
|
+
|
|
883
|
+
const ATTEMPTS = createAttemptStore({ key: 'atoms' }); // atoms:attempts:v1
|
|
884
|
+
|
|
885
|
+
<ExerciseSeries
|
|
886
|
+
tool={ELECTRONS}
|
|
887
|
+
store={ATTEMPTS}
|
|
888
|
+
label={(ion) => <QuestionFormula formula={ion.formula} />}
|
|
889
|
+
prompt={(ion) => <p>How many electrons has {ion.name}?</p>}
|
|
890
|
+
seed={parseSeed(route.params.seed)}
|
|
891
|
+
onSeed={(seed, history) => writeSeed(tab, seed, history)}
|
|
892
|
+
count={questionCount}
|
|
893
|
+
onCount={setQuestionCount}
|
|
894
|
+
split={SERIES_SPLIT.parse(route.params.split ?? null)}
|
|
895
|
+
onSplit={(split) => writeSplit(tab, split)}
|
|
896
|
+
/>;
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
`pickSeeded` draws the series. Its `draw` option names the generator call a
|
|
900
|
+
site's links were written with — `getFloat` for atoms, inorganic and moles,
|
|
901
|
+
`getUint32` with `wrap` for dbe — so every `?seed=` already handed out opens
|
|
902
|
+
the same questions. `seedParam` reads a seed a link pins, and `?seed=each` for
|
|
903
|
+
one series per student. `createProgressController(signal)` is the handful of
|
|
904
|
+
actions an exercise page performs on progress kept in a signal.
|
|
905
|
+
|
|
906
|
+
Formulas come from their own door, because they are read by `mf-parser` and
|
|
907
|
+
drawn by `react-mf`: `readFormula` reads `NO3-`, `SO4--` and `CuSO4.5H2O` the
|
|
908
|
+
way a student types them, which the parser alone reads as neutral or as a
|
|
909
|
+
decimal; `CopyableFormula` copies a formula as text and as HTML, so a paste
|
|
910
|
+
keeps its subscripts.
|
|
911
|
+
|
|
912
|
+
`SiteShell` is the chrome around a page: the theme, the bar with About · Cite ·
|
|
913
|
+
Tools · Contact · Share, the page, and the footer, with nothing but the page
|
|
914
|
+
under `?embed`. A site fills the slots between the shared entries
|
|
915
|
+
(`actionsAfterAbout`, `actionsAfterCite`, `actions`, `language`, `account`) and
|
|
916
|
+
never re-orders them. Given the site's router, it marks the tab on show and
|
|
917
|
+
serves the About tab as `AboutPage`. Its `share` takes what `ShareControl`
|
|
918
|
+
takes — the Share entry and its dialog in one, which is also what a header's
|
|
919
|
+
own `share` prop takes.
|
|
920
|
+
|
|
921
|
+
A prerendered site that writes text for a few of its pages passes them as
|
|
922
|
+
`pages` to `cheminfoPrerender`; every other address then says the name and the
|
|
923
|
+
sentence its route is indexed under.
|
|
924
|
+
|
|
857
925
|
## Framed by a notebook
|
|
858
926
|
|
|
859
927
|
A page that frames a tool — an electronic lab notebook such as SciPeaks, a
|
|
@@ -1016,6 +1084,39 @@ Still English, with the runtime in place and no catalog yet: the spectra
|
|
|
1016
1084
|
settings editor and the projection panels (`react-cheminfo/spectra`, the
|
|
1017
1085
|
projection viewers), which no site of the family reads in a second language yet.
|
|
1018
1086
|
|
|
1087
|
+
## Routing a translated site
|
|
1088
|
+
|
|
1089
|
+
A router given `languages` reads the language off the prefix and writes it
|
|
1090
|
+
back, English bare, so the share vocabulary, the query and the mount stay where
|
|
1091
|
+
they were:
|
|
1092
|
+
|
|
1093
|
+
```ts
|
|
1094
|
+
const router = createTabRouter<Tab>({
|
|
1095
|
+
tabs: ['generator', 'exercises'],
|
|
1096
|
+
home: 'generator',
|
|
1097
|
+
languages: ['en', 'fr', 'de'],
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
router.parse('/fr/exercises?embed'); // { tab: 'exercises', language: 'fr', … }
|
|
1101
|
+
router.format({ tab: 'exercises', language: 'de' }); // '/de/exercises'
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
`readRoute` moves a `?lang=` a sibling handed over into the path, once, in
|
|
1105
|
+
place; a prefix the address already carries always wins, so a deep link is
|
|
1106
|
+
never steered. `openingRoute(router, preferred)` opens a bare `/` in the
|
|
1107
|
+
language the reader last chose, and nothing else. `writeRoute` keeps the
|
|
1108
|
+
language on screen when the route names none.
|
|
1109
|
+
|
|
1110
|
+
Beside it: `persistSignalBucket` takes `legacyKeys` (adopted once, through a
|
|
1111
|
+
`migrate` when the shape changed) and `syncAcrossTabs`; `createSiteAddresses`
|
|
1112
|
+
answers `anchorHref` and `storedAssetSrc`; a vocabulary takes
|
|
1113
|
+
`legacyEmbedParts`, so `?hide=header` still opens framed; `keySetParam` writes
|
|
1114
|
+
`?flags=` with `none` for the empty set; `createWorkerChannel` takes a
|
|
1115
|
+
`failure` hook, `retryAfterWorkerFailure`, and runs in-process when a browser
|
|
1116
|
+
refuses the worker; `oclResourcesUrl()` comes from `./conformers`, and
|
|
1117
|
+
`resetCamera`, `focusPoint`, `sceneSphere` and `subscribeHoverLabel` from
|
|
1118
|
+
`./molstar/core`.
|
|
1119
|
+
|
|
1019
1120
|
## Carrying talks
|
|
1020
1121
|
|
|
1021
1122
|
A deck is one Markdown file in the repository of the site whose subject it
|
|
@@ -1253,6 +1354,192 @@ answers its own 404. Without a build, `staticSite` logs it and serves the API
|
|
|
1253
1354
|
alone. `fastify` (5) and `@fastify/static` (10) are optional peers, installed
|
|
1254
1355
|
by a site that has a server.
|
|
1255
1356
|
|
|
1357
|
+
`basePath` (`BASE_PATH`) serves one image at a mount chosen at startup, behind a
|
|
1358
|
+
proxy that takes the path off: it is written into the `<base href="/">` of every
|
|
1359
|
+
page when the build is read, and in front of every redirect.
|
|
1360
|
+
|
|
1361
|
+
### A tool site's server, from its environment
|
|
1362
|
+
|
|
1363
|
+
A site that serves its tools beside its pages has nothing of its own to write
|
|
1364
|
+
but the tools. `readServerConfig` reads the environment once and refuses a
|
|
1365
|
+
malformed value; `toolSiteServer` builds Fastify, registers the API the site
|
|
1366
|
+
passes, then `staticSite`; `startToolServer` listens and closes on `SIGTERM`
|
|
1367
|
+
and `SIGINT`, setting `process.exitCode = 1` when a close fails.
|
|
1368
|
+
|
|
1369
|
+
```ts
|
|
1370
|
+
// server/main.ts
|
|
1371
|
+
import { join } from 'node:path';
|
|
1372
|
+
|
|
1373
|
+
import {
|
|
1374
|
+
readServerConfig,
|
|
1375
|
+
startToolServer,
|
|
1376
|
+
toolSiteServer,
|
|
1377
|
+
} from 'react-cheminfo/server';
|
|
1378
|
+
|
|
1379
|
+
const config = readServerConfig(process.env, {
|
|
1380
|
+
siteId: 'osiris',
|
|
1381
|
+
port: 10_620,
|
|
1382
|
+
root: join(import.meta.dirname, '../dist'),
|
|
1383
|
+
});
|
|
1384
|
+
|
|
1385
|
+
await startToolServer(
|
|
1386
|
+
(settings) =>
|
|
1387
|
+
toolSiteServer({
|
|
1388
|
+
siteId: 'osiris',
|
|
1389
|
+
config: settings,
|
|
1390
|
+
// name: 'osiris.cheminfo.org', version: the repository root's release
|
|
1391
|
+
registerApi: (app, { name, version }) =>
|
|
1392
|
+
registerTools(app, name, version),
|
|
1393
|
+
}),
|
|
1394
|
+
config,
|
|
1395
|
+
);
|
|
1396
|
+
```
|
|
1397
|
+
|
|
1398
|
+
| Variable | Read as | Default |
|
|
1399
|
+
| ----------------- | ------------------------------------------------------------------- | ---------------------------- |
|
|
1400
|
+
| `PORT` | an integer from 1 to 65535 | the site's own port |
|
|
1401
|
+
| `HOST` | the interface listened on | `0.0.0.0` |
|
|
1402
|
+
| `TRACKING_SCRIPT` | the analytics snippet, verbatim | nothing loaded |
|
|
1403
|
+
| `SITE_URL` | the address answers link to, path kept, ending in `/` | the site's own address |
|
|
1404
|
+
| `PUBLIC_URL` | this server's address, which a chat frames, ending in `/` | `http://localhost:<PORT>/` |
|
|
1405
|
+
| `TRUST_PROXY` | an address, a CIDR, a list of either, or `true`; a hop count throws | `false` |
|
|
1406
|
+
| `SERVER_ROOT` | the build served | the `root` option, or `dist` |
|
|
1407
|
+
| `BASE_PATH` | the mount, behind a proxy that takes it off | none |
|
|
1408
|
+
|
|
1409
|
+
The pieces are exported on their own for a backend that is not a tool site:
|
|
1410
|
+
`parseTrustProxy`, `readEnvNumber` (blank is unset, a malformed value throws),
|
|
1411
|
+
`readHttpAddress`, `readRepositoryVersion` (the root `package.json`, found as
|
|
1412
|
+
`cheminfoBuildInfo` finds it), `healthRoute` (`GET /health`, silent),
|
|
1413
|
+
`listenSite` (listen, and close on a signal, then run `onClose`), and the
|
|
1414
|
+
type-only `FastifyTyped` (`@fastify/type-provider-typebox` is an optional peer).
|
|
1415
|
+
|
|
1416
|
+
### A single-page app, served by its backend
|
|
1417
|
+
|
|
1418
|
+
A backend that serves a Vite single-page app answers every address the app
|
|
1419
|
+
routes with the built page, under the head of that address and a crawl path of
|
|
1420
|
+
its own. `spaSite` does that, and writes `sitemap.xml` and `robots.txt` from the
|
|
1421
|
+
route table at the address the site is served at; serves the build's files, with
|
|
1422
|
+
`assets/` kept for a year; leaves `/v1/` and `/docs` to the API; and answers
|
|
1423
|
+
`/health`.
|
|
1424
|
+
|
|
1425
|
+
```ts
|
|
1426
|
+
await app.register(spaSite, {
|
|
1427
|
+
root: join(import.meta.dirname, '../../frontend/dist'),
|
|
1428
|
+
site: 'wikidata',
|
|
1429
|
+
siteUrl: process.env.SITE_URL, // blank: the origin the request arrived on
|
|
1430
|
+
trackingScript: process.env.TRACKING_SCRIPT,
|
|
1431
|
+
noscript: { heading: 'wikidata.cheminfo.org', hrefs: 'relative' },
|
|
1432
|
+
// A compound under its own name; undefined falls back to the table.
|
|
1433
|
+
page: (url) => compoundPage(db, url),
|
|
1434
|
+
sitemapPaths: () => db.pageIds().map((id) => `/compound/${id}`),
|
|
1435
|
+
});
|
|
1436
|
+
```
|
|
1437
|
+
|
|
1438
|
+
The route table is the one the app reads, written beside the page at build time
|
|
1439
|
+
by `cheminfoRouteTable` from `react-cheminfo/vite`, which also runs
|
|
1440
|
+
`assertRoutes` when the build starts; `readRouteTable(root, fallback)` reads it
|
|
1441
|
+
back. `notFoundStatus: 404` with `knownRoute` answers an address the app does not
|
|
1442
|
+
route with a real 404, `structuredData` takes a function writing the whole block,
|
|
1443
|
+
and `indexed: false` keeps an admin site out of every index.
|
|
1444
|
+
|
|
1445
|
+
```ts
|
|
1446
|
+
// frontend/vite.config.ts
|
|
1447
|
+
plugins: [react(), cheminfoRouteTable({ routes: ROUTES })],
|
|
1448
|
+
```
|
|
1449
|
+
|
|
1450
|
+
### Writing to molecules.cheminfo.org
|
|
1451
|
+
|
|
1452
|
+
`createMoleculesClient` from `react-cheminfo/core` is the client a site writes
|
|
1453
|
+
its source through: `startImport`, `importState`, `submit`, `lookup` and
|
|
1454
|
+
`purge`, each attempt with its own deadline, retried on 429, 502, 503, 504 or no
|
|
1455
|
+
answer with doubling, spread pauses that honour `Retry-After`, bodies gzipped.
|
|
1456
|
+
It reads no Node module.
|
|
1457
|
+
|
|
1458
|
+
```ts
|
|
1459
|
+
const molecules = createMoleculesClient({
|
|
1460
|
+
baseUrl: 'https://molecules.cheminfo.org',
|
|
1461
|
+
token: process.env.MOLECULES_TOKEN_LOTUS,
|
|
1462
|
+
onRetry: (details) =>
|
|
1463
|
+
logger.warn(details, 'molecules.cheminfo.org: retrying'),
|
|
1464
|
+
});
|
|
1465
|
+
const { importKey } = await molecules.startImport();
|
|
1466
|
+
```
|
|
1467
|
+
|
|
1468
|
+
## Answers shown in a chat
|
|
1469
|
+
|
|
1470
|
+
A site's tool server answers mcp.cheminfo.org with a link to the page people
|
|
1471
|
+
share and a card: the same page on this server under `?embed=1&card=1`, which
|
|
1472
|
+
the chat frames inline, and the page itself over the full screen. The card and
|
|
1473
|
+
the page read the same parameters, so they never disagree about what was
|
|
1474
|
+
asked.
|
|
1475
|
+
|
|
1476
|
+
The server writes both addresses with `react-cheminfo/server`. `siteUrl` and
|
|
1477
|
+
`publicUrl` may be an origin or an origin and a mount, with or without a
|
|
1478
|
+
trailing slash, and a page is named from the site's own root: every helper
|
|
1479
|
+
joins them with exactly one slash.
|
|
1480
|
+
|
|
1481
|
+
```ts
|
|
1482
|
+
import {
|
|
1483
|
+
answerAddresses,
|
|
1484
|
+
cardMeta,
|
|
1485
|
+
pageAnswer,
|
|
1486
|
+
siteView,
|
|
1487
|
+
} from 'react-cheminfo/server';
|
|
1488
|
+
|
|
1489
|
+
const addresses = answerAddresses({ siteUrl, publicUrl });
|
|
1490
|
+
// { link: 'https://equilibrium.cheminfo.org/titration?ind=thymol', meta }
|
|
1491
|
+
const answer = pageAnswer(addresses, '/titration', { ind: 'thymol' });
|
|
1492
|
+
// A query written by the site's own codec, and what only the card reads.
|
|
1493
|
+
const meta = cardMeta(addresses, `/?${libraryQuery}`, {
|
|
1494
|
+
hide: ['editor'],
|
|
1495
|
+
extra: { rows: '10' },
|
|
1496
|
+
});
|
|
1497
|
+
const view = siteView({ uri: 'ui://vcl/page', name, description, addresses });
|
|
1498
|
+
```
|
|
1499
|
+
|
|
1500
|
+
A card address longer than `maxLength` (8000) is not carried: `meta` is then
|
|
1501
|
+
undefined and the chat draws the answer itself, while `link` still names the
|
|
1502
|
+
page. These helpers are built on `embedMeta` and `embedView`, so
|
|
1503
|
+
`cheminfo-mcp-server` (an optional peer) is installed by a site that imports
|
|
1504
|
+
`react-cheminfo/server`. The addresses alone — `CARD_PARAM`, `sitePageUrl`,
|
|
1505
|
+
`cardPageUrl`, `framedPageUrl` — are in `react-cheminfo/core`, for the page.
|
|
1506
|
+
|
|
1507
|
+
The card itself is drawn with `react-cheminfo/card` and
|
|
1508
|
+
`react-cheminfo/styles/card.css`:
|
|
1509
|
+
|
|
1510
|
+
```tsx
|
|
1511
|
+
import 'react-cheminfo/styles/card.css';
|
|
1512
|
+
import {
|
|
1513
|
+
CardDetailsButton,
|
|
1514
|
+
CardFigure,
|
|
1515
|
+
CardFrame,
|
|
1516
|
+
CopyTableButton,
|
|
1517
|
+
} from 'react-cheminfo/card';
|
|
1518
|
+
import { StructureExportButton } from 'react-cheminfo/structure';
|
|
1519
|
+
|
|
1520
|
+
<CardFrame>
|
|
1521
|
+
<p className="card__header card__title">pH 8.72 at equivalence</p>
|
|
1522
|
+
<CardFigure
|
|
1523
|
+
fileName="titration"
|
|
1524
|
+
tools={<StructureExportButton smiles={smiles} />}
|
|
1525
|
+
>
|
|
1526
|
+
<TitrationChart />
|
|
1527
|
+
</CardFigure>
|
|
1528
|
+
<div className="card__end">
|
|
1529
|
+
<CopyTableButton table={() => toDelimited(rows)} />
|
|
1530
|
+
<CardDetailsButton address={{ cardParams: ['scale', 'ph'] }} />
|
|
1531
|
+
</div>
|
|
1532
|
+
</CardFrame>;
|
|
1533
|
+
```
|
|
1534
|
+
|
|
1535
|
+
`CardFrame` reports the card's height to the frame and grows the card while a
|
|
1536
|
+
dialog or a popover it opened is open, so the frame holds it — only when the
|
|
1537
|
+
page is framed. A card that keeps its own root uses `ref={fitCardToFrame}`, or
|
|
1538
|
+
`useFitCardToFrame(ref)`. `CardDetailsButton` opens the card's address without
|
|
1539
|
+
`card`, `embed`, `hide` and the parameters only the card reads, in a new tab
|
|
1540
|
+
when framed and in place otherwise. Their words come from the chrome's
|
|
1541
|
+
catalog, in the language of the page.
|
|
1542
|
+
|
|
1256
1543
|
## Saying which build is running
|
|
1257
1544
|
|
|
1258
1545
|
A report of something going wrong is worth answering only when we know what was
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The card of an answer, as its address says it.
|
|
3
|
+
*
|
|
4
|
+
* A chat shows a tool's answer twice: inline, as a card drawing only what the
|
|
5
|
+
* question asked, and over the full screen, as the site's page. The card is
|
|
6
|
+
* that page with `card` in its query, always with `embed`, so the card and
|
|
7
|
+
* the page behind it read the same parameters and can never disagree about
|
|
8
|
+
* what was asked. `card` is read by its presence: `?card` and `?card=1` both
|
|
9
|
+
* ask for it.
|
|
10
|
+
*
|
|
11
|
+
* Pure string work: the page reads these addresses, and the tool server
|
|
12
|
+
* writes them, in Node.
|
|
13
|
+
*/
|
|
14
|
+
/** The parameter asking for the answer's card instead of the page. */
|
|
15
|
+
export declare const CARD_PARAM = "card";
|
|
16
|
+
/**
|
|
17
|
+
* Whether an address asks for a card.
|
|
18
|
+
* @param search - The query string, with or without its leading `?`.
|
|
19
|
+
* @returns True when it names `card`, with a value or bare.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isCardAddress(search: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* The address a card is at: `globalThis.location`, a `URL`, or any record of
|
|
24
|
+
* the three parts.
|
|
25
|
+
*/
|
|
26
|
+
export interface CardLocation {
|
|
27
|
+
/** Its origin, e.g. `https://equilibrium.cheminfo.org`. */
|
|
28
|
+
readonly origin: string;
|
|
29
|
+
/** Its path, the mount and a language prefix included. */
|
|
30
|
+
readonly pathname: string;
|
|
31
|
+
/** Its query string, with or without its `?`. */
|
|
32
|
+
readonly search: string;
|
|
33
|
+
}
|
|
34
|
+
/** How {@link sitePageUrl} tells the card's parameters from the page's. */
|
|
35
|
+
export interface SitePageOptions {
|
|
36
|
+
/**
|
|
37
|
+
* The parameters only the site's card reads, beside `card` itself: what a
|
|
38
|
+
* card draws beyond the page, e.g. `['rows']`, `['scale', 'ph']`.
|
|
39
|
+
* @default []
|
|
40
|
+
*/
|
|
41
|
+
cardParams?: readonly string[];
|
|
42
|
+
/**
|
|
43
|
+
* Read a `+` in a key as a plus rather than as a space, as
|
|
44
|
+
* `parseQueryEntries` does. A key carries no `+` on any site of the family,
|
|
45
|
+
* so this only matters to a site that writes its own addresses with
|
|
46
|
+
* `URLSearchParams`.
|
|
47
|
+
* @default true
|
|
48
|
+
*/
|
|
49
|
+
literalPlus?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* A parameter the page at a given path does not read, though another page
|
|
52
|
+
* of the site does: a tutorial step reads no InChI, the converter does.
|
|
53
|
+
* @default undefined - nothing beyond `card`, `embed`, `hide` and
|
|
54
|
+
* `cardParams` is left out
|
|
55
|
+
*/
|
|
56
|
+
isCardOnly?: (key: string, pathname: string) => boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The site's own page a card stands for, with its chrome: the card's address
|
|
60
|
+
* without `card`, `embed`, `hide` and what only the card reads. Every other
|
|
61
|
+
* parameter is kept exactly as it was written, so the `+` of a charged atom
|
|
62
|
+
* stays a plus and the commas of a list stay commas. This is the address an
|
|
63
|
+
* answer's `link` names, and the one the card's Details button opens.
|
|
64
|
+
* @param location - The card's address: `globalThis.location`, or
|
|
65
|
+
* `new URL(href)` for an address held as text.
|
|
66
|
+
* @param options - What only the site's card reads.
|
|
67
|
+
* @returns The page's absolute address, without a fragment.
|
|
68
|
+
*/
|
|
69
|
+
export declare function sitePageUrl(location: CardLocation, options?: SitePageOptions): string;
|
|
70
|
+
//# sourceMappingURL=cardAddress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardAddress.d.ts","sourceRoot":"","sources":["../../../src/card/core/cardAddress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,sEAAsE;AACtE,eAAO,MAAM,UAAU,SAAS,CAAC;AAEjC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAKrD;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CACzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,YAAY,EACtB,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAeR"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The card of an answer, as its address says it.
|
|
3
|
+
*
|
|
4
|
+
* A chat shows a tool's answer twice: inline, as a card drawing only what the
|
|
5
|
+
* question asked, and over the full screen, as the site's page. The card is
|
|
6
|
+
* that page with `card` in its query, always with `embed`, so the card and
|
|
7
|
+
* the page behind it read the same parameters and can never disagree about
|
|
8
|
+
* what was asked. `card` is read by its presence: `?card` and `?card=1` both
|
|
9
|
+
* ask for it.
|
|
10
|
+
*
|
|
11
|
+
* Pure string work: the page reads these addresses, and the tool server
|
|
12
|
+
* writes them, in Node.
|
|
13
|
+
*/
|
|
14
|
+
import { parseQueryEntries } from "../../router/core/query.js";
|
|
15
|
+
import { EMBED_PARAM, HIDE_PARAM } from "../../share/core/config.js";
|
|
16
|
+
/** The parameter asking for the answer's card instead of the page. */
|
|
17
|
+
export const CARD_PARAM = 'card';
|
|
18
|
+
/**
|
|
19
|
+
* Whether an address asks for a card.
|
|
20
|
+
* @param search - The query string, with or without its leading `?`.
|
|
21
|
+
* @returns True when it names `card`, with a value or bare.
|
|
22
|
+
*/
|
|
23
|
+
export function isCardAddress(search) {
|
|
24
|
+
for (const [key] of parseQueryEntries(search)) {
|
|
25
|
+
if (key === CARD_PARAM)
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The site's own page a card stands for, with its chrome: the card's address
|
|
32
|
+
* without `card`, `embed`, `hide` and what only the card reads. Every other
|
|
33
|
+
* parameter is kept exactly as it was written, so the `+` of a charged atom
|
|
34
|
+
* stays a plus and the commas of a list stay commas. This is the address an
|
|
35
|
+
* answer's `link` names, and the one the card's Details button opens.
|
|
36
|
+
* @param location - The card's address: `globalThis.location`, or
|
|
37
|
+
* `new URL(href)` for an address held as text.
|
|
38
|
+
* @param options - What only the site's card reads.
|
|
39
|
+
* @returns The page's absolute address, without a fragment.
|
|
40
|
+
*/
|
|
41
|
+
export function sitePageUrl(location, options = {}) {
|
|
42
|
+
const { cardParams = [], literalPlus = true, isCardOnly } = options;
|
|
43
|
+
const dropped = new Set([CARD_PARAM, EMBED_PARAM, HIDE_PARAM, ...cardParams]);
|
|
44
|
+
const kept = [];
|
|
45
|
+
const search = location.search.startsWith('?')
|
|
46
|
+
? location.search.slice(1)
|
|
47
|
+
: location.search;
|
|
48
|
+
for (const part of search.split('&')) {
|
|
49
|
+
const [entry] = parseQueryEntries(part, { literalPlus });
|
|
50
|
+
if (entry === undefined || dropped.has(entry[0]))
|
|
51
|
+
continue;
|
|
52
|
+
if (isCardOnly?.(entry[0], location.pathname))
|
|
53
|
+
continue;
|
|
54
|
+
kept.push(part);
|
|
55
|
+
}
|
|
56
|
+
const query = kept.join('&');
|
|
57
|
+
return `${location.origin}${location.pathname}${query === '' ? '' : `?${query}`}`;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=cardAddress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardAddress.js","sourceRoot":"","sources":["../../../src/card/core/cardAddress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAErE,sEAAsE;AACtE,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC;AAEjC;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,IAAI,GAAG,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC;IACtC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAwCD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CACzB,QAAsB,EACtB,UAA2B,EAAE;IAE7B,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,WAAW,GAAG,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACpE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;QAC5C,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1B,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QACzD,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,SAAS;QAC3D,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC;YAAE,SAAS;QACxD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,QAAQ,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two addresses a chat frames for one answer: the card, inline, and the
|
|
3
|
+
* page itself, over the full screen. Both are the site's page under `embed`,
|
|
4
|
+
* so neither carries the site's chrome; the card adds `card` and what only it
|
|
5
|
+
* reads.
|
|
6
|
+
*/
|
|
7
|
+
/** How {@link framedPageUrl} frames a page. */
|
|
8
|
+
export interface FramedPageOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The parts of the page left out, on the card and on the full page alike:
|
|
11
|
+
* keys of the site's `hide` vocabulary, written `hide=a,b`.
|
|
12
|
+
* @default []
|
|
13
|
+
*/
|
|
14
|
+
hide?: readonly string[];
|
|
15
|
+
}
|
|
16
|
+
/** What {@link cardPageUrl} adds to the framed page. */
|
|
17
|
+
export interface CardPageOptions extends FramedPageOptions {
|
|
18
|
+
/**
|
|
19
|
+
* What `card` carries, for a site whose page draws more than one card:
|
|
20
|
+
* wikidata's `card=infobox`.
|
|
21
|
+
* @default '1'
|
|
22
|
+
*/
|
|
23
|
+
card?: string;
|
|
24
|
+
/**
|
|
25
|
+
* What only the card reads, written after `card` in the order given, e.g.
|
|
26
|
+
* `{ rows: '10' }`. A value left `undefined` or empty is not written.
|
|
27
|
+
* @default {}
|
|
28
|
+
*/
|
|
29
|
+
extra?: Readonly<Record<string, string | undefined>>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The page under `embed=1`, and `hide` when parts are left out: what a chat
|
|
33
|
+
* shows over the full screen when the reader asks for more than the card.
|
|
34
|
+
* @param page - The site's page as people open it, with its own query and
|
|
35
|
+
* without `embed`, `hide` or `card`; absolute, or a path.
|
|
36
|
+
* @param options - The parts left out.
|
|
37
|
+
* @returns The framed page's address.
|
|
38
|
+
*/
|
|
39
|
+
export declare function framedPageUrl(page: string, options?: FramedPageOptions): string;
|
|
40
|
+
/**
|
|
41
|
+
* The card of an answer: the framed page with `card`, and what only the card
|
|
42
|
+
* reads after it.
|
|
43
|
+
* @param page - The site's page as people open it, with its own query and
|
|
44
|
+
* without `embed`, `hide` or `card`; absolute, or a path.
|
|
45
|
+
* @param options - The parts left out, and what the card draws.
|
|
46
|
+
* @returns The card's address.
|
|
47
|
+
*/
|
|
48
|
+
export declare function cardPageUrl(page: string, options?: CardPageOptions): string;
|
|
49
|
+
//# sourceMappingURL=cardPageUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardPageUrl.d.ts","sourceRoot":"","sources":["../../../src/card/core/cardPageUrl.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,wDAAwD;AACxD,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CACtD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAKR;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAOR"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two addresses a chat frames for one answer: the card, inline, and the
|
|
3
|
+
* page itself, over the full screen. Both are the site's page under `embed`,
|
|
4
|
+
* so neither carries the site's chrome; the card adds `card` and what only it
|
|
5
|
+
* reads.
|
|
6
|
+
*/
|
|
7
|
+
import { formatQueryEntries } from "../../router/core/query.js";
|
|
8
|
+
import { EMBED_PARAM, HIDE_PARAM } from "../../share/core/config.js";
|
|
9
|
+
import { CARD_PARAM } from "./cardAddress.js";
|
|
10
|
+
/**
|
|
11
|
+
* The page under `embed=1`, and `hide` when parts are left out: what a chat
|
|
12
|
+
* shows over the full screen when the reader asks for more than the card.
|
|
13
|
+
* @param page - The site's page as people open it, with its own query and
|
|
14
|
+
* without `embed`, `hide` or `card`; absolute, or a path.
|
|
15
|
+
* @param options - The parts left out.
|
|
16
|
+
* @returns The framed page's address.
|
|
17
|
+
*/
|
|
18
|
+
export function framedPageUrl(page, options = {}) {
|
|
19
|
+
const { hide = [] } = options;
|
|
20
|
+
const entries = [[EMBED_PARAM, '1']];
|
|
21
|
+
if (hide.length > 0)
|
|
22
|
+
entries.push([HIDE_PARAM, hide.join(',')]);
|
|
23
|
+
return withQueryEntries(page, entries);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The card of an answer: the framed page with `card`, and what only the card
|
|
27
|
+
* reads after it.
|
|
28
|
+
* @param page - The site's page as people open it, with its own query and
|
|
29
|
+
* without `embed`, `hide` or `card`; absolute, or a path.
|
|
30
|
+
* @param options - The parts left out, and what the card draws.
|
|
31
|
+
* @returns The card's address.
|
|
32
|
+
*/
|
|
33
|
+
export function cardPageUrl(page, options = {}) {
|
|
34
|
+
const { card = '1', extra = {} } = options;
|
|
35
|
+
const entries = [[CARD_PARAM, card]];
|
|
36
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
37
|
+
if (value !== undefined && value !== '')
|
|
38
|
+
entries.push([key, value]);
|
|
39
|
+
}
|
|
40
|
+
return withQueryEntries(framedPageUrl(page, options), entries);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Append parameters to an address, before its fragment.
|
|
44
|
+
* @param address - The address, with or without a query.
|
|
45
|
+
* @param entries - The parameters, in the order they are written.
|
|
46
|
+
* @returns The address carrying them.
|
|
47
|
+
*/
|
|
48
|
+
function withQueryEntries(address, entries) {
|
|
49
|
+
const hashIndex = address.indexOf('#');
|
|
50
|
+
const head = hashIndex === -1 ? address : address.slice(0, hashIndex);
|
|
51
|
+
const fragment = hashIndex === -1 ? '' : address.slice(hashIndex);
|
|
52
|
+
const separator = head.includes('?')
|
|
53
|
+
? head.endsWith('?') || head.endsWith('&')
|
|
54
|
+
? ''
|
|
55
|
+
: '&'
|
|
56
|
+
: '?';
|
|
57
|
+
return `${head}${separator}${formatQueryEntries(entries)}${fragment}`;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=cardPageUrl.js.map
|