ekms 9.4.5 → 9.5.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 (43) hide show
  1. package/common/animals.instance.json +40 -280
  2. package/common/colors.instance.json +92 -320
  3. package/common/comparable.instance.json +42 -10
  4. package/common/crew.instance.json +673 -965
  5. package/common/crew.js +0 -15
  6. package/common/dates.instance.json +2 -84
  7. package/common/dates.js +1 -0
  8. package/common/dimension.instance.json +2 -2
  9. package/common/dimension.js +1 -1
  10. package/common/edible.instance.json +874 -2097
  11. package/common/fastfood.instance.json +4865 -6422
  12. package/common/fastfood.js +1 -0
  13. package/common/gdefaults.js +34 -2
  14. package/common/helpers/concept.js +2 -1
  15. package/common/helpers/dialogues.js +2 -1
  16. package/common/kirk.instance.json +3 -23
  17. package/common/latin.instance.json +472 -1
  18. package/common/latin.js +145 -19
  19. package/common/latin.test.json +5325 -0
  20. package/common/latin_helpers.js +358 -0
  21. package/common/length.instance.json +128 -384
  22. package/common/menus.instance.json +21 -61
  23. package/common/people.instance.json +128 -96
  24. package/common/percentages.js +1 -0
  25. package/common/pipboy.instance.json +84 -366
  26. package/common/pipboy.js +2 -1
  27. package/common/pipboy.test.json +1690 -0
  28. package/common/pokemon.instance.json +351 -103
  29. package/common/pos.js +39 -34
  30. package/common/pressure.instance.json +32 -124
  31. package/common/properties.js +0 -16
  32. package/common/reminders.test.json +2702 -2786
  33. package/common/reports.instance.json +2 -2
  34. package/common/reports.js +4 -1
  35. package/common/reports.test.json +5547 -4514
  36. package/common/spock.instance.json +3 -23
  37. package/common/temperature.instance.json +40 -196
  38. package/common/tokenize.js +30 -2
  39. package/common/weight.instance.json +241 -301
  40. package/common/wp.instance.json +347 -373
  41. package/common/wp.js +25 -4
  42. package/common/wp.test.json +3104 -0
  43. package/package.json +3 -2
