@fpw/en-wiktionary-la-modules 0.0.10 → 0.0.13

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 (45) hide show
  1. package/dist/LaEngine.js +6 -6
  2. package/dist/LaEngine.js.map +1 -1
  3. package/dist/index.js +5 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/modules/conjugation/LaVerb.d.ts +1 -1
  6. package/dist/modules/conjugation/LaVerb.js +379 -375
  7. package/dist/modules/conjugation/LaVerb.js.map +1 -1
  8. package/dist/modules/conjugation/VerbForm.js +2 -2
  9. package/dist/modules/conjugation/VerbForm.js.map +1 -1
  10. package/dist/modules/conjugation/VerbType.d.ts +1 -0
  11. package/dist/modules/conjugation/VerbType.js +3 -2
  12. package/dist/modules/conjugation/VerbType.js.map +1 -1
  13. package/dist/modules/declination/LaAdjData.d.ts +1 -1
  14. package/dist/modules/declination/LaAdjData.js +505 -428
  15. package/dist/modules/declination/LaAdjData.js.map +1 -1
  16. package/dist/modules/declination/LaNominal.d.ts +10 -0
  17. package/dist/modules/declination/LaNominal.js +79 -73
  18. package/dist/modules/declination/LaNominal.js.map +1 -1
  19. package/dist/modules/declination/LaNounData.js +467 -417
  20. package/dist/modules/declination/LaNounData.js.map +1 -1
  21. package/dist/modules/declination/NominalForm.js +2 -2
  22. package/dist/modules/declination/NominalForm.js.map +1 -1
  23. package/dist/modules/headword/HeadwordParser.js +17 -17
  24. package/dist/modules/headword/HeadwordParser.js.map +1 -1
  25. package/package.json +9 -8
  26. package/src/LaEngine.ts +82 -0
  27. package/src/index.ts +16 -0
  28. package/src/modules/common.ts +164 -0
  29. package/src/modules/conjugation/LaVerb.ts +2490 -0
  30. package/src/modules/conjugation/VerbAffix.ts +18 -0
  31. package/src/modules/conjugation/VerbForm.ts +223 -0
  32. package/src/modules/conjugation/VerbType.ts +51 -0
  33. package/src/modules/declination/LaAdjData.ts +913 -0
  34. package/src/modules/declination/LaNominal.ts +1992 -0
  35. package/src/modules/declination/LaNounData.ts +896 -0
  36. package/src/modules/declination/LaPersonalPronoun.ts +77 -0
  37. package/src/modules/declination/NominalForm.ts +89 -0
  38. package/src/modules/headword/HeadWord.ts +132 -0
  39. package/src/modules/headword/HeadwordParser.ts +514 -0
  40. package/dist/modules/LaEngine.d.ts +0 -15
  41. package/dist/modules/LaEngine.js +0 -46
  42. package/dist/modules/LaEngine.js.map +0 -1
  43. package/dist/modules/LaWiktionary.d.ts +0 -18
  44. package/dist/modules/LaWiktionary.js +0 -171
  45. package/dist/modules/LaWiktionary.js.map +0 -1
