react-cheminfo 0.2.0 → 0.3.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 +47 -6
- 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/ecosystem/core/sites.d.ts +1 -1
- package/lib/ecosystem/core/sites.d.ts.map +1 -1
- package/lib/ecosystem/core/sites.js +18 -0
- package/lib/ecosystem/core/sites.js.map +1 -1
- package/lib/ecosystem/ui/glyphs.d.ts +16 -0
- package/lib/ecosystem/ui/glyphs.d.ts.map +1 -0
- package/lib/ecosystem/ui/glyphs.js +41 -0
- package/lib/ecosystem/ui/glyphs.js.map +1 -0
- package/lib/ecosystem/ui/marks.d.ts.map +1 -1
- package/lib/ecosystem/ui/marks.js +2 -33
- package/lib/ecosystem/ui/marks.js.map +1 -1
- package/lib/orbital/core/atomicGrid.d.ts +58 -0
- package/lib/orbital/core/atomicGrid.d.ts.map +1 -0
- package/lib/orbital/core/atomicGrid.js +69 -0
- package/lib/orbital/core/atomicGrid.js.map +1 -0
- package/lib/orbital/core/atomicOrbitals.d.ts +97 -0
- package/lib/orbital/core/atomicOrbitals.d.ts.map +1 -0
- package/lib/orbital/core/atomicOrbitals.js +135 -0
- package/lib/orbital/core/atomicOrbitals.js.map +1 -0
- package/lib/orbital/core/constants.d.ts +33 -0
- package/lib/orbital/core/constants.d.ts.map +1 -0
- package/lib/orbital/core/constants.js +21 -0
- package/lib/orbital/core/constants.js.map +1 -0
- package/lib/orbital/core/electronConfiguration.d.ts +106 -0
- package/lib/orbital/core/electronConfiguration.d.ts.map +1 -0
- package/lib/orbital/core/electronConfiguration.js +207 -0
- package/lib/orbital/core/electronConfiguration.js.map +1 -0
- package/lib/orbital/core/grid.d.ts +60 -0
- package/lib/orbital/core/grid.d.ts.map +1 -0
- package/lib/orbital/core/grid.js +81 -0
- package/lib/orbital/core/grid.js.map +1 -0
- package/lib/orbital/core/hydrogenic.d.ts +99 -0
- package/lib/orbital/core/hydrogenic.d.ts.map +1 -0
- package/lib/orbital/core/hydrogenic.js +181 -0
- package/lib/orbital/core/hydrogenic.js.map +1 -0
- package/lib/orbital/core/index.d.ts +22 -0
- package/lib/orbital/core/index.d.ts.map +1 -0
- package/lib/orbital/core/index.js +12 -0
- package/lib/orbital/core/index.js.map +1 -0
- package/lib/orbital/core/numerics.d.ts +39 -0
- package/lib/orbital/core/numerics.d.ts.map +1 -0
- package/lib/orbital/core/numerics.js +75 -0
- package/lib/orbital/core/numerics.js.map +1 -0
- package/lib/orbital/core/occupancy.d.ts +44 -0
- package/lib/orbital/core/occupancy.d.ts.map +1 -0
- package/lib/orbital/core/occupancy.js +85 -0
- package/lib/orbital/core/occupancy.js.map +1 -0
- package/lib/orbital/core/palette.d.ts +36 -0
- package/lib/orbital/core/palette.d.ts.map +1 -0
- package/lib/orbital/core/palette.js +37 -0
- package/lib/orbital/core/palette.js.map +1 -0
- package/lib/orbital/core/realHarmonics.d.ts +57 -0
- package/lib/orbital/core/realHarmonics.d.ts.map +1 -0
- package/lib/orbital/core/realHarmonics.js +144 -0
- package/lib/orbital/core/realHarmonics.js.map +1 -0
- package/lib/orbital/core/sample.d.ts +52 -0
- package/lib/orbital/core/sample.d.ts.map +1 -0
- package/lib/orbital/core/sample.js +54 -0
- package/lib/orbital/core/sample.js.map +1 -0
- package/lib/orbital/core/screening.d.ts +46 -0
- package/lib/orbital/core/screening.d.ts.map +1 -0
- package/lib/orbital/core/screening.js +72 -0
- package/lib/orbital/core/screening.js.map +1 -0
- package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts +57 -0
- package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts.map +1 -0
- package/lib/orbital/ui/AtomicOrbitalCanvas.js +105 -0
- package/lib/orbital/ui/AtomicOrbitalCanvas.js.map +1 -0
- package/lib/orbital/ui/AtomicOrbitalViewer.d.ts +73 -0
- package/lib/orbital/ui/AtomicOrbitalViewer.d.ts.map +1 -0
- package/lib/orbital/ui/AtomicOrbitalViewer.js +49 -0
- package/lib/orbital/ui/AtomicOrbitalViewer.js.map +1 -0
- package/lib/orbital/ui/camera.d.ts +36 -0
- package/lib/orbital/ui/camera.d.ts.map +1 -0
- package/lib/orbital/ui/camera.js +98 -0
- package/lib/orbital/ui/camera.js.map +1 -0
- package/lib/orbital/ui/capability.d.ts +28 -0
- package/lib/orbital/ui/capability.d.ts.map +1 -0
- package/lib/orbital/ui/capability.js +77 -0
- package/lib/orbital/ui/capability.js.map +1 -0
- package/lib/orbital/ui/index.d.ts +17 -0
- package/lib/orbital/ui/index.d.ts.map +1 -0
- package/lib/orbital/ui/index.js +13 -0
- package/lib/orbital/ui/index.js.map +1 -0
- package/lib/orbital/ui/renderVolume.d.ts +57 -0
- package/lib/orbital/ui/renderVolume.d.ts.map +1 -0
- package/lib/orbital/ui/renderVolume.js +120 -0
- package/lib/orbital/ui/renderVolume.js.map +1 -0
- package/lib/orbital/ui/viewer.d.ts +86 -0
- package/lib/orbital/ui/viewer.d.ts.map +1 -0
- package/lib/orbital/ui/viewer.js +155 -0
- package/lib/orbital/ui/viewer.js.map +1 -0
- package/lib/orbital/ui/volumeField.d.ts +49 -0
- package/lib/orbital/ui/volumeField.d.ts.map +1 -0
- package/lib/orbital/ui/volumeField.js +108 -0
- package/lib/orbital/ui/volumeField.js.map +1 -0
- package/lib/orbital.d.ts +11 -0
- package/lib/orbital.d.ts.map +1 -0
- package/lib/orbital.js +11 -0
- package/lib/orbital.js.map +1 -0
- package/package.json +11 -3
- package/src/core.ts +1 -0
- package/src/ecosystem/core/sites.ts +21 -1
- package/src/ecosystem/ui/glyphs.tsx +246 -0
- package/src/ecosystem/ui/marks.tsx +4 -201
- package/src/orbital/core/atomicGrid.ts +115 -0
- package/src/orbital/core/atomicOrbitals.ts +212 -0
- package/src/orbital/core/constants.ts +36 -0
- package/src/orbital/core/electronConfiguration.ts +242 -0
- package/src/orbital/core/grid.ts +126 -0
- package/src/orbital/core/hydrogenic.ts +222 -0
- package/src/orbital/core/index.ts +72 -0
- package/src/orbital/core/numerics.ts +79 -0
- package/src/orbital/core/occupancy.ts +100 -0
- package/src/orbital/core/palette.ts +56 -0
- package/src/orbital/core/realHarmonics.ts +172 -0
- package/src/orbital/core/sample.ts +91 -0
- package/src/orbital/core/screening.ts +90 -0
- package/src/orbital/ui/AtomicOrbitalCanvas.tsx +181 -0
- package/src/orbital/ui/AtomicOrbitalViewer.tsx +150 -0
- package/src/orbital/ui/camera.ts +125 -0
- package/src/orbital/ui/capability.ts +102 -0
- package/src/orbital/ui/index.ts +17 -0
- package/src/orbital/ui/renderVolume.ts +190 -0
- package/src/orbital/ui/viewer.ts +186 -0
- package/src/orbital/ui/volumeField.ts +128 -0
- package/src/orbital.ts +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-cheminfo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Assembled React components shared by the cheminfo sites: a Cite button and an ecosystem menu",
|
|
6
6
|
"author": "Luc Patiny",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"exports": {
|
|
15
15
|
"./core": "./lib/core.js",
|
|
16
|
+
"./orbital": "./lib/orbital.js",
|
|
16
17
|
"./ui": "./lib/ui.js"
|
|
17
18
|
},
|
|
18
19
|
"files": [
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
"eslint": "^9.39.5",
|
|
53
54
|
"eslint-config-cheminfo-react": "^20.1.0",
|
|
54
55
|
"eslint-config-cheminfo-typescript": "^22.1.0",
|
|
56
|
+
"molstar": "^5.11.0",
|
|
55
57
|
"prettier": "^3.9.6",
|
|
56
58
|
"react": "^19.2.8",
|
|
57
59
|
"react-dom": "^19.2.8",
|
|
@@ -66,7 +68,8 @@
|
|
|
66
68
|
"@blueprintjs/core": "^6.18.0",
|
|
67
69
|
"react": "^18.3.1 || >=19",
|
|
68
70
|
"react-dom": "^18.3.1 || >=19",
|
|
69
|
-
"react-science": "^20.6.2 || ^21.0.0 || ^22.0.0 || ^23.0.0"
|
|
71
|
+
"react-science": "^20.6.2 || ^21.0.0 || ^22.0.0 || ^23.0.0",
|
|
72
|
+
"molstar": "^5.11.0"
|
|
70
73
|
},
|
|
71
74
|
"repository": {
|
|
72
75
|
"type": "git",
|
|
@@ -75,5 +78,10 @@
|
|
|
75
78
|
"bugs": {
|
|
76
79
|
"url": "https://github.com/cheminfo/react-cheminfo/issues"
|
|
77
80
|
},
|
|
78
|
-
"homepage": "https://github.com/cheminfo/react-cheminfo#readme"
|
|
81
|
+
"homepage": "https://github.com/cheminfo/react-cheminfo#readme",
|
|
82
|
+
"peerDependenciesMeta": {
|
|
83
|
+
"molstar": {
|
|
84
|
+
"optional": true
|
|
85
|
+
}
|
|
86
|
+
}
|
|
79
87
|
}
|
package/src/core.ts
CHANGED
|
@@ -12,7 +12,9 @@ export type SiteId =
|
|
|
12
12
|
| 'pdb'
|
|
13
13
|
| 'elucidation'
|
|
14
14
|
| 'equilibrium'
|
|
15
|
-
| 'polycarp'
|
|
15
|
+
| 'polycarp'
|
|
16
|
+
| '3d'
|
|
17
|
+
| 'pt';
|
|
16
18
|
|
|
17
19
|
export interface SiteName {
|
|
18
20
|
/** First half of the name, set in the site's leading colour. */
|
|
@@ -182,6 +184,24 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
|
|
|
182
184
|
brandAlt: '#0c9ba3',
|
|
183
185
|
mark: { plate: '#0d1d37', accent: '#0c9ba3' },
|
|
184
186
|
},
|
|
187
|
+
{
|
|
188
|
+
id: '3d',
|
|
189
|
+
name: { lead: '3d', alt: 'cheminfo', dot: true },
|
|
190
|
+
host: '3d.cheminfo.org',
|
|
191
|
+
tagline: 'Conformers in 3D from a structure you draw.',
|
|
192
|
+
brand: '#155e75',
|
|
193
|
+
brandAlt: '#b45309',
|
|
194
|
+
mark: { plate: '#155e75', accent: '#f97316' },
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: 'pt',
|
|
198
|
+
name: { lead: 'pt', alt: 'cheminfo', dot: true },
|
|
199
|
+
host: 'pt.cheminfo.org',
|
|
200
|
+
tagline: 'The periodic table, coloured, plotted and taken apart.',
|
|
201
|
+
brand: '#15803d',
|
|
202
|
+
brandAlt: '#a16207',
|
|
203
|
+
mark: { plate: '#15803d', accent: '#fbbf24' },
|
|
204
|
+
},
|
|
185
205
|
];
|
|
186
206
|
|
|
187
207
|
/**
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The drawing on each site's plate.
|
|
3
|
+
*
|
|
4
|
+
* One file of pure artwork, so `marks.tsx` stays the eight lines that put a
|
|
5
|
+
* glyph on a plate and every new site is one entry here rather than a longer
|
|
6
|
+
* component.
|
|
7
|
+
*
|
|
8
|
+
* Each keeps the geometry of that site's own logo where it has one, and carries
|
|
9
|
+
* the site's answering colour on exactly one element — which is what stops it
|
|
10
|
+
* collapsing into a flat shape at 16 px.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { ReactNode } from 'react';
|
|
14
|
+
|
|
15
|
+
import type { SiteId } from '../core/sites.ts';
|
|
16
|
+
|
|
17
|
+
/** Every mark, keyed by site, drawn on top of its plate. */
|
|
18
|
+
export const GLYPHS: Record<SiteId, (alt: string) => ReactNode> = {
|
|
19
|
+
// A hexagon with a tail: the structure, and the string it hashes into.
|
|
20
|
+
inchi: (alt) => (
|
|
21
|
+
<g
|
|
22
|
+
fill="none"
|
|
23
|
+
stroke={alt}
|
|
24
|
+
strokeWidth="2.4"
|
|
25
|
+
strokeLinecap="round"
|
|
26
|
+
strokeLinejoin="round"
|
|
27
|
+
>
|
|
28
|
+
<polygon points="13,6.5 7.7,9.6 7.7,15.7 13,18.8 18.3,15.7 18.3,9.6" />
|
|
29
|
+
<path d="M16.4 16.2 25.2 25" />
|
|
30
|
+
</g>
|
|
31
|
+
),
|
|
32
|
+
// The core carrying three R groups, which is what this tool combines.
|
|
33
|
+
vcl: (alt) => (
|
|
34
|
+
<>
|
|
35
|
+
<g
|
|
36
|
+
fill="none"
|
|
37
|
+
stroke="#ffffff"
|
|
38
|
+
strokeWidth="2"
|
|
39
|
+
strokeLinecap="round"
|
|
40
|
+
strokeLinejoin="round"
|
|
41
|
+
>
|
|
42
|
+
<path d="M16 9.5 10.8 12.5 10.8 18.5 16 21.5 21.2 18.5 21.2 12.5Z" />
|
|
43
|
+
<path d="M16 9.5 16 5.5M21.2 18.5 24.8 20.6M10.8 18.5 7.2 20.6" />
|
|
44
|
+
</g>
|
|
45
|
+
<circle cx="16" cy="4.6" r="2.6" fill={alt} />
|
|
46
|
+
<circle cx="25.6" cy="21.2" r="2.6" fill={alt} />
|
|
47
|
+
<circle cx="6.4" cy="21.2" r="2.6" fill={alt} />
|
|
48
|
+
</>
|
|
49
|
+
),
|
|
50
|
+
// A ring over the line of characters that writes it down.
|
|
51
|
+
smiles: (alt) => (
|
|
52
|
+
<>
|
|
53
|
+
<path
|
|
54
|
+
d="M16 7.5 22.1 11.1 22.1 18.3 16 21.9 9.9 18.3 9.9 11.1Z"
|
|
55
|
+
fill="none"
|
|
56
|
+
stroke="#ffffff"
|
|
57
|
+
strokeWidth="2.2"
|
|
58
|
+
strokeLinejoin="round"
|
|
59
|
+
/>
|
|
60
|
+
<path
|
|
61
|
+
d="M5.5 25.5h21"
|
|
62
|
+
fill="none"
|
|
63
|
+
stroke={alt}
|
|
64
|
+
strokeWidth="3"
|
|
65
|
+
strokeLinecap="round"
|
|
66
|
+
/>
|
|
67
|
+
</>
|
|
68
|
+
),
|
|
69
|
+
// An isotopic pattern: the answer this one is asked for most.
|
|
70
|
+
chemcalc: (alt) => (
|
|
71
|
+
<g strokeLinecap="round" strokeWidth="3.4" fill="none">
|
|
72
|
+
<path d="M9 24V15" stroke="#ffffff" />
|
|
73
|
+
<path d="M16 24V7" stroke={alt} />
|
|
74
|
+
<path d="M23 24V18" stroke="#ffffff" />
|
|
75
|
+
</g>
|
|
76
|
+
),
|
|
77
|
+
// The official NMRium symbol, from `Logo.tsx` of the NMRium sources: the
|
|
78
|
+
// orange half is theirs, and the half their logo sets in plum is set in white
|
|
79
|
+
// here because the plate already is that plum.
|
|
80
|
+
nmrium: (accent) => (
|
|
81
|
+
<g fillRule="evenodd" transform="translate(5.25 6.25) scale(0.088)">
|
|
82
|
+
<path
|
|
83
|
+
fill={accent}
|
|
84
|
+
d="M.64,31.7A31.67,31.67,0,0,1,54.72,9.29l0,0A31.66,31.66,0,0,1,64,31.7V190a13.39,13.39,0,0,0,26.77,0V54a31.7,31.7,0,0,1,31.7-31.7V40.58A13.38,13.38,0,0,0,109.13,54V190a31.71,31.71,0,0,1-63.41,0V31.7a13.29,13.29,0,0,0-3.88-9.46l0,0A13.41,13.41,0,0,0,19,31.7V164.82H.64Z"
|
|
85
|
+
/>
|
|
86
|
+
<path
|
|
87
|
+
fill="#ffffff"
|
|
88
|
+
d="M154.21,54v68.17a13.34,13.34,0,0,0,3.89,9.47h0A13.39,13.39,0,0,0,181,122.14V99.32h-.06a31.63,31.63,0,0,1,9.29-22.38l0,0a31.65,31.65,0,0,1,44.8,0l0,0a31.58,31.58,0,0,1,9.3,22.39V118H226V99.32a13.3,13.3,0,0,0-3.89-9.46h0a13.44,13.44,0,0,0-18.93,0l0,0a13.3,13.3,0,0,0-3.83,8.19v24.09a31.7,31.7,0,0,1-54.11,22.42v0a31.66,31.66,0,0,1-9.3-22.4V54Z"
|
|
89
|
+
/>
|
|
90
|
+
</g>
|
|
91
|
+
),
|
|
92
|
+
// One formula branching into every structure it can be.
|
|
93
|
+
surge: (alt) => (
|
|
94
|
+
<>
|
|
95
|
+
<g
|
|
96
|
+
fill="none"
|
|
97
|
+
stroke="#ffffff"
|
|
98
|
+
strokeWidth="2"
|
|
99
|
+
strokeLinecap="round"
|
|
100
|
+
strokeLinejoin="round"
|
|
101
|
+
>
|
|
102
|
+
<path d="M7 16h6" />
|
|
103
|
+
<path d="M13 16 25 8.5M13 16h12M13 16 25 23.5" />
|
|
104
|
+
</g>
|
|
105
|
+
<circle cx="25" cy="8.5" r="3" fill={alt} />
|
|
106
|
+
<circle cx="25" cy="16" r="3" fill={alt} />
|
|
107
|
+
<circle cx="25" cy="23.5" r="3" fill={alt} />
|
|
108
|
+
</>
|
|
109
|
+
),
|
|
110
|
+
// A radical over its radicand: a formula being set.
|
|
111
|
+
tex: (alt) => (
|
|
112
|
+
<>
|
|
113
|
+
<rect x="18.5" y="12" width="8.5" height="8.5" rx="1.6" fill={alt} />
|
|
114
|
+
<path
|
|
115
|
+
d="M4.5 15.5h3l3.6 8.2L16.8 7.5h10.4"
|
|
116
|
+
fill="none"
|
|
117
|
+
stroke="#ffffff"
|
|
118
|
+
strokeWidth="2.4"
|
|
119
|
+
strokeLinecap="round"
|
|
120
|
+
strokeLinejoin="round"
|
|
121
|
+
/>
|
|
122
|
+
</>
|
|
123
|
+
),
|
|
124
|
+
// The site's own favicon: two lobes of opposite phase overlapping end-on,
|
|
125
|
+
// the simplest sigma bond, in the phase palette its viewer renders with.
|
|
126
|
+
lcao: (alt) => (
|
|
127
|
+
<>
|
|
128
|
+
<path
|
|
129
|
+
d="M16 16C16 10.2 13.3 5 9 5S2 10.2 2 16s2.7 11 7 11 7-5.2 7-11z"
|
|
130
|
+
fill="#1565c0"
|
|
131
|
+
/>
|
|
132
|
+
<path
|
|
133
|
+
d="M16 16c0 5.8 2.7 11 7 11s7-5.2 7-11-2.7-11-7-11-7 5.2-7 11z"
|
|
134
|
+
fill={alt}
|
|
135
|
+
/>
|
|
136
|
+
<circle cx="16" cy="16" r="2.25" fill="#37474f" />
|
|
137
|
+
</>
|
|
138
|
+
),
|
|
139
|
+
// The pattern that matches anything, which is where everyone starts.
|
|
140
|
+
regexp: (alt) => (
|
|
141
|
+
<text
|
|
142
|
+
x="50%"
|
|
143
|
+
y="53%"
|
|
144
|
+
dominantBaseline="central"
|
|
145
|
+
textAnchor="middle"
|
|
146
|
+
fontFamily="ui-monospace, SFMono-Regular, Menlo, monospace"
|
|
147
|
+
fontSize="18"
|
|
148
|
+
fontWeight="700"
|
|
149
|
+
fill={alt}
|
|
150
|
+
>
|
|
151
|
+
.*
|
|
152
|
+
</text>
|
|
153
|
+
),
|
|
154
|
+
// Three residues of a chain, one of them the ligand you came for.
|
|
155
|
+
pdb: (alt) => (
|
|
156
|
+
<>
|
|
157
|
+
<g
|
|
158
|
+
stroke="#ffffff"
|
|
159
|
+
strokeWidth="1.9"
|
|
160
|
+
strokeLinecap="round"
|
|
161
|
+
fill="none"
|
|
162
|
+
opacity="0.85"
|
|
163
|
+
>
|
|
164
|
+
<path d="M9.2 12.4 22 15.4 15.6 23Z" />
|
|
165
|
+
</g>
|
|
166
|
+
<circle cx="9.2" cy="12.4" r="3.1" fill="#ffffff" />
|
|
167
|
+
<circle cx="22" cy="15.4" r="3.1" fill="#ffffff" />
|
|
168
|
+
<circle cx="15.6" cy="23" r="3.1" fill={alt} />
|
|
169
|
+
</>
|
|
170
|
+
),
|
|
171
|
+
// The site's own favicon: a spectrum, and the one signal being assigned.
|
|
172
|
+
elucidation: (alt) => (
|
|
173
|
+
<>
|
|
174
|
+
<path
|
|
175
|
+
d="M5 24h4l2-11 2 11h4l2-15 2 15h3l1.5-7 1.5 7"
|
|
176
|
+
fill="none"
|
|
177
|
+
stroke="#ffffff"
|
|
178
|
+
strokeWidth="2"
|
|
179
|
+
strokeLinecap="round"
|
|
180
|
+
strokeLinejoin="round"
|
|
181
|
+
/>
|
|
182
|
+
<circle cx="19" cy="9" r="3" fill={alt} />
|
|
183
|
+
</>
|
|
184
|
+
),
|
|
185
|
+
// The site's own favicon: the double harpoon, one direction per colour.
|
|
186
|
+
equilibrium: (alt) => (
|
|
187
|
+
<g
|
|
188
|
+
fill="none"
|
|
189
|
+
strokeWidth="2.5"
|
|
190
|
+
strokeLinecap="round"
|
|
191
|
+
strokeLinejoin="round"
|
|
192
|
+
>
|
|
193
|
+
<path d="M6.5 12.5h17l-4-4" stroke="#ffffff" />
|
|
194
|
+
<path d="M25.5 19.5h-17l4 4" stroke={alt} />
|
|
195
|
+
</g>
|
|
196
|
+
),
|
|
197
|
+
// A chain of monomers, one of them the comonomer written into it.
|
|
198
|
+
polycarp: (alt) => (
|
|
199
|
+
<>
|
|
200
|
+
<path
|
|
201
|
+
d="M6.5 20 12.5 12 19.5 20 25.5 12"
|
|
202
|
+
fill="none"
|
|
203
|
+
stroke="#ffffff"
|
|
204
|
+
strokeWidth="2"
|
|
205
|
+
strokeLinecap="round"
|
|
206
|
+
strokeLinejoin="round"
|
|
207
|
+
/>
|
|
208
|
+
<circle cx="6.5" cy="20" r="3" fill="#ffffff" />
|
|
209
|
+
<circle cx="12.5" cy="12" r="3" fill="#ffffff" />
|
|
210
|
+
<circle cx="19.5" cy="20" r="3" fill={alt} />
|
|
211
|
+
<circle cx="25.5" cy="12" r="3" fill="#ffffff" />
|
|
212
|
+
</>
|
|
213
|
+
),
|
|
214
|
+
// The stepped corner of the table, with the one cell a visitor has picked
|
|
215
|
+
// carrying the accent — which is what every tool of that site is: the table,
|
|
216
|
+
// and one element read off it.
|
|
217
|
+
pt: (alt) => (
|
|
218
|
+
<>
|
|
219
|
+
<g fill="#ffffff" opacity="0.55">
|
|
220
|
+
<rect x="5" y="6" width="5" height="5" rx="1" />
|
|
221
|
+
<rect x="22" y="6" width="5" height="5" rx="1" />
|
|
222
|
+
<rect x="5" y="12.5" width="5" height="5" rx="1" />
|
|
223
|
+
<rect x="11.75" y="12.5" width="5" height="5" rx="1" />
|
|
224
|
+
<rect x="18.5" y="12.5" width="5" height="5" rx="1" />
|
|
225
|
+
<rect x="5" y="19" width="5" height="5" rx="1" />
|
|
226
|
+
<rect x="11.75" y="19" width="5" height="5" rx="1" />
|
|
227
|
+
</g>
|
|
228
|
+
<rect x="18.5" y="19" width="8.5" height="5" rx="1" fill={alt} />
|
|
229
|
+
</>
|
|
230
|
+
),
|
|
231
|
+
// A stereocentre: two bonds in the plane of the drawing and one wedged out
|
|
232
|
+
// of it, which is the whole of what this site does to a flat structure.
|
|
233
|
+
'3d': (alt) => (
|
|
234
|
+
<>
|
|
235
|
+
<path
|
|
236
|
+
d="M16 16 16 5.6M16 16 7.2 21.2"
|
|
237
|
+
fill="none"
|
|
238
|
+
stroke="#ffffff"
|
|
239
|
+
strokeWidth="2.4"
|
|
240
|
+
strokeLinecap="round"
|
|
241
|
+
/>
|
|
242
|
+
<path d="M16 16 24.2 24 26.9 19.6Z" fill={alt} />
|
|
243
|
+
<circle cx="16" cy="16" r="2.9" fill="#ffffff" />
|
|
244
|
+
</>
|
|
245
|
+
),
|
|
246
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type { CSSProperties, ReactElement
|
|
1
|
+
import type { CSSProperties, ReactElement } from 'react';
|
|
2
2
|
|
|
3
|
-
import type { EcosystemSite
|
|
3
|
+
import type { EcosystemSite } from '../core/sites.ts';
|
|
4
|
+
|
|
5
|
+
import { GLYPHS } from './glyphs.tsx';
|
|
4
6
|
|
|
5
7
|
// Every mark is drawn in the same 32×32 box, on a plate of the site's own
|
|
6
8
|
// colour, so every mark of the family still reads as one row. Each keeps the
|
|
@@ -49,202 +51,3 @@ export function SiteMark(props: SiteMarkProps): ReactElement {
|
|
|
49
51
|
</svg>
|
|
50
52
|
);
|
|
51
53
|
}
|
|
52
|
-
|
|
53
|
-
/** Every mark, keyed by site, drawn on top of its plate. */
|
|
54
|
-
const GLYPHS: Record<SiteId, (alt: string) => ReactNode> = {
|
|
55
|
-
// A hexagon with a tail: the structure, and the string it hashes into.
|
|
56
|
-
inchi: (alt) => (
|
|
57
|
-
<g
|
|
58
|
-
fill="none"
|
|
59
|
-
stroke={alt}
|
|
60
|
-
strokeWidth="2.4"
|
|
61
|
-
strokeLinecap="round"
|
|
62
|
-
strokeLinejoin="round"
|
|
63
|
-
>
|
|
64
|
-
<polygon points="13,6.5 7.7,9.6 7.7,15.7 13,18.8 18.3,15.7 18.3,9.6" />
|
|
65
|
-
<path d="M16.4 16.2 25.2 25" />
|
|
66
|
-
</g>
|
|
67
|
-
),
|
|
68
|
-
// The core carrying three R groups, which is what this tool combines.
|
|
69
|
-
vcl: (alt) => (
|
|
70
|
-
<>
|
|
71
|
-
<g
|
|
72
|
-
fill="none"
|
|
73
|
-
stroke="#ffffff"
|
|
74
|
-
strokeWidth="2"
|
|
75
|
-
strokeLinecap="round"
|
|
76
|
-
strokeLinejoin="round"
|
|
77
|
-
>
|
|
78
|
-
<path d="M16 9.5 10.8 12.5 10.8 18.5 16 21.5 21.2 18.5 21.2 12.5Z" />
|
|
79
|
-
<path d="M16 9.5 16 5.5M21.2 18.5 24.8 20.6M10.8 18.5 7.2 20.6" />
|
|
80
|
-
</g>
|
|
81
|
-
<circle cx="16" cy="4.6" r="2.6" fill={alt} />
|
|
82
|
-
<circle cx="25.6" cy="21.2" r="2.6" fill={alt} />
|
|
83
|
-
<circle cx="6.4" cy="21.2" r="2.6" fill={alt} />
|
|
84
|
-
</>
|
|
85
|
-
),
|
|
86
|
-
// A ring over the line of characters that writes it down.
|
|
87
|
-
smiles: (alt) => (
|
|
88
|
-
<>
|
|
89
|
-
<path
|
|
90
|
-
d="M16 7.5 22.1 11.1 22.1 18.3 16 21.9 9.9 18.3 9.9 11.1Z"
|
|
91
|
-
fill="none"
|
|
92
|
-
stroke="#ffffff"
|
|
93
|
-
strokeWidth="2.2"
|
|
94
|
-
strokeLinejoin="round"
|
|
95
|
-
/>
|
|
96
|
-
<path
|
|
97
|
-
d="M5.5 25.5h21"
|
|
98
|
-
fill="none"
|
|
99
|
-
stroke={alt}
|
|
100
|
-
strokeWidth="3"
|
|
101
|
-
strokeLinecap="round"
|
|
102
|
-
/>
|
|
103
|
-
</>
|
|
104
|
-
),
|
|
105
|
-
// An isotopic pattern: the answer this one is asked for most.
|
|
106
|
-
chemcalc: (alt) => (
|
|
107
|
-
<g strokeLinecap="round" strokeWidth="3.4" fill="none">
|
|
108
|
-
<path d="M9 24V15" stroke="#ffffff" />
|
|
109
|
-
<path d="M16 24V7" stroke={alt} />
|
|
110
|
-
<path d="M23 24V18" stroke="#ffffff" />
|
|
111
|
-
</g>
|
|
112
|
-
),
|
|
113
|
-
// The official NMRium symbol, from `Logo.tsx` of the NMRium sources: the
|
|
114
|
-
// orange half is theirs, and the half their logo sets in plum is set in white
|
|
115
|
-
// here because the plate already is that plum.
|
|
116
|
-
nmrium: (accent) => (
|
|
117
|
-
<g fillRule="evenodd" transform="translate(5.25 6.25) scale(0.088)">
|
|
118
|
-
<path
|
|
119
|
-
fill={accent}
|
|
120
|
-
d="M.64,31.7A31.67,31.67,0,0,1,54.72,9.29l0,0A31.66,31.66,0,0,1,64,31.7V190a13.39,13.39,0,0,0,26.77,0V54a31.7,31.7,0,0,1,31.7-31.7V40.58A13.38,13.38,0,0,0,109.13,54V190a31.71,31.71,0,0,1-63.41,0V31.7a13.29,13.29,0,0,0-3.88-9.46l0,0A13.41,13.41,0,0,0,19,31.7V164.82H.64Z"
|
|
121
|
-
/>
|
|
122
|
-
<path
|
|
123
|
-
fill="#ffffff"
|
|
124
|
-
d="M154.21,54v68.17a13.34,13.34,0,0,0,3.89,9.47h0A13.39,13.39,0,0,0,181,122.14V99.32h-.06a31.63,31.63,0,0,1,9.29-22.38l0,0a31.65,31.65,0,0,1,44.8,0l0,0a31.58,31.58,0,0,1,9.3,22.39V118H226V99.32a13.3,13.3,0,0,0-3.89-9.46h0a13.44,13.44,0,0,0-18.93,0l0,0a13.3,13.3,0,0,0-3.83,8.19v24.09a31.7,31.7,0,0,1-54.11,22.42v0a31.66,31.66,0,0,1-9.3-22.4V54Z"
|
|
125
|
-
/>
|
|
126
|
-
</g>
|
|
127
|
-
),
|
|
128
|
-
// One formula branching into every structure it can be.
|
|
129
|
-
surge: (alt) => (
|
|
130
|
-
<>
|
|
131
|
-
<g
|
|
132
|
-
fill="none"
|
|
133
|
-
stroke="#ffffff"
|
|
134
|
-
strokeWidth="2"
|
|
135
|
-
strokeLinecap="round"
|
|
136
|
-
strokeLinejoin="round"
|
|
137
|
-
>
|
|
138
|
-
<path d="M7 16h6" />
|
|
139
|
-
<path d="M13 16 25 8.5M13 16h12M13 16 25 23.5" />
|
|
140
|
-
</g>
|
|
141
|
-
<circle cx="25" cy="8.5" r="3" fill={alt} />
|
|
142
|
-
<circle cx="25" cy="16" r="3" fill={alt} />
|
|
143
|
-
<circle cx="25" cy="23.5" r="3" fill={alt} />
|
|
144
|
-
</>
|
|
145
|
-
),
|
|
146
|
-
// A radical over its radicand: a formula being set.
|
|
147
|
-
tex: (alt) => (
|
|
148
|
-
<>
|
|
149
|
-
<rect x="18.5" y="12" width="8.5" height="8.5" rx="1.6" fill={alt} />
|
|
150
|
-
<path
|
|
151
|
-
d="M4.5 15.5h3l3.6 8.2L16.8 7.5h10.4"
|
|
152
|
-
fill="none"
|
|
153
|
-
stroke="#ffffff"
|
|
154
|
-
strokeWidth="2.4"
|
|
155
|
-
strokeLinecap="round"
|
|
156
|
-
strokeLinejoin="round"
|
|
157
|
-
/>
|
|
158
|
-
</>
|
|
159
|
-
),
|
|
160
|
-
// The site's own favicon: two lobes of opposite phase overlapping end-on,
|
|
161
|
-
// the simplest sigma bond, in the phase palette its viewer renders with.
|
|
162
|
-
lcao: (alt) => (
|
|
163
|
-
<>
|
|
164
|
-
<path
|
|
165
|
-
d="M16 16C16 10.2 13.3 5 9 5S2 10.2 2 16s2.7 11 7 11 7-5.2 7-11z"
|
|
166
|
-
fill="#1565c0"
|
|
167
|
-
/>
|
|
168
|
-
<path
|
|
169
|
-
d="M16 16c0 5.8 2.7 11 7 11s7-5.2 7-11-2.7-11-7-11-7 5.2-7 11z"
|
|
170
|
-
fill={alt}
|
|
171
|
-
/>
|
|
172
|
-
<circle cx="16" cy="16" r="2.25" fill="#37474f" />
|
|
173
|
-
</>
|
|
174
|
-
),
|
|
175
|
-
// The pattern that matches anything, which is where everyone starts.
|
|
176
|
-
regexp: (alt) => (
|
|
177
|
-
<text
|
|
178
|
-
x="50%"
|
|
179
|
-
y="53%"
|
|
180
|
-
dominantBaseline="central"
|
|
181
|
-
textAnchor="middle"
|
|
182
|
-
fontFamily="ui-monospace, SFMono-Regular, Menlo, monospace"
|
|
183
|
-
fontSize="18"
|
|
184
|
-
fontWeight="700"
|
|
185
|
-
fill={alt}
|
|
186
|
-
>
|
|
187
|
-
.*
|
|
188
|
-
</text>
|
|
189
|
-
),
|
|
190
|
-
// Three residues of a chain, one of them the ligand you came for.
|
|
191
|
-
pdb: (alt) => (
|
|
192
|
-
<>
|
|
193
|
-
<g
|
|
194
|
-
stroke="#ffffff"
|
|
195
|
-
strokeWidth="1.9"
|
|
196
|
-
strokeLinecap="round"
|
|
197
|
-
fill="none"
|
|
198
|
-
opacity="0.85"
|
|
199
|
-
>
|
|
200
|
-
<path d="M9.2 12.4 22 15.4 15.6 23Z" />
|
|
201
|
-
</g>
|
|
202
|
-
<circle cx="9.2" cy="12.4" r="3.1" fill="#ffffff" />
|
|
203
|
-
<circle cx="22" cy="15.4" r="3.1" fill="#ffffff" />
|
|
204
|
-
<circle cx="15.6" cy="23" r="3.1" fill={alt} />
|
|
205
|
-
</>
|
|
206
|
-
),
|
|
207
|
-
// The site's own favicon: a spectrum, and the one signal being assigned.
|
|
208
|
-
elucidation: (alt) => (
|
|
209
|
-
<>
|
|
210
|
-
<path
|
|
211
|
-
d="M5 24h4l2-11 2 11h4l2-15 2 15h3l1.5-7 1.5 7"
|
|
212
|
-
fill="none"
|
|
213
|
-
stroke="#ffffff"
|
|
214
|
-
strokeWidth="2"
|
|
215
|
-
strokeLinecap="round"
|
|
216
|
-
strokeLinejoin="round"
|
|
217
|
-
/>
|
|
218
|
-
<circle cx="19" cy="9" r="3" fill={alt} />
|
|
219
|
-
</>
|
|
220
|
-
),
|
|
221
|
-
// The site's own favicon: the double harpoon, one direction per colour.
|
|
222
|
-
equilibrium: (alt) => (
|
|
223
|
-
<g
|
|
224
|
-
fill="none"
|
|
225
|
-
strokeWidth="2.5"
|
|
226
|
-
strokeLinecap="round"
|
|
227
|
-
strokeLinejoin="round"
|
|
228
|
-
>
|
|
229
|
-
<path d="M6.5 12.5h17l-4-4" stroke="#ffffff" />
|
|
230
|
-
<path d="M25.5 19.5h-17l4 4" stroke={alt} />
|
|
231
|
-
</g>
|
|
232
|
-
),
|
|
233
|
-
// A chain of monomers, one of them the comonomer written into it.
|
|
234
|
-
polycarp: (alt) => (
|
|
235
|
-
<>
|
|
236
|
-
<path
|
|
237
|
-
d="M6.5 20 12.5 12 19.5 20 25.5 12"
|
|
238
|
-
fill="none"
|
|
239
|
-
stroke="#ffffff"
|
|
240
|
-
strokeWidth="2"
|
|
241
|
-
strokeLinecap="round"
|
|
242
|
-
strokeLinejoin="round"
|
|
243
|
-
/>
|
|
244
|
-
<circle cx="6.5" cy="20" r="3" fill="#ffffff" />
|
|
245
|
-
<circle cx="12.5" cy="12" r="3" fill="#ffffff" />
|
|
246
|
-
<circle cx="19.5" cy="20" r="3" fill={alt} />
|
|
247
|
-
<circle cx="25.5" cy="12" r="3" fill="#ffffff" />
|
|
248
|
-
</>
|
|
249
|
-
),
|
|
250
|
-
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sampling one atomic orbital onto the scalar field the isosurface renderer
|
|
3
|
+
* consumes.
|
|
4
|
+
*
|
|
5
|
+
* The box is sized from the orbital itself rather than fixed: a 1s on fluorine
|
|
6
|
+
* and a 4f on caesium differ by more than an order of magnitude in extent, and a
|
|
7
|
+
* box that suits one either buries the other in empty space or slices its lobes
|
|
8
|
+
* off at a face. {@link enclosingRadius} gives the sphere holding almost all of
|
|
9
|
+
* the electron, and the cube is drawn around that.
|
|
10
|
+
*
|
|
11
|
+
* Pure: no React, no molstar. `src/viewer` turns the returned field into a
|
|
12
|
+
* surface, and the worker calls this off the main thread.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { AtomicOrbital } from './atomicOrbitals.ts';
|
|
16
|
+
import { hydrogenicParametersOf } from './atomicOrbitals.ts';
|
|
17
|
+
import type { GridBox, OrbitalEvaluator, OrbitalGrid } from './grid.ts';
|
|
18
|
+
import { evaluateGrid } from './grid.ts';
|
|
19
|
+
import { createRadialFunction, enclosingRadius } from './hydrogenic.ts';
|
|
20
|
+
|
|
21
|
+
/** How finely, and how far out, an orbital is sampled. */
|
|
22
|
+
export interface AtomicGridOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Samples along each edge of the cube. The cost is the cube of this, and 56
|
|
25
|
+
* resolves the radial node of a 3s while staying near 30 ms.
|
|
26
|
+
* @default 56
|
|
27
|
+
*/
|
|
28
|
+
resolution?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Share of `∫ r²R² dr` the box must contain before padding.
|
|
31
|
+
* @default 0.985
|
|
32
|
+
*/
|
|
33
|
+
enclosedFraction?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Multiplier applied to the enclosing radius, so the surface closes inside
|
|
36
|
+
* the box instead of touching a face.
|
|
37
|
+
* @default 1.15
|
|
38
|
+
*/
|
|
39
|
+
padding?: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Sample an atomic orbital onto a cubic grid centred on its nucleus.
|
|
44
|
+
* @param orbital - The orbital to draw.
|
|
45
|
+
* @param options - See {@link AtomicGridOptions}.
|
|
46
|
+
* @returns The signed field, its layout and its statistics.
|
|
47
|
+
* @throws {Error} When the resolution is below 2.
|
|
48
|
+
*/
|
|
49
|
+
export function sampleAtomicOrbital(
|
|
50
|
+
orbital: AtomicOrbital,
|
|
51
|
+
options: AtomicGridOptions = {},
|
|
52
|
+
): OrbitalGrid {
|
|
53
|
+
const {
|
|
54
|
+
resolution = DEFAULT_RESOLUTION,
|
|
55
|
+
enclosedFraction = DEFAULT_ENCLOSED_FRACTION,
|
|
56
|
+
padding = DEFAULT_PADDING,
|
|
57
|
+
} = options;
|
|
58
|
+
return evaluateGrid(
|
|
59
|
+
createAtomicOrbitalEvaluator(orbital),
|
|
60
|
+
atomicGridBox(orbital, enclosedFraction, padding),
|
|
61
|
+
resolution,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Build `ψ(x, y, z) = R(r) Y(x, y, z)` for one orbital, centred on the origin.
|
|
67
|
+
* @param orbital - The orbital to evaluate.
|
|
68
|
+
* @returns An allocation-free evaluator in ångström, returning Å^(-3/2).
|
|
69
|
+
*/
|
|
70
|
+
export function createAtomicOrbitalEvaluator(
|
|
71
|
+
orbital: AtomicOrbital,
|
|
72
|
+
): OrbitalEvaluator {
|
|
73
|
+
const radial = createRadialFunction(hydrogenicParametersOf(orbital));
|
|
74
|
+
const angular = orbital.harmonic.evaluate;
|
|
75
|
+
// Every ℓ > 0 harmonic divides by the radius, and the nucleus is a grid point
|
|
76
|
+
// whenever the resolution is odd, so the singularity is real and is answered
|
|
77
|
+
// here: only an s orbital has amplitude at r = 0.
|
|
78
|
+
const atNucleus = orbital.l === 0 ? radial(0) * angular(0, 0, 0, 1) : 0;
|
|
79
|
+
return (x, y, z) => {
|
|
80
|
+
const squared = x * x + y * y + z * z;
|
|
81
|
+
if (squared === 0) return atNucleus;
|
|
82
|
+
const radius = Math.sqrt(squared);
|
|
83
|
+
return radial(radius) * angular(x, y, z, radius);
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The cube one orbital is sampled over.
|
|
89
|
+
* @param orbital - The orbital to fit.
|
|
90
|
+
* @param enclosedFraction - Share of the electron to contain.
|
|
91
|
+
* @param padding - Multiplier applied to the enclosing radius.
|
|
92
|
+
* @returns A cube centred on the nucleus.
|
|
93
|
+
*/
|
|
94
|
+
export function atomicGridBox(
|
|
95
|
+
orbital: AtomicOrbital,
|
|
96
|
+
enclosedFraction = DEFAULT_ENCLOSED_FRACTION,
|
|
97
|
+
padding = DEFAULT_PADDING,
|
|
98
|
+
): GridBox {
|
|
99
|
+
const half =
|
|
100
|
+
enclosingRadius(hydrogenicParametersOf(orbital), enclosedFraction) *
|
|
101
|
+
padding;
|
|
102
|
+
return {
|
|
103
|
+
origin: { x: -half, y: -half, z: -half },
|
|
104
|
+
size: { x: 2 * half, y: 2 * half, z: 2 * half },
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Samples per edge; the cost is the cube of it. */
|
|
109
|
+
const DEFAULT_RESOLUTION = 56;
|
|
110
|
+
|
|
111
|
+
/** A tail past this holds too little density to change the surface. */
|
|
112
|
+
const DEFAULT_ENCLOSED_FRACTION = 0.985;
|
|
113
|
+
|
|
114
|
+
/** Room for the surface to close before the box ends. */
|
|
115
|
+
const DEFAULT_PADDING = 1.15;
|