react-cheminfo 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README.md +28 -28
  2. package/bin/check-seo.mjs +333 -0
  3. package/lib/about/core/about.d.ts +1 -30
  4. package/lib/about/core/about.d.ts.map +1 -1
  5. package/lib/about/core/about.js +0 -16
  6. package/lib/about/core/about.js.map +1 -1
  7. package/lib/about/core/index.d.ts +0 -1
  8. package/lib/about/core/index.d.ts.map +1 -1
  9. package/lib/about/core/index.js +0 -1
  10. package/lib/about/core/index.js.map +1 -1
  11. package/lib/about/ui/AboutBuild.d.ts +2 -5
  12. package/lib/about/ui/AboutBuild.d.ts.map +1 -1
  13. package/lib/about/ui/AboutBuild.js +7 -19
  14. package/lib/about/ui/AboutBuild.js.map +1 -1
  15. package/lib/about/ui/AboutPage.d.ts +2 -2
  16. package/lib/about/ui/AboutPage.d.ts.map +1 -1
  17. package/lib/about/ui/AboutPage.js +3 -14
  18. package/lib/about/ui/AboutPage.js.map +1 -1
  19. package/lib/about/ui/AboutVersion.d.ts +0 -4
  20. package/lib/about/ui/AboutVersion.d.ts.map +1 -1
  21. package/lib/about/ui/AboutVersion.js +3 -31
  22. package/lib/about/ui/AboutVersion.js.map +1 -1
  23. package/lib/download/core/index.d.ts +0 -5
  24. package/lib/download/core/index.d.ts.map +1 -1
  25. package/lib/download/core/index.js +0 -3
  26. package/lib/download/core/index.js.map +1 -1
  27. package/lib/download/ui/FigureDownload.d.ts +4 -55
  28. package/lib/download/ui/FigureDownload.d.ts.map +1 -1
  29. package/lib/download/ui/FigureDownload.js +6 -66
  30. package/lib/download/ui/FigureDownload.js.map +1 -1
  31. package/lib/download/ui/FigureDownloadPanel.d.ts +16 -2
  32. package/lib/download/ui/FigureDownloadPanel.d.ts.map +1 -1
  33. package/lib/download/ui/FigureDownloadPanel.js +11 -30
  34. package/lib/download/ui/FigureDownloadPanel.js.map +1 -1
  35. package/lib/download/ui/figureDownloadHint.d.ts +30 -0
  36. package/lib/download/ui/figureDownloadHint.d.ts.map +1 -0
  37. package/lib/download/ui/figureDownloadHint.js +33 -0
  38. package/lib/download/ui/figureDownloadHint.js.map +1 -0
  39. package/lib/download/ui/index.d.ts +3 -10
  40. package/lib/download/ui/index.d.ts.map +1 -1
  41. package/lib/download/ui/index.js +1 -5
  42. package/lib/download/ui/index.js.map +1 -1
  43. package/lib/download/ui/useFigureActions.d.ts +50 -0
  44. package/lib/download/ui/useFigureActions.d.ts.map +1 -0
  45. package/lib/download/ui/useFigureActions.js +58 -0
  46. package/lib/download/ui/useFigureActions.js.map +1 -0
  47. package/lib/download/ui/useFigureDownload.d.ts +85 -0
  48. package/lib/download/ui/useFigureDownload.d.ts.map +1 -0
  49. package/lib/download/ui/useFigureDownload.js +75 -0
  50. package/lib/download/ui/useFigureDownload.js.map +1 -0
  51. package/lib/ecosystem/core/sites.d.ts.map +1 -1
  52. package/lib/ecosystem/core/sites.js +0 -40
  53. package/lib/ecosystem/core/sites.js.map +1 -1
  54. package/lib/ecosystem/core/types.d.ts +0 -10
  55. package/lib/ecosystem/core/types.d.ts.map +1 -1
  56. package/lib/i18n/core/chromeCatalog.d.ts +1 -1
  57. package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
  58. package/lib/ir/core/irCommands.d.ts +2 -2
  59. package/lib/ir/core/irCommands.js +2 -2
  60. package/lib/ir/core/irCommands.js.map +1 -1
  61. package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -1
  62. package/lib/ir/ui/IrAboutDialog.js +1 -1
  63. package/lib/ir/ui/IrAboutDialog.js.map +1 -1
  64. package/lib/ir/ui/IrCanvas.d.ts +6 -0
  65. package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
  66. package/lib/ir/ui/IrCanvas.js +2 -2
  67. package/lib/ir/ui/IrCanvas.js.map +1 -1
  68. package/lib/ir/ui/IrShell.d.ts.map +1 -1
  69. package/lib/ir/ui/IrShell.js +16 -11
  70. package/lib/ir/ui/IrShell.js.map +1 -1
  71. package/lib/ir/ui/IrToolbar.d.ts +11 -1
  72. package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
  73. package/lib/ir/ui/IrToolbar.js +12 -2
  74. package/lib/ir/ui/IrToolbar.js.map +1 -1
  75. package/lib/ir/ui/index.d.ts +1 -0
  76. package/lib/ir/ui/index.d.ts.map +1 -1
  77. package/lib/ir/ui/index.js.map +1 -1
  78. package/lib/language/core/index.d.ts +2 -0
  79. package/lib/language/core/index.d.ts.map +1 -1
  80. package/lib/language/core/index.js +1 -0
  81. package/lib/language/core/index.js.map +1 -1
  82. package/lib/language/core/languagePath.d.ts +52 -0
  83. package/lib/language/core/languagePath.d.ts.map +1 -0
  84. package/lib/language/core/languagePath.js +65 -0
  85. package/lib/language/core/languagePath.js.map +1 -0
  86. package/lib/locales/de.json +2 -4
  87. package/lib/locales/en.json +2 -4
  88. package/lib/locales/es.json +2 -4
  89. package/lib/locales/fr.json +2 -4
  90. package/lib/locales/it.json +2 -4
  91. package/lib/overlay/ui/OverlayPanel.d.ts +6 -0
  92. package/lib/overlay/ui/OverlayPanel.d.ts.map +1 -1
  93. package/lib/overlay/ui/OverlayPanel.js +2 -2
  94. package/lib/overlay/ui/OverlayPanel.js.map +1 -1
  95. package/lib/overlay/ui/overlayPanelStyles.d.ts +2 -1
  96. package/lib/overlay/ui/overlayPanelStyles.d.ts.map +1 -1
  97. package/lib/overlay/ui/overlayPanelStyles.js +3 -1
  98. package/lib/overlay/ui/overlayPanelStyles.js.map +1 -1
  99. package/lib/periodic/ui/ElementCell.d.ts +0 -6
  100. package/lib/periodic/ui/ElementCell.d.ts.map +1 -1
  101. package/lib/periodic/ui/ElementCell.js +34 -30
  102. package/lib/periodic/ui/ElementCell.js.map +1 -1
  103. package/lib/periodic/ui/PeriodicTable.d.ts.map +1 -1
  104. package/lib/periodic/ui/PeriodicTable.js +12 -15
  105. package/lib/periodic/ui/PeriodicTable.js.map +1 -1
  106. package/lib/seo/core/alternates.d.ts +40 -0
  107. package/lib/seo/core/alternates.d.ts.map +1 -0
  108. package/lib/seo/core/alternates.js +42 -0
  109. package/lib/seo/core/alternates.js.map +1 -0
  110. package/lib/seo/core/index.d.ts +3 -0
  111. package/lib/seo/core/index.d.ts.map +1 -1
  112. package/lib/seo/core/index.js +2 -0
  113. package/lib/seo/core/index.js.map +1 -1
  114. package/lib/seo/core/noscript.d.ts +9 -0
  115. package/lib/seo/core/noscript.d.ts.map +1 -1
  116. package/lib/seo/core/noscript.js +7 -2
  117. package/lib/seo/core/noscript.js.map +1 -1
  118. package/lib/seo/core/pageMeta.d.ts +23 -0
  119. package/lib/seo/core/pageMeta.d.ts.map +1 -1
  120. package/lib/seo/core/pageMeta.js +52 -3
  121. package/lib/seo/core/pageMeta.js.map +1 -1
  122. package/lib/seo/core/pageProse.d.ts +76 -0
  123. package/lib/seo/core/pageProse.d.ts.map +1 -0
  124. package/lib/seo/core/pageProse.js +92 -0
  125. package/lib/seo/core/pageProse.js.map +1 -0
  126. package/lib/seo/core/routeProblems.d.ts +33 -0
  127. package/lib/seo/core/routeProblems.d.ts.map +1 -0
  128. package/lib/seo/core/routeProblems.js +89 -0
  129. package/lib/seo/core/routeProblems.js.map +1 -0
  130. package/lib/seo/core/routes.d.ts +14 -0
  131. package/lib/seo/core/routes.d.ts.map +1 -1
  132. package/lib/seo/core/routes.js.map +1 -1
  133. package/lib/seo/core/siteFiles.d.ts.map +1 -1
  134. package/lib/seo/core/siteFiles.js +2 -1
  135. package/lib/seo/core/siteFiles.js.map +1 -1
  136. package/lib/seo/vite/prerender.d.ts +13 -0
  137. package/lib/seo/vite/prerender.d.ts.map +1 -1
  138. package/lib/seo/vite/prerender.js +17 -10
  139. package/lib/seo/vite/prerender.js.map +1 -1
  140. package/package.json +2 -1
  141. package/src/about/core/about.ts +1 -51
  142. package/src/about/core/index.ts +0 -1
  143. package/src/about/ui/AboutBuild.tsx +8 -37
  144. package/src/about/ui/AboutPage.tsx +8 -64
  145. package/src/about/ui/AboutVersion.tsx +5 -45
  146. package/src/download/core/index.ts +0 -25
  147. package/src/download/ui/FigureDownload.tsx +11 -148
  148. package/src/download/ui/FigureDownloadPanel.tsx +46 -45
  149. package/src/download/ui/figureDownloadHint.ts +52 -0
  150. package/src/download/ui/index.ts +6 -10
  151. package/src/download/ui/useFigureActions.ts +113 -0
  152. package/src/download/ui/useFigureDownload.tsx +191 -0
  153. package/src/ecosystem/core/sites.ts +0 -40
  154. package/src/ecosystem/core/types.ts +0 -10
  155. package/src/ir/core/irCommands.ts +2 -2
  156. package/src/ir/ui/IrAboutDialog.tsx +0 -13
  157. package/src/ir/ui/IrCanvas.tsx +8 -2
  158. package/src/ir/ui/IrShell.tsx +23 -25
  159. package/src/ir/ui/IrToolbar.tsx +36 -6
  160. package/src/ir/ui/index.ts +1 -0
  161. package/src/language/core/index.ts +2 -0
  162. package/src/language/core/languagePath.ts +78 -0
  163. package/src/locales/de.json +2 -4
  164. package/src/locales/en.json +2 -4
  165. package/src/locales/es.json +2 -4
  166. package/src/locales/fr.json +2 -4
  167. package/src/locales/it.json +2 -4
  168. package/src/overlay/ui/OverlayPanel.tsx +8 -2
  169. package/src/overlay/ui/overlayPanelStyles.ts +3 -0
  170. package/src/periodic/ui/ElementCell.tsx +34 -37
  171. package/src/periodic/ui/PeriodicTable.tsx +12 -17
  172. package/src/seo/core/alternates.ts +65 -0
  173. package/src/seo/core/index.ts +3 -0
  174. package/src/seo/core/noscript.ts +18 -2
  175. package/src/seo/core/pageMeta.ts +74 -3
  176. package/src/seo/core/pageProse.ts +146 -0
  177. package/src/seo/core/routeProblems.ts +111 -0
  178. package/src/seo/core/routes.ts +14 -0
  179. package/src/seo/core/siteFiles.ts +2 -1
  180. package/src/seo/vite/prerender.ts +30 -11
  181. package/lib/about/core/repository.d.ts +0 -14
  182. package/lib/about/core/repository.d.ts.map +0 -1
  183. package/lib/about/core/repository.js +0 -21
  184. package/lib/about/core/repository.js.map +0 -1
  185. package/lib/download/core/exportStyles.d.ts +0 -22
  186. package/lib/download/core/exportStyles.d.ts.map +0 -1
  187. package/lib/download/core/exportStyles.js +0 -19
  188. package/lib/download/core/exportStyles.js.map +0 -1
  189. package/lib/download/core/imageResolution.d.ts +0 -88
  190. package/lib/download/core/imageResolution.d.ts.map +0 -1
  191. package/lib/download/core/imageResolution.js +0 -77
  192. package/lib/download/core/imageResolution.js.map +0 -1
  193. package/lib/download/core/pictureExport.d.ts +0 -93
  194. package/lib/download/core/pictureExport.d.ts.map +0 -1
  195. package/lib/download/core/pictureExport.js +0 -116
  196. package/lib/download/core/pictureExport.js.map +0 -1
  197. package/lib/download/ui/ExportDialogFrame.d.ts +0 -46
  198. package/lib/download/ui/ExportDialogFrame.d.ts.map +0 -1
  199. package/lib/download/ui/ExportDialogFrame.js +0 -24
  200. package/lib/download/ui/ExportDialogFrame.js.map +0 -1
  201. package/lib/download/ui/ExportImageDialog.d.ts +0 -47
  202. package/lib/download/ui/ExportImageDialog.d.ts.map +0 -1
  203. package/lib/download/ui/ExportImageDialog.js +0 -25
  204. package/lib/download/ui/ExportImageDialog.js.map +0 -1
  205. package/lib/download/ui/ExportNameField.d.ts +0 -29
  206. package/lib/download/ui/ExportNameField.d.ts.map +0 -1
  207. package/lib/download/ui/ExportNameField.js +0 -99
  208. package/lib/download/ui/ExportNameField.js.map +0 -1
  209. package/lib/download/ui/ExportPictureSection.d.ts +0 -38
  210. package/lib/download/ui/ExportPictureSection.d.ts.map +0 -1
  211. package/lib/download/ui/ExportPictureSection.js +0 -48
  212. package/lib/download/ui/ExportPictureSection.js.map +0 -1
  213. package/lib/download/ui/useDrawingBox.d.ts +0 -23
  214. package/lib/download/ui/useDrawingBox.d.ts.map +0 -1
  215. package/lib/download/ui/useDrawingBox.js +0 -21
  216. package/lib/download/ui/useDrawingBox.js.map +0 -1
  217. package/src/about/core/repository.ts +0 -22
  218. package/src/download/core/exportStyles.ts +0 -20
  219. package/src/download/core/imageResolution.ts +0 -118
  220. package/src/download/core/pictureExport.ts +0 -207
  221. package/src/download/ui/ExportDialogFrame.tsx +0 -86
  222. package/src/download/ui/ExportImageDialog.tsx +0 -91
  223. package/src/download/ui/ExportNameField.tsx +0 -148
  224. package/src/download/ui/ExportPictureSection.tsx +0 -142
  225. package/src/download/ui/useDrawingBox.ts +0 -37