@@ -0,0 +1,896 @@
1
+ /**
2
+ * This is a complete re-implementation of Wiktionary's Module:la-adj/data, developed by Benwing2.
3
+ * It was converted from Lua to TypeScript by Folke Will <folko@solhost.org>.
4
+ *
5
+ * Original source: https://en.wiktionary.org/wiki/Module:la-noun/data
6
+ * Based on version: https://en.wiktionary.org/w/index.php?title=Module:la-noun/data&oldid=63744261
7
+ *
8
+ * Lua idioms, function and variable names kept as in the original in order to easily
9
+ * backport later changes to this implementation.
10
+ *
11
+ * For that reason, it's suggested to add a type-aware wrapper around this class and leave
12
+ * this code unchanged instead of improving the types and use of idioms in this class.
13
+ *
14
+ */
15
+ import { strip_macrons } from "../common";
16
+ import { NumberTantum, SegmentData } from "./LaNominal";
17
+ import { getNominalForm, setNominalForm } from "./NominalForm";
18
+
19
+ export const m_noun_decl: Map<string, ((data: SegmentData, args: string[]) => void)> = new Map([
20
+ ["1", (data, args) => {
21
+ const stem = args[0];
22
+
23
+ setNominalForm(data.forms, "nom_sg", [stem + "a"]);
24
+ setNominalForm(data.forms, "gen_sg", [stem + "ae"]);
25
+ setNominalForm(data.forms, "dat_sg", [stem + "ae"]);
26
+ setNominalForm(data.forms, "acc_sg", [stem + "am"]);
27
+ setNominalForm(data.forms, "abl_sg", [stem + "ā"]);
28
+ setNominalForm(data.forms, "voc_sg", [stem + "a"]);
29
+
30
+ setNominalForm(data.forms, "nom_pl", [stem + "ae"]);
31
+ setNominalForm(data.forms, "gen_pl", [stem + "ārum"]);
32
+ setNominalForm(data.forms, "dat_pl", [stem + "īs"]);
33
+ setNominalForm(data.forms, "acc_pl", [stem + "ās"]);
34
+ setNominalForm(data.forms, "abl_pl", [stem + "īs"]);
35
+ setNominalForm(data.forms, "voc_pl", [stem + "ae"]);
36
+
37
+ if (data.types.has("abus")) {
38
+ data.subtitles.push(["dative/ablative plural in ", "'-ābus'"]);
39
+ setNominalForm(data.forms, "dat_pl", [stem + "ābus"]);
40
+ setNominalForm(data.forms, "abl_pl", [stem + "ābus"]);
41
+ } else if (data.types.has("not_abus")) {
42
+ data.subtitles.push(["dative/ablative plural in ", "'-īs'"]);
43
+ }
44
+
45
+ if (data.types.has("am")) {
46
+ data.subtitles.push(["nominative/vocative singular in ", "'-ām'"]);
47
+ setNominalForm(data.forms, "nom_sg", [stem + "ām"]);
48
+ setNominalForm(data.forms, "acc_sg", [stem + "ām"]);
49
+ setNominalForm(data.forms, "voc_sg", [stem + "ām"]);
50
+ setNominalForm(data.forms, "abl_sg", [stem + "ām", stem + "ā"]);
51
+ } else if (data.types.has("Greek")) {
52
+ if (data.types.has("Ma")) {
53
+ data.subtitles.push("masculine Greek-type with nominative singular in '-ās'");
54
+ setNominalForm(data.forms, "nom_sg", [stem + "ās"]);
55
+ setNominalForm(data.forms, "acc_sg", [stem + "ān"]);
56
+ setNominalForm(data.forms, "voc_sg", [stem + "ā"]);
57
+ } else if (data.types.has("Me")) {
58
+ data.subtitles.push("masculine Greek-type with nominative singular in '-ēs'");
59
+ setNominalForm(data.forms, "nom_sg", [stem + "ēs"]);
60
+ setNominalForm(data.forms, "acc_sg", [stem + "ēn"]);
61
+ setNominalForm(data.forms, "abl_sg", [stem + "ē"]);
62
+ setNominalForm(data.forms, "voc_sg", [stem + "ē"]);
63
+ } else {
64
+ data.subtitles.push("Greek-type");
65
+ setNominalForm(data.forms, "nom_sg", [stem + "ē"]);
66
+ setNominalForm(data.forms, "gen_sg", [stem + "ēs"]);
67
+ setNominalForm(data.forms, "acc_sg", [stem + "ēn"]);
68
+ setNominalForm(data.forms, "abl_sg", [stem + "ē"]);
69
+ setNominalForm(data.forms, "voc_sg", [stem + "ē"]);
70
+ }
71
+ } else if (data.types.has("not_Greek")) {
72
+ data.subtitles.push("non-Greek-type");
73
+ } else if (data.types.has("not_am")) {
74
+ data.subtitles.push(["nominative/vocative singular in ", "'-a'"]);
75
+ }
76
+
77
+ if (data.loc) {
78
+ setNominalForm(data.forms, "loc_sg", [stem + "ae"]);
79
+ setNominalForm(data.forms, "loc_pl", [stem + "īs"]);
80
+ }
81
+ }],
82
+ ["2", (data, args) => {
83
+ const stem1 = args[0];
84
+ const stem2 = args[1];
85
+
86
+ setNominalForm(data.forms, "nom_sg", [stem1 + "us"]);
87
+ setNominalForm(data.forms, "gen_sg", [stem1 + "ī"]);
88
+ setNominalForm(data.forms, "dat_sg", [stem1 + "ō"]);
89
+ setNominalForm(data.forms, "acc_sg", [stem1 + "um"]);
90
+ setNominalForm(data.forms, "abl_sg", [stem1 + "ō"]);
91
+ setNominalForm(data.forms, "voc_sg", [stem1 + "e"]);
92
+
93
+ setNominalForm(data.forms, "nom_pl", [stem1 + "ī"]);
94
+ setNominalForm(data.forms, "gen_pl", [stem1 + "ōrum"]);
95
+ setNominalForm(data.forms, "dat_pl", [stem1 + "īs"]);
96
+ setNominalForm(data.forms, "acc_pl", [stem1 + "ōs"]);
97
+ setNominalForm(data.forms, "abl_pl", [stem1 + "īs"]);
98
+ setNominalForm(data.forms, "voc_pl", [stem1 + "ī"]);
99
+
100
+ if (data.types.has("N")) {
101
+ data.subtitles.push("neuter");
102
+ setNominalForm(data.forms, "nom_sg", [stem1 + "um"]);
103
+ setNominalForm(data.forms, "voc_sg", [stem1 + "um"]);
104
+
105
+ setNominalForm(data.forms, "nom_pl", [stem1 + "a"]);
106
+ setNominalForm(data.forms, "acc_pl", [stem1 + "a"]);
107
+ setNominalForm(data.forms, "voc_pl", [stem1 + "a"]);
108
+
109
+ if (data.types.has("ium")) {
110
+ setNominalForm(data.forms, "nom_sg", [stem1 + "ium"]);
111
+ if (!data.declOpts.suppressOldGenitive) {
112
+ setNominalForm(data.forms, "gen_sg", [stem1 + "iī", stem1 + "ī"]);
113
+ } else {
114
+ setNominalForm(data.forms, "gen_sg", [stem1 + "iī"]);
115
+ }
116
+ setNominalForm(data.forms, "dat_sg", [stem1 + "iō"]);
117
+ setNominalForm(data.forms, "acc_sg", [stem1 + "ium"]);
118
+ setNominalForm(data.forms, "abl_sg", [stem1 + "iō"]);
119
+ setNominalForm(data.forms, "voc_sg", [stem1 + "ium"]);
120
+
121
+ setNominalForm(data.forms, "nom_pl", [stem1 + "ia"]);
122
+ setNominalForm(data.forms, "gen_pl", [stem1 + "iōrum"]);
123
+ setNominalForm(data.forms, "dat_pl", [stem1 + "iīs"]);
124
+ setNominalForm(data.forms, "acc_pl", [stem1 + "ia"]);
125
+ setNominalForm(data.forms, "abl_pl", [stem1 + "iīs"]);
126
+ setNominalForm(data.forms, "voc_pl", [stem1 + "ia"]);
127
+
128
+ if (!data.declOpts.suppressOldGenitive) {
129
+ data.notes.set("gen_sg2", "Found in older Latin (until the Augustan Age).");
130
+ }
131
+ } else if (data.types.has("a")) {
132
+ data.subtitles.push("nominative/accusative/vocative plural in '-a'");
133
+
134
+ setNominalForm(data.forms, "nom_sg", [stem1 + "us"]);
135
+ setNominalForm(data.forms, "acc_sg", [stem1 + "us"]);
136
+ setNominalForm(data.forms, "voc_sg", [stem1 + "us"]);
137
+
138
+ setNominalForm(data.forms, "nom_pl", [stem1 + "a"]);
139
+ setNominalForm(data.forms, "acc_pl", [stem1 + "a"]);
140
+ setNominalForm(data.forms, "voc_pl", [stem1 + "a"]);
141
+ } else if (data.types.has("vom")) {
142
+ data.subtitles.push("nominative singular in '-om' after 'v'");
143
+ setNominalForm(data.forms, "nom_sg", [stem1 + "om"]);
144
+ setNominalForm(data.forms, "acc_sg", [stem1 + "om"]);
145
+ setNominalForm(data.forms, "voc_sg", [stem1 + "om"]);
146
+ } else if (data.types.has("Greek") && data.types.has("us")) {
147
+ data.subtitles.push("Greek-type");
148
+ data.subtitles.push("nominative/accusative/vocative in '-os'");
149
+
150
+ setNominalForm(data.forms, "nom_sg", [stem1 + "os"]);
151
+ setNominalForm(data.forms, "acc_sg", [stem1 + "os"]);
152
+ setNominalForm(data.forms, "voc_sg", [stem1 + "os"]);
153
+
154
+ setNominalForm(data.forms, "nom_pl", [stem1 + "ē"]);
155
+ setNominalForm(data.forms, "gen_pl", [stem1 + "ōn"]);
156
+ setNominalForm(data.forms, "acc_pl", [stem1 + "ē"]);
157
+ setNominalForm(data.forms, "voc_pl", [stem1 + "ē"]);
158
+ } else if (data.types.has("Greek")) {
159
+ data.subtitles.push("Greek-type");
160
+ setNominalForm(data.forms, "nom_sg", [stem1 + "on"]);
161
+ setNominalForm(data.forms, "acc_sg", [stem1 + "on"]);
162
+ setNominalForm(data.forms, "voc_sg", [stem1 + "on"]);
163
+ } else if (data.types.has("us")) {
164
+ data.subtitles.push("nominative/accusative/vocative in '-us'");
165
+ setNominalForm(data.forms, "nom_sg", [stem1 + "us"]);
166
+ setNominalForm(data.forms, "acc_sg", [stem1 + "us"]);
167
+ setNominalForm(data.forms, "voc_sg", [stem1 + "us"]);
168
+
169
+ setNominalForm(data.forms, "nom_pl", [stem1 + "ī"]);
170
+ setNominalForm(data.forms, "acc_pl", [stem1 + "ōs"]);
171
+ setNominalForm(data.forms, "voc_pl", [stem1 + "ī"]);
172
+ } else if (data.types.has("not_Greek") || data.types.has("not_us")) {
173
+ data.subtitles.push("nominative/accusative/vocative in '-um'");
174
+ }
175
+ } else if (data.types.has("er")) {
176
+ if (stem1.match(/[aiouy]r$/)) {
177
+ data.subtitles.push("nominative singular in '-r'");
178
+ } else {
179
+ data.subtitles.push("nominative singular in '-er'");
180
+ }
181
+
182
+ setNominalForm(data.forms, "nom_sg", [stem1]);
183
+ setNominalForm(data.forms, "gen_sg", [stem2 + "ī"]);
184
+ setNominalForm(data.forms, "dat_sg", [stem2 + "ō"]);
185
+ setNominalForm(data.forms, "acc_sg", [stem2 + "um"]);
186
+ setNominalForm(data.forms, "abl_sg", [stem2 + "ō"]);
187
+ setNominalForm(data.forms, "voc_sg", [stem1]);
188
+
189
+ setNominalForm(data.forms, "nom_pl", [stem2 + "ī"]);
190
+ setNominalForm(data.forms, "gen_pl", [stem2 + "ōrum"]);
191
+ setNominalForm(data.forms, "dat_pl", [stem2 + "īs"]);
192
+ setNominalForm(data.forms, "acc_pl", [stem2 + "ōs"]);
193
+ setNominalForm(data.forms, "abl_pl", [stem2 + "īs"]);
194
+ setNominalForm(data.forms, "voc_pl", [stem2 + "ī"]);
195
+ } else if (data.types.has("ius")) {
196
+ setNominalForm(data.forms, "nom_sg", [stem1 + "ius"]);
197
+ if (!data.declOpts.suppressOldGenitive) {
198
+ setNominalForm(data.forms, "gen_sg", [stem1 + "iī", stem1 + "ī"]);
199
+ } else {
200
+ setNominalForm(data.forms, "gen_sg", [stem1 + "iī"]);
201
+ }
202
+ setNominalForm(data.forms, "dat_sg", [stem1 + "iō"]);
203
+ setNominalForm(data.forms, "acc_sg", [stem1 + "ium"]);
204
+ setNominalForm(data.forms, "abl_sg", [stem1 + "iō"]);
205
+
206
+ if (data.types.has("voci")) {
207
+ setNominalForm(data.forms, "voc_sg", [stem1 + "ī"]);
208
+ } else {
209
+ setNominalForm(data.forms, "voc_sg", [stem1 + "ie"]);
210
+ }
211
+
212
+ setNominalForm(data.forms, "nom_pl", [stem1 + "iī"]);
213
+ setNominalForm(data.forms, "gen_pl", [stem1 + "iōrum"]);
214
+ setNominalForm(data.forms, "dat_pl", [stem1 + "iīs"]);
215
+ setNominalForm(data.forms, "acc_pl", [stem1 + "iōs"]);
216
+ setNominalForm(data.forms, "abl_pl", [stem1 + "iīs"]);
217
+ setNominalForm(data.forms, "voc_pl", [stem1 + "iī"]);
218
+
219
+ if (!data.declOpts.suppressOldGenitive) {
220
+ data.notes.set("gen_sg2", "Found in older Latin (until the Augustan Age).");
221
+ }
222
+ } else if (data.types.has("vos")) {
223
+ data.subtitles.push("nominative singular in '-os' after 'v'");
224
+ setNominalForm(data.forms, "nom_sg", [stem1 + "os"]);
225
+ setNominalForm(data.forms, "acc_sg", [stem1 + "om"]);
226
+ } else if (data.types.has("Greek")) {
227
+ data.subtitles.push("Greek-type");
228
+ setNominalForm(data.forms, "nom_sg", [stem1 + "os"]);
229
+ setNominalForm(data.forms, "acc_sg", [stem1 + "on"]);
230
+ } else if (data.types.has("not_Greek")) {
231
+ data.subtitles.push("non-Greek-type");
232
+ }
233
+
234
+ if (data.types.has("genplum")) {
235
+ data.subtitles.push(["contracted", " genitive plural"]);
236
+ data.notes.set("gen_pl2", "Contraction found in poetry.");
237
+ if (data.types.has("ius") || data.types.has("ium")) {
238
+ setNominalForm(data.forms, "gen_pl", [stem2 + "iōrum", stem2 + "ium"]);
239
+ } else {
240
+ setNominalForm(data.forms, "gen_pl", [stem2 + "ōrum", stem2 + "um"]);
241
+ }
242
+ } else if (data.types.has("not_genplum")) {
243
+ data.subtitles.push(["normal", " genitive plural"]);
244
+ }
245
+
246
+ if (data.loc) {
247
+ if (data.types.has("ius") || data.types.has("ium")) {
248
+ setNominalForm(data.forms, "loc_sg", [stem2 + "iī"]);
249
+ setNominalForm(data.forms, "loc_pl", [stem2 + "iīs"]);
250
+ } else {
251
+ setNominalForm(data.forms, "loc_sg", [stem2 + "ī"]);
252
+ setNominalForm(data.forms, "loc_pl", [stem2 + "īs"]);
253
+ }
254
+ }
255
+ }],
256
+ ["3", (data, args) => {
257
+ let stem1 = args[0];
258
+ const stem2 = args[1];
259
+
260
+ function parisyllabic_type(): string {
261
+ const stem1_vowels = strip_macrons(stem1).replace(/[^AEIOUYaeiouy]/g, "");
262
+ const stem2_vowels = strip_macrons(stem2).replace(/[^AEIOUYaeiouy]/g, "");
263
+ return stem1_vowels.length > stem2_vowels.length ? "parisyllabic" : "imparisyllabic";
264
+ }
265
+
266
+ function non_i_stem_type() {
267
+ return parisyllabic_type() + " non-i-stem";
268
+ }
269
+
270
+ setNominalForm(data.forms, "nom_sg", [stem1]);
271
+ setNominalForm(data.forms, "gen_sg", [stem2 + "is"]);
272
+ setNominalForm(data.forms, "dat_sg", [stem2 + "ī"]);
273
+ setNominalForm(data.forms, "acc_sg", [stem2 + "em"]);
274
+ setNominalForm(data.forms, "abl_sg", [stem2 + "e"]);
275
+ setNominalForm(data.forms, "voc_sg", [stem1]);
276
+
277
+ setNominalForm(data.forms, "nom_pl", [stem2 + "ēs"]);
278
+ setNominalForm(data.forms, "gen_pl", [stem2 + "um"]);
279
+ setNominalForm(data.forms, "dat_pl", [stem2 + "ibus"]);
280
+ setNominalForm(data.forms, "acc_pl", [stem2 + "ēs"]);
281
+ setNominalForm(data.forms, "abl_pl", [stem2 + "ibus"]);
282
+ setNominalForm(data.forms, "voc_pl", [stem2 + "ēs"]);
283
+
284
+ let acc_sg_i_stem_subtype = false;
285
+ let not_acc_sg_i_stem_subtype = false;
286
+
287
+ for (const subtype of data.types.keys()) {
288
+ if (acc_sg_i_stem_subtypes.has(subtype)) {
289
+ acc_sg_i_stem_subtype = true;
290
+ break;
291
+ }
292
+ }
293
+
294
+ for (const [acc_sg_subtype, [endings, title]] of acc_sg_i_stem_subtypes) {
295
+ if (data.types.has("not_" + acc_sg_subtype)) {
296
+ not_acc_sg_i_stem_subtype = true;
297
+ break;
298
+ }
299
+ }
300
+
301
+ let abl_sg_i_stem_subtype = false;
302
+ let not_abl_sg_i_stem_subtype = false;
303
+ for (const subtype of data.types.keys()) {
304
+ if (abl_sg_i_stem_subtypes.has(subtype)) {
305
+ abl_sg_i_stem_subtype = true;
306
+ break;
307
+ }
308
+ }
309
+
310
+ for (const [abl_sg_subtype, [endings, title]] of abl_sg_i_stem_subtypes) {
311
+ if (data.types.has("not_" + abl_sg_subtype)) {
312
+ not_abl_sg_i_stem_subtype = true;
313
+ break;
314
+ }
315
+ }
316
+
317
+
318
+ if (data.types.has("Greek")) {
319
+ data.subtitles.push("Greek-type");
320
+
321
+ if (data.types.has("er")) {
322
+ data.subtitles.push("variant with nominative singular in '-ēr'");
323
+ stem1 = extract_stem(stem1, "ēr");
324
+
325
+ setNominalForm(data.forms, "nom_sg", [stem1 + "ēr"]);
326
+ setNominalForm(data.forms, "gen_sg", [stem1 + "eris"]);
327
+ setNominalForm(data.forms, "dat_sg", [stem1 + "erī"]);
328
+ setNominalForm(data.forms, "acc_sg", [stem1 + "era", stem1 + "erem"]);
329
+ setNominalForm(data.forms, "abl_sg", [stem1 + "ere"]);
330
+ setNominalForm(data.forms, "voc_sg", [stem1 + "ēr"]);
331
+
332
+ setNominalForm(data.forms, "nom_pl", [stem1 + "erēs"]);
333
+ setNominalForm(data.forms, "gen_pl", [stem1 + "erum"]);
334
+ setNominalForm(data.forms, "dat_pl", [stem1 + "eribus"]);
335
+ setNominalForm(data.forms, "acc_pl", [stem1 + "erēs"]);
336
+ setNominalForm(data.forms, "abl_pl", [stem1 + "eribus"]);
337
+ setNominalForm(data.forms, "voc_pl", [stem1 + "erēs"]);
338
+ } else if (data.types.has("on")) {
339
+ data.subtitles.push("variant with nominative singular in '-ōn'");
340
+ stem1 = extract_stem(stem1, "ōn");
341
+
342
+ setNominalForm(data.forms, "nom_sg", [stem1 + "ōn"]);
343
+ setNominalForm(data.forms, "gen_sg", [stem1 + "ontis", stem1 + "ontos"]);
344
+ setNominalForm(data.forms, "dat_sg", [stem1 + "ontī"]);
345
+ setNominalForm(data.forms, "acc_sg", [stem1 + "onta"]);
346
+ setNominalForm(data.forms, "abl_sg", [stem1 + "onte"]);
347
+ setNominalForm(data.forms, "voc_sg", [stem1 + "ōn"]);
348
+
349
+ setNominalForm(data.forms, "nom_pl", [stem1 + "ontēs"]);
350
+ setNominalForm(data.forms, "gen_pl", [stem1 + "ontum", stem1 + "ontium"]);
351
+ setNominalForm(data.forms, "dat_pl", [stem1 + "ontibus"]);
352
+ setNominalForm(data.forms, "acc_pl", [stem1 + "ontēs", stem1 + "ontās"]);
353
+ setNominalForm(data.forms, "abl_pl", [stem1 + "ontibus"]);
354
+ setNominalForm(data.forms, "voc_pl", [stem1 + "ontēs"]);
355
+ } else if (data.types.has("I")) {
356
+ data.subtitles.push("i-stem");
357
+ setNominalForm(data.forms, "gen_sg", [stem2 + "is", stem2 + "eōs", stem2 + "ios"]);
358
+ setNominalForm(data.forms, "acc_sg", [stem2 + "im", stem2 + "in", stem2 + "em"]);
359
+ setNominalForm(data.forms, "abl_sg", [stem2 + "ī", stem2 + "e"]);
360
+ setNominalForm(data.forms, "voc_sg", [stem2 + "is", stem2 + "i"]);
361
+
362
+ data.notes.set("acc_sg3", "Found sometimes in Medieval and New Latin.");
363
+ data.notes.set("abl_sg2", "Found sometimes in Medieval and New Latin.");
364
+
365
+ setNominalForm(data.forms, "nom_pl", [stem2 + "ēs", stem2 + "eis"]);
366
+ setNominalForm(data.forms, "gen_pl", [stem2 + "ium", stem2 + "eōn"]);
367
+ setNominalForm(data.forms, "acc_pl", [stem2 + "ēs", stem2 + "eis"]);
368
+ setNominalForm(data.forms, "voc_pl", [stem2 + "ēs", stem2 + "eis"]);
369
+
370
+ if (data.types.has("poetic_esi")) {
371
+ setNominalForm(data.forms, "dat_pl", [stem2 + "ibus", stem2 + "esi"]);
372
+ setNominalForm(data.forms, "abl_pl", [stem2 + "ibus", stem2 + "esi"]);
373
+ data.notes.set("dat_pl2", "Primarily in poetry.");
374
+ data.notes.set("abl_pl2", "Primarily in poetry.");
375
+ }
376
+ } else {
377
+ data.subtitles.push("normal variant");
378
+
379
+ setNominalForm(data.forms, "gen_sg", [stem2 + "os"]);
380
+ if (stem2.match(/y$/)) {
381
+ setNominalForm(data.forms, "acc_sg", [stem2 + "n"]);
382
+ } else {
383
+ setNominalForm(data.forms, "acc_sg", [stem2 + "a"]);
384
+ }
385
+ setNominalForm(data.forms, "nom_pl", [stem2 + "es"]);
386
+ setNominalForm(data.forms, "acc_pl", [stem2 + "as"]);
387
+ setNominalForm(data.forms, "voc_pl", [stem2 + "es"]);
388
+
389
+ if (stem1.match(/[iyï]s$/)) {
390
+ setNominalForm(data.forms, "voc_sg", [stem1, stem1.replace(/s/g, "")]);
391
+ data.notes.set("voc_sg2", "In poetry.");
392
+ }
393
+ }
394
+ } else if (data.types.has("not_Greek")) {
395
+ data.subtitles.push("non-Greek-type");
396
+ }
397
+
398
+ if (data.types.has("polis")) {
399
+ stem1 = extract_stem(stem1, "polis");
400
+ data.subtitles.push("i-stem, partially Greek-type");
401
+ setNominalForm(data.forms, "nom_sg", [stem1 + "polis"]);
402
+ setNominalForm(data.forms, "gen_sg", [stem1 + "polis"]);
403
+ setNominalForm(data.forms, "dat_sg", [stem1 + "polī"]);
404
+ setNominalForm(data.forms, "acc_sg", [stem1 + "polim", stem1 + "polin"]);
405
+ setNominalForm(data.forms, "abl_sg", [stem1 + "polī"]);
406
+ setNominalForm(data.forms, "voc_sg", [stem1 + "polis", stem1 + "polī"]);
407
+ } else if (data.types.has("not_polis")) {
408
+ data.subtitles.push(non_i_stem_type());
409
+ }
410
+
411
+ if (data.types.has("N")) {
412
+ data.subtitles.push("neuter");
413
+
414
+ setNominalForm(data.forms, "acc_sg", [stem1]);
415
+
416
+ if (data.types.has("I")) {
417
+ if (data.types.has("pure")) {
418
+ data.subtitles.push("“pure” i-stem");
419
+
420
+ setNominalForm(data.forms, "abl_sg", [stem2 + "ī"]);
421
+
422
+ setNominalForm(data.forms, "nom_pl", [stem2 + "ia"]);
423
+ setNominalForm(data.forms, "gen_pl", [stem2 + "ium"]);
424
+ setNominalForm(data.forms, "acc_pl", [stem2 + "ia"]);
425
+ setNominalForm(data.forms, "voc_pl", [stem2 + "ia"]);
426
+ } else {
427
+ data.subtitles.push("i-stem");
428
+ setNominalForm(data.forms, "nom_pl", [stem2 + "a"]);
429
+ setNominalForm(data.forms, "gen_pl", [stem2 + "ium", stem2 + "um"]);
430
+ setNominalForm(data.forms, "acc_pl", [stem2 + "a"]);
431
+ setNominalForm(data.forms, "voc_pl", [stem2 + "a"]);
432
+ }
433
+ } else {
434
+ data.subtitles.push(non_i_stem_type());
435
+ setNominalForm(data.forms, "nom_pl", [stem2 + "a"]);
436
+ setNominalForm(data.forms, "acc_pl", [stem2 + "a"]);
437
+ setNominalForm(data.forms, "voc_pl", [stem2 + "a"]);
438
+ }
439
+ } else if (data.types.has("I") || acc_sg_i_stem_subtype || abl_sg_i_stem_subtype) {
440
+ if (data.types.has("not_N")) {
441
+ data.subtitles.push("non-neuter i-stem");
442
+ } else {
443
+ data.subtitles.push("i-stem");
444
+ }
445
+
446
+ setNominalForm(data.forms, "gen_pl", [stem2 + "ium"]);
447
+ if (!data.declOpts.suppressNonNeuterIStemAccIs) {
448
+ setNominalForm(data.forms, "acc_pl", [stem2 + "ēs", stem2 + "īs"]);
449
+ } else {
450
+ setNominalForm(data.forms, "acc_pl", [stem2 + "ēs"]);
451
+ }
452
+
453
+ for (const subtype of data.types) {
454
+ const acc_sg_i_stem_props = acc_sg_i_stem_subtypes.get(subtype);
455
+ if (acc_sg_i_stem_props) {
456
+ setNominalForm(data.forms, "acc_sg", []);
457
+ for (const ending of acc_sg_i_stem_props[0]) {
458
+ setNominalForm(data.forms, "acc_sg", (getNominalForm(data.forms, "acc_sg") || []).concat([stem2 + ending]));
459
+ }
460
+ if (data.num != "pl") {
461
+ data.subtitles.push(acc_sg_i_stem_props[1]);
462
+ }
463
+ break;
464
+ }
465
+ }
466
+
467
+ for (const subtype of data.types) {
468
+ const abl_sg_i_stem_props = abl_sg_i_stem_subtypes.get(subtype);
469
+ if (abl_sg_i_stem_props) {
470
+ setNominalForm(data.forms, "abl_sg", []);
471
+ for (const ending of abl_sg_i_stem_props[0]) {
472
+ setNominalForm(data.forms, "abl_sg", (getNominalForm(data.forms, "abl_sg") || []).concat([stem2 + ending]));
473
+ }
474
+ if (data.num != "pl") {
475
+ data.subtitles.push(abl_sg_i_stem_props[1]);
476
+ }
477
+ break;
478
+ }
479
+ }
480
+ } else if (data.types.has("not_N") && data.types.has("not_I")) {
481
+ data.subtitles.push("non-neuter " + non_i_stem_type());
482
+ } else if (data.types.has("not_N")) {
483
+ data.subtitles.push("non-neuter");
484
+ } else if (data.types.has("not_I")) {
485
+ data.subtitles.push(non_i_stem_type());
486
+ }
487
+
488
+ if (data.loc) {
489
+ const loc_sg = Array.from(getNominalForm(data.forms, "dat_sg") || []);
490
+ const abl_sg = getNominalForm(data.forms, "abl_sg") || [];
491
+ for (const form of abl_sg) {
492
+ insert_if_not(loc_sg, form);
493
+ }
494
+ setNominalForm(data.forms, "loc_sg", loc_sg);
495
+ setNominalForm(data.forms, "loc_pl", getNominalForm(data.forms, "abl_pl") || []);
496
+ }
497
+ }],
498
+ ["4", (data, args) => {
499
+ const stem = args[0];
500
+
501
+ setNominalForm(data.forms, "nom_sg", [stem + "us"]);
502
+ setNominalForm(data.forms, "gen_sg", [stem + "ūs"]);
503
+ setNominalForm(data.forms, "dat_sg", [stem + "uī"]);
504
+ setNominalForm(data.forms, "acc_sg", [stem + "um"]);
505
+ setNominalForm(data.forms, "abl_sg", [stem + "ū"]);
506
+ setNominalForm(data.forms, "voc_sg", [stem + "us"]);
507
+
508
+ setNominalForm(data.forms, "nom_pl", [stem + "ūs"]);
509
+ setNominalForm(data.forms, "gen_pl", [stem + "uum"]);
510
+ setNominalForm(data.forms, "dat_pl", [stem + "ibus"]);
511
+ setNominalForm(data.forms, "acc_pl", [stem + "ūs"]);
512
+ setNominalForm(data.forms, "abl_pl", [stem + "ibus"]);
513
+ setNominalForm(data.forms, "voc_pl", [stem + "ūs"]);
514
+
515
+ if (data.types.has("echo")) {
516
+ data.subtitles.push("nominative/vocative singular in '-ō'");
517
+ setNominalForm(data.forms, "nom_sg", [stem + "ō"]);
518
+ setNominalForm(data.forms, "voc_sg", [stem + "ō"]);
519
+ } else if (data.types.has("argo")) {
520
+ data.subtitles.push("nominative/accusative/vocative singular in '-ō', ablative singular in '-uī'");
521
+ setNominalForm(data.forms, "nom_sg", [stem + "ō"]);
522
+ setNominalForm(data.forms, "acc_sg", [stem + "ō"]);
523
+ setNominalForm(data.forms, "abl_sg", [stem + "uī"]);
524
+ setNominalForm(data.forms, "voc_sg", [stem + "ō"]);
525
+ } else if (data.types.has("Callisto")) {
526
+ data.subtitles.push("all cases except the genitive singular in '-ō'");
527
+ setNominalForm(data.forms, "nom_sg", [stem + "ō"]);
528
+ setNominalForm(data.forms, "dat_sg", [stem + "ō"]);
529
+ setNominalForm(data.forms, "acc_sg", [stem + "ō"]);
530
+ setNominalForm(data.forms, "abl_sg", [stem + "ō"]);
531
+ setNominalForm(data.forms, "voc_sg", [stem + "ō"]);
532
+ }
533
+
534
+ if (data.types.has("N")) {
535
+ data.subtitles.push("neuter");
536
+
537
+ setNominalForm(data.forms, "nom_sg", [stem + "ū"]);
538
+ setNominalForm(data.forms, "dat_sg", [stem + "ū"]);
539
+ setNominalForm(data.forms, "acc_sg", [stem + "ū"]);
540
+ setNominalForm(data.forms, "voc_sg", [stem + "ū"]);
541
+
542
+ setNominalForm(data.forms, "nom_pl", [stem + "ua"]);
543
+ setNominalForm(data.forms, "acc_pl", [stem + "ua"]);
544
+ setNominalForm(data.forms, "voc_pl", [stem + "ua"]);
545
+ }
546
+
547
+ if (data.types.has("ubus")) {
548
+ data.subtitles.push("dative/ablative plural in '-ubus'");
549
+
550
+ setNominalForm(data.forms, "dat_pl", [stem + "ubus"]);
551
+ setNominalForm(data.forms, "abl_pl", [stem + "ubus"]);
552
+ } else if (data.types.has("not_ubus")) {
553
+ data.subtitles.push("'-ibus'");
554
+ }
555
+
556
+ if (data.loc) {
557
+ setNominalForm(data.forms, "loc_sg", getNominalForm(data.forms, "abl_sg") || []);
558
+ setNominalForm(data.forms, "loc_pl", getNominalForm(data.forms, "abl_pl") || []);
559
+ }
560
+
561
+ }],
562
+ ["5", (data, args) => {
563
+ let stem = args[0];
564
+
565
+ if (data.types.has("i")) {
566
+ stem = stem + "i";
567
+ }
568
+
569
+ setNominalForm(data.forms, "nom_sg", [stem + "ēs"]);
570
+ setNominalForm(data.forms, "gen_sg", [stem + "eī"]);
571
+ setNominalForm(data.forms, "dat_sg", [stem + "eī"]);
572
+ setNominalForm(data.forms, "acc_sg", [stem + "em"]);
573
+ setNominalForm(data.forms, "abl_sg", [stem + "ē"]);
574
+ setNominalForm(data.forms, "voc_sg", [stem + "ēs"]);
575
+
576
+ setNominalForm(data.forms, "nom_pl", [stem + "ēs"]);
577
+ setNominalForm(data.forms, "gen_pl", [stem + "ērum"]);
578
+ setNominalForm(data.forms, "dat_pl", [stem + "ēbus"]);
579
+ setNominalForm(data.forms, "acc_pl", [stem + "ēs"]);
580
+ setNominalForm(data.forms, "abl_pl", [stem + "ēbus"]);
581
+ setNominalForm(data.forms, "voc_pl", [stem + "ēs"]);
582
+
583
+ if (data.types.has("i")) {
584
+ setNominalForm(data.forms, "gen_sg", [stem + "ēī"]);
585
+ setNominalForm(data.forms, "dat_sg", [stem + "ēī"]);
586
+ }
587
+
588
+ if (data.loc) {
589
+ setNominalForm(data.forms, "loc_sg", [stem + "ē"]);
590
+ setNominalForm(data.forms, "loc_pl", [stem + "ēbus"]);
591
+ }
592
+ }],
593
+ ["0", (data, args) => {
594
+ const stem = args[0];
595
+
596
+ setNominalForm(data.forms, "nom_sg", [stem]);
597
+ setNominalForm(data.forms, "gen_sg", [stem]);
598
+ setNominalForm(data.forms, "dat_sg", [stem]);
599
+ setNominalForm(data.forms, "acc_sg", [stem]);
600
+ setNominalForm(data.forms, "abl_sg", [stem]);
601
+ setNominalForm(data.forms, "voc_sg", [stem]);
602
+
603
+ setNominalForm(data.forms, "nom_pl", [stem]);
604
+ setNominalForm(data.forms, "gen_pl", [stem]);
605
+ setNominalForm(data.forms, "dat_pl", [stem]);
606
+ setNominalForm(data.forms, "acc_pl", [stem]);
607
+ setNominalForm(data.forms, "abl_pl", [stem]);
608
+ setNominalForm(data.forms, "voc_pl", [stem]);
609
+
610
+ if (data.loc) {
611
+ setNominalForm(data.forms, "loc_sg", [stem]);
612
+ setNominalForm(data.forms, "loc_pl", [stem]);
613
+ }
614
+ }],
615
+ ["indecl", (data, args) => {
616
+ data.title = "Not declined; used only in the nominative and accusative singular.";
617
+
618
+ const stem = args[0];
619
+
620
+ setNominalForm(data.forms, "nom_sg", ["-"]);
621
+ setNominalForm(data.forms, "gen_sg", ["-"]);
622
+ setNominalForm(data.forms, "dat_sg", ["-"]);
623
+ setNominalForm(data.forms, "acc_sg", ["-"]);
624
+ setNominalForm(data.forms, "abl_sg", ["-"]);
625
+ setNominalForm(data.forms, "voc_sg", ["-"]);
626
+
627
+ setNominalForm(data.forms, "nom_pl", ["-"]);
628
+ setNominalForm(data.forms, "gen_pl", ["-"]);
629
+ setNominalForm(data.forms, "dat_pl", ["-"]);
630
+ setNominalForm(data.forms, "acc_pl", ["-"]);
631
+ setNominalForm(data.forms, "abl_pl", ["-"]);
632
+ setNominalForm(data.forms, "voc_pl", ["-"]);
633
+
634
+ setNominalForm(data.forms, "nom_sg", [stem]);
635
+ setNominalForm(data.forms, "acc_sg", [stem]);
636
+ data.num = NumberTantum.Singular;
637
+ }],
638
+ ["irreg", (data, args) => {
639
+ const stem = args[0];
640
+ setNominalForm(data.forms, "nom_sg", ["-"]);
641
+ setNominalForm(data.forms, "gen_sg", ["-"]);
642
+ setNominalForm(data.forms, "dat_sg", ["-"]);
643
+ setNominalForm(data.forms, "acc_sg", ["-"]);
644
+ setNominalForm(data.forms, "abl_sg", ["-"]);
645
+ setNominalForm(data.forms, "voc_sg", ["-"]);
646
+
647
+ setNominalForm(data.forms, "nom_pl", ["-"]);
648
+ setNominalForm(data.forms, "gen_pl", ["-"]);
649
+ setNominalForm(data.forms, "dat_pl", ["-"]);
650
+ setNominalForm(data.forms, "acc_pl", ["-"]);
651
+ setNominalForm(data.forms, "abl_pl", ["-"]);
652
+ setNominalForm(data.forms, "voc_pl", ["-"]);
653
+
654
+ if (stem == "bōs") {
655
+ setNominalForm(data.forms, "nom_sg", ["bōs"]);
656
+ setNominalForm(data.forms, "gen_sg", ["bovis"]);
657
+ setNominalForm(data.forms, "dat_sg", ["bovī"]);
658
+ setNominalForm(data.forms, "acc_sg", ["bovem"]);
659
+ setNominalForm(data.forms, "abl_sg", ["bove"]);
660
+ setNominalForm(data.forms, "voc_sg", ["bōs"]);
661
+
662
+ setNominalForm(data.forms, "nom_pl", ["bovēs"]);
663
+ setNominalForm(data.forms, "gen_pl", ["boum"]);
664
+ if (!data.declOpts.suppressRareIrregForms) {
665
+ setNominalForm(data.forms, "dat_pl", ["bōbus", "būbus"]);
666
+ setNominalForm(data.forms, "abl_pl", ["bōbus", "būbus"]);
667
+ } else {
668
+ setNominalForm(data.forms, "dat_pl", ["bōbus"]);
669
+ setNominalForm(data.forms, "abl_pl", ["bōbus"]);
670
+ }
671
+ setNominalForm(data.forms, "acc_pl", ["bovēs"]);
672
+ setNominalForm(data.forms, "voc_pl", ["bovēs"]);
673
+ } else if (stem == "cherub") {
674
+ data.title = "mostly indeclinable";
675
+ data.subtitles.push("with a distinct plural");
676
+
677
+ setNominalForm(data.forms, "nom_sg", ["cherub"]);
678
+ setNominalForm(data.forms, "gen_sg", ["cherub"]);
679
+ setNominalForm(data.forms, "dat_sg", ["cherub"]);
680
+ setNominalForm(data.forms, "acc_sg", ["cherub"]);
681
+ setNominalForm(data.forms, "abl_sg", ["cherub"]);
682
+ setNominalForm(data.forms, "voc_sg", ["cherub"]);
683
+
684
+ setNominalForm(data.forms, "nom_pl", ["cherubim", "cherubin"]);
685
+ setNominalForm(data.forms, "gen_pl", ["cherubim", "cherubin"]);
686
+ setNominalForm(data.forms, "dat_pl", ["cherubim", "cherubin"]);
687
+ setNominalForm(data.forms, "acc_pl", ["cherubim", "cherubin"]);
688
+ setNominalForm(data.forms, "abl_pl", ["cherubim", "cherubin"]);
689
+ setNominalForm(data.forms, "voc_pl", ["cherubim", "cherubin"]);
690
+ } else if (stem == "deus") {
691
+ setNominalForm(data.forms, "nom_sg", ["deus"]);
692
+ setNominalForm(data.forms, "gen_sg", ["deī"]);
693
+ setNominalForm(data.forms, "dat_sg", ["deō"]);
694
+ setNominalForm(data.forms, "acc_sg", ["deum"]);
695
+ setNominalForm(data.forms, "abl_sg", ["deō"]);
696
+ setNominalForm(data.forms, "voc_sg", ["deus"]);
697
+
698
+ setNominalForm(data.forms, "nom_pl", ["dī", "diī", "deī"]);
699
+ setNominalForm(data.forms, "gen_pl", ["deōrum", "deûm", "divom"]);
700
+ setNominalForm(data.forms, "dat_pl", ["dīs", "diīs", "deīs"]);
701
+ setNominalForm(data.forms, "acc_pl", ["deōs"]);
702
+ setNominalForm(data.forms, "abl_pl", ["dīs", "diīs", "deīs"]);
703
+ setNominalForm(data.forms, "voc_pl", ["dī", "diī", "deī"]);
704
+ } else if (stem == "Deus") {
705
+ setNominalForm(data.forms, "nom_sg", ["Deus"]);
706
+ setNominalForm(data.forms, "gen_sg", ["Deī"]);
707
+ setNominalForm(data.forms, "dat_sg", ["Deō"]);
708
+ setNominalForm(data.forms, "acc_sg", ["Deum"]);
709
+ setNominalForm(data.forms, "abl_sg", ["Deō"]);
710
+ setNominalForm(data.forms, "voc_sg", ["Deus"]);
711
+ data.num = NumberTantum.Singular;
712
+ } else if (stem == "domus") {
713
+ data.title = "fourth/second-declension noun";
714
+
715
+ setNominalForm(data.forms, "nom_sg", ["domus"]);
716
+ if (!data.declOpts.suppressRareIrregForms) {
717
+ setNominalForm(data.forms, "gen_sg", ["domūs", "domī"]);
718
+ setNominalForm(data.forms, "dat_sg", ["domuī", "domō", "domū"]);
719
+ setNominalForm(data.forms, "abl_sg", ["domū", "domō"]);
720
+
721
+ setNominalForm(data.forms, "gen_pl", ["domuum", "domōrum"]);
722
+ setNominalForm(data.forms, "acc_pl", ["domūs", "domōs"]);
723
+ } else {
724
+ setNominalForm(data.forms, "gen_sg", ["domūs"]);
725
+ setNominalForm(data.forms, "dat_sg", ["domuī"]);
726
+ setNominalForm(data.forms, "abl_sg", ["domō"]);
727
+
728
+ setNominalForm(data.forms, "gen_pl", ["domuum"]);
729
+ setNominalForm(data.forms, "acc_pl", ["domōs"]);
730
+ }
731
+ setNominalForm(data.forms, "acc_sg", ["domum"]);
732
+ setNominalForm(data.forms, "voc_sg", ["domus"]);
733
+ setNominalForm(data.forms, "loc_sg", ["domī"]);
734
+
735
+ setNominalForm(data.forms, "nom_pl", ["domūs"]);
736
+ setNominalForm(data.forms, "dat_pl", ["domibus"]);
737
+ setNominalForm(data.forms, "abl_pl", ["domibus"]);
738
+ setNominalForm(data.forms, "voc_pl", ["domūs"]);
739
+ setNominalForm(data.forms, "loc_pl", ["domibus"]);
740
+
741
+ data.loc = true;
742
+ } else if (stem == "Iēsus" || stem == "Iēsūs") {
743
+ data.subtitles.push("highly irregular");
744
+ const ij = stem[0];
745
+ setNominalForm(data.forms, "nom_sg", [stem]);
746
+ setNominalForm(data.forms, "gen_sg", [ij + "ēsū"]);
747
+ setNominalForm(data.forms, "dat_sg", [ij + "ēsū"]);
748
+ setNominalForm(data.forms, "acc_sg", [ij + "ēsum"]);
749
+ setNominalForm(data.forms, "abl_sg", [ij + "ēsū"]);
750
+ setNominalForm(data.forms, "voc_sg", [ij + "ēsū"]);
751
+ data.num = NumberTantum.Singular;
752
+ } else if (stem == "Jesus") {
753
+ data.subtitles.push("highly irregular");
754
+ const ij = stem[0];
755
+ setNominalForm(data.forms, "nom_sg", [stem]);
756
+ setNominalForm(data.forms, "gen_sg", [ij + "esu"]);
757
+ setNominalForm(data.forms, "dat_sg", [ij + "esu"]);
758
+ setNominalForm(data.forms, "acc_sg", [ij + "esum"]);
759
+ setNominalForm(data.forms, "abl_sg", [ij + "esu"]);
760
+ setNominalForm(data.forms, "voc_sg", [ij + "esu"]);
761
+ data.num = NumberTantum.Singular;
762
+ } else if (stem == "iūgerum" || stem == "jūgerum") {
763
+ const ij = stem[0];
764
+ data.title = "second–third-declension hybrid noun";
765
+ data.subtitles.push("neuter");
766
+
767
+ setNominalForm(data.forms, "nom_sg", [ij + "ūgerum"]);
768
+ setNominalForm(data.forms, "gen_sg", [ij + "ūgerī"]);
769
+ setNominalForm(data.forms, "dat_sg", [ij + "ūgerō"]);
770
+ setNominalForm(data.forms, "acc_sg", [ij + "ūgerum"]);
771
+ setNominalForm(data.forms, "abl_sg", [ij + "ūgerō"]);
772
+ setNominalForm(data.forms, "voc_sg", [ij + "ūgerum"]);
773
+ setNominalForm(data.forms, "nom_pl", [ij + "ūgera"]);
774
+ setNominalForm(data.forms, "gen_pl", [ij + "ūgerum"]);
775
+ setNominalForm(data.forms, "dat_pl", [ij + "ūgeribus"]);
776
+ setNominalForm(data.forms, "acc_pl", [ij + "ūgera"]);
777
+ setNominalForm(data.forms, "abl_pl", [ij + "ūgeribus", ij + "ūgerīs"]);
778
+ setNominalForm(data.forms, "voc_pl", [ij + "ūgera"]);
779
+
780
+ data.notes.set("abl_pl2", "Once only, in:<br/>M. Terentius Varro, 'Res Rusticae', bk I, ch. x");
781
+ } else if (stem == "sūs") {
782
+ setNominalForm(data.forms, "nom_sg", ["sūs"]);
783
+ setNominalForm(data.forms, "gen_sg", ["suis"]);
784
+ setNominalForm(data.forms, "dat_sg", ["suī"]);
785
+ setNominalForm(data.forms, "acc_sg", ["suem"]);
786
+ setNominalForm(data.forms, "abl_sg", ["sue"]);
787
+ setNominalForm(data.forms, "voc_sg", ["sūs"]);
788
+
789
+ setNominalForm(data.forms, "nom_pl", ["suēs"]);
790
+ setNominalForm(data.forms, "gen_pl", ["suum"]);
791
+ setNominalForm(data.forms, "dat_pl", ["suibus", "sūbus", "subus"]);
792
+ setNominalForm(data.forms, "acc_pl", ["suēs"]);
793
+ setNominalForm(data.forms, "abl_pl", ["suibus", "sūbus", "subus"]);
794
+ setNominalForm(data.forms, "voc_pl", ["suēs"]);
795
+ } else if (stem == "ēthos") {
796
+ data.subtitles.push("irregular");
797
+ data.subtitles.push("Greek-type");
798
+
799
+ setNominalForm(data.forms, "nom_sg", ["ēthos"]);
800
+ setNominalForm(data.forms, "gen_sg", ["ētheos"]);
801
+ setNominalForm(data.forms, "acc_sg", ["ēthos"]);
802
+ setNominalForm(data.forms, "voc_sg", ["ēthos"]);
803
+
804
+ setNominalForm(data.forms, "nom_pl", ["ēthea", "ēthē"]);
805
+ setNominalForm(data.forms, "dat_pl", ["ēthesi", "ēthesin"]);
806
+ setNominalForm(data.forms, "acc_pl", ["ēthea", "ēthē"]);
807
+ setNominalForm(data.forms, "abl_pl", ["ēthesi", "ēthesin"]);
808
+ setNominalForm(data.forms, "voc_pl", ["ēthea", "ēthē"]);
809
+ } else if (stem == "lexis") {
810
+ data.subtitles.push("irregular");
811
+ data.subtitles.push("Greek-type");
812
+
813
+ setNominalForm(data.forms, "nom_sg", ["lexis"]);
814
+ setNominalForm(data.forms, "gen_sg", ["lexeōs"]);
815
+ setNominalForm(data.forms, "acc_pl", ["lexeis"]);
816
+ } else if (stem == "Athōs") {
817
+ data.subtitles.push("highly irregular");
818
+ data.subtitles.push("Greek-type");
819
+
820
+ setNominalForm(data.forms, "nom_sg", ["Athōs"]);
821
+ setNominalForm(data.forms, "gen_sg", ["Athō"]);
822
+ setNominalForm(data.forms, "dat_sg", ["Athō"]);
823
+ setNominalForm(data.forms, "acc_sg", ["Athō", "Athōn"]);
824
+ setNominalForm(data.forms, "abl_sg", ["Athō"]);
825
+ setNominalForm(data.forms, "voc_sg", ["Athōs"]);
826
+ data.num = NumberTantum.Singular;
827
+ } else if (stem == "vēnum") {
828
+ data.title = "fourth/second-declension noun";
829
+ data.subtitles.push("defective");
830
+
831
+ setNominalForm(data.forms, "dat_sg", ["vēnuī", "vēnō"]);
832
+ setNominalForm(data.forms, "acc_sg", ["vēnum"]);
833
+ data.num = NumberTantum.Singular;
834
+ } else if (stem == "vīs") {
835
+ data.subtitles.push("irregular");
836
+ data.subtitles.push("defective");
837
+
838
+ if (!data.declOpts.suppressRareIrregForms) {
839
+ setNominalForm(data.forms, "gen_sg", ["*vīs"]);
840
+ setNominalForm(data.forms, "dat_sg", ["*vī"]);
841
+
842
+ setNominalForm(data.forms, "acc_pl", ["vīrēs", "vīrīs"]);
843
+ } else {
844
+ setNominalForm(data.forms, "acc_pl", ["vīrēs"]);
845
+ }
846
+
847
+ setNominalForm(data.forms, "nom_sg", ["vīs"]);
848
+ setNominalForm(data.forms, "acc_sg", ["vim"]);
849
+ setNominalForm(data.forms, "abl_sg", ["vī"]);
850
+ setNominalForm(data.forms, "voc_sg", ["vīs"]);
851
+
852
+ setNominalForm(data.forms, "nom_pl", ["vīrēs"]);
853
+ setNominalForm(data.forms, "gen_pl", ["vīrium"]);
854
+ setNominalForm(data.forms, "dat_pl", ["vīribus"]);
855
+ setNominalForm(data.forms, "abl_pl", ["vīribus"]);
856
+ setNominalForm(data.forms, "voc_pl", ["vīrēs"]);
857
+ } else {
858
+ throw Error(`Stem ${stem} not recognized.`);
859
+ }
860
+ }],
861
+ ]);
862
+
863
+ const acc_sg_i_stem_subtypes = new Map<string, [string[], string]>([
864
+ ["acc_im", [["im"], "accusative singular in '-im'"]],
865
+ ["acc_im_in", [["im", "in"], "accusative singular in '-im' or '-in'"]],
866
+ ["acc_im_in_em", [["im", "in", "em"], "accusative singular in '-im', '-in' or '-em'"]],
867
+ ["acc_im_em", [["im", "em"], "accusative singular in '-im' or '-em'"]],
868
+ ["acc_im_occ_em", [["im", "em"], "accusative singular in '-im' or occasionally '-em'"]],
869
+ ["acc_em_im", [["em", "im"], "accusative singular in '-em' or '-im'"]],
870
+ ]);
871
+
872
+ const abl_sg_i_stem_subtypes = new Map<string, [string[], string]>([
873
+ ["abl_i", [["ī"], "ablative singular in '-ī'"]],
874
+ ["abl_i_e", [["ī", "e"], "ablative singular in '-ī' or '-e'"]],
875
+ ["abl_e_i", [["e", "ī"], "ablative singular in '-e' or '-ī'"]],
876
+ ["abl_e_occ_i", [["e", "ī"], "ablative singular in '-e' or occasionally '-ī'"]],
877
+ ]);
878
+
879
+ function extract_stem(form: string, ending: string): string {
880
+ const base = form.match(new RegExp(`^(.*)${ending}$`));
881
+ if (!base) {
882
+ throw Error(`Form ${form} should end in -${ending}`);
883
+ }
884
+ return base[1];
885
+ }
886
+
887
+ function insert_if_not(data: string[], entry: string, pos = 0) {
888
+ if (data.includes(entry)) {
889
+ return;
890
+ }
891
+ if (pos == 0) {
892
+ data.push(entry);
893
+ } else {
894
+ data.splice(pos - 1, 0, entry);
895
+ }
896
+ }