@@ -0,0 +1,358 @@
1
+ function wordPlusInflectedWord(choice) {
2
+ const inflected_word = choice.word
3
+ const word = inflected_word.normalize('NFKD').replace(/[^\x00-\x7F]/g, '');
4
+ choice.inflected_word = inflected_word
5
+ choice.word = word
6
+ return choice
7
+ }
8
+
9
+ function getDeclensions(nominative, genitive = null) {
10
+ // Normalize input
11
+ nominative = nominative.toLowerCase().trim();
12
+ genitive = genitive ? genitive.toLowerCase().trim() : null;
13
+
14
+ // Regular expressions for declension identification
15
+ const firstDeclension = /a$/;
16
+ const secondDeclensionUs = /us$/;
17
+ const secondDeclensionEr = /er$/;
18
+ const secondDeclensionUm = /um$/;
19
+ const fourthDeclensionUs = /us$/; // Needs context (genitive)
20
+ const fourthDeclensionU = /u$/;
21
+ const fifthDeclension = /es$/;
22
+
23
+ // Irregular nouns
24
+ const irregularNouns = {
25
+ vis: {
26
+ declension: "3rd-i",
27
+ forms: [
28
+ { declension: "nominative", number: "singular", ending: "vis", word: "vis" },
29
+ { declension: "genitive", number: "singular", ending: "vis", word: "vis" },
30
+ { declension: "dative", number: "singular", ending: "vi", word: "vi" },
31
+ { declension: "accusative", number: "singular", ending: "vim", word: "vim" },
32
+ { declension: "ablative", number: "singular", ending: "vi", word: "vi" },
33
+ { declension: "nominative", number: "plural", ending: "vires", word: "vires" },
34
+ { declension: "genitive", number: "plural", ending: "virium", word: "virium" },
35
+ { declension: "dative", number: "plural", ending: "viribus", word: "viribus" },
36
+ { declension: "accusative", number: "plural", ending: "vires", word: "vires" },
37
+ { declension: "ablative", number: "plural", ending: "viribus", word: "viribus" }
38
+ ].map( wordPlusInflectedWord )
39
+ },
40
+ domus: {
41
+ declension: "4th",
42
+ forms: [
43
+ { declension: "nominative", number: "singular", ending: "domus", word: "domus" },
44
+ { declension: "genitive", number: "singular", ending: "ūs", word: "domūs" },
45
+ { declension: "dative", number: "singular", ending: "uī", word: "domuī" },
46
+ { declension: "accusative", number: "singular", ending: "um", word: "domum" },
47
+ { declension: "ablative", number: "singular", ending: "ō", word: "domō" },
48
+ { declension: "nominative", number: "plural", ending: "ūs", word: "domūs" },
49
+ { declension: "genitive", number: "plural", ending: "uum", word: "domuum" },
50
+ { declension: "dative", number: "plural", ending: "ibus", word: "domibus" },
51
+ { declension: "accusative", number: "plural", ending: "ūs", word: "domūs" },
52
+ { declension: "ablative", number: "plural", ending: "ibus", word: "domibus" },
53
+ { declension: "vocative", number: "singular", ending: "domus", word: "domus" }
54
+ ].map( wordPlusInflectedWord )
55
+ }
56
+ };
57
+
58
+ // Helper to get stem
59
+ function getStem(noun, declension, gen) {
60
+ if (irregularNouns[noun]) return null; // Handled separately
61
+ if (declension === "1st") return noun.slice(0, -1); // Remove -a
62
+ if (declension === "2nd-us") return noun.slice(0, -2); // Remove -us
63
+ if (declension === "2nd-er") {
64
+ const knownErWithE = ["puer", "liber", "vir"];
65
+ return knownErWithE.includes(noun) ? noun : noun.slice(0, -2) + "r"; // Remove -er, add r for ager
66
+ }
67
+ if (declension === "2nd-um") return noun.slice(0, -2); // Remove -um
68
+ if (declension === "4th-us") return noun.slice(0, -2); // Remove -us
69
+ if (declension === "4th-u") return noun.slice(0, -1); // Remove -u only
70
+ if (declension === "5th") return noun.slice(0, -2); // Remove -es
71
+ if (declension === "3rd" || declension === "3rd-i") {
72
+ if (!gen) throw new Error("Genitive required for 3rd declension.");
73
+ return gen.slice(0, -2); // Remove -is from genitive
74
+ }
75
+ return null;
76
+ }
77
+
78
+ // Determine declension
79
+ let declension = null;
80
+ let isNeuter = false;
81
+ if (irregularNouns[nominative]) {
82
+ declension = irregularNouns[nominative].declension;
83
+ } else if (firstDeclension.test(nominative)) {
84
+ declension = "1st";
85
+ } else if (secondDeclensionUs.test(nominative)) {
86
+ // Differentiate 2nd vs 4th using genitive if provided
87
+ if (genitive && genitive.endsWith("ūs")) declension = "4th-us";
88
+ else declension = "2nd-us";
89
+ } else if (secondDeclensionEr.test(nominative)) {
90
+ declension = "2nd-er";
91
+ } else if (secondDeclensionUm.test(nominative)) {
92
+ declension = "2nd-um";
93
+ isNeuter = true;
94
+ } else if (fourthDeclensionU.test(nominative)) {
95
+ declension = "4th-u";
96
+ isNeuter = true;
97
+ } else if (fifthDeclension.test(nominative)) {
98
+ declension = "5th";
99
+ } else if (genitive) {
100
+ // Assume 3rd declension if genitive provided and no other match
101
+ const iStemNouns = ["navis", "mare", "animal"];
102
+ declension = iStemNouns.includes(nominative) ? "3rd-i" : "3rd";
103
+ if (nominative === "mare") isNeuter = true;
104
+ } else {
105
+ return [{ declension: "error", number: null, ending: null, word: "Invalid noun or missing genitive for 3rd declension." }];
106
+ }
107
+
108
+ // Handle irregular nouns
109
+ if (irregularNouns[nominative]) {
110
+ return irregularNouns[nominative].forms;
111
+ }
112
+
113
+ // Get stem
114
+ let stem;
115
+ try {
116
+ stem = getStem(nominative, declension, genitive);
117
+ } catch (e) {
118
+ return [{ declension: "error", number: null, ending: null, word: e.message }];
119
+ }
120
+ if (!stem) return [{ declension: "error", number: null, ending: null, word: "Unable to determine stem." }];
121
+
122
+ // Define endings for each declension
123
+ const endings = {
124
+ "1st": {
125
+ nominativeSingular: { ending: "a", number: "singular" },
126
+ genitiveSingular: { ending: "ae", number: "singular" },
127
+ dativeSingular: { ending: "ae", number: "singular" },
128
+ accusativeSingular: { ending: "am", number: "singular" },
129
+ ablativeSingular: { ending: "ā", number: "singular" },
130
+ nominativePlural: { ending: "ae", number: "plural" },
131
+ genitivePlural: { ending: "ārum", number: "plural" },
132
+ dativePlural: { ending: "īs", number: "plural" },
133
+ accusativePlural: { ending: "ās", number: "plural" },
134
+ ablativePlural: { ending: "īs", number: "plural" },
135
+ vocativeSingular: { ending: "a", number: "singular" }
136
+ },
137
+ "2nd-us": {
138
+ nominativeSingular: { ending: "us", number: "singular" },
139
+ genitiveSingular: { ending: "ī", number: "singular" },
140
+ dativeSingular: { ending: "ō", number: "singular" },
141
+ accusativeSingular: { ending: "um", number: "singular" },
142
+ ablativeSingular: { ending: "ō", number: "singular" },
143
+ nominativePlural: { ending: "ī", number: "plural" },
144
+ genitivePlural: { ending: "ōrum", number: "plural" },
145
+ dativePlural: { ending: "īs", number: "plural" },
146
+ accusativePlural: { ending: "ōs", number: "plural" },
147
+ ablativePlural: { ending: "īs", number: "plural" },
148
+ vocativeSingular: { ending: "e", number: "singular" }
149
+ },
150
+ "2nd-er": {
151
+ nominativeSingular: { ending: nominative, number: "singular" },
152
+ genitiveSingular: { ending: "ī", number: "singular" },
153
+ dativeSingular: { ending: "ō", number: "singular" },
154
+ accusativeSingular: { ending: nominative === "puer" || nominative === "liber" || nominative === "ager" ? "um" : "rum", number: "singular" },
155
+ ablativeSingular: { ending: "ō", number: "singular" },
156
+ nominativePlural: { ending: "ī", number: "plural" },
157
+ genitivePlural: { ending: "ōrum", number: "plural" },
158
+ dativePlural: { ending: "īs", number: "plural" },
159
+ accusativePlural: { ending: "ōs", number: "plural" },
160
+ ablativePlural: { ending: "īs", number: "plural" },
161
+ vocativeSingular: { ending: nominative, number: "singular" }
162
+ },
163
+ "2nd-um": {
164
+ nominativeSingular: { ending: "um", number: "singular" },
165
+ genitiveSingular: { ending: "ī", number: "singular" },
166
+ dativeSingular: { ending: "ō", number: "singular" },
167
+ accusativeSingular: { ending: "um", number: "singular" },
168
+ ablativeSingular: { ending: "ō", number: "singular" },
169
+ nominativePlural: { ending: "a", number: "plural" },
170
+ genitivePlural: { ending: "ōrum", number: "plural" },
171
+ dativePlural: { ending: "īs", number: "plural" },
172
+ accusativePlural: { ending: "a", number: "plural" },
173
+ ablativePlural: { ending: "īs", number: "plural" },
174
+ vocativeSingular: { ending: "um", number: "singular" }
175
+ },
176
+ "3rd": {
177
+ nominativeSingular: { ending: nominative, number: "singular" },
178
+ genitiveSingular: { ending: "is", number: "singular" },
179
+ dativeSingular: { ending: "ī", number: "singular" },
180
+ accusativeSingular: { ending: isNeuter ? nominative : "em", number: "singular" },
181
+ ablativeSingular: { ending: "e", number: "singular" },
182
+ nominativePlural: { ending: isNeuter ? "a" : "ēs", number: "plural" },
183
+ genitivePlural: { ending: "um", number: "plural" },
184
+ dativePlural: { ending: "ibus", number: "plural" },
185
+ accusativePlural: { ending: isNeuter ? "a" : "ēs", number: "plural" },
186
+ ablativePlural: { ending: "ibus", number: "plural" },
187
+ vocativeSingular: { ending: nominative, number: "singular" }
188
+ },
189
+ "3rd-i": {
190
+ nominativeSingular: { ending: nominative, number: "singular" },
191
+ genitiveSingular: { ending: "is", number: "singular" },
192
+ dativeSingular: { ending: "ī", number: "singular" },
193
+ accusativeSingular: { ending: isNeuter ? nominative : "em", number: "singular" },
194
+ ablativeSingular: { ending: isNeuter ? "ī" : "e", number: "singular" },
195
+ nominativePlural: { ending: isNeuter ? "ia" : "ēs", number: "plural" },
196
+ genitivePlural: { ending: "ium", number: "plural" },
197
+ dativePlural: { ending: "ibus", number: "plural" },
198
+ accusativePlural: { ending: isNeuter ? "ia" : "ēs", number: "plural" },
199
+ ablativePlural: { ending: "ibus", number: "plural" },
200
+ vocativeSingular: { ending: nominative, number: "singular" }
201
+ },
202
+ "4th-us": {
203
+ nominativeSingular: { ending: "us", number: "singular" },
204
+ genitiveSingular: { ending: "ūs", number: "singular" },
205
+ dativeSingular: { ending: "uī", number: "singular" },
206
+ accusativeSingular: { ending: "um", number: "singular" },
207
+ ablativeSingular: { ending: "ū", number: "singular" },
208
+ nominativePlural: { ending: "ūs", number: "plural" },
209
+ genitivePlural: { ending: "uum", number: "plural" },
210
+ dativePlural: { ending: "ibus", number: "plural" },
211
+ accusativePlural: { ending: "ūs", number: "plural" },
212
+ ablativePlural: { ending: "ibus", number: "plural" },
213
+ vocativeSingular: { ending: "us", number: "singular" }
214
+ },
215
+ "4th-u": {
216
+ nominativeSingular: { ending: "ū", number: "singular" },
217
+ genitiveSingular: { ending: "ūs", number: "singular" },
218
+ dativeSingular: { ending: "ū", number: "singular" },
219
+ accusativeSingular: { ending: "ū", number: "singular" },
220
+ ablativeSingular: { ending: "ū", number: "singular" },
221
+ nominativePlural: { ending: "ua", number: "plural" },
222
+ genitivePlural: { ending: "uum", number: "plural" },
223
+ dativePlural: { ending: "ibus", number: "plural" },
224
+ accusativePlural: { ending: "ua", number: "plural" },
225
+ ablativePlural: { ending: "ibus", number: "plural" },
226
+ vocativeSingular: { ending: "ū", number: "singular" }
227
+ },
228
+ "5th": {
229
+ nominativeSingular: { ending: "ēs", number: "singular" },
230
+ genitiveSingular: { ending: "eī", number: "singular" },
231
+ dativeSingular: { ending: "eī", number: "singular" },
232
+ accusativeSingular: { ending: "em", number: "singular" },
233
+ ablativeSingular: { ending: "ē", number: "singular" },
234
+ nominativePlural: { ending: "ēs", number: "plural" },
235
+ genitivePlural: { ending: "ērum", number: "plural" },
236
+ dativePlural: { ending: "ēbus", number: "plural" },
237
+ accusativePlural: { ending: "ēs", number: "plural" },
238
+ ablativePlural: { ending: "ēbus", number: "plural" },
239
+ vocativeSingular: { ending: "ēs", number: "singular" }
240
+ }
241
+ };
242
+
243
+ // Generate forms
244
+ const forms = [];
245
+ for (const caseName in endings[declension]) {
246
+ const [caseType, number] = caseName.match(/([a-zA-Z]+)(Singular|Plural)/).slice(1);
247
+ const ending = endings[declension][caseName].ending;
248
+ const word = ending === nominative ? nominative : stem + ending;
249
+ forms.push(wordPlusInflectedWord({
250
+ declension: caseType.toLowerCase(),
251
+ number: number.toLowerCase(),
252
+ ending,
253
+ word,
254
+ }));
255
+ }
256
+
257
+ return forms;
258
+ }
259
+
260
+ function getIsIOType(infinitive) {
261
+ const thirdIOVerbs = [
262
+ 'capere', // to take, seize
263
+ 'cupere', // to desire
264
+ 'facere', // to make, do
265
+ 'iacere', // to throw
266
+ 'quaerere', // to seek, ask
267
+ 'sapere', // to know, taste
268
+ 'sedēre' // to sit (semi-deponent)
269
+ ];
270
+
271
+ return thirdIOVerbs.includes(infinitive);
272
+ }
273
+
274
+ function conjugateVerb(infinitive) {
275
+ if (typeof infinitive !== 'string' || !infinitive.endsWith('re')) {
276
+ throw new Error('Input must be a Latin verb infinitive ending in -re');
277
+ }
278
+
279
+ let conjugation, stem, first_singular_stem, isIOType;
280
+ if (infinitive.endsWith('are')) {
281
+ conjugation = 1;
282
+ stem = infinitive.slice(0, -2); // Remove "-are" (e.g., "amare" → "ama")
283
+ first_singular_stem = infinitive.slice(0, -3); // Remove "-are" (e.g., "amare" → "ama")
284
+ } else if (infinitive.endsWith('ēre') && !['ducere', 'capere', 'facere'].includes(infinitive)) {
285
+ conjugation = 2;
286
+ stem = infinitive.slice(0, -3); // Remove "-ere" (e.g., "videre" → "vide")
287
+ first_singular_stem = stem
288
+ } else if (infinitive.endsWith('ire')) {
289
+ conjugation = 4;
290
+ stem = infinitive.slice(0, -2); // Remove "-ire" (e.g., "audire" → "audi")
291
+ first_singular_stem = stem
292
+ } else {
293
+ conjugation = 3; // Third and third -io (e.g., "ducere" → "duc")
294
+ stem = infinitive.slice(0, -3); // Remove "-ere"
295
+ first_singular_stem = stem
296
+ isIOType = getIsIOType(infinitive)
297
+ }
298
+
299
+ const endings = {
300
+ 1: [
301
+ { number: 'singular', person: 'first', ending: 'o' },
302
+ { number: 'singular', person: 'second', ending: 's' },
303
+ { number: 'singular', person: 'third', ending: 't' },
304
+ { number: 'plural', person: 'first', ending: 'mus' },
305
+ { number: 'plural', person: 'second', ending: 'tis' },
306
+ { number: 'plural', person: 'third', ending: 'nt' },
307
+ ],
308
+ 2: [
309
+ { number: 'singular', person: 'first', ending: 'eo' },
310
+ { number: 'singular', person: 'second', ending: 'es' },
311
+ { number: 'singular', person: 'third', ending: 'et' },
312
+ { number: 'plural', person: 'first', ending: 'emus' },
313
+ { number: 'plural', person: 'second', ending: 'etis' },
314
+ { number: 'plural', person: 'third', ending: 'ent' },
315
+ ],
316
+ 3: [
317
+ { number: 'singular', person: 'first', ending: 'o' },
318
+ { number: 'singular', person: 'second', ending: 'is' },
319
+ { number: 'singular', person: 'third', ending: 'it' },
320
+ { number: 'plural', person: 'first', ending: 'imus' },
321
+ { number: 'plural', person: 'second', ending: 'itis' },
322
+ { number: 'plural', person: 'third', ending: 'unt' },
323
+ ],
324
+ 4: [
325
+ { number: 'singular', person: 'first', ending: 'o' },
326
+ { number: 'singular', person: 'second', ending: 's' },
327
+ { number: 'singular', person: 'third', ending: 't' },
328
+ { number: 'plural', person: 'first', ending: 'mus' },
329
+ { number: 'plural', person: 'second', ending: 'tis' },
330
+ { number: 'plural', person: 'third', ending: 'unt' },
331
+ ],
332
+ };
333
+
334
+ // if (conjugation === 3 && ['capere', 'facere'].includes(infinitive)) {
335
+ if (conjugation === 3 && isIOType) {
336
+ endings[3][0].ending = 'io'; // Third -io first-person singular
337
+ endings[3][5].ending = 'iunt'; // Third -io third-person plural
338
+ }
339
+
340
+ const conjugationEndings = endings[conjugation];
341
+ const conjugations = conjugationEndings.map(({ number, person, ending }) => {
342
+ // Special handling for "dare" first-person singular
343
+ let word;
344
+ if (person === 'first' && number === 'singular') {
345
+ word = first_singular_stem + ending;
346
+ } else if (conjugation === 1 || conjugation === 4) {
347
+ // Preserve stem vowel for first and fourth conjugations
348
+ word = stem + ending;
349
+ } else {
350
+ word = stem + ending;
351
+ }
352
+ return { word, number, person };
353
+ });
354
+
355
+ return conjugations;
356
+ }
357
+
358
+ module.exports = { conjugateVerb, getDeclensions };