@@ -20,7 +20,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
20
20
  id: 'learn',
21
21
  name: { lead: 'learn', alt: 'cheminfo', dot: true },
22
22
  host: 'learn.cheminfo.org',
23
- repository: 'https://github.com/cheminfo/learn.cheminfo.org',
24
23
  tagline: 'Arrange the tools into a course and hand out its link.',
25
24
  group: 'computing',
26
25
  brand: '#0d9488',
@@ -31,7 +30,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
31
30
  id: 'inchi',
32
31
  name: { lead: 'inchi', alt: 'cheminfo', dot: true },
33
32
  host: 'inchi.cheminfo.org',
34
- repository: 'https://github.com/cheminfo/inchi.cheminfo.org',
35
33
  tagline: 'InChI and InChIKey from a structure, in the browser.',
36
34
  group: 'structures',
37
35
  brand: '#5b21b6',
@@ -42,7 +40,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
42
40
  id: 'vcl',
43
41
  name: { lead: 'vcl', alt: 'cheminfo', dot: true },
44
42
  host: 'vcl.cheminfo.org',
45
- repository: 'https://github.com/cheminfo/vcl.cheminfo.org',
46
43
  tagline: 'Combine a core and fragments into a screened library.',
47
44
  group: 'research',
48
45
  brand: '#2d72d2',
