react-cheminfo 0.23.0 → 0.24.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 (260) hide show
  1. package/README.md +39 -26
  2. package/lib/chrome/ui/HeaderToggle.d.ts +52 -0
  3. package/lib/chrome/ui/HeaderToggle.d.ts.map +1 -0
  4. package/lib/chrome/ui/HeaderToggle.js +31 -0
  5. package/lib/chrome/ui/HeaderToggle.js.map +1 -0
  6. package/lib/chrome/ui/index.d.ts +2 -0
  7. package/lib/chrome/ui/index.d.ts.map +1 -1
  8. package/lib/chrome/ui/index.js +1 -0
  9. package/lib/chrome/ui/index.js.map +1 -1
  10. package/lib/citation/core/gfn2Paper.d.ts +10 -0
  11. package/lib/citation/core/gfn2Paper.d.ts.map +1 -0
  12. package/lib/citation/core/gfn2Paper.js +28 -0
  13. package/lib/citation/core/gfn2Paper.js.map +1 -0
  14. package/lib/citation/core/index.d.ts +1 -0
  15. package/lib/citation/core/index.d.ts.map +1 -1
  16. package/lib/citation/core/index.js +1 -0
  17. package/lib/citation/core/index.js.map +1 -1
  18. package/lib/clipboard/ui/ClickToCopy.d.ts +8 -7
  19. package/lib/clipboard/ui/ClickToCopy.d.ts.map +1 -1
  20. package/lib/clipboard/ui/ClickToCopy.js +3 -3
  21. package/lib/clipboard/ui/ClickToCopy.js.map +1 -1
  22. package/lib/conformers.d.ts +27 -0
  23. package/lib/conformers.d.ts.map +1 -0
  24. package/lib/conformers.js +19 -0
  25. package/lib/conformers.js.map +1 -0
  26. package/lib/core.d.ts +1 -0
  27. package/lib/core.d.ts.map +1 -1
  28. package/lib/core.js +1 -0
  29. package/lib/core.js.map +1 -1
  30. package/lib/credits/core/credits.d.ts +12 -0
  31. package/lib/credits/core/credits.d.ts.map +1 -1
  32. package/lib/credits/core/credits.js +14 -0
  33. package/lib/credits/core/credits.js.map +1 -1
  34. package/lib/ecosystem/core/index.d.ts +1 -1
  35. package/lib/ecosystem/core/index.d.ts.map +1 -1
  36. package/lib/ecosystem/core/index.js.map +1 -1
  37. package/lib/ecosystem/core/sites.d.ts +11 -1
  38. package/lib/ecosystem/core/sites.d.ts.map +1 -1
  39. package/lib/ecosystem/core/sites.js +7 -2
  40. package/lib/ecosystem/core/sites.js.map +1 -1
  41. package/lib/ecosystem/ui/EcosystemLinks.d.ts.map +1 -1
  42. package/lib/ecosystem/ui/EcosystemLinks.js +3 -1
  43. package/lib/ecosystem/ui/EcosystemLinks.js.map +1 -1
  44. package/lib/ecosystem/ui/SiteTile.d.ts.map +1 -1
  45. package/lib/ecosystem/ui/SiteTile.js +3 -1
  46. package/lib/ecosystem/ui/SiteTile.js.map +1 -1
  47. package/lib/format/core/index.d.ts +1 -1
  48. package/lib/format/core/index.d.ts.map +1 -1
  49. package/lib/format/core/index.js +1 -1
  50. package/lib/format/core/index.js.map +1 -1
  51. package/lib/format/core/words.d.ts +9 -0
  52. package/lib/format/core/words.d.ts.map +1 -1
  53. package/lib/format/core/words.js +16 -0
  54. package/lib/format/core/words.js.map +1 -1
  55. package/lib/language/core/index.d.ts +3 -0
  56. package/lib/language/core/index.d.ts.map +1 -0
  57. package/lib/language/core/index.js +3 -0
  58. package/lib/language/core/index.js.map +1 -0
  59. package/lib/language/core/languageName.d.ts +8 -0
  60. package/lib/language/core/languageName.d.ts.map +1 -0
  61. package/lib/language/core/languageName.js +16 -0
  62. package/lib/language/core/languageName.js.map +1 -0
  63. package/lib/language/core/languageParam.d.ts +35 -0
  64. package/lib/language/core/languageParam.d.ts.map +1 -0
  65. package/lib/language/core/languageParam.js +67 -0
  66. package/lib/language/core/languageParam.js.map +1 -0
  67. package/lib/language/ui/SiteLanguage.d.ts +20 -0
  68. package/lib/language/ui/SiteLanguage.d.ts.map +1 -0
  69. package/lib/language/ui/SiteLanguage.js +14 -0
  70. package/lib/language/ui/SiteLanguage.js.map +1 -0
  71. package/lib/language/ui/index.d.ts +4 -0
  72. package/lib/language/ui/index.d.ts.map +1 -0
  73. package/lib/language/ui/index.js +3 -0
  74. package/lib/language/ui/index.js.map +1 -0
  75. package/lib/language/ui/siteLanguageContext.d.ts +12 -0
  76. package/lib/language/ui/siteLanguageContext.d.ts.map +1 -0
  77. package/lib/language/ui/siteLanguageContext.js +19 -0
  78. package/lib/language/ui/siteLanguageContext.js.map +1 -0
  79. package/lib/orbital/core/atomicOrbitals.d.ts +9 -1
  80. package/lib/orbital/core/atomicOrbitals.d.ts.map +1 -1
  81. package/lib/orbital/core/atomicOrbitals.js +7 -0
  82. package/lib/orbital/core/atomicOrbitals.js.map +1 -1
  83. package/lib/orbital/core/hydrogenic.d.ts +2 -1
  84. package/lib/orbital/core/hydrogenic.d.ts.map +1 -1
  85. package/lib/orbital/core/hydrogenic.js +2 -1
  86. package/lib/orbital/core/hydrogenic.js.map +1 -1
  87. package/lib/orbital/core/index.d.ts +1 -0
  88. package/lib/orbital/core/index.d.ts.map +1 -1
  89. package/lib/orbital/core/index.js +1 -0
  90. package/lib/orbital/core/index.js.map +1 -1
  91. package/lib/orbital/core/slaterEnergy.d.ts +35 -0
  92. package/lib/orbital/core/slaterEnergy.d.ts.map +1 -0
  93. package/lib/orbital/core/slaterEnergy.js +66 -0
  94. package/lib/orbital/core/slaterEnergy.js.map +1 -0
  95. package/lib/shared/ui/MenuButton.d.ts +3 -2
  96. package/lib/shared/ui/MenuButton.d.ts.map +1 -1
  97. package/lib/shared/ui/MenuButton.js +1 -1
  98. package/lib/shared/ui/MenuButton.js.map +1 -1
  99. package/lib/structure/core/conformerMinimise.d.ts +36 -0
  100. package/lib/structure/core/conformerMinimise.d.ts.map +1 -0
  101. package/lib/structure/core/conformerMinimise.js +81 -0
  102. package/lib/structure/core/conformerMinimise.js.map +1 -0
  103. package/lib/structure/core/conformerMinimum.d.ts +62 -0
  104. package/lib/structure/core/conformerMinimum.d.ts.map +1 -0
  105. package/lib/structure/core/conformerMinimum.js +90 -0
  106. package/lib/structure/core/conformerMinimum.js.map +1 -0
  107. package/lib/structure/core/conformerOptions.d.ts +62 -0
  108. package/lib/structure/core/conformerOptions.d.ts.map +1 -0
  109. package/lib/structure/core/conformerOptions.js +83 -0
  110. package/lib/structure/core/conformerOptions.js.map +1 -0
  111. package/lib/structure/core/conformerRefine.d.ts +104 -0
  112. package/lib/structure/core/conformerRefine.d.ts.map +1 -0
  113. package/lib/structure/core/conformerRefine.js +130 -0
  114. package/lib/structure/core/conformerRefine.js.map +1 -0
  115. package/lib/structure/core/conformerRefineRank.d.ts +36 -0
  116. package/lib/structure/core/conformerRefineRank.d.ts.map +1 -0
  117. package/lib/structure/core/conformerRefineRank.js +69 -0
  118. package/lib/structure/core/conformerRefineRank.js.map +1 -0
  119. package/lib/structure/core/conformerSession.d.ts +50 -0
  120. package/lib/structure/core/conformerSession.d.ts.map +1 -0
  121. package/lib/structure/core/conformerSession.js +88 -0
  122. package/lib/structure/core/conformerSession.js.map +1 -0
  123. package/lib/structure/core/conformerShape.d.ts +36 -0
  124. package/lib/structure/core/conformerShape.d.ts.map +1 -0
  125. package/lib/structure/core/conformerShape.js +150 -0
  126. package/lib/structure/core/conformerShape.js.map +1 -0
  127. package/lib/structure/core/conformers.d.ts +107 -0
  128. package/lib/structure/core/conformers.d.ts.map +1 -0
  129. package/lib/structure/core/conformers.js +149 -0
  130. package/lib/structure/core/conformers.js.map +1 -0
  131. package/lib/structure/core/geometryRelaxer.d.ts +66 -0
  132. package/lib/structure/core/geometryRelaxer.d.ts.map +1 -0
  133. package/lib/structure/core/geometryRelaxer.js +2 -0
  134. package/lib/structure/core/geometryRelaxer.js.map +1 -0
  135. package/lib/structure/core/index.d.ts +4 -0
  136. package/lib/structure/core/index.d.ts.map +1 -1
  137. package/lib/structure/core/index.js +2 -0
  138. package/lib/structure/core/index.js.map +1 -1
  139. package/lib/structure/core/moleculeCoordinates.d.ts +31 -0
  140. package/lib/structure/core/moleculeCoordinates.d.ts.map +1 -0
  141. package/lib/structure/core/moleculeCoordinates.js +80 -0
  142. package/lib/structure/core/moleculeCoordinates.js.map +1 -0
  143. package/lib/structure/core/molfileExport.d.ts +42 -0
  144. package/lib/structure/core/molfileExport.d.ts.map +1 -0
  145. package/lib/structure/core/molfileExport.js +47 -0
  146. package/lib/structure/core/molfileExport.js.map +1 -0
  147. package/lib/structure/core/oclResources.d.ts +12 -0
  148. package/lib/structure/core/oclResources.d.ts.map +1 -0
  149. package/lib/structure/core/oclResources.js +35 -0
  150. package/lib/structure/core/oclResources.js.map +1 -0
  151. package/lib/translate/core/catalog.d.ts +61 -0
  152. package/lib/translate/core/catalog.d.ts.map +1 -0
  153. package/lib/translate/core/catalog.js +49 -0
  154. package/lib/translate/core/catalog.js.map +1 -0
  155. package/lib/translate/core/checkTranslation.d.ts +32 -0
  156. package/lib/translate/core/checkTranslation.d.ts.map +1 -0
  157. package/lib/translate/core/checkTranslation.js +98 -0
  158. package/lib/translate/core/checkTranslation.js.map +1 -0
  159. package/lib/translate/core/contribution.d.ts +88 -0
  160. package/lib/translate/core/contribution.d.ts.map +1 -0
  161. package/lib/translate/core/contribution.js +14 -0
  162. package/lib/translate/core/contribution.js.map +1 -0
  163. package/lib/translate/core/index.d.ts +19 -0
  164. package/lib/translate/core/index.d.ts.map +1 -0
  165. package/lib/translate/core/index.js +15 -0
  166. package/lib/translate/core/index.js.map +1 -0
  167. package/lib/translate/core/marker.d.ts +45 -0
  168. package/lib/translate/core/marker.d.ts.map +1 -0
  169. package/lib/translate/core/marker.js +79 -0
  170. package/lib/translate/core/marker.js.map +1 -0
  171. package/lib/translate/core/mergeMessages.d.ts +35 -0
  172. package/lib/translate/core/mergeMessages.d.ts.map +1 -0
  173. package/lib/translate/core/mergeMessages.js +69 -0
  174. package/lib/translate/core/mergeMessages.js.map +1 -0
  175. package/lib/translate/core/session.d.ts +102 -0
  176. package/lib/translate/core/session.d.ts.map +1 -0
  177. package/lib/translate/core/session.js +162 -0
  178. package/lib/translate/core/session.js.map +1 -0
  179. package/lib/translate/core/start.d.ts +70 -0
  180. package/lib/translate/core/start.d.ts.map +1 -0
  181. package/lib/translate/core/start.js +73 -0
  182. package/lib/translate/core/start.js.map +1 -0
  183. package/lib/translate/core/suggestions.d.ts +77 -0
  184. package/lib/translate/core/suggestions.d.ts.map +1 -0
  185. package/lib/translate/core/suggestions.js +143 -0
  186. package/lib/translate/core/suggestions.js.map +1 -0
  187. package/lib/translate/core/tables.d.ts +100 -0
  188. package/lib/translate/core/tables.d.ts.map +1 -0
  189. package/lib/translate/core/tables.js +51 -0
  190. package/lib/translate/core/tables.js.map +1 -0
  191. package/lib/translate.d.ts +2 -0
  192. package/lib/translate.d.ts.map +1 -0
  193. package/lib/translate.js +6 -0
  194. package/lib/translate.js.map +1 -0
  195. package/lib/ui.d.ts +1 -0
  196. package/lib/ui.d.ts.map +1 -1
  197. package/lib/ui.js +1 -0
  198. package/lib/ui.js.map +1 -1
  199. package/lib/xtb/core/xtbRelaxer.d.ts +61 -0
  200. package/lib/xtb/core/xtbRelaxer.d.ts.map +1 -0
  201. package/lib/xtb/core/xtbRelaxer.js +108 -0
  202. package/lib/xtb/core/xtbRelaxer.js.map +1 -0
  203. package/lib/xtb.d.ts +11 -0
  204. package/lib/xtb.d.ts.map +1 -0
  205. package/lib/xtb.js +10 -0
  206. package/lib/xtb.js.map +1 -0
  207. package/package.json +18 -11
  208. package/src/chrome/ui/HeaderToggle.tsx +100 -0
  209. package/src/chrome/ui/index.ts +2 -0
  210. package/src/citation/core/gfn2Paper.ts +32 -0
  211. package/src/citation/core/index.ts +1 -0
  212. package/src/clipboard/ui/ClickToCopy.tsx +8 -7
  213. package/src/conformers.ts +87 -0
  214. package/src/core.ts +1 -0
  215. package/src/credits/core/credits.ts +16 -0
  216. package/src/ecosystem/core/index.ts +1 -0
  217. package/src/ecosystem/core/sites.ts +20 -2
  218. package/src/ecosystem/ui/EcosystemLinks.tsx +3 -1
  219. package/src/ecosystem/ui/SiteTile.tsx +3 -1
  220. package/src/format/core/index.ts +1 -1
  221. package/src/format/core/words.ts +19 -0
  222. package/src/language/core/index.ts +7 -0
  223. package/src/language/core/languageName.ts +16 -0
  224. package/src/language/core/languageParam.ts +70 -0
  225. package/src/language/ui/SiteLanguage.tsx +26 -0
  226. package/src/language/ui/index.ts +3 -0
  227. package/src/language/ui/siteLanguageContext.ts +20 -0
  228. package/src/orbital/core/atomicOrbitals.ts +17 -1
  229. package/src/orbital/core/hydrogenic.ts +2 -1
  230. package/src/orbital/core/index.ts +1 -0
  231. package/src/orbital/core/slaterEnergy.ts +83 -0
  232. package/src/shared/ui/MenuButton.tsx +4 -3
  233. package/src/structure/core/conformerMinimise.ts +99 -0
  234. package/src/structure/core/conformerMinimum.ts +125 -0
  235. package/src/structure/core/conformerOptions.ts +125 -0
  236. package/src/structure/core/conformerRefine.ts +234 -0
  237. package/src/structure/core/conformerRefineRank.ts +89 -0
  238. package/src/structure/core/conformerSession.ts +123 -0
  239. package/src/structure/core/conformerShape.ts +181 -0
  240. package/src/structure/core/conformers.ts +282 -0
  241. package/src/structure/core/geometryRelaxer.ts +71 -0
  242. package/src/structure/core/index.ts +13 -0
  243. package/src/structure/core/moleculeCoordinates.ts +93 -0
  244. package/src/structure/core/molfileExport.ts +62 -0
  245. package/src/structure/core/oclResources.ts +41 -0
  246. package/src/translate/core/catalog.ts +83 -0
  247. package/src/translate/core/checkTranslation.ts +128 -0
  248. package/src/translate/core/contribution.ts +99 -0
  249. package/src/translate/core/index.ts +72 -0
  250. package/src/translate/core/marker.ts +85 -0
  251. package/src/translate/core/mergeMessages.ts +74 -0
  252. package/src/translate/core/session.ts +250 -0
  253. package/src/translate/core/start.ts +121 -0
  254. package/src/translate/core/suggestions.ts +211 -0
  255. package/src/translate/core/tables.ts +120 -0
  256. package/src/translate.ts +5 -0
  257. package/src/ui.ts +1 -0
  258. package/src/xtb/core/xtbRelaxer.ts +160 -0
  259. package/src/xtb.ts +16 -0
  260. package/styles/chrome.css +61 -30
