react-cheminfo 0.23.0 → 0.25.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 +39 -26
- package/lib/chrome/ui/HeaderToggle.d.ts +52 -0
- package/lib/chrome/ui/HeaderToggle.d.ts.map +1 -0
- package/lib/chrome/ui/HeaderToggle.js +31 -0
- package/lib/chrome/ui/HeaderToggle.js.map +1 -0
- package/lib/chrome/ui/index.d.ts +2 -0
- package/lib/chrome/ui/index.d.ts.map +1 -1
- package/lib/chrome/ui/index.js +1 -0
- package/lib/chrome/ui/index.js.map +1 -1
- package/lib/citation/core/gfn2Paper.d.ts +10 -0
- package/lib/citation/core/gfn2Paper.d.ts.map +1 -0
- package/lib/citation/core/gfn2Paper.js +28 -0
- package/lib/citation/core/gfn2Paper.js.map +1 -0
- package/lib/citation/core/index.d.ts +1 -0
- package/lib/citation/core/index.d.ts.map +1 -1
- package/lib/citation/core/index.js +1 -0
- package/lib/citation/core/index.js.map +1 -1
- package/lib/clipboard/ui/ClickToCopy.d.ts +8 -7
- package/lib/clipboard/ui/ClickToCopy.d.ts.map +1 -1
- package/lib/clipboard/ui/ClickToCopy.js +3 -3
- package/lib/clipboard/ui/ClickToCopy.js.map +1 -1
- package/lib/conformers.d.ts +27 -0
- package/lib/conformers.d.ts.map +1 -0
- package/lib/conformers.js +19 -0
- package/lib/conformers.js.map +1 -0
- package/lib/core.d.ts +1 -0
- package/lib/core.d.ts.map +1 -1
- package/lib/core.js +1 -0
- package/lib/core.js.map +1 -1
- package/lib/credits/core/credits.d.ts +12 -0
- package/lib/credits/core/credits.d.ts.map +1 -1
- package/lib/credits/core/credits.js +14 -0
- package/lib/credits/core/credits.js.map +1 -1
- package/lib/ecosystem/core/index.d.ts +1 -1
- package/lib/ecosystem/core/index.d.ts.map +1 -1
- package/lib/ecosystem/core/index.js.map +1 -1
- package/lib/ecosystem/core/sites.d.ts +11 -1
- package/lib/ecosystem/core/sites.d.ts.map +1 -1
- package/lib/ecosystem/core/sites.js +11 -4
- package/lib/ecosystem/core/sites.js.map +1 -1
- package/lib/ecosystem/ui/EcosystemLinks.d.ts.map +1 -1
- package/lib/ecosystem/ui/EcosystemLinks.js +3 -1
- package/lib/ecosystem/ui/EcosystemLinks.js.map +1 -1
- package/lib/ecosystem/ui/SiteTile.d.ts.map +1 -1
- package/lib/ecosystem/ui/SiteTile.js +3 -1
- package/lib/ecosystem/ui/SiteTile.js.map +1 -1
- package/lib/ecosystem/ui/glyphs.d.ts.map +1 -1
- package/lib/ecosystem/ui/glyphs.js +6 -5
- package/lib/ecosystem/ui/glyphs.js.map +1 -1
- package/lib/format/core/index.d.ts +1 -1
- package/lib/format/core/index.d.ts.map +1 -1
- package/lib/format/core/index.js +1 -1
- package/lib/format/core/index.js.map +1 -1
- package/lib/format/core/words.d.ts +9 -0
- package/lib/format/core/words.d.ts.map +1 -1
- package/lib/format/core/words.js +16 -0
- package/lib/format/core/words.js.map +1 -1
- package/lib/language/core/index.d.ts +3 -0
- package/lib/language/core/index.d.ts.map +1 -0
- package/lib/language/core/index.js +3 -0
- package/lib/language/core/index.js.map +1 -0
- package/lib/language/core/languageName.d.ts +8 -0
- package/lib/language/core/languageName.d.ts.map +1 -0
- package/lib/language/core/languageName.js +16 -0
- package/lib/language/core/languageName.js.map +1 -0
- package/lib/language/core/languageParam.d.ts +35 -0
- package/lib/language/core/languageParam.d.ts.map +1 -0
- package/lib/language/core/languageParam.js +67 -0
- package/lib/language/core/languageParam.js.map +1 -0
- package/lib/language/ui/SiteLanguage.d.ts +20 -0
- package/lib/language/ui/SiteLanguage.d.ts.map +1 -0
- package/lib/language/ui/SiteLanguage.js +14 -0
- package/lib/language/ui/SiteLanguage.js.map +1 -0
- package/lib/language/ui/index.d.ts +4 -0
- package/lib/language/ui/index.d.ts.map +1 -0
- package/lib/language/ui/index.js +3 -0
- package/lib/language/ui/index.js.map +1 -0
- package/lib/language/ui/siteLanguageContext.d.ts +12 -0
- package/lib/language/ui/siteLanguageContext.d.ts.map +1 -0
- package/lib/language/ui/siteLanguageContext.js +19 -0
- package/lib/language/ui/siteLanguageContext.js.map +1 -0
- package/lib/orbital/core/atomicOrbitals.d.ts +9 -1
- package/lib/orbital/core/atomicOrbitals.d.ts.map +1 -1
- package/lib/orbital/core/atomicOrbitals.js +7 -0
- package/lib/orbital/core/atomicOrbitals.js.map +1 -1
- package/lib/orbital/core/hydrogenic.d.ts +2 -1
- package/lib/orbital/core/hydrogenic.d.ts.map +1 -1
- package/lib/orbital/core/hydrogenic.js +2 -1
- package/lib/orbital/core/hydrogenic.js.map +1 -1
- package/lib/orbital/core/index.d.ts +1 -0
- package/lib/orbital/core/index.d.ts.map +1 -1
- package/lib/orbital/core/index.js +1 -0
- package/lib/orbital/core/index.js.map +1 -1
- package/lib/orbital/core/slaterEnergy.d.ts +35 -0
- package/lib/orbital/core/slaterEnergy.d.ts.map +1 -0
- package/lib/orbital/core/slaterEnergy.js +66 -0
- package/lib/orbital/core/slaterEnergy.js.map +1 -0
- package/lib/shared/ui/MenuButton.d.ts +3 -2
- package/lib/shared/ui/MenuButton.d.ts.map +1 -1
- package/lib/shared/ui/MenuButton.js +1 -1
- package/lib/shared/ui/MenuButton.js.map +1 -1
- package/lib/structure/core/conformerMinimise.d.ts +36 -0
- package/lib/structure/core/conformerMinimise.d.ts.map +1 -0
- package/lib/structure/core/conformerMinimise.js +81 -0
- package/lib/structure/core/conformerMinimise.js.map +1 -0
- package/lib/structure/core/conformerMinimum.d.ts +62 -0
- package/lib/structure/core/conformerMinimum.d.ts.map +1 -0
- package/lib/structure/core/conformerMinimum.js +90 -0
- package/lib/structure/core/conformerMinimum.js.map +1 -0
- package/lib/structure/core/conformerOptions.d.ts +62 -0
- package/lib/structure/core/conformerOptions.d.ts.map +1 -0
- package/lib/structure/core/conformerOptions.js +83 -0
- package/lib/structure/core/conformerOptions.js.map +1 -0
- package/lib/structure/core/conformerRefine.d.ts +104 -0
- package/lib/structure/core/conformerRefine.d.ts.map +1 -0
- package/lib/structure/core/conformerRefine.js +130 -0
- package/lib/structure/core/conformerRefine.js.map +1 -0
- package/lib/structure/core/conformerRefineRank.d.ts +36 -0
- package/lib/structure/core/conformerRefineRank.d.ts.map +1 -0
- package/lib/structure/core/conformerRefineRank.js +69 -0
- package/lib/structure/core/conformerRefineRank.js.map +1 -0
- package/lib/structure/core/conformerSession.d.ts +50 -0
- package/lib/structure/core/conformerSession.d.ts.map +1 -0
- package/lib/structure/core/conformerSession.js +88 -0
- package/lib/structure/core/conformerSession.js.map +1 -0
- package/lib/structure/core/conformerShape.d.ts +36 -0
- package/lib/structure/core/conformerShape.d.ts.map +1 -0
- package/lib/structure/core/conformerShape.js +150 -0
- package/lib/structure/core/conformerShape.js.map +1 -0
- package/lib/structure/core/conformers.d.ts +107 -0
- package/lib/structure/core/conformers.d.ts.map +1 -0
- package/lib/structure/core/conformers.js +149 -0
- package/lib/structure/core/conformers.js.map +1 -0
- package/lib/structure/core/geometryRelaxer.d.ts +66 -0
- package/lib/structure/core/geometryRelaxer.d.ts.map +1 -0
- package/lib/structure/core/geometryRelaxer.js +2 -0
- package/lib/structure/core/geometryRelaxer.js.map +1 -0
- package/lib/structure/core/index.d.ts +4 -0
- package/lib/structure/core/index.d.ts.map +1 -1
- package/lib/structure/core/index.js +2 -0
- package/lib/structure/core/index.js.map +1 -1
- package/lib/structure/core/moleculeCoordinates.d.ts +31 -0
- package/lib/structure/core/moleculeCoordinates.d.ts.map +1 -0
- package/lib/structure/core/moleculeCoordinates.js +80 -0
- package/lib/structure/core/moleculeCoordinates.js.map +1 -0
- package/lib/structure/core/molfileExport.d.ts +42 -0
- package/lib/structure/core/molfileExport.d.ts.map +1 -0
- package/lib/structure/core/molfileExport.js +47 -0
- package/lib/structure/core/molfileExport.js.map +1 -0
- package/lib/structure/core/oclResources.d.ts +12 -0
- package/lib/structure/core/oclResources.d.ts.map +1 -0
- package/lib/structure/core/oclResources.js +35 -0
- package/lib/structure/core/oclResources.js.map +1 -0
- package/lib/translate/core/catalog.d.ts +61 -0
- package/lib/translate/core/catalog.d.ts.map +1 -0
- package/lib/translate/core/catalog.js +49 -0
- package/lib/translate/core/catalog.js.map +1 -0
- package/lib/translate/core/checkTranslation.d.ts +32 -0
- package/lib/translate/core/checkTranslation.d.ts.map +1 -0
- package/lib/translate/core/checkTranslation.js +98 -0
- package/lib/translate/core/checkTranslation.js.map +1 -0
- package/lib/translate/core/contribution.d.ts +88 -0
- package/lib/translate/core/contribution.d.ts.map +1 -0
- package/lib/translate/core/contribution.js +14 -0
- package/lib/translate/core/contribution.js.map +1 -0
- package/lib/translate/core/index.d.ts +19 -0
- package/lib/translate/core/index.d.ts.map +1 -0
- package/lib/translate/core/index.js +15 -0
- package/lib/translate/core/index.js.map +1 -0
- package/lib/translate/core/marker.d.ts +45 -0
- package/lib/translate/core/marker.d.ts.map +1 -0
- package/lib/translate/core/marker.js +79 -0
- package/lib/translate/core/marker.js.map +1 -0
- package/lib/translate/core/mergeMessages.d.ts +35 -0
- package/lib/translate/core/mergeMessages.d.ts.map +1 -0
- package/lib/translate/core/mergeMessages.js +69 -0
- package/lib/translate/core/mergeMessages.js.map +1 -0
- package/lib/translate/core/session.d.ts +102 -0
- package/lib/translate/core/session.d.ts.map +1 -0
- package/lib/translate/core/session.js +162 -0
- package/lib/translate/core/session.js.map +1 -0
- package/lib/translate/core/start.d.ts +103 -0
- package/lib/translate/core/start.d.ts.map +1 -0
- package/lib/translate/core/start.js +92 -0
- package/lib/translate/core/start.js.map +1 -0
- package/lib/translate/core/suggestions.d.ts +77 -0
- package/lib/translate/core/suggestions.d.ts.map +1 -0
- package/lib/translate/core/suggestions.js +143 -0
- package/lib/translate/core/suggestions.js.map +1 -0
- package/lib/translate/core/tables.d.ts +100 -0
- package/lib/translate/core/tables.d.ts.map +1 -0
- package/lib/translate/core/tables.js +51 -0
- package/lib/translate/core/tables.js.map +1 -0
- package/lib/translate.d.ts +2 -0
- package/lib/translate.d.ts.map +1 -0
- package/lib/translate.js +6 -0
- package/lib/translate.js.map +1 -0
- package/lib/ui.d.ts +1 -0
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +1 -0
- package/lib/ui.js.map +1 -1
- package/lib/xtb/core/xtbRelaxer.d.ts +61 -0
- package/lib/xtb/core/xtbRelaxer.d.ts.map +1 -0
- package/lib/xtb/core/xtbRelaxer.js +108 -0
- package/lib/xtb/core/xtbRelaxer.js.map +1 -0
- package/lib/xtb.d.ts +11 -0
- package/lib/xtb.d.ts.map +1 -0
- package/lib/xtb.js +10 -0
- package/lib/xtb.js.map +1 -0
- package/package.json +18 -11
- package/src/chrome/ui/HeaderToggle.tsx +100 -0
- package/src/chrome/ui/index.ts +2 -0
- package/src/citation/core/gfn2Paper.ts +32 -0
- package/src/citation/core/index.ts +1 -0
- package/src/clipboard/ui/ClickToCopy.tsx +8 -7
- package/src/conformers.ts +87 -0
- package/src/core.ts +1 -0
- package/src/credits/core/credits.ts +16 -0
- package/src/ecosystem/core/index.ts +1 -0
- package/src/ecosystem/core/sites.ts +24 -4
- package/src/ecosystem/ui/EcosystemLinks.tsx +3 -1
- package/src/ecosystem/ui/SiteTile.tsx +3 -1
- package/src/ecosystem/ui/glyphs.tsx +16 -22
- package/src/format/core/index.ts +1 -1
- package/src/format/core/words.ts +19 -0
- package/src/language/core/index.ts +7 -0
- package/src/language/core/languageName.ts +16 -0
- package/src/language/core/languageParam.ts +70 -0
- package/src/language/ui/SiteLanguage.tsx +26 -0
- package/src/language/ui/index.ts +3 -0
- package/src/language/ui/siteLanguageContext.ts +20 -0
- package/src/orbital/core/atomicOrbitals.ts +17 -1
- package/src/orbital/core/hydrogenic.ts +2 -1
- package/src/orbital/core/index.ts +1 -0
- package/src/orbital/core/slaterEnergy.ts +83 -0
- package/src/shared/ui/MenuButton.tsx +4 -3
- package/src/structure/core/conformerMinimise.ts +99 -0
- package/src/structure/core/conformerMinimum.ts +125 -0
- package/src/structure/core/conformerOptions.ts +125 -0
- package/src/structure/core/conformerRefine.ts +234 -0
- package/src/structure/core/conformerRefineRank.ts +89 -0
- package/src/structure/core/conformerSession.ts +123 -0
- package/src/structure/core/conformerShape.ts +181 -0
- package/src/structure/core/conformers.ts +282 -0
- package/src/structure/core/geometryRelaxer.ts +71 -0
- package/src/structure/core/index.ts +13 -0
- package/src/structure/core/moleculeCoordinates.ts +93 -0
- package/src/structure/core/molfileExport.ts +62 -0
- package/src/structure/core/oclResources.ts +41 -0
- package/src/translate/core/catalog.ts +83 -0
- package/src/translate/core/checkTranslation.ts +128 -0
- package/src/translate/core/contribution.ts +99 -0
- package/src/translate/core/index.ts +72 -0
- package/src/translate/core/marker.ts +85 -0
- package/src/translate/core/mergeMessages.ts +74 -0
- package/src/translate/core/session.ts +250 -0
- package/src/translate/core/start.ts +183 -0
- package/src/translate/core/suggestions.ts +211 -0
- package/src/translate/core/tables.ts +120 -0
- package/src/translate.ts +5 -0
- package/src/ui.ts +1 -0
- package/src/xtb/core/xtbRelaxer.ts +160 -0
- package/src/xtb.ts +16 -0
- package/styles/chrome.css +61 -30
|
@@ -12,6 +12,7 @@ export {
|
|
|
12
12
|
citationFilename,
|
|
13
13
|
formatCitation,
|
|
14
14
|
} from './formats.ts';
|
|
15
|
+
export { GFN2_XTB_PAPER, GFN2_XTB_WORK } from './gfn2Paper.ts';
|
|
15
16
|
export { OPENCHEMLIB_PAPER, OPENCHEMLIB_WORK } from './openchemlibPaper.ts';
|
|
16
17
|
export { PLATFORM_PAPER, PLATFORM_WORK } from './platformPaper.ts';
|
|
17
18
|
export type { Reference, ReferenceAuthor } from './reference.ts';
|
|
@@ -24,7 +24,7 @@ export interface ClickToCopyProps {
|
|
|
24
24
|
* function is called only when the value is clicked.
|
|
25
25
|
*/
|
|
26
26
|
value: ClipboardContent | (() => ClipboardContent);
|
|
27
|
-
/** What is shown; the pointer turns into
|
|
27
|
+
/** What is shown; the pointer turns into a clipboard over it. */
|
|
28
28
|
children: ReactNode;
|
|
29
29
|
/**
|
|
30
30
|
* What the value is, named in the hover title: `Copy the SMILES (C=CC=O)`.
|
|
@@ -46,9 +46,10 @@ export interface ClickToCopyProps {
|
|
|
46
46
|
*/
|
|
47
47
|
as?: ClickToCopyElement;
|
|
48
48
|
/**
|
|
49
|
-
* Whether the value is a tab stop and a button of its own, with
|
|
50
|
-
* Off when a copy button beside it
|
|
51
|
-
*
|
|
49
|
+
* Whether the value is a tab stop and a button of its own, with the glyph a
|
|
50
|
+
* keyboard is shown instead of the cursor. Off when a copy button beside it
|
|
51
|
+
* already copies the same value, so the keyboard and a screen reader meet
|
|
52
|
+
* one control.
|
|
52
53
|
* @default true
|
|
53
54
|
*/
|
|
54
55
|
focusable?: boolean;
|
|
@@ -83,9 +84,9 @@ const NESTED_CONTROL =
|
|
|
83
84
|
* A value that is copied by clicking it.
|
|
84
85
|
*
|
|
85
86
|
* Text in a tool is not selectable — a drag across a viewer must not paint the
|
|
86
|
-
* page — so what is worth taking away is copied this way instead:
|
|
87
|
-
*
|
|
88
|
-
*
|
|
87
|
+
* page — so what is worth taking away is copied this way instead: a cursor
|
|
88
|
+
* carrying a clipboard and a tint announce it on hover, a click or `Enter` puts
|
|
89
|
+
* it on the clipboard, and a tick confirms it. The click stops there, so
|
|
89
90
|
* a value inside a clickable row copies without also opening the row, and a
|
|
90
91
|
* link or a button nested in the value keeps its own click.
|
|
91
92
|
* @param props - See {@link ClickToCopyProps}.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conformers of a structure: generated, MMFF94-ranked, duplicate minima
|
|
3
|
+
* dropped, and refined against a `GeometryRelaxer`.
|
|
4
|
+
*
|
|
5
|
+
* Its own door because every step runs openchemlib, and `react-cheminfo/core`
|
|
6
|
+
* costs nothing on import. The relaxer contract itself, and the coordinates a
|
|
7
|
+
* relaxer reads and writes, stay in `react-cheminfo/core`: the code that
|
|
8
|
+
* orchestrates a refinement needs neither openchemlib nor WebAssembly.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type {
|
|
12
|
+
Conformer,
|
|
13
|
+
ConformerLimits,
|
|
14
|
+
ConformerRanking,
|
|
15
|
+
ConformerSet,
|
|
16
|
+
StopReason,
|
|
17
|
+
} from './structure/core/conformers.ts';
|
|
18
|
+
export {
|
|
19
|
+
continueConformers,
|
|
20
|
+
generateConformers,
|
|
21
|
+
strategyConstant,
|
|
22
|
+
} from './structure/core/conformers.ts';
|
|
23
|
+
export type {
|
|
24
|
+
ConformerRefinement,
|
|
25
|
+
ConformerSetRefinement,
|
|
26
|
+
RefineConformersOptions,
|
|
27
|
+
} from './structure/core/conformerRefine.ts';
|
|
28
|
+
export {
|
|
29
|
+
REFINED_RANKING,
|
|
30
|
+
REFINED_SAME_ENERGY_TOLERANCE,
|
|
31
|
+
refineConformers,
|
|
32
|
+
} from './structure/core/conformerRefine.ts';
|
|
33
|
+
export type {
|
|
34
|
+
RefinedMinimum,
|
|
35
|
+
RefinedRanking,
|
|
36
|
+
} from './structure/core/conformerRefineRank.ts';
|
|
37
|
+
export {
|
|
38
|
+
isRefinedDuplicate,
|
|
39
|
+
rankByRefinedEnergy,
|
|
40
|
+
} from './structure/core/conformerRefineRank.ts';
|
|
41
|
+
export type { RankedConformer } from './structure/core/conformerMinimise.ts';
|
|
42
|
+
export {
|
|
43
|
+
minimiseConformer,
|
|
44
|
+
rankByEnergy,
|
|
45
|
+
} from './structure/core/conformerMinimise.ts';
|
|
46
|
+
export type { KeptConformer } from './structure/core/conformerMinimum.ts';
|
|
47
|
+
export {
|
|
48
|
+
SAME_CHIRALITY_TOLERANCE,
|
|
49
|
+
SAME_ENERGY_TOLERANCE,
|
|
50
|
+
SAME_SHAPE_TOLERANCE,
|
|
51
|
+
isKeptMinimum,
|
|
52
|
+
isSameMinimum,
|
|
53
|
+
isSameShape,
|
|
54
|
+
minimisedShapes,
|
|
55
|
+
} from './structure/core/conformerMinimum.ts';
|
|
56
|
+
export type {
|
|
57
|
+
ConformerOptions,
|
|
58
|
+
ConformerStrategy,
|
|
59
|
+
MinimisationAlgorithm,
|
|
60
|
+
} from './structure/core/conformerOptions.ts';
|
|
61
|
+
export {
|
|
62
|
+
CONFORMER_STRATEGIES,
|
|
63
|
+
DEFAULT_CONFORMER_OPTIONS,
|
|
64
|
+
MINIMISATION_ALGORITHMS,
|
|
65
|
+
MINIMISATION_LABELS,
|
|
66
|
+
ROTATABLE_BOND_WARNING,
|
|
67
|
+
STRATEGY_DETAILS,
|
|
68
|
+
STRATEGY_LABELS,
|
|
69
|
+
isConformerStrategy,
|
|
70
|
+
isMinimisationAlgorithm,
|
|
71
|
+
sameConformerOptions,
|
|
72
|
+
} from './structure/core/conformerOptions.ts';
|
|
73
|
+
export type { ConformerSession } from './structure/core/conformerSession.ts';
|
|
74
|
+
export {
|
|
75
|
+
keepConformerSession,
|
|
76
|
+
openConformerSession,
|
|
77
|
+
readPotentialCount,
|
|
78
|
+
} from './structure/core/conformerSession.ts';
|
|
79
|
+
export type {
|
|
80
|
+
ConformerShape,
|
|
81
|
+
PrincipalMoments,
|
|
82
|
+
} from './structure/core/conformerShape.ts';
|
|
83
|
+
export {
|
|
84
|
+
conformerShape,
|
|
85
|
+
hasFiniteCoordinates,
|
|
86
|
+
} from './structure/core/conformerShape.ts';
|
|
87
|
+
export { registerResources } from './structure/core/oclResources.ts';
|
package/src/core.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from './download/core/index.ts';
|
|
|
10
10
|
export * from './ecosystem/core/index.ts';
|
|
11
11
|
export * from './error/core/index.ts';
|
|
12
12
|
export * from './format/core/index.ts';
|
|
13
|
+
export * from './language/core/index.ts';
|
|
13
14
|
export * from './orbital/core/index.ts';
|
|
14
15
|
export * from './overlay/core/index.ts';
|
|
15
16
|
export * from './parallel/core/index.ts';
|
|
@@ -143,6 +143,22 @@ export const CREDITS = [
|
|
|
143
143
|
description: 'the array and spectrum operations the data goes through.',
|
|
144
144
|
license: 'MIT',
|
|
145
145
|
},
|
|
146
|
+
{
|
|
147
|
+
id: 'occ',
|
|
148
|
+
name: 'OCC',
|
|
149
|
+
href: 'https://github.com/peterspackman/occ',
|
|
150
|
+
description:
|
|
151
|
+
'the GFN2-xTB implementation the refined geometries and energies come from.',
|
|
152
|
+
license: 'GPL-3.0',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: 'xtb-wasm',
|
|
156
|
+
name: 'xtb-wasm',
|
|
157
|
+
href: 'https://github.com/cheminfo/xtb-wasm',
|
|
158
|
+
description:
|
|
159
|
+
'GFN2-xTB compiled to WebAssembly, driven from a pool of web workers.',
|
|
160
|
+
license: 'MIT',
|
|
161
|
+
},
|
|
146
162
|
{
|
|
147
163
|
id: 'molstar',
|
|
148
164
|
name: 'Mol*',
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// tokens-ok: file — every site's two colours are declared here.
|
|
2
|
+
import { withLanguageParam } from '../../language/core/languageParam.ts';
|
|
3
|
+
|
|
2
4
|
import type { EcosystemSite, SiteRecord } from './types.ts';
|
|
3
5
|
|
|
4
6
|
export type {
|
|
@@ -118,8 +120,10 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
|
|
|
118
120
|
tagline: 'Turn a batch of NMR spectra into a map of your samples.',
|
|
119
121
|
group: 'spectra',
|
|
120
122
|
brand: '#4d7c0f',
|
|
121
|
-
|
|
122
|
-
|
|
123
|
+
// A yellow, because it is what stays apart from both this green and the
|
|
124
|
+
// white for a red–green colour-blind visitor; any red merges with the plate.
|
|
125
|
+
brandAlt: '#a16207',
|
|
126
|
+
mark: { plate: '#4d7c0f', accent: '#fde047' },
|
|
123
127
|
},
|
|
124
128
|
{
|
|
125
129
|
id: 'derepflow',
|
|
@@ -294,6 +298,7 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
|
|
|
294
298
|
name: { lead: 'atoms', alt: 'cheminfo', dot: true },
|
|
295
299
|
host: 'atoms.cheminfo.org',
|
|
296
300
|
repository: 'https://github.com/cheminfo/atoms.cheminfo.org',
|
|
301
|
+
publicRepository: true,
|
|
297
302
|
tagline: 'Electrons, neutrons, Lewis structures and oxidation states.',
|
|
298
303
|
group: 'practice',
|
|
299
304
|
brand: '#b91c1c',
|
|
@@ -307,6 +312,7 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
|
|
|
307
312
|
name: { lead: 'moles', alt: 'cheminfo', dot: true },
|
|
308
313
|
host: 'moles.cheminfo.org',
|
|
309
314
|
repository: 'https://github.com/cheminfo/moles.cheminfo.org',
|
|
315
|
+
publicRepository: true,
|
|
310
316
|
tagline: 'Balance a reaction, and work out its mass composition.',
|
|
311
317
|
group: 'practice',
|
|
312
318
|
brand: '#334155',
|
|
@@ -330,11 +336,25 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
|
|
|
330
336
|
},
|
|
331
337
|
];
|
|
332
338
|
|
|
339
|
+
/** How a link to a site is written, beyond the site itself. */
|
|
340
|
+
export interface SiteUrlOptions {
|
|
341
|
+
/**
|
|
342
|
+
* The language the visitor is reading in, carried so the site opens in it
|
|
343
|
+
* rather than in the one it defaults to.
|
|
344
|
+
* @default undefined — the link names no language
|
|
345
|
+
*/
|
|
346
|
+
language?: string;
|
|
347
|
+
}
|
|
348
|
+
|
|
333
349
|
/**
|
|
334
350
|
* The address of a site, which is its host over https.
|
|
335
351
|
* @param site - The site being linked to.
|
|
352
|
+
* @param options - See {@link SiteUrlOptions}.
|
|
336
353
|
* @returns The URL to open.
|
|
337
354
|
*/
|
|
338
|
-
export function siteUrl(
|
|
339
|
-
|
|
355
|
+
export function siteUrl(
|
|
356
|
+
site: SiteRecord,
|
|
357
|
+
options: SiteUrlOptions = {},
|
|
358
|
+
): string {
|
|
359
|
+
return withLanguageParam(`https://${site.host}/`, options.language);
|
|
340
360
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, ReactElement } from 'react';
|
|
2
2
|
|
|
3
|
+
import { useSiteLanguage } from '../../language/ui/siteLanguageContext.ts';
|
|
3
4
|
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
4
5
|
import { TOKEN } from '../../tokens/core/familyTokens.ts';
|
|
5
6
|
import { groupedSites } from '../core/lookup.ts';
|
|
@@ -87,6 +88,7 @@ export interface EcosystemLinksProps {
|
|
|
87
88
|
* @returns The section of links.
|
|
88
89
|
*/
|
|
89
90
|
export function EcosystemLinks(props: EcosystemLinksProps): ReactElement {
|
|
91
|
+
const language = useSiteLanguage();
|
|
90
92
|
const {
|
|
91
93
|
className,
|
|
92
94
|
currentSiteId,
|
|
@@ -117,7 +119,7 @@ export function EcosystemLinks(props: EcosystemLinksProps): ReactElement {
|
|
|
117
119
|
<a
|
|
118
120
|
key={site.id}
|
|
119
121
|
style={{ ...LINK_STYLE, color: site.brand }}
|
|
120
|
-
href={siteUrl(site)}
|
|
122
|
+
href={siteUrl(site, { language })}
|
|
121
123
|
>
|
|
122
124
|
{site.host}
|
|
123
125
|
</a>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, ReactElement } from 'react';
|
|
2
2
|
|
|
3
|
+
import { useSiteLanguage } from '../../language/ui/siteLanguageContext.ts';
|
|
3
4
|
import { TOKEN } from '../../tokens/core/familyTokens.ts';
|
|
4
5
|
import { siteNameColors } from '../core/nameColors.ts';
|
|
5
6
|
import type { EcosystemSite, SiteId } from '../core/sites.ts';
|
|
@@ -85,6 +86,7 @@ export interface SiteTileProps {
|
|
|
85
86
|
* @returns The tile.
|
|
86
87
|
*/
|
|
87
88
|
export function SiteTile(props: SiteTileProps): ReactElement {
|
|
89
|
+
const language = useSiteLanguage();
|
|
88
90
|
const {
|
|
89
91
|
className,
|
|
90
92
|
site,
|
|
@@ -140,7 +142,7 @@ export function SiteTile(props: SiteTileProps): ReactElement {
|
|
|
140
142
|
<a
|
|
141
143
|
className={className}
|
|
142
144
|
style={style}
|
|
143
|
-
href={siteUrl(site)}
|
|
145
|
+
href={siteUrl(site, { language })}
|
|
144
146
|
target={newTab ? '_blank' : undefined}
|
|
145
147
|
rel={newTab ? 'noreferrer' : undefined}
|
|
146
148
|
onMouseEnter={() => onHover?.(site.id)}
|
|
@@ -179,30 +179,24 @@ export const GLYPHS: Record<SiteId, (alt: string) => ReactNode> = {
|
|
|
179
179
|
/>
|
|
180
180
|
</g>
|
|
181
181
|
),
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
//
|
|
182
|
+
// A score plot without its axes: four samples, and the three the analysis
|
|
183
|
+
// sets apart carrying the answering colour — the map the tool exists to
|
|
184
|
+
// draw. The spacing is irregular so the groups read as measured samples
|
|
185
|
+
// rather than as a pattern, and the two groups sit six units apart, against
|
|
186
|
+
// under one inside either.
|
|
186
187
|
metabo: (accent) => (
|
|
187
188
|
<>
|
|
188
|
-
<
|
|
189
|
-
cx="
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
cx="20.5"
|
|
200
|
-
cy="20"
|
|
201
|
-
rx="5.4"
|
|
202
|
-
ry="8.6"
|
|
203
|
-
fill={accent}
|
|
204
|
-
transform="rotate(32 20.5 20)"
|
|
205
|
-
/>
|
|
189
|
+
<g fill="#ffffff">
|
|
190
|
+
<circle cx="6.6" cy="20.4" r="2.6" />
|
|
191
|
+
<circle cx="12.4" cy="18.3" r="2.6" />
|
|
192
|
+
<circle cx="9.3" cy="25.8" r="2.6" />
|
|
193
|
+
<circle cx="14.9" cy="24.1" r="2.6" />
|
|
194
|
+
</g>
|
|
195
|
+
<g fill={accent}>
|
|
196
|
+
<circle cx="20.1" cy="7.2" r="2.6" />
|
|
197
|
+
<circle cx="25.8" cy="8.6" r="2.6" />
|
|
198
|
+
<circle cx="22.2" cy="13.2" r="2.6" />
|
|
199
|
+
</g>
|
|
206
200
|
</>
|
|
207
201
|
),
|
|
208
202
|
// One formula branching into every structure it can be.
|
package/src/format/core/index.ts
CHANGED
|
@@ -14,4 +14,4 @@ export { roundTo } from './roundTo.ts';
|
|
|
14
14
|
export { formatSuperscript } from './superscript.ts';
|
|
15
15
|
export type { DurationStyle, FormatDurationOptions } from './units.ts';
|
|
16
16
|
export { formatBytes, formatDuration } from './units.ts';
|
|
17
|
-
export { pluralize } from './words.ts';
|
|
17
|
+
export { ordinal, pluralize } from './words.ts';
|
package/src/format/core/words.ts
CHANGED
|
@@ -15,3 +15,22 @@ export function pluralize(
|
|
|
15
15
|
): string {
|
|
16
16
|
return count === 1 ? singular : plural;
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* English ordinal of a position.
|
|
21
|
+
*
|
|
22
|
+
* Only the ordinal comes back, never the noun it counts, so the caller writes
|
|
23
|
+
* the sentence: `the ${ordinal(n)} conformer produced`.
|
|
24
|
+
* @param position - 1-based position.
|
|
25
|
+
* @returns E.g. `1st`, `2nd`, `12th`, `23rd`.
|
|
26
|
+
*/
|
|
27
|
+
export function ordinal(position: number): string {
|
|
28
|
+
const teens = position % 100;
|
|
29
|
+
const suffix =
|
|
30
|
+
teens >= 11 && teens <= 13
|
|
31
|
+
? 'th'
|
|
32
|
+
: (ORDINAL_SUFFIXES[position % 10] ?? 'th');
|
|
33
|
+
return `${position}${suffix}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const ORDINAL_SUFFIXES: Record<number, string> = { 1: 'st', 2: 'nd', 3: 'rd' };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The name of a language, e.g. `French` for `fr`.
|
|
3
|
+
* @param locale - The locale to name.
|
|
4
|
+
* @param displayLocale - The language the name is written in.
|
|
5
|
+
* @returns The name, or the tag itself when the runtime cannot name it.
|
|
6
|
+
*/
|
|
7
|
+
export function languageName(locale: string, displayLocale = 'en'): string {
|
|
8
|
+
try {
|
|
9
|
+
return (
|
|
10
|
+
new Intl.DisplayNames([displayLocale], { type: 'language' }).of(locale) ??
|
|
11
|
+
locale
|
|
12
|
+
);
|
|
13
|
+
} catch {
|
|
14
|
+
return locale;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The language a page is read in, as the family carries it between its sites.
|
|
3
|
+
*
|
|
4
|
+
* A link from one site to another keeps the language the visitor is reading
|
|
5
|
+
* in: the tag travels as a query parameter rather than as the path prefix a
|
|
6
|
+
* translated site routes by, because the site being linked to may not speak
|
|
7
|
+
* that language at all. A parameter it does not know is ignored; a `/fr/`
|
|
8
|
+
* path it does not have is a 404.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { parseQueryString } from '../../router/core/query.ts';
|
|
12
|
+
|
|
13
|
+
/** Query parameter every site of the family carries its language in. */
|
|
14
|
+
export const LANGUAGE_PARAM = 'lang';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Whether a string is a language a link may name: a BCP 47 tag already
|
|
18
|
+
* written in its canonical form, e.g. `fr`, `pt-BR`, `zh-Hant`.
|
|
19
|
+
* @param value - The candidate tag.
|
|
20
|
+
* @returns True when the tag is valid and canonical.
|
|
21
|
+
*/
|
|
22
|
+
export function isLanguageTag(value: string): boolean {
|
|
23
|
+
if (value.length === 0 || value.length > 35) return false;
|
|
24
|
+
try {
|
|
25
|
+
return Intl.getCanonicalLocales(value)[0] === value;
|
|
26
|
+
} catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The language an address names.
|
|
33
|
+
* @param search - The query string, with or without its leading `?`.
|
|
34
|
+
* @returns The tag, or `undefined` when the address names none or names
|
|
35
|
+
* something that is not a language.
|
|
36
|
+
*/
|
|
37
|
+
export function readLanguageParam(search: string): string | undefined {
|
|
38
|
+
const value = parseQueryString(search)[LANGUAGE_PARAM];
|
|
39
|
+
if (value === undefined || !isLanguageTag(value)) return undefined;
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* An address that names the language it should be read in.
|
|
45
|
+
* @param url - The address, absolute or relative.
|
|
46
|
+
* @param language - The tag to write, or `undefined` to leave the address
|
|
47
|
+
* alone — which is what a site passes while it is in the language every
|
|
48
|
+
* other site defaults to.
|
|
49
|
+
* @returns The address, with the language written into its query.
|
|
50
|
+
*/
|
|
51
|
+
export function withLanguageParam(
|
|
52
|
+
url: string,
|
|
53
|
+
language: string | undefined,
|
|
54
|
+
): string {
|
|
55
|
+
if (language === undefined || !isLanguageTag(language)) return url;
|
|
56
|
+
let address: URL;
|
|
57
|
+
try {
|
|
58
|
+
address = new URL(url, RELATIVE_BASE);
|
|
59
|
+
} catch {
|
|
60
|
+
return url;
|
|
61
|
+
}
|
|
62
|
+
address.searchParams.set(LANGUAGE_PARAM, language);
|
|
63
|
+
const written = address.toString();
|
|
64
|
+
return written.startsWith(RELATIVE_BASE)
|
|
65
|
+
? written.slice(RELATIVE_BASE.length)
|
|
66
|
+
: written;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Only ever used to resolve a relative address, and stripped again after.
|
|
70
|
+
const RELATIVE_BASE = 'https://relative.invalid';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
import { SiteLanguageContext } from './siteLanguageContext.ts';
|
|
4
|
+
|
|
5
|
+
/** Props of {@link SiteLanguage}. */
|
|
6
|
+
export interface SiteLanguageProps {
|
|
7
|
+
/**
|
|
8
|
+
* The language the page is being read in, or `undefined` while it is the
|
|
9
|
+
* one every site opens in — a link then names no language at all.
|
|
10
|
+
*/
|
|
11
|
+
value: string | undefined;
|
|
12
|
+
/** The page. */
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Tells every link to a sibling site which language the visitor is reading in,
|
|
18
|
+
* so moving between the tools of the family keeps the language rather than
|
|
19
|
+
* landing in English again.
|
|
20
|
+
* @param props - The language, and the page under it.
|
|
21
|
+
* @returns The page.
|
|
22
|
+
*/
|
|
23
|
+
export function SiteLanguage(props: SiteLanguageProps): ReactElement {
|
|
24
|
+
const { value, children } = props;
|
|
25
|
+
return <SiteLanguageContext value={value}>{children}</SiteLanguageContext>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createContext, use } from 'react';
|
|
2
|
+
|
|
3
|
+
import { readLanguageParam } from '../core/languageParam.ts';
|
|
4
|
+
|
|
5
|
+
/** What a site declares the page is being read in. */
|
|
6
|
+
export const SiteLanguageContext = createContext<string | undefined>(undefined);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The language a link out of this page should name.
|
|
10
|
+
*
|
|
11
|
+
* Under a `SiteLanguage` it is what the site declared. Without one it is
|
|
12
|
+
* whatever the address itself names, so a site that has not been told anything
|
|
13
|
+
* still passes on the language it was opened in.
|
|
14
|
+
* @returns The tag, or `undefined` when no language is to be carried.
|
|
15
|
+
*/
|
|
16
|
+
export function useSiteLanguage(): string | undefined {
|
|
17
|
+
const declared = use(SiteLanguageContext);
|
|
18
|
+
if (declared !== undefined) return declared;
|
|
19
|
+
return readLanguageParam(globalThis.location?.search ?? '');
|
|
20
|
+
}
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
import type { RealHarmonic } from './realHarmonics.ts';
|
|
30
30
|
import { harmonicsOf, subshellLetter } from './realHarmonics.ts';
|
|
31
31
|
import { slaterScreening } from './screening.ts';
|
|
32
|
+
import { slaterRemovalEnergy } from './slaterEnergy.ts';
|
|
32
33
|
|
|
33
34
|
/** One atomic orbital of one element: a shape, a size and an occupancy. */
|
|
34
35
|
export interface AtomicOrbital {
|
|
@@ -50,8 +51,16 @@ export interface AtomicOrbital {
|
|
|
50
51
|
effectiveCharge: number;
|
|
51
52
|
/** Shielding `S` those rules produced. */
|
|
52
53
|
shielding: number;
|
|
53
|
-
/** `−13.
|
|
54
|
+
/** `−13.606 Z_eff²/n²`, electronvolts: one rydberg times `Z_eff²/n²`. */
|
|
54
55
|
energy: number;
|
|
56
|
+
/**
|
|
57
|
+
* Energy to pull this electron off the atom, electronvolts: the difference
|
|
58
|
+
* of Slater total energies between the ion and the atom. `null` when the
|
|
59
|
+
* subshell is empty, there being no electron to remove. This, not
|
|
60
|
+
* {@link AtomicOrbital.energy}, is the number to compare with a measured
|
|
61
|
+
* ionisation energy — see `slaterEnergy.ts`.
|
|
62
|
+
*/
|
|
63
|
+
removalEnergy: number | null;
|
|
55
64
|
/** `n − ℓ − 1` spheres on which the wavefunction changes sign. */
|
|
56
65
|
radialNodes: number;
|
|
57
66
|
/** ℓ planes or cones on which it changes sign. */
|
|
@@ -120,6 +129,12 @@ export function atomicOrbitalsOf(
|
|
|
120
129
|
l: subshell.l,
|
|
121
130
|
charge,
|
|
122
131
|
};
|
|
132
|
+
// Once per subshell, not once per harmonic: the seven orbitals of an f
|
|
133
|
+
// subshell share one removal energy.
|
|
134
|
+
const removalEnergy =
|
|
135
|
+
subshellElectrons === 0
|
|
136
|
+
? null
|
|
137
|
+
: slaterRemovalEnergy(atomicNumber, configuration, subshell);
|
|
123
138
|
const harmonics = harmonicsOf(subshell.l);
|
|
124
139
|
const spread = hundDistribution(subshellElectrons, harmonics.length);
|
|
125
140
|
for (let index = 0; index < harmonics.length; index++) {
|
|
@@ -135,6 +150,7 @@ export function atomicOrbitalsOf(
|
|
|
135
150
|
effectiveCharge: charge,
|
|
136
151
|
shielding: screening.shielding,
|
|
137
152
|
energy: orbitalEnergy(parameters),
|
|
153
|
+
removalEnergy,
|
|
138
154
|
radialNodes: radialNodeCount(parameters),
|
|
139
155
|
angularNodes: subshell.l,
|
|
140
156
|
meanRadius: meanRadius(parameters),
|
|
@@ -57,7 +57,8 @@ export function meanRadius(parameters: HydrogenicParameters): number {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
|
-
* Orbital energy in the hydrogen-like model, `E = −13.
|
|
60
|
+
* Orbital energy in the hydrogen-like model, `E = −13.606 Z²/n²` eV — one
|
|
61
|
+
* rydberg times `Z²/n²`.
|
|
61
62
|
* @param parameters - Which orbital.
|
|
62
63
|
* @returns The energy in electronvolts, always negative.
|
|
63
64
|
*/
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What Slater's rules are actually good for: the energy it takes to pull one
|
|
3
|
+
* electron off the atom.
|
|
4
|
+
*
|
|
5
|
+
* The hydrogen-like orbital energy `−Ry Z_eff²/n²` is the model's own number
|
|
6
|
+
* and it orders the orbitals correctly, but it is not an ionisation energy and
|
|
7
|
+
* must never be read as one — it is 5.4× the measured value for neon, while
|
|
8
|
+
* being within 10% for lithium, so it is not even a constant factor off.
|
|
9
|
+
*
|
|
10
|
+
* Slater fitted his rules to *total* energies, and that is how they are used:
|
|
11
|
+
* add up `n Z_eff²/n²` over every electron of the atom, do the same for the ion
|
|
12
|
+
* with one electron gone — recomputing the shielding, which is the whole point,
|
|
13
|
+
* since the remaining electrons are screened by one fewer neighbour — and
|
|
14
|
+
* subtract. Over the first four periods that difference lands within a factor
|
|
15
|
+
* 0.74–1.81 of the measured first ionisation energy, against 0.9–5.4 for the
|
|
16
|
+
* orbital energy.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { RYDBERG_ELECTRONVOLTS } from './constants.ts';
|
|
20
|
+
import type { Subshell, SubshellOccupancy } from './electronConfiguration.ts';
|
|
21
|
+
import { slaterScreening } from './screening.ts';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Total electronic energy of a configuration in the Slater model.
|
|
25
|
+
* @param atomicNumber - Proton count, the `Z` each electron is screened from.
|
|
26
|
+
* @param configuration - Every occupied subshell.
|
|
27
|
+
* @returns The sum of `−Ry Z_eff²/n²` over every electron, electronvolts.
|
|
28
|
+
*/
|
|
29
|
+
export function slaterTotalEnergy(
|
|
30
|
+
atomicNumber: number,
|
|
31
|
+
configuration: readonly SubshellOccupancy[],
|
|
32
|
+
): number {
|
|
33
|
+
let energy = 0;
|
|
34
|
+
for (const occupied of configuration) {
|
|
35
|
+
const { effectiveCharge } = slaterScreening(
|
|
36
|
+
atomicNumber,
|
|
37
|
+
configuration,
|
|
38
|
+
occupied,
|
|
39
|
+
);
|
|
40
|
+
energy -=
|
|
41
|
+
(occupied.electrons *
|
|
42
|
+
RYDBERG_ELECTRONVOLTS *
|
|
43
|
+
effectiveCharge *
|
|
44
|
+
effectiveCharge) /
|
|
45
|
+
(occupied.n * occupied.n);
|
|
46
|
+
}
|
|
47
|
+
return energy;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Energy needed to take one electron out of a subshell and off the atom.
|
|
52
|
+
* @param atomicNumber - Proton count.
|
|
53
|
+
* @param configuration - Every occupied subshell of the neutral atom.
|
|
54
|
+
* @param subshell - The subshell the electron leaves.
|
|
55
|
+
* @returns `E(ion) − E(atom)`, electronvolts, positive for a bound electron.
|
|
56
|
+
* @throws {RangeError} When that subshell holds no electron to remove.
|
|
57
|
+
*/
|
|
58
|
+
export function slaterRemovalEnergy(
|
|
59
|
+
atomicNumber: number,
|
|
60
|
+
configuration: readonly SubshellOccupancy[],
|
|
61
|
+
subshell: Subshell,
|
|
62
|
+
): number {
|
|
63
|
+
const ion: SubshellOccupancy[] = [];
|
|
64
|
+
let found = false;
|
|
65
|
+
for (const occupied of configuration) {
|
|
66
|
+
if (occupied.n === subshell.n && occupied.l === subshell.l) {
|
|
67
|
+
found = true;
|
|
68
|
+
if (occupied.electrons === 1) continue;
|
|
69
|
+
ion.push({ ...occupied, electrons: occupied.electrons - 1 });
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
ion.push(occupied);
|
|
73
|
+
}
|
|
74
|
+
if (!found) {
|
|
75
|
+
throw new RangeError(
|
|
76
|
+
`the ${subshell.n}${'spdf'[subshell.l] ?? '?'} subshell holds no electron to remove`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
return (
|
|
80
|
+
slaterTotalEnergy(atomicNumber, ion) -
|
|
81
|
+
slaterTotalEnergy(atomicNumber, configuration)
|
|
82
|
+
);
|
|
83
|
+
}
|