@@ -53,7 +50,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
53
50
  id: 'smiles',
54
51
  name: { lead: 'smiles', alt: 'cheminfo', dot: true },
55
52
  host: 'smiles.cheminfo.org',
56
- repository: 'https://github.com/cheminfo/smiles.cheminfo.org',
57
53
  tagline: 'Draw a structure, read its SMILES, learn the notation.',
58
54
  group: 'structures',
59
55
  brand: '#1c6e42',
@@ -64,8 +60,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
64
60
  id: 'openbabel',
65
61
  name: { lead: 'openbabel', alt: 'cheminfo', dot: true },
66
62
  host: 'openbabel.cheminfo.org',
67
- repository: 'https://github.com/cheminfo/openbabel.cheminfo.org',
68
- publicRepository: true,
69
63
  tagline: 'Convert a structure between any pair of chemical file formats.',
70
64
  group: 'structures',
71
65
  brand: '#0f766e',
@@ -76,7 +70,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
76
70
  id: 'chemcalc',
77
71
  name: { lead: 'Chem', alt: 'Calc' },
78
72
  host: 'www.chemcalc.org',
79
- repository: 'https://github.com/cheminfo/chemcalc.org',
80
73
  tagline: 'Molecular formula, exact mass and isotopic distribution.',
81
74
  group: 'basics',
82
75
  brand: '#5b52e0',
@@ -87,8 +80,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
87
80
  id: 'dbe',
88
81
  name: { lead: 'dbe', alt: 'cheminfo', dot: true },
89
82
  host: 'dbe.cheminfo.org',
90
- repository: 'https://github.com/cheminfo/dbe.cheminfo.org',
91
- publicRepository: true,
92
83
  tagline: 'Count rings and double bonds from a formula or a structure.',
93
84
  group: 'basics',
94
85
  brand: '#63123f',
@@ -101,8 +92,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
101
92
  id: 'nmrium',
102
93
  name: { lead: 'NMR', alt: 'ium' },
103
94
  host: 'www.nmrium.org',
104
- repository: 'https://github.com/cheminfo/nmrium',
105
- publicRepository: true,
106
95
  tagline: 'Process and assign NMR spectra in the browser.',
107
96
  group: 'spectra',
108
97
  brand: '#ea580c',
@@ -116,7 +105,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
116
105
  // of the cheminfo tools.
117
106
  name: { lead: 'metabo', alt: 'nmrium', dot: true },
118
107
  host: 'metabo.nmrium.com',
119
- repository: 'https://github.com/cheminfo/metabo',
120
108
  tagline: 'Turn a batch of NMR spectra into a map of your samples.',