@@ -0,0 +1,162 @@
1
+ import { IntlMessageFormat } from 'intl-messageformat';
2
+ import { SOURCE_LOCALE, ownMessage } from "./catalog.js";
3
+ import { checkTranslation } from "./checkTranslation.js";
4
+ import { markText } from "./marker.js";
5
+ /** The version of the page ↔ overlay protocol this session speaks. */
6
+ export const BRIDGE_PROTOCOL = 2;
7
+ /** Where a page in translate mode exposes its session to the overlay. */
8
+ export const BRIDGE_GLOBAL = '__cheminfoTranslate';
9
+ /**
10
+ * Formats the messages of a page, and in translate mode lets the overlay edit
11
+ * them live: a draft replaces the published message as soon as it can be
12
+ * formatted, and a draft that cannot is ignored rather than breaking the page.
13
+ */
14
+ export class TranslateSession {
15
+ protocol = BRIDGE_PROTOCOL;
16
+ locale;
17
+ #marked;
18
+ #catalogs = new Map();
19
+ #ids = new Map();
20
+ #refs = [];
21
+ #listeners = new Set();
22
+ #formatters = new Map();
23
+ #checked = new Map();
24
+ #tables;
25
+ #version = 0;
26
+ constructor(options) {
27
+ const { locale, catalogs, translations = {}, marked = false, tables = [], } = options;
28
+ this.locale = locale;
29
+ this.#marked = marked;
30
+ this.#tables = tables;
31
+ for (const source of catalogs) {
32
+ this.#catalogs.set(source.id, {
33
+ source,
34
+ translation: translations[source.id] ?? {},
35
+ drafts: new Map(),
36
+ });
37
+ }
38
+ }
39
+ /**
40
+ * Increases on every draft change, for a view that re-renders on it.
41
+ * @returns The current version.
42
+ */
43
+ get version() {
44
+ return this.#version;
45
+ }
46
+ /**
47
+ * Format one message: the draft, else the published translation, else the
48
+ * English message — the first that passes its check against the English
49
+ * one and formats. A draft that drops a placeholder formats without error,
50
+ * so the check, not the formatting, is what keeps it off the page.
51
+ * @param catalogId - The catalog the message belongs to.
52
+ * @param key - The key of the message.
53
+ * @param values - What the placeholders are filled with.
54
+ * @returns The text to show; the key itself when no catalog has it.
55
+ */
56
+ format(catalogId, key, values) {
57
+ const catalog = this.#catalogs.get(catalogId);
58
+ if (catalog === undefined)
59
+ return key;
60
+ const source = ownMessage(catalog.source.messages, key);
61
+ if (source === undefined)
62
+ return key;
63
+ const draft = this.#usable(source, catalog.drafts.get(key));
64
+ const translation = this.#usable(source, ownMessage(catalog.translation, key));
65
+ const text = this.#tryFormat(draft, this.locale, values) ??
66
+ this.#tryFormat(translation, this.locale, values) ??
67
+ this.#tryFormat(source, SOURCE_LOCALE, values) ??
68
+ source;
69
+ return this.#marked ? markText(text, this.#idOf(catalogId, key)) : text;
70
+ }
71
+ catalogs() {
72
+ const snapshots = [];
73
+ for (const { source, translation, drafts } of this.#catalogs.values()) {
74
+ snapshots.push({
75
+ ...source,
76
+ translation,
77
+ drafts: Object.fromEntries(drafts),
78
+ });
79
+ }
80
+ return snapshots;
81
+ }
82
+ /**
83
+ * The tables whose rows a translator may write.
84
+ * @returns One entry per table the page declared.
85
+ */
86
+ tables() {
87
+ return [...this.#tables];
88
+ }
89
+ resolveMarker(id) {
90
+ return this.#refs[id];
91
+ }
92
+ setDraft(ref, message) {
93
+ const catalog = this.#catalogs.get(ref.catalogId);
94
+ if (catalog === undefined)
95
+ return;
96
+ if (ownMessage(catalog.source.messages, ref.key) === undefined)
97
+ return;
98
+ if (catalog.drafts.get(ref.key) === message)
99
+ return;
100
+ if (message === undefined) {
101
+ catalog.drafts.delete(ref.key);
102
+ }
103
+ else {
104
+ catalog.drafts.set(ref.key, message);
105
+ }
106
+ this.#version++;
107
+ for (const listener of this.#listeners)
108
+ listener();
109
+ }
110
+ subscribe(listener) {
111
+ this.#listeners.add(listener);
112
+ return () => {
113
+ this.#listeners.delete(listener);
114
+ };
115
+ }
116
+ #idOf(catalogId, key) {
117
+ const name = `${catalogId}\n${key}`;
118
+ let id = this.#ids.get(name);
119
+ if (id === undefined) {
120
+ id = this.#refs.length;
121
+ this.#refs.push({ catalogId, key });
122
+ this.#ids.set(name, id);
123
+ }
124
+ return id;
125
+ }
126
+ #usable(source, message) {
127
+ if (message === undefined)
128
+ return undefined;
129
+ const name = JSON.stringify([source, message]);
130
+ let usable = this.#checked.get(name);
131
+ if (usable === undefined) {
132
+ usable = checkTranslation(source, message).length === 0;
133
+ this.#checked.set(name, usable);
134
+ }
135
+ return usable ? message : undefined;
136
+ }
137
+ #tryFormat(message, locale, values) {
138
+ if (message === undefined)
139
+ return undefined;
140
+ const name = `${locale}\n${message}`;
141
+ let formatter = this.#formatters.get(name);
142
+ if (formatter === undefined) {
143
+ try {
144
+ formatter = new IntlMessageFormat(message, locale);
145
+ }
146
+ catch {
147
+ formatter = null;
148
+ }
149
+ this.#formatters.set(name, formatter);
150
+ }
151
+ if (formatter === null)
152
+ return undefined;
153
+ try {
154
+ const output = formatter.format(values);
155
+ return Array.isArray(output) ? output.join('') : String(output);
156
+ }
157
+ catch {
158
+ return undefined;
159
+ }
160
+ }
161
+ }
162
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/translate/core/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Turning a page into a translatable one.
3
+ *
4
+ * A site opened with `?translate=<locale>` formats every message with its
5
+ * invisible marker, hands its session to the overlay as
6
+ * `window.__cheminfoTranslate`, and loads that overlay from
7
+ * translate.cheminfo.org. Nothing of this is paid for by an ordinary visit:
8
+ * the site imports this module only once it has seen the parameter.
9
+ */
10
+ import type { CatalogSource, Messages } from './catalog.ts';
11
+ import { TranslateSession } from './session.ts';
12
+ import type { TranslatableTable } from './tables.ts';
13
+ /** The query parameter that opens a page in translate mode. */
14
+ export declare const TRANSLATE_PARAM = "translate";
15
+ /** Where the overlay is served from unless a site says otherwise. */
16
+ export declare const TRANSLATE_ORIGIN = "https://translate.cheminfo.org";
17
+ /**
18
+ * The locale a page is being translated into, from its address:
19
+ * `?translate=fr` opens the overlay for French.
20
+ * @param search - The query string, e.g. `location.search`.
21
+ * @returns The locale, or `undefined` when the page is not in translate mode,
22
+ * or names English, or names something that is not a language at all.
23
+ */
24
+ export declare function readTranslateLocale(search: string): string | undefined;
25
+ /** How a page enters translate mode. */
26
+ export interface StartTranslatingOptions {
27
+ /** The locale being translated into, from {@link readTranslateLocale}. */
28
+ locale: string;
29
+ /** Every catalog the page renders messages from. */
30
+ catalogs: readonly CatalogSource[];
31
+ /**
32
+ * The published messages of the locale, by catalog id, so the overlay opens
33
+ * on what the site already ships rather than on English.
34
+ * @default {}
35
+ */
36
+ translations?: Readonly<Record<string, Messages>>;
37
+ /**
38
+ * The tables whose rows a translator may write.
39
+ * @default []
40
+ */
41
+ tables?: readonly TranslatableTable[];
42
+ /**
43
+ * Where the overlay is loaded from.
44
+ * @default 'https://translate.cheminfo.org'
45
+ */
46
+ origin?: string;
47
+ /**
48
+ * The document the overlay script is added to.
49
+ * @default globalThis.document
50
+ */
51
+ document?: Document;
52
+ }
53
+ /**
54
+ * Put a page into translate mode.
55
+ *
56
+ * The session is exposed before the overlay is loaded, so the overlay finds a
57
+ * page already formatting marked messages. The site is handed the session back
58
+ * and must format through it from then on — that is what makes an edit show up
59
+ * as it is typed.
60
+ * @param options - See {@link StartTranslatingOptions}.
61
+ * @returns The session the page formats through.
62
+ */
63
+ export declare function startTranslating(options: StartTranslatingOptions): TranslateSession;
64
+ /**
65
+ * Add the overlay script to the page, once.
66
+ * @param origin - Where the overlay is served from.
67
+ * @param target - The document to add it to.
68
+ */
69
+ export declare function loadOverlay(origin: string, target?: Document): void;
70
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/translate/core/start.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAiB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,+DAA+D;AAC/D,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,mCAAmC,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMtE;AAED,wCAAwC;AACxC,MAAM,WAAW,uBAAuB;IACtC,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IACnC;;;;OAIG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAClD;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB,CAoBlB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,MAAM,WAAsB,GAC3B,IAAI,CAWN"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Turning a page into a translatable one.
3
+ *
4
+ * A site opened with `?translate=<locale>` formats every message with its
5
+ * invisible marker, hands its session to the overlay as
6
+ * `window.__cheminfoTranslate`, and loads that overlay from
7
+ * translate.cheminfo.org. Nothing of this is paid for by an ordinary visit:
8
+ * the site imports this module only once it has seen the parameter.
9
+ */
10
+ import { isLanguageTag } from "../../language/core/languageParam.js";
11
+ import { SOURCE_LOCALE } from "./catalog.js";
12
+ import { BRIDGE_GLOBAL, TranslateSession } from "./session.js";
13
+ /** The query parameter that opens a page in translate mode. */
14
+ export const TRANSLATE_PARAM = 'translate';
15
+ /** Where the overlay is served from unless a site says otherwise. */
16
+ export const TRANSLATE_ORIGIN = 'https://translate.cheminfo.org';
17
+ /**
18
+ * The locale a page is being translated into, from its address:
19
+ * `?translate=fr` opens the overlay for French.
20
+ * @param search - The query string, e.g. `location.search`.
21
+ * @returns The locale, or `undefined` when the page is not in translate mode,
22
+ * or names English, or names something that is not a language at all.
23
+ */
24
+ export function readTranslateLocale(search) {
25
+ const value = new URLSearchParams(search).get(TRANSLATE_PARAM);
26
+ if (value === null || value === SOURCE_LOCALE || !isLanguageTag(value)) {
27
+ return undefined;
28
+ }
29
+ return value;
30
+ }
31
+ /**
32
+ * Put a page into translate mode.
33
+ *
34
+ * The session is exposed before the overlay is loaded, so the overlay finds a
35
+ * page already formatting marked messages. The site is handed the session back
36
+ * and must format through it from then on — that is what makes an edit show up
37
+ * as it is typed.
38
+ * @param options - See {@link StartTranslatingOptions}.
39
+ * @returns The session the page formats through.
40
+ */
41
+ export function startTranslating(options) {
42
+ const { locale, catalogs, translations = {}, tables = [], origin = TRANSLATE_ORIGIN, document: target = globalThis.document, } = options;
43
+ const session = new TranslateSession({
44
+ locale,
45
+ catalogs,
46
+ translations,
47
+ tables,
48
+ marked: true,
49
+ });
50
+ Object.assign(globalThis, { [BRIDGE_GLOBAL]: session });
51
+ loadOverlay(origin, target);
52
+ return session;
53
+ }
54
+ /**
55
+ * Add the overlay script to the page, once.
56
+ * @param origin - Where the overlay is served from.
57
+ * @param target - The document to add it to.
58
+ */
59
+ export function loadOverlay(origin, target = globalThis.document) {
60
+ if (target === undefined)
61
+ return;
62
+ const src = `${origin.replace(/\/$/, '')}/overlay.js`;
63
+ for (const loaded of target.querySelectorAll('script')) {
64
+ if (loaded.src === src)
65
+ return;
66
+ }
67
+ const script = target.createElement('script');
68
+ script.type = 'module';
69
+ script.src = src;
70
+ script.async = true;
71
+ target.head.append(script);
72
+ }
73
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/translate/core/start.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAG/D,+DAA+D;AAC/D,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;AAE3C,qEAAqE;AACrE,MAAM,CAAC,MAAM,gBAAgB,GAAG,gCAAgC,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC/D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,aAAa,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACvE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AA+BD;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAgC;IAEhC,MAAM,EACJ,MAAM,EACN,QAAQ,EACR,YAAY,GAAG,EAAE,EACjB,MAAM,GAAG,EAAE,EACX,MAAM,GAAG,gBAAgB,EACzB,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,QAAQ,GACvC,GAAG,OAAO,CAAC;IAEZ,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC;QACnC,MAAM;QACN,QAAQ;QACR,YAAY;QACZ,MAAM;QACN,MAAM,EAAE,IAAI;KACb,CAAC,CAAC;IACH,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACxD,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,MAAM,GAAG,UAAU,CAAC,QAAQ;IAE5B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO;IACjC,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC;IACtD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG;YAAE,OAAO;IACjC,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * What a translator is offered before typing: the translations already made
3
+ * for the same English, for English that differs only where the text is not
4
+ * language, and for English that merely looks like it.
5
+ *
6
+ * A table is where this earns its place. Half of 118 element names are the
7
+ * same word in two languages and the other half differ by an ending; a column
8
+ * of quantities is a handful of phrases repeated with one word changed. A
9
+ * translator who is shown what was done three rows above confirms instead of
10
+ * typing, and the column stays consistent with itself — which is the thing a
11
+ * long table loses first.
12
+ *
13
+ * Nothing here invents a translation. Every suggestion is a translation
14
+ * somebody already wrote, either as it stands or with the part that is not
15
+ * language put back.
16
+ */
17
+ /** One message already translated, which a suggestion is drawn from. */
18
+ export interface TranslatedPair {
19
+ /** The key it is kept under, so the translator can see where it came from. */
20
+ key: string;
21
+ /** The English message. */
22
+ source: string;
23
+ /** Its translation. */
24
+ target: string;
25
+ }
26
+ /**
27
+ * How a suggestion was arrived at.
28
+ *
29
+ * - `exact` — the same English message, translated elsewhere.
30
+ * - `pattern` — English that differs only in a part that is not language (a
31
+ * number, a symbol, a formula), with that part put back into the
32
+ * translation.
33
+ * - `similar` — English that looks like this one; the translation is offered
34
+ * to be adapted, not to be taken as it is.
35
+ */
36
+ export type SuggestionKind = 'exact' | 'pattern' | 'similar';
37
+ /** One translation offered for a message. */
38
+ export interface MessageSuggestion {
39
+ /** What goes in the box if the translator takes it. */
40
+ message: string;
41
+ /** How it was arrived at. */
42
+ kind: SuggestionKind;
43
+ /** Between 0 and 1; 1 is the same English message. */
44
+ score: number;
45
+ /** The already-translated message it was drawn from. */
46
+ from: TranslatedPair;
47
+ }
48
+ /** How suggestions are chosen. */
49
+ export interface SuggestionOptions {
50
+ /**
51
+ * The most suggestions to return.
52
+ * @default 5
53
+ */
54
+ limit?: number;
55
+ /**
56
+ * How alike two English messages must be before one is offered for the
57
+ * other, between 0 and 1.
58
+ * @default 0.55
59
+ */
60
+ minimumScore?: number;
61
+ }
62
+ /**
63
+ * The translations worth offering for one English message.
64
+ * @param source - The English message being translated.
65
+ * @param pairs - Every message already translated in this language.
66
+ * @param options - See {@link SuggestionOptions}.
67
+ * @returns The suggestions, best first; empty when nothing is close enough.
68
+ */
69
+ export declare function messageSuggestions(source: string, pairs: readonly TranslatedPair[], options?: SuggestionOptions): MessageSuggestion[];
70
+ /**
71
+ * How alike two messages are, as the suggestions rank them.
72
+ * @param first - One message.
73
+ * @param second - The other.
74
+ * @returns 1 when they are the same, 0 when they share nothing.
75
+ */
76
+ export declare function messageSimilarity(first: string, second: string): number;
77
+ //# sourceMappingURL=suggestions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestions.d.ts","sourceRoot":"","sources":["../../../src/translate/core/suggestions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,GAAG,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAE7D,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,IAAI,EAAE,cAAc,CAAC;IACrB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,kCAAkC;AAClC,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAUD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,OAAO,GAAE,iBAAsB,GAC9B,iBAAiB,EAAE,CAqBrB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIvE"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * What a translator is offered before typing: the translations already made
3
+ * for the same English, for English that differs only where the text is not
4
+ * language, and for English that merely looks like it.
5
+ *
6
+ * A table is where this earns its place. Half of 118 element names are the
7
+ * same word in two languages and the other half differ by an ending; a column
8
+ * of quantities is a handful of phrases repeated with one word changed. A
9
+ * translator who is shown what was done three rows above confirms instead of
10
+ * typing, and the column stays consistent with itself — which is the thing a
11
+ * long table loses first.
12
+ *
13
+ * Nothing here invents a translation. Every suggestion is a translation
14
+ * somebody already wrote, either as it stands or with the part that is not
15
+ * language put back.
16
+ */
17
+ import leven from 'leven';
18
+ const DEFAULT_LIMIT = 5;
19
+ const DEFAULT_MINIMUM = 0.55;
20
+ const KIND_ORDER = {
21
+ exact: 0,
22
+ pattern: 1,
23
+ similar: 2,
24
+ };
25
+ /**
26
+ * The translations worth offering for one English message.
27
+ * @param source - The English message being translated.
28
+ * @param pairs - Every message already translated in this language.
29
+ * @param options - See {@link SuggestionOptions}.
30
+ * @returns The suggestions, best first; empty when nothing is close enough.
31
+ */
32
+ export function messageSuggestions(source, pairs, options = {}) {
33
+ const { limit = DEFAULT_LIMIT, minimumScore = DEFAULT_MINIMUM } = options;
34
+ if (source === '' || limit <= 0)
35
+ return [];
36
+ const found = [];
37
+ for (const pair of pairs) {
38
+ if (pair.target === '' || pair.source === '')
39
+ continue;
40
+ const suggestion = suggestFrom(source, pair, minimumScore);
41
+ if (suggestion !== undefined)
42
+ found.push(suggestion);
43
+ }
44
+ found.sort(compareSuggestions);
45
+ const best = [];
46
+ const taken = new Set();
47
+ for (const suggestion of found) {
48
+ if (taken.has(suggestion.message))
49
+ continue;
50
+ taken.add(suggestion.message);
51
+ best.push(suggestion);
52
+ if (best.length === limit)
53
+ break;
54
+ }
55
+ return best;
56
+ }
57
+ /**
58
+ * How alike two messages are, as the suggestions rank them.
59
+ * @param first - One message.
60
+ * @param second - The other.
61
+ * @returns 1 when they are the same, 0 when they share nothing.
62
+ */
63
+ export function messageSimilarity(first, second) {
64
+ const longest = Math.max(first.length, second.length);
65
+ if (longest === 0)
66
+ return 1;
67
+ return 1 - leven(first, second) / longest;
68
+ }
69
+ /**
70
+ * The best offer one already-translated message can make for another.
71
+ * @param source - The English being translated.
72
+ * @param pair - The already-translated message to draw from.
73
+ * @param minimumScore - How alike the two must be to be worth offering.
74
+ * @returns The suggestion, or `undefined` when the pair is too far away.
75
+ */
76
+ function suggestFrom(source, pair, minimumScore) {
77
+ if (pair.source === source) {
78
+ return { message: pair.target, kind: 'exact', score: 1, from: pair };
79
+ }
80
+ // An edit can never be smaller than the difference in length, so a pair that
81
+ // cannot reach the threshold is dropped before the distance is computed.
82
+ const longest = Math.max(source.length, pair.source.length);
83
+ const shortest = Math.min(source.length, pair.source.length);
84
+ if (longest === 0 || shortest / longest < minimumScore)
85
+ return undefined;
86
+ const pattern = patternSuggestion(source, pair);
87
+ if (pattern !== undefined && pattern.score >= minimumScore)
88
+ return pattern;
89
+ const score = messageSimilarity(source, pair.source);
90
+ if (score < minimumScore)
91
+ return undefined;
92
+ return { message: pair.target, kind: 'similar', score, from: pair };
93
+ }
94
+ /**
95
+ * A translation whose English differs from this one only in a run of text
96
+ * that survives into the translation unchanged — a number, a symbol, a
97
+ * formula. That run is the only thing put back, so nothing is invented.
98
+ * @param source - The English being translated.
99
+ * @param pair - The already-translated message to draw from.
100
+ * @returns The suggestion, or `undefined` when the run cannot be put back.
101
+ */
102
+ function patternSuggestion(source, pair) {
103
+ const prefix = commonPrefix(source, pair.source);
104
+ const suffix = commonSuffix(source.slice(prefix), pair.source.slice(prefix));
105
+ const own = source.slice(prefix, source.length - suffix);
106
+ const theirs = pair.source.slice(prefix, pair.source.length - suffix);
107
+ if (theirs === '')
108
+ return undefined;
109
+ // The varying run must appear once and only once, or putting it back would
110
+ // be a guess about which occurrence was meant.
111
+ const at = pair.target.indexOf(theirs);
112
+ if (at === -1 || pair.target.includes(theirs, at + 1))
113
+ return undefined;
114
+ const message = pair.target.slice(0, at) + own + pair.target.slice(at + theirs.length);
115
+ const kept = prefix + suffix;
116
+ const score = kept / Math.max(source.length, pair.source.length);
117
+ return { message, kind: 'pattern', score, from: pair };
118
+ }
119
+ function commonPrefix(first, second) {
120
+ const limit = Math.min(first.length, second.length);
121
+ let length = 0;
122
+ while (length < limit && first[length] === second[length])
123
+ length++;
124
+ return length;
125
+ }
126
+ function commonSuffix(first, second) {
127
+ const limit = Math.min(first.length, second.length);
128
+ let length = 0;
129
+ while (length < limit &&
130
+ first[first.length - 1 - length] === second[second.length - 1 - length]) {
131
+ length++;
132
+ }
133
+ return length;
134
+ }
135
+ function compareSuggestions(first, second) {
136
+ if (first.kind !== second.kind) {
137
+ return KIND_ORDER[first.kind] - KIND_ORDER[second.kind];
138
+ }
139
+ if (first.score !== second.score)
140
+ return second.score - first.score;
141
+ return first.from.key < second.from.key ? -1 : 1;
142
+ }
143
+ //# sourceMappingURL=suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestions.js","sourceRoot":"","sources":["../../../src/translate/core/suggestions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The tables of a site whose rows are translated: the element sheet, a list of
3
+ * ions, the rules of a nomenclature.
4
+ *
5
+ * A site's prose is not only its interface. Most of what a chemistry tool
6
+ * shows is a table, and a table mixes two kinds of column: what was measured
7
+ * or computed — an atomic number, a mass, a formula, an identifier — and what
8
+ * was written — a name, where the name comes from, a note. The first kind is
9
+ * the same in every language and must never reach a translator; the second is
10
+ * exactly what a translator is for.
11
+ *
12
+ * The line between them is drawn once, here. A site declares its tables, and
13
+ * only a field it declares can be edited, in a catalog key built the same way
14
+ * everywhere:
15
+ *
16
+ * ```text
17
+ * <table>.<row>.<field> element.Fe.name, element.Fe.origin
18
+ * ```
19
+ *
20
+ * Everything else about the row — the mass, the density, the id itself — stays
21
+ * in the data the site generates from its source, out of reach.
22
+ */
23
+ /** How much room a field's text needs, which is how the editor draws it. */
24
+ export type TranslatableFieldSize = 'line' | 'paragraph';
25
+ /** One translated column of a table. */
26
+ export interface TranslatableField {
27
+ /** Last part of the key, e.g. `name`. */
28
+ id: string;
29
+ /** What the column is called in the editor, in English. */
30
+ label: string;
31
+ /**
32
+ * How much text it holds, which is whether the editor gives it one line or
33
+ * a box.
34
+ * @default 'line'
35
+ */
36
+ size?: TranslatableFieldSize;
37
+ /**
38
+ * Whether every row is expected to carry it, so the editor can say what is
39
+ * still missing rather than only what is there.
40
+ * @default false
41
+ */
42
+ required?: boolean;
43
+ /**
44
+ * One sentence telling the translator what the column is, shown above the
45
+ * column in the editor.
46
+ * @default undefined
47
+ */
48
+ hint?: string;
49
+ }
50
+ /** One row of a table. */
51
+ export interface TranslatableRow {
52
+ /** Middle part of the key, e.g. `Fe`. */
53
+ id: string;
54
+ /**
55
+ * What names the row in the editor — an atomic number and a symbol, a
56
+ * formula. It is data, never translated, and never a key.
57
+ */
58
+ label: string;
59
+ }
60
+ /** A table whose rows carry translated text. */
61
+ export interface TranslatableTable {
62
+ /** First part of the key, e.g. `element`. */
63
+ id: string;
64
+ /** What the table is called in the editor, in English. */
65
+ label: string;
66
+ /** The catalog its keys belong to, as the page registered it. */
67
+ catalogId: string;
68
+ /** The columns a translator may write, in the order the editor shows them. */
69
+ fields: readonly TranslatableField[];
70
+ /** The rows, in the order the editor lists them. */
71
+ rows: readonly TranslatableRow[];
72
+ }
73
+ /**
74
+ * The key one field of one row is kept under.
75
+ * @param table - The table the row belongs to.
76
+ * @param rowId - The row.
77
+ * @param fieldId - The column.
78
+ * @returns The catalog key, e.g. `element.Fe.name`.
79
+ */
80
+ export declare function tableKey(table: Pick<TranslatableTable, 'id'>, rowId: string, fieldId: string): string;
81
+ /**
82
+ * Every key a table can hold, row by row and field by field.
83
+ *
84
+ * It is what the editor walks to draw the grid, and what tells it which cells
85
+ * are still empty: a key absent from the catalog is a translation nobody has
86
+ * written yet, not a field that does not exist.
87
+ * @param table - The table to walk.
88
+ * @returns One entry per cell, in reading order.
89
+ */
90
+ export declare function tableCells(table: TranslatableTable): TableCell[];
91
+ /** One cell of a table: where it is, and what it is kept under. */
92
+ export interface TableCell {
93
+ /** The catalog key. */
94
+ key: string;
95
+ /** The row it belongs to. */
96
+ row: TranslatableRow;
97
+ /** The column it belongs to. */
98
+ field: TranslatableField;
99
+ }
100
+ //# sourceMappingURL=tables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../../src/translate/core/tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,WAAW,CAAC;AAEzD,wCAAwC;AACxC,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,0BAA0B;AAC1B,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACrC,oDAAoD;IACpD,IAAI,EAAE,SAAS,eAAe,EAAE,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,EACpC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,SAAS,EAAE,CAQhE;AAED,mEAAmE;AACnE,MAAM,WAAW,SAAS;IACxB,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,6BAA6B;IAC7B,GAAG,EAAE,eAAe,CAAC;IACrB,gCAAgC;IAChC,KAAK,EAAE,iBAAiB,CAAC;CAC1B"}