121
109
  group: 'spectra',
122
110
  brand: '#4d7c0f',
@@ -129,7 +117,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
129
117
  id: 'derepflow',
130
118
  name: { lead: 'Derep', alt: 'Flow', ink: 'lead' },
131
119
  host: 'derepflow.cheminfo.org',
132
- repository: 'https://github.com/cheminfo/derepflow',
133
120
  tagline: 'Identify the constituents of a mixture from its ¹³C spectrum.',
134
121
  group: 'spectra',
135
122
  brand: '#127ba3',
@@ -140,8 +127,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
140
127
  id: 'surge',
141
128
  name: { lead: 'surge', alt: 'cheminfo', dot: true },
142
129
  host: 'surge.cheminfo.org',
143
- repository: 'https://github.com/cheminfo/surge.cheminfo.org',
144
- publicRepository: true,
145
130
  tagline: 'Every constitutional isomer of a molecular formula.',
146
131
  group: 'structures',
147
132
  brand: '#4338ca',
@@ -152,8 +137,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
152
137
  id: 'tex',
153
138
  name: { lead: 'tex', alt: 'cheminfo', dot: true },
154
139
  host: 'tex.cheminfo.org',
155
- repository: 'https://github.com/cheminfo/tex.cheminfo.org',
156
- publicRepository: true,
157
140
  tagline: 'LaTeX formulas rendered to SVG or PNG from a URL.',
158
141
  group: 'computing',
159
142
  brand: '#a21caf',
@@ -164,7 +147,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
164
147
  id: 'lcao',
165
148
  name: { lead: 'lcao', alt: 'cheminfo', dot: true },
166
149
  host: 'lcao.cheminfo.org',
167
- repository: 'https://github.com/cheminfo/lcao.cheminfo.org',
168
150
  tagline: 'Combine atomic orbitals into molecular ones.',
169
151
  group: 'basics',
170
152
  brand: '#1565c0',
@@ -175,8 +157,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
175
157
  id: 'regexp',
176
158
  name: { lead: 'regexp', alt: 'cheminfo', dot: true },
177
159
  host: 'regexp.cheminfo.org',
178
- repository: 'https://github.com/cheminfo/regexp.cheminfo.org',
179
- publicRepository: true,
180
160
  tagline: 'Learn regular expressions in a live playground.',
181
161
  group: 'computing',
182
162
  brand: '#1e3a8a',
@@ -187,8 +167,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
187
167
  id: 'pdb',
188
168
  name: { lead: 'pdb', alt: 'cheminfo', dot: true },
189
169
  host: 'pdb.cheminfo.org',
190
- repository: 'https://github.com/cheminfo/pdb.cheminfo.org',
191
- publicRepository: true,
192
170
  tagline: 'A fast look at any Protein Data Bank entry.',
193
171
  group: 'research',
194
172
  brand: '#2563eb',
@@ -199,8 +177,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
199
177
  id: 'elucidation',
200
178
  name: { lead: 'elucidation', alt: 'cheminfo', dot: true },
201
179
  host: 'elucidation.cheminfo.org',
202
- repository: 'https://github.com/cheminfo/elucidation.cheminfo.org',
203
- publicRepository: true,
204
180
  tagline: 'A structure from a 1H NMR spectrum and a formula.',
205
181
  group: 'spectra',
206
182
  brand: '#7e22ce',
@@ -211,7 +187,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
211
187
  id: 'equilibrium',
212
188
  name: { lead: 'Equi', alt: 'Librium' },
213
189
  host: 'equilibrium.cheminfo.org',
214
- repository: 'https://github.com/cheminfo/equilibrium.cheminfo.org',
215
190
  tagline: 'Chemical equilibria: pH, speciation and titration curves.',
216
191
  group: 'basics',
217
192
  brand: '#0b5754',
@@ -222,8 +197,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
222
197
  id: 'polycarp',
223
198
  name: { lead: 'Poly', alt: 'Carp' },
224
199
  host: 'polycarp.cheminfo.org',
225
- repository: 'https://github.com/cheminfo/polycarp.cheminfo.org',
226
- publicRepository: true,
227
200
  tagline: 'Predict the microstructure of a radical copolymerisation.',
228
201
  group: 'research',
229
202
  brand: '#701a75',
@@ -234,7 +207,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
234
207
  id: '3d',
235
208
  name: { lead: '3d', alt: 'cheminfo', dot: true },
236
209
  host: '3d.cheminfo.org',
237
- repository: 'https://github.com/cheminfo/3d.cheminfo.org',
238
210
  tagline: 'Conformers in 3D from a structure you draw.',
239
211
  group: 'structures',
240
212
  brand: '#155e75',
@@ -245,7 +217,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
245
217
  id: 'periodic-table',
246
218
  name: { lead: 'Periodic', alt: 'Table' },
247
219
  host: 'periodic-table.cheminfo.org',
248
- repository: 'https://github.com/cheminfo/periodic-table.cheminfo.org',
249
220
  tagline: 'The periodic table, coloured, plotted and taken apart.',
250
221
  group: 'basics',
251
222
  brand: '#15803d',
@@ -256,8 +227,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
256
227
  id: 'database',
257
228
  name: { lead: 'database', alt: 'cheminfo', dot: true },
258
229
  host: 'database.cheminfo.org',
259
- repository: 'https://github.com/cheminfo/database.cheminfo.org',
260
- publicRepository: true,
261
230
  tagline: 'Query a real chemical dataset in SQL and in Mango.',
262
231
  group: 'research',
263
232
  brand: '#7c2d12',
@@ -268,8 +237,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
268
237
  id: 'symmetry',
269
238
  name: { lead: 'Symme', alt: 'Try' },
270
239
  host: 'symmetry.cheminfo.org',
271
- repository: 'https://github.com/cheminfo/symmetry.cheminfo.org',
272
- publicRepository: true,
273
240
  tagline: 'Find the symmetry of a molecule, a crystal or a pattern.',
274
241
  group: 'basics',
275
242
  brand: '#9f1239',
@@ -282,8 +249,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
282
249
  id: 'osiris',
283
250
  name: { lead: 'osiris', alt: 'cheminfo', dot: true },
284
251
  host: 'osiris.cheminfo.org',
285
- repository: 'https://github.com/cheminfo/osiris.cheminfo.org',
286
- publicRepository: true,
287
252
  tagline: 'Predicted toxicity risks and properties, one molecule or many.',
288
253
  group: 'research',
289
254
  brand: '#854d0e',
@@ -297,8 +262,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
297
262
  id: 'atoms',
298
263
  name: { lead: 'atoms', alt: 'cheminfo', dot: true },
299
264
  host: 'atoms.cheminfo.org',
300
- repository: 'https://github.com/cheminfo/atoms.cheminfo.org',
301
- publicRepository: true,
302
265
  tagline: 'Electrons, neutrons, Lewis structures and oxidation states.',
303
266
  group: 'practice',
304
267
  brand: '#b91c1c',
@@ -311,8 +274,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
311
274
  id: 'moles',
312
275
  name: { lead: 'moles', alt: 'cheminfo', dot: true },
313
276
  host: 'moles.cheminfo.org',
314
- repository: 'https://github.com/cheminfo/moles.cheminfo.org',
315
- publicRepository: true,
316
277
  tagline: 'Balance a reaction, and work out its mass composition.',
317
278
  group: 'practice',
318
279
  brand: '#334155',
@@ -325,7 +286,6 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
325
286
  id: 'inorganic',
326
287
  name: { lead: 'inorganic', alt: 'cheminfo', dot: true },
327
288
  host: 'inorganic.cheminfo.org',
328
- repository: 'https://github.com/cheminfo/inorganic.cheminfo.org',
329
289
  tagline: 'Name an inorganic compound, and write its formula.',
330
290
  group: 'practice',
331
291
  brand: '#a3620a',
@@ -65,16 +65,6 @@ export interface SiteRecord {
65
65
  name: SiteName;
66
66
  /** Where the site lives, written the way it is typed. */
67
67
  host: string;
68
- /** Where the sources live, and what a Source link opens. */
69
- repository: string;
70
- /**
71
- * Whether a visitor can open that repository. A private one is named
72
- * nowhere: no licence-and-source section, no link from the version, no issue
73
- * tracker a reader cannot reach. It is stated rather than assumed, so a site
74
- * whose record forgets it advertises nothing rather than a dead link.
75
- * @default false
76
- */
77
- publicRepository?: boolean;
78
68
  /** One line on what the site does. */
79
69
  tagline: string;
80
70
  /**
@@ -120,10 +120,10 @@ export const irCommands = {
120
120
  'Writes what each labelled band might be under its wavenumber. Worth turning off once the chart is crowded.',
121
121
  },
122
122
  exportImage: {
123
- title: 'Export as an image…',
123
+ title: 'Save figure…',
124
124
  shortcut: { keys: ['x'] },
125
125
  description:
126
- 'The chart as it stands, at a chosen resolution — PNG, or SVG, which is drawn again at whatever size it is printed rather than enlarged.',
126
+ 'The chart as it stands, saved as a PNG or an SVG at a chosen resolution, or copied as a PNG.',
127
127
  },
128
128
  clear: {
129
129
  title: 'Close every spectrum',
@@ -82,19 +82,6 @@ export function IrAboutDialog(props: IrAboutDialogProps) {
82
82
  reader with a colour vision deficiency.
83
83
  </li>
84
84
  </ul>
85
-
86
- <h4 style={headingStyle}>Licence</h4>
87
- <p style={paragraphStyle}>
88
- MIT, in the{' '}
89
- <a
90
- href="https://github.com/cheminfo/glycans"
91
- target="_blank"
92
- rel="noopener noreferrer"
93
- >
94
- cheminfo/glycans
95
- </a>{' '}
96
- monorepo.
97
- </p>
98
85
  </DialogBody>
99
86
  </Dialog>
100
87
  );
@@ -26,6 +26,12 @@ export interface IrCanvasProps {
26
26
  * @default undefined
27
27
  */
28
28
  attachChart?: (element: HTMLDivElement | null) => void;
29
+ /**
30
+ * The `id` put on the box the chart is drawn in, which the "Save figure"
31
+ * panel is pointed at.
32
+ * @default undefined
33
+ */
34
+ chartId?: string;
29
35
  }
30
36
 
31
37
  /**
@@ -44,7 +50,7 @@ export interface IrCanvasProps {
44
50
  * @returns The canvas.
45
51
  */
46
52
  export function IrCanvas(props: IrCanvasProps) {
47
- const { highlight = null, onHighlight, attachChart } = props;
53
+ const { highlight = null, onHighlight, attachChart, chartId } = props;
48
54
  const { state, visibleSpectra, assigned } = useIrEditorState();
49
55
  const actions = useIrActions();
50
56
  const { domain, tool, selectedId } = state.view;
@@ -59,7 +65,7 @@ export function IrCanvas(props: IrCanvasProps) {
59
65
 
60
66
  return (
61
67
  <div style={rootStyle}>
62
- <div ref={attachChart} style={chartStyle}>
68
+ <div ref={attachChart} id={chartId} style={chartStyle}>
63
69
  <IrChart
64
70
  spectra={visibleSpectra}
65
71
  mode={mode}
@@ -1,10 +1,15 @@
1
1
  import type { Ref } from 'react';
2
- import { useCallback, useImperativeHandle, useMemo, useState } from 'react';
2
+ import {
3
+ useCallback,
4
+ useId,
5
+ useImperativeHandle,
6
+ useMemo,
7
+ useState,
8
+ } from 'react';
3
9
  import { SplitPane, useFullscreen } from 'react-science/ui';
4
10
 
5
11
  import { sanitizeFileName } from '../../download/core/sanitizeFileName.ts';
6
- import { ExportImageDialog } from '../../download/ui/ExportImageDialog.tsx';
7
- import { useDrawingBox } from '../../download/ui/useDrawingBox.ts';
12
+ import { useFigureDownload } from '../../download/ui/useFigureDownload.tsx';
8
13
  import { PanelRail } from '../../panel/ui/PanelRail.tsx';
9
14
  import type { IrBand } from '../core/irBand.ts';
10
15
  import type { IrCommandHandlers } from '../core/irCommands.ts';
@@ -58,12 +63,16 @@ export function IrShell(props: IrShellProps) {
58
63
 
59
64
  const [isAboutOpen, setIsAboutOpen] = useState(false);
60
65
  const [isDocumentationOpen, setIsDocumentationOpen] = useState(false);
61
- const [isExportImageOpen, setIsExportImageOpen] = useState(false);
62
66
 
63
- // The chart is the picture, so the box it is drawn in is what the export
64
- // dialog is pointed at: the viewer around it is full of SVG — every icon in
65
- // every toolbar is one — and the first found there would be a magnifier.
66
- const chart = useDrawingBox();
67
+ // The chart is the picture, so the box it is drawn in is what the figure
68
+ // panel is pointed at: the viewer around it is full of SVG — every icon in
69
+ // every toolbar is one.
70
+ const chartId = useId();
71
+ const figure = useFigureDownload({
72
+ targetId: chartId,
73
+ fileName: pictureName(visibleSpectra, selectedSpectrum),
74
+ });
75
+ const { isOpen: isFigureOpen, setOpen: setFigureOpen } = figure;
67
76
  // The highlight is held here rather than in the reducer: what the pointer is
68
77
  // resting on is not part of the document and changes on every move across the
69
78
  // chart, so putting it through the reducer would run every panel's memo sixty
@@ -106,7 +115,7 @@ export function IrShell(props: IrShellProps) {
106
115
  togglePicking: () => actions.setSettings({ pickBands: !pickBands }),
107
116
  toggleAssignments: () =>
108
117
  actions.setSettings({ showAssignments: !showAssignments }),
109
- exportImage: () => setIsExportImageOpen(true),
118
+ exportImage: () => setFigureOpen(!isFigureOpen),
110
119
  clear: () => actions.clear(),
111
120
  }),
112
121
  [
@@ -117,6 +126,8 @@ export function IrShell(props: IrShellProps) {
117
126
  showAssignments,
118
127
  scaleValueAxis,
119
128
  toggleFullScreen,
129
+ isFigureOpen,
130
+ setFigureOpen,
120
131
  ],
121
132
  );
122
133
 
@@ -176,7 +187,7 @@ export function IrShell(props: IrShellProps) {
176
187
  default: in a narrow viewer the row would take the width it is
177
188
  short of out of them, and half an icon is what that looks like. */}
178
189
  <div style={railStyle}>
179
- <IrToolbar />
190
+ <IrToolbar figure={figure} />
180
191
  </div>
181
192
 
182
193
  <SplitPane
@@ -189,7 +200,7 @@ export function IrShell(props: IrShellProps) {
189
200
  <IrCanvas
190
201
  highlight={highlight}
191
202
  onHighlight={setHighlight}
192
- attachChart={chart.attach}
203
+ chartId={chartId}
193
204
  />
194
205
 
195
206
  <IrSidePanel highlight={highlight} onHighlight={setHighlight} />
@@ -215,19 +226,6 @@ export function IrShell(props: IrShellProps) {
215
226
  isOpen={isDocumentationOpen}
216
227
  onClose={() => setIsDocumentationOpen(false)}
217
228
  />
218
-
219
- {/* `element`, not `content`: the chart is drawn to the box it was given,
220
- so the box is the picture — measuring the marks inside it would crop
221
- the frame to wherever the trace happens to reach and leave the axes
222
- hanging. */}
223
- <ExportImageDialog
224
- isOpen={isExportImageOpen}
225
- getDrawing={chart.getDrawing}
226
- frame="element"
227
- filename={pictureName(visibleSpectra, selectedSpectrum)}
228
- label="Infrared spectrum"
229
- onClose={() => setIsExportImageOpen(false)}
230
- />
231
229
  </IrCommandProvider>
232
230
  );
233
231
  }
@@ -245,7 +243,7 @@ const ZOOM_STEP = 1.2;
245
243
  const DEFAULT_FRAME_WIDTH = 200;
246
244
 
247
245
  /**
248
- * What a picture of the chart is called before anything is typed in the box.
246
+ * What a picture of the chart is called.
249
247
  *
250
248
  * The spectrum being looked at, since a figure of the chart is a figure of that
251
249
  * spectrum, and a chemist who has one run open should not have to work out
@@ -1,10 +1,20 @@
1
1
  import { Toolbar } from 'react-science/ui';
2
2
 
3
+ import type { FigureDownloadState } from '../../download/ui/useFigureDownload.tsx';
3
4
  import { boxZoomOnly } from '../core/irMode.ts';
4
5
 
5
6
  import { useIrCommandProps } from './irCommandContext.tsx';
6
7
  import { useIrEditorState } from './irStateContext.ts';
7
8
 
9
+ /** What {@link IrToolbar} needs. */
10
+ export interface IrToolbarProps {
11
+ /**
12
+ * The "Save figure" panel the picture button opens.
13
+ * @default undefined — the button only runs the `exportImage` command
14
+ */
15
+ figure?: FigureDownloadState;
16
+ }
17
+
8
18
  /**
9
19
  * The tools, down the left of the chart.
10
20
  *
@@ -19,9 +29,11 @@ import { useIrEditorState } from './irStateContext.ts';
19
29
  * drag on that axis is a rectangle, so both buttons go dead with the square zoom
20
30
  * lit. Showing `read` as available there would offer a gesture the chart does not
21
31
  * make, and showing it as *active* would name the wrong one.
32
+ * @param props - Component props.
22
33
  * @returns The toolbar.
23
34
  */
24
- export function IrToolbar() {
35
+ export function IrToolbar(props: IrToolbarProps) {
36
+ const { figure } = props;
25
37
  const { state, selectedSpectrum } = useIrEditorState();
26
38
  const command = useIrCommandProps();
27
39
  const { spectra } = state.data;
@@ -29,6 +41,8 @@ export function IrToolbar() {
29
41
  const { mode, pickBands, showAssignments } = state.settings;
30
42
 
31
43
  const isEmpty = spectra.length === 0;
44
+ // The popover opens the panel itself, so the command's own click is left out.
45
+ const exportCommand = command('exportImage');
32
46
  const settled = boxZoomOnly(mode);
33
47
 
34
48
  return (
@@ -92,11 +106,27 @@ export function IrToolbar() {
92
106
  window it was dragged to, the way up it is being read, the
93
107
  assignments written under the bands — so the picture is taken here
94
108
  rather than rebuilt from the spectra in a panel. */}
95
- <Toolbar.Item
96
- icon="media"
97
- {...command('exportImage')}
98
- disabled={isEmpty}
99
- />
109
+ {figure === undefined ? (
110
+ <Toolbar.Item
111
+ icon="media"
112
+ {...command('exportImage')}
113
+ disabled={isEmpty}
114
+ />
115
+ ) : (
116
+ <Toolbar.PopoverItem
117
+ isOpen={figure.isOpen}
118
+ onInteraction={figure.setOpen}
119
+ content={figure.panel}
120
+ disabled={isEmpty}
121
+ itemProps={{
122
+ icon: 'media',
123
+ tooltip: exportCommand.tooltip,
124
+ 'aria-label': exportCommand['aria-label'],
125
+ active: figure.isOpen,
126
+ disabled: isEmpty,
127
+ }}
128
+ />
129
+ )}
100
130
  </Toolbar>
101
131
  );
102
132
  }
@@ -34,6 +34,7 @@ export { IrSidePanel } from './IrSidePanel.tsx';
34
34
  export type { IrStateProviderProps } from './IrStateProvider.tsx';
35
35
  export { IrStateProvider } from './IrStateProvider.tsx';
36
36
  export { IrStatusBar } from './IrStatusBar.tsx';
37
+ export type { IrToolbarProps } from './IrToolbar.tsx';
37
38
  export { IrToolbar } from './IrToolbar.tsx';
38
39
  export type { IrTracesProps } from './IrTraces.tsx';
39
40
  export { IrTraces } from './IrTraces.tsx';
@@ -1,4 +1,6 @@
1
1
  export { languageName } from './languageName.ts';
2
+ export type { LanguagePath } from './languagePath.ts';
3
+ export { readLanguagePath, withLanguagePath } from './languagePath.ts';
2
4
  export {
3
5
  LANGUAGE_PARAM,
4
6
  isLanguageTag,
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The language a translated site routes by: a prefix on its own addresses.
3
+ *
4
+ * `/fr/tutorial` is the French tutorial, and English is written with no prefix
5
+ * at all, so every link already handed out in a course stays alive and the site
6
+ * does not acquire a second spelling of its own front page.
7
+ *
8
+ * This is the half of the design that makes a translation *findable*. A site
9
+ * that keeps its language in a query parameter, in the hash or in
10
+ * `localStorage` serves five languages at one address: a crawler sees one page,
11
+ * indexes one language, and the other four may as well not have been written.
12
+ * The parameter stays — it is how the language travels to a sibling that may
13
+ * not speak it (`./languageParam.ts`) — but it is not how a translated site
14
+ * routes.
15
+ *
16
+ * The prefix sits between the mount and the route, so a tool served as one of
17
+ * several on a shared host reads `/surge/fr/exercises`: the mount comes off
18
+ * first (`router/core/basePath.ts`), then the language, then the table is read.
19
+ */
20
+
21
+ import type { Language } from '../../i18n/core/languages.ts';
22
+ import { DEFAULT_LANGUAGE } from '../../i18n/core/languages.ts';
23
+ import { trimTrailingSlash } from '../../router/core/address.ts';
24
+
25
+ /** An address split into the language it names and the page it opens. */
26
+ export interface LanguagePath {
27
+ /** The language named, or the default one when the address names none. */
28
+ language: Language;
29
+ /** The address from the site's own root, with the prefix taken off. */
30
+ path: string;
31
+ }
32
+
33
+ /**
34
+ * Read the language prefix off one of the site's own addresses.
35
+ *
36
+ * Only a language the site actually speaks is read as a prefix: on a site with
37
+ * no Italian, `/it` is whatever page is called `it`, not an empty Italian front
38
+ * page. So the list is the site's, never the family's.
39
+ * @param path - An address from the site's own root, the mount already off,
40
+ * e.g. `/fr/tutorial`.
41
+ * @param languages - The languages this site is written in, the default one
42
+ * included.
43
+ * @returns The language it names and the page it opens.
44
+ */
45
+ export function readLanguagePath(
46
+ path: string,
47
+ languages: readonly Language[],
48
+ ): LanguagePath {
49
+ const opened = path.startsWith('/') ? path : `/${path}`;
50
+ const cut = opened.indexOf('/', 1);
51
+ const first = cut === -1 ? opened.slice(1) : opened.slice(1, cut);
52
+
53
+ for (const language of languages) {
54
+ if (language === DEFAULT_LANGUAGE || language !== first) continue;
55
+ const rest = cut === -1 ? '/' : opened.slice(cut);
56
+ return { language, path: trimTrailingSlash(rest) || '/' };
57
+ }
58
+ return {
59
+ language: DEFAULT_LANGUAGE,
60
+ path: trimTrailingSlash(opened) || '/',
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Write one of the site's own addresses in a language.
66
+ *
67
+ * The default language is written with no prefix: an address naming no language
68
+ * is English, which is what keeps every link handed out before the site was
69
+ * translated pointing at the same page.
70
+ * @param language - The language to write it in.
71
+ * @param path - The address from the site's own root, e.g. `/tutorial`.
72
+ * @returns The address under that language, e.g. `/fr/tutorial`.
73
+ */
74
+ export function withLanguagePath(language: Language, path: string): string {
75
+ const opened = path.startsWith('/') ? path : `/${path}`;
76
+ if (language === DEFAULT_LANGUAGE) return opened;
77
+ return opened === '/' ? `/${language}` : `/${language}${opened}`;
78
+ }
@@ -86,10 +86,6 @@
86
86
  "about.whatYouCanDo": "Was Sie hier tun können",
87
87
  "about.builtOn": "Aufgebaut auf",
88
88
  "about.howToCite": "Wie zu zitieren",
89
- "about.licenceAndSource": "Lizenz und Quelltext",
90
- "about.licence": "{license}, © cheminfo. Nutzen Sie es in einem Kurs, forken Sie es, oder übernehmen Sie einen Teil davon anderswo. Der Quelltext liegt auf {sources}.",
91
- "about.foundAProblem": "Ein Problem gefunden?",
92
- "about.reportIt": "Sagen Sie es uns: ein Bericht, der nennt, was Sie eingegeben haben und was zurückkam, ist die schnellste Korrektur, die es gibt. {tracker}.",
93
89
  "about.citeWork": "{what} zitieren",
94
90
  "about.built": "Erstellt {builtAt}.",
95
91
  "about.builtFromCommit": "Erstellt {builtAt} aus Commit {commit}.",
@@ -189,6 +185,8 @@
189
185
  "download.hintRasterSvg": "Ein SVG, das ein Bild von {pixels} enthält: eine 3D-Szene hat keine Vektorform.",
190
186
  "download.hintSvg": "Öffnet sich mit {pixels} und bleibt in jeder Größe scharf.",
191
187
  "download.hintPng": "Gespeichert {pixels}.",
188
+ "download.hintCopied": "In die Zwischenablage kopiert: PNG mit {pixels}.",
189
+ "download.copyUnsupported": "Dieser Browser kann kein Bild in die Zwischenablage legen. Speichern Sie es stattdessen.",
192
190
  "download.size": "Größe",
193
191
  "download.sizeHelp": "Die Form, in der die Abbildung für die Datei gezeichnet wird. Sie wird neu gesetzt, sodass Achsen und Beschriftungen in diese Form passen, statt hineingedehnt zu werden. Eine Zeitschriftenspalte ist 8,5 cm breit, und ihr Text wird in der Größe gedruckt, in der er auf dem Bildschirm steht.",
194
192
  "download.sizeScreen": "Wie angezeigt",
@@ -86,10 +86,6 @@
86
86
  "about.whatYouCanDo": "What you can do here",
87
87
  "about.builtOn": "Built on",
88
88
  "about.howToCite": "How to cite",
89
- "about.licenceAndSource": "Licence and source",
90
- "about.licence": "{license}, © cheminfo. Use it in a course, fork it, or lift a piece of it into something else. The sources are at {sources}.",
91
- "about.foundAProblem": "Found a problem?",
92
- "about.reportIt": "Tell us: a report naming what you typed and what came back is the fastest fix there is. {tracker}.",
93
89
  "about.citeWork": "Cite {what}",
94
90
  "about.built": "Built {builtAt}.",
95
91
  "about.builtFromCommit": "Built {builtAt} from commit {commit}.",
@@ -189,6 +185,8 @@
189
185
  "download.hintRasterSvg": "An SVG holding a picture of {pixels}: a 3D scene has no vector form.",
190
186
  "download.hintSvg": "Opens at {pixels}, and stays sharp at any size.",
191
187
  "download.hintPng": "Saved {pixels}.",
188
+ "download.hintCopied": "Copied {pixels} to the clipboard, as a PNG.",
189
+ "download.copyUnsupported": "This browser cannot put a picture on the clipboard. Save it instead.",
192
190
  "download.size": "Size",
193
191
  "download.sizeHelp": "The shape the figure is drawn at for the file. It is laid out again, so the axes and labels fit that shape instead of being stretched into it. A journal column is 8.5 cm wide, and its text prints at the size it reads on screen.",
194
192
  "download.sizeScreen": "As shown",
@@ -86,10 +86,6 @@
86
86
  "about.whatYouCanDo": "Lo que puede hacer aquí",
87
87
  "about.builtOn": "Construido sobre",
88
88
  "about.howToCite": "Cómo citar",
89
- "about.licenceAndSource": "Licencia y código fuente",
90
- "about.licence": "{license}, © cheminfo. Úselo en un curso, bifúrquelo, o llévese un trozo a otra parte. El código está en {sources}.",
91
- "about.foundAProblem": "¿Ha encontrado un problema?",
92
- "about.reportIt": "Díganoslo: un informe que indique lo que escribió y lo que obtuvo es la corrección más rápida que existe. {tracker}.",
93
89
  "about.citeWork": "Citar {what}",
94
90
  "about.built": "Compilado {builtAt}.",
95
91
  "about.builtFromCommit": "Compilado {builtAt} desde el commit {commit}.",
@@ -189,6 +185,8 @@
189
185
  "download.hintRasterSvg": "Un SVG que contiene una imagen de {pixels}: una escena 3D no tiene forma vectorial.",
190
186
  "download.hintSvg": "Se abre a {pixels}, y se mantiene nítido a cualquier tamaño.",
191
187
  "download.hintPng": "Guardado {pixels}.",
188
+ "download.hintCopied": "Copiado al portapapeles: PNG de {pixels}.",
189
+ "download.copyUnsupported": "Este navegador no puede poner una imagen en el portapapeles. Guárdala en su lugar.",
192
190
  "download.size": "Tamaño",
193
191
  "download.sizeHelp": "La forma con la que se dibuja la figura para el archivo. Se vuelve a maquetar, de modo que los ejes y las etiquetas se ajustan a esa forma en lugar de estirarse. Una columna de revista mide 8,5 cm, y su texto se imprime al tamaño con que se lee en pantalla.",
194
192
  "download.sizeScreen": "Como se muestra",
@@ -86,10 +86,6 @@
86
86
  "about.whatYouCanDo": "Ce que vous pouvez faire ici",
87
87
  "about.builtOn": "Construit sur",
88
88
  "about.howToCite": "Comment citer",
89
- "about.licenceAndSource": "Licence et sources",
90
- "about.licence": "{license}, © cheminfo. Utilisez-le dans un cours, forkez-le, ou reprenez-en un morceau ailleurs. Les sources sont sur {sources}.",
91
- "about.foundAProblem": "Un problème ?",
92
- "about.reportIt": "Dites-le-nous : un rapport indiquant ce que vous avez saisi et ce qui est revenu est la correction la plus rapide qui soit. {tracker}.",
93
89
  "about.citeWork": "Citer {what}",
94
90
  "about.built": "Compilé {builtAt}.",
95
91
  "about.builtFromCommit": "Compilé {builtAt} depuis le commit {commit}.",
@@ -189,6 +185,8 @@
189
185
  "download.hintRasterSvg": "Un SVG contenant une image de {pixels} : une scène 3D n'a pas de forme vectorielle.",
190
186
  "download.hintSvg": "S'ouvre à {pixels}, et reste net à toute taille.",
191
187
  "download.hintPng": "Enregistré {pixels}.",
188
+ "download.hintCopied": "Copié dans le presse-papiers : PNG de {pixels}.",
189
+ "download.copyUnsupported": "Ce navigateur ne peut pas copier une image dans le presse-papiers. Enregistrez-la plutôt.",
192
190
  "download.size": "Taille",
193
191
  "download.sizeHelp": "La forme à laquelle la figure est dessinée pour le fichier. Elle est remise en page, si bien que les axes et les étiquettes s'ajustent à cette forme au lieu d'y être étirés. Une colonne de revue mesure 8,5 cm, et son texte s'imprime à la taille où il se lit à l'écran.",
194
192
  "download.sizeScreen": "Comme affichée",