ekms 9.5.1-beta.5 → 9.5.1-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/common/animals.instance.json +21 -61
- package/common/asking.js +102 -100
- package/common/can.instance.json +17 -0
- package/common/can.js +188 -0
- package/common/characters.js +3 -3
- package/common/colors.instance.json +38 -10
- package/common/comparable.instance.json +2 -2
- package/common/concept.test.json +54 -40
- package/common/conjunction.js +13 -5
- package/common/crew.instance.json +26 -26
- package/common/crew.js +1 -1
- package/common/currency.js +1 -1
- package/common/dates.instance.json +87 -3
- package/common/dialogues.js +11 -8
- package/common/dimension.instance.json +1 -1
- package/common/edible.instance.json +79 -95
- package/common/emotions.instance.json +6 -10
- package/common/emotions.js +1 -1
- package/common/english_helpers.js +277 -67
- package/common/fastfood.instance.json +235 -807
- package/common/fastfood.js +4 -4
- package/common/formulas.instance.json +1 -1
- package/common/gdefaults.js +41 -9
- package/common/help.js +2 -2
- package/common/helpers/concept.js +1 -1
- package/common/helpers/conjunction.js +54 -44
- package/common/helpers/dateTimeSelectors.js +2 -2
- package/common/helpers/dialogues.js +1 -1
- package/common/helpers/formulas.js +13 -11
- package/common/helpers/menus.js +12 -12
- package/common/helpers/meta.js +8 -8
- package/common/helpers/properties.js +76 -15
- package/common/helpers.js +82 -46
- package/common/hierarchy.js +3 -3
- package/common/kirk.instance.json +1 -1
- package/common/length.instance.json +2 -2
- package/common/math.instance.json +20 -20
- package/common/math.js +45 -44
- package/common/menus.instance.json +3 -3
- package/common/menus.js +1 -1
- package/common/meta.js +49 -33
- package/common/ordering.instance.json +16 -28
- package/common/ordering.js +1 -1
- package/common/ordering.test.json +354 -296
- package/common/people.instance.json +36 -47
- package/common/people.js +1 -1
- package/common/people.test.json +952 -681
- package/common/pipboy.instance.json +72 -16
- package/common/pokemon.instance.json +8 -8
- package/common/pokemon.js +1 -1
- package/common/pressure.instance.json +2 -2
- package/common/properties.instance.json +1 -1
- package/common/properties.js +16 -3
- package/common/reminders.js +1 -1
- package/common/reports.instance.json +3 -3
- package/common/reports.js +18 -16
- package/common/scorekeeper.js +4 -4
- package/common/sdefaults.js +22 -2
- package/common/spock.instance.json +1 -1
- package/common/stgame.js +1 -1
- package/common/stm.js +2 -2
- package/common/tell.js +1 -1
- package/common/temperature.instance.json +2 -2
- package/common/tester.js +3 -3
- package/common/time.js +3 -3
- package/common/tokenize.js +1 -1
- package/common/weight.instance.json +2 -2
- package/common/wp.instance.json +62 -6
- package/common/wp.js +4 -4
- package/package.json +4 -2
|
@@ -1,121 +1,331 @@
|
|
|
1
1
|
function conjugateVerb(infinitive) {
|
|
2
|
-
|
|
3
|
-
if (typeof infinitive !== 'string') {
|
|
2
|
+
if (typeof infinitive !== 'string' || infinitive.trim() === '') {
|
|
4
3
|
throw new Error('Input must be a non-empty string');
|
|
5
4
|
}
|
|
6
5
|
|
|
7
|
-
// Normalise input – remove optional leading "to " and trim
|
|
8
6
|
const baseVerb = infinitive.replace(/^to\s+/i, '').trim().toLowerCase();
|
|
7
|
+
if (!baseVerb) throw new Error('Input must be a non-empty string');
|
|
9
8
|
|
|
10
|
-
// Validate
|
|
11
|
-
if (!baseVerb) {
|
|
12
|
-
throw new Error('Input must be a non-empty string');
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Result container
|
|
16
9
|
const conjugations = [];
|
|
17
10
|
|
|
18
|
-
//
|
|
19
|
-
conjugations.push({
|
|
11
|
+
// Add infinitive (bare form, no "to")
|
|
12
|
+
conjugations.push({
|
|
13
|
+
form: 'infinitive',
|
|
14
|
+
word: baseVerb,
|
|
15
|
+
tense: 'infinitive',
|
|
16
|
+
aspect: null,
|
|
17
|
+
number: 'none',
|
|
18
|
+
person: 'none'
|
|
19
|
+
});
|
|
20
20
|
|
|
21
|
-
// Irregular
|
|
21
|
+
// === Irregular verb database ===
|
|
22
22
|
const irregulars = {
|
|
23
23
|
be: {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
present: {
|
|
25
|
+
singular: { first: 'am', second: 'are', third: 'is' },
|
|
26
|
+
plural: { first: 'are', second: 'are', third: 'are' }
|
|
27
|
+
},
|
|
28
|
+
past: {
|
|
29
|
+
singular: { first: 'was', second: 'were', third: 'was' },
|
|
30
|
+
plural: { first: 'were', second: 'were', third: 'were' }
|
|
31
|
+
},
|
|
32
|
+
pastParticiple: 'been',
|
|
33
|
+
presentParticiple: 'being'
|
|
26
34
|
},
|
|
27
35
|
have: {
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
present: {
|
|
37
|
+
singular: { first: 'have', second: 'have', third: 'has' },
|
|
38
|
+
plural: { first: 'have', second: 'have', third: 'have' }
|
|
39
|
+
},
|
|
40
|
+
past: { singular: { first: 'had', second: 'had', third: 'had' }, plural: { first: 'had', second: 'had', third: 'had' } },
|
|
41
|
+
pastParticiple: 'had',
|
|
42
|
+
presentParticiple: 'having'
|
|
30
43
|
},
|
|
31
44
|
do: {
|
|
32
|
-
|
|
33
|
-
|
|
45
|
+
present: {
|
|
46
|
+
singular: { first: 'do', second: 'do', third: 'does' },
|
|
47
|
+
plural: { first: 'do', second: 'do', third: 'do' }
|
|
48
|
+
},
|
|
49
|
+
past: { singular: { first: 'did', second: 'did', third: 'did' }, plural: { first: 'did', second: 'did', third: 'did' } },
|
|
50
|
+
pastParticiple: 'done',
|
|
51
|
+
presentParticiple: 'doing'
|
|
34
52
|
},
|
|
35
53
|
go: {
|
|
36
|
-
|
|
37
|
-
|
|
54
|
+
present: {
|
|
55
|
+
singular: { first: 'go', second: 'go', third: 'goes' },
|
|
56
|
+
plural: { first: 'go', second: 'go', third: 'go' }
|
|
57
|
+
},
|
|
58
|
+
past: { singular: { first: 'went', second: 'went', third: 'went' }, plural: { first: 'went', second: 'went', third: 'went' } },
|
|
59
|
+
pastParticiple: 'gone',
|
|
60
|
+
presentParticiple: 'going'
|
|
38
61
|
},
|
|
39
62
|
say: {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
63
|
+
present: {
|
|
64
|
+
singular: { first: 'say', second: 'say', third: 'says' },
|
|
65
|
+
plural: { first: 'say', second: 'say', third: 'say' }
|
|
66
|
+
},
|
|
67
|
+
past: {
|
|
68
|
+
singular: { first: 'said', second: 'said', third: 'said' },
|
|
69
|
+
plural: { first: 'said', second: 'said', third: 'said' }
|
|
70
|
+
},
|
|
71
|
+
pastParticiple: 'said',
|
|
72
|
+
presentParticiple: 'saying'
|
|
73
|
+
},
|
|
74
|
+
make: {
|
|
75
|
+
present: {
|
|
76
|
+
singular: { first: 'make', second: 'make', third: 'makes' },
|
|
77
|
+
plural: { first: 'make', second: 'make', third: 'make' }
|
|
78
|
+
},
|
|
79
|
+
past: {
|
|
80
|
+
singular: { first: 'made', second: 'made', third: 'made' },
|
|
81
|
+
plural: { first: 'made', second: 'made', third: 'made' }
|
|
82
|
+
},
|
|
83
|
+
pastParticiple: 'made',
|
|
84
|
+
presentParticiple: 'making'
|
|
85
|
+
},
|
|
86
|
+
// Add more irregulars as needed...
|
|
43
87
|
};
|
|
44
88
|
|
|
45
|
-
|
|
46
|
-
function conjugateRegular(verb, number, person) {
|
|
47
|
-
if (number === 'singular' && person === 'third') {
|
|
48
|
-
if (/[sxz]$/.test(verb)) return verb + 'es'; // box → boxes
|
|
49
|
-
if (/[^aeiou]y$/.test(verb)) return verb.slice(0, -1) + 'ies'; // fly → flies
|
|
50
|
-
if (/o$/.test(verb)) return verb + 'es'; // go → goes (fallback)
|
|
51
|
-
if (/[cs]h$/.test(verb)) return verb + 'es'; // watch → watches
|
|
52
|
-
return verb + 's'; // walk → walks
|
|
53
|
-
}
|
|
54
|
-
return verb;
|
|
55
|
-
}
|
|
89
|
+
const irreg = irregulars[baseVerb];
|
|
56
90
|
|
|
57
91
|
const numbers = ['singular', 'plural'];
|
|
58
92
|
const persons = ['first', 'second', 'third'];
|
|
59
93
|
|
|
60
|
-
//
|
|
61
|
-
if (
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
94
|
+
// === Present tense ===
|
|
95
|
+
if (irreg) {
|
|
96
|
+
for (const num of numbers) {
|
|
97
|
+
for (const pers of persons) {
|
|
98
|
+
conjugations.push({
|
|
99
|
+
form: 'finite',
|
|
100
|
+
word: irreg.present[num][pers],
|
|
101
|
+
tense: 'present',
|
|
102
|
+
aspect: 'simple',
|
|
103
|
+
number: num,
|
|
104
|
+
person: pers
|
|
105
|
+
});
|
|
66
106
|
}
|
|
67
107
|
}
|
|
68
108
|
} else {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
109
|
+
// Regular present tense
|
|
110
|
+
for (const num of numbers) {
|
|
111
|
+
for (const pers of persons) {
|
|
112
|
+
const word = conjugateRegularPresent(baseVerb, num, pers);
|
|
113
|
+
conjugations.push({
|
|
114
|
+
form: 'finite',
|
|
115
|
+
word,
|
|
116
|
+
tense: 'present',
|
|
117
|
+
aspect: 'simple',
|
|
118
|
+
number: num,
|
|
119
|
+
person: pers
|
|
120
|
+
});
|
|
73
121
|
}
|
|
74
122
|
}
|
|
75
123
|
}
|
|
76
124
|
|
|
125
|
+
// === Past tense (simple past) ===
|
|
126
|
+
let pastForm;
|
|
127
|
+
if (irreg && irreg.past) {
|
|
128
|
+
const pastMap = irreg.past;
|
|
129
|
+
for (const num of numbers) {
|
|
130
|
+
for (const pers of persons) {
|
|
131
|
+
conjugations.push({
|
|
132
|
+
form: 'finite',
|
|
133
|
+
word: pastMap[num][pers],
|
|
134
|
+
tense: 'past',
|
|
135
|
+
aspect: 'simple',
|
|
136
|
+
number: num,
|
|
137
|
+
person: pers
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
pastForm = pastMap.singular.first; // representative
|
|
142
|
+
} else {
|
|
143
|
+
pastForm = conjugateRegularPast(baseVerb);
|
|
144
|
+
for (const num of numbers) {
|
|
145
|
+
for (const pers of persons) {
|
|
146
|
+
conjugations.push({
|
|
147
|
+
form: 'finite',
|
|
148
|
+
word: pastForm,
|
|
149
|
+
tense: 'past',
|
|
150
|
+
aspect: 'simple',
|
|
151
|
+
number: num,
|
|
152
|
+
person: pers
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// === Past Participle ===
|
|
159
|
+
const pastParticiple = irreg?.pastParticiple ?? conjugateRegularPast(baseVerb); // same as past for regular verbs
|
|
160
|
+
conjugations.push({
|
|
161
|
+
form: 'pastParticiple',
|
|
162
|
+
word: pastParticiple,
|
|
163
|
+
tense: 'perfect',
|
|
164
|
+
aspect: 'perfect',
|
|
165
|
+
number: 'none',
|
|
166
|
+
person: 'none'
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Optional: Present Participle (-ing form)
|
|
170
|
+
const presentParticiple = irreg?.presentParticiple ?? conjugatePresentParticiple(baseVerb);
|
|
171
|
+
conjugations.push({
|
|
172
|
+
form: 'presentParticiple',
|
|
173
|
+
word: presentParticiple,
|
|
174
|
+
tense: 'progressive',
|
|
175
|
+
aspect: 'continuous',
|
|
176
|
+
number: 'none',
|
|
177
|
+
person: 'none'
|
|
178
|
+
});
|
|
179
|
+
|
|
77
180
|
return conjugations;
|
|
78
181
|
}
|
|
79
182
|
|
|
80
|
-
|
|
81
|
-
|
|
183
|
+
// Helper: regular present 3rd person singular
|
|
184
|
+
function conjugateRegularPresent(verb, number, person) {
|
|
185
|
+
if (number === 'singular' && person === 'third') {
|
|
186
|
+
if (/[sxz]$/.test(verb) || /[cs]h$/.test(verb) || /o$/.test(verb)) {
|
|
187
|
+
return verb + 'es';
|
|
188
|
+
}
|
|
189
|
+
if (/[^aeiou]y$/.test(verb)) {
|
|
190
|
+
return verb.slice(0, -1) + 'ies';
|
|
191
|
+
}
|
|
192
|
+
return verb + 's';
|
|
193
|
+
}
|
|
194
|
+
1
|
|
195
|
+
return verb;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Helper: regular past & past participle (same for regular verbs)
|
|
199
|
+
function conjugateRegularPast(verb) {
|
|
200
|
+
if (verb.endsWith('e')) {
|
|
201
|
+
return verb + 'd';
|
|
202
|
+
}
|
|
203
|
+
if (/[aeiou][^aeiouyw]$/.test(verb.slice(-2)) && /[bcdfghjklmnpqrstvwxz]$/.test(verb)) {
|
|
204
|
+
// doubled consonant: stop → stopped
|
|
205
|
+
return verb + verb.slice(-1) + 'ed';
|
|
206
|
+
}
|
|
207
|
+
if (/[^aeiou]y$/.test(verb)) {
|
|
208
|
+
return verb.slice(0, -1) + 'ied';
|
|
209
|
+
}
|
|
210
|
+
return verb + 'ed';
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Helper: present participle (-ing)
|
|
214
|
+
function conjugatePresentParticiple(verb) {
|
|
215
|
+
if (verb.endsWith('e') && !verb.endsWith('ee') && !verb.endsWith('ie') && !verb.endsWith('ye')) {
|
|
216
|
+
return verb.slice(0, -1) + 'ing';
|
|
217
|
+
}
|
|
218
|
+
if (/[aeiou][^aeiouyw]$/.test(verb.slice(-2)) && /[bcdfghjklmnpqrstvwxz]$/.test(verb.slice(-1))) {
|
|
219
|
+
return verb + verb.slice(-1) + 'ing'; // stop → stopping
|
|
220
|
+
}
|
|
221
|
+
if (verb.endsWith('ie')) {
|
|
222
|
+
return verb.slice(0, -2) + 'ying'; // lie → lying
|
|
223
|
+
}
|
|
224
|
+
return verb + 'ing';
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// === Bonus: Improved getInfinitive with past participle support ===
|
|
228
|
+
function getInfinitive(form) {
|
|
229
|
+
const word = form.trim().toLowerCase();
|
|
82
230
|
if (!word) throw new Error('Input must be a non-empty string');
|
|
83
231
|
|
|
84
|
-
//
|
|
232
|
+
// ------------------------------------------------------------
|
|
233
|
+
// 1. Irregular forms (present, past, past participle, -ing)
|
|
234
|
+
// ------------------------------------------------------------
|
|
85
235
|
const irregularMap = {
|
|
86
|
-
'is':
|
|
87
|
-
'
|
|
88
|
-
'
|
|
89
|
-
'
|
|
90
|
-
'
|
|
91
|
-
'
|
|
92
|
-
|
|
236
|
+
am: 'be', is: 'be', are: 'be',
|
|
237
|
+
was: 'be', were: 'be', been: 'be', being: 'be',
|
|
238
|
+
have: 'have', has: 'have', had: 'have',
|
|
239
|
+
do: 'do', does: 'do', did: 'do', done: 'do',
|
|
240
|
+
go: 'go', goes: 'go', went: 'go', gone: 'go',
|
|
241
|
+
say: 'say', says: 'say', said: 'say',
|
|
242
|
+
made: 'make',
|
|
93
243
|
};
|
|
94
244
|
|
|
95
|
-
if (irregularMap[word])
|
|
96
|
-
|
|
245
|
+
if (irregularMap[word]) return irregularMap[word];
|
|
246
|
+
|
|
247
|
+
// ------------------------------------------------------------
|
|
248
|
+
// 2. Past tense / Past participle (regular verbs)
|
|
249
|
+
// ------------------------------------------------------------
|
|
250
|
+
if (word.endsWith('ed')) {
|
|
251
|
+
// 2a – cried → cry
|
|
252
|
+
if (word.endsWith('ied')) {
|
|
253
|
+
return word.slice(0, -3) + 'y';
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// 2. liked, moved, danced → like, move, dance
|
|
257
|
+
// These are verbs that end in 'e' → add only 'd' → ends with "ed", but third char from end is 'e'
|
|
258
|
+
if (word.length >= 3 && word[word.length - 3] === 'e') {
|
|
259
|
+
return word.slice(0, -1); // remove only the final 'd'
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// 2c – stopped, rubbed (consonant doubling)
|
|
263
|
+
let stem = word.slice(0, -2); // remove "ed"
|
|
264
|
+
if (
|
|
265
|
+
stem.length >= 2 &&
|
|
266
|
+
stem[stem.length - 1] === stem[stem.length - 2] && // doubled consonant
|
|
267
|
+
!/[aeiou]/.test(stem[stem.length - 1]) // not a vowel
|
|
268
|
+
) {
|
|
269
|
+
stem = stem.slice(0, -1); // remove one of the doubled letters
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const restoreECases = ['liked'];
|
|
273
|
+
if (restoreECases.includes(word)) {
|
|
274
|
+
stem += 'e';
|
|
275
|
+
}
|
|
276
|
+
return stem;
|
|
97
277
|
}
|
|
98
278
|
|
|
99
|
-
//
|
|
279
|
+
// ------------------------------------------------------------
|
|
280
|
+
// 3. Present participle (-ing)
|
|
281
|
+
// ------------------------------------------------------------
|
|
282
|
+
if (word.endsWith('ing')) {
|
|
283
|
+
let stem = word.slice(0, -3);
|
|
284
|
+
|
|
285
|
+
// lying → lie
|
|
286
|
+
if (word.endsWith('ying')) {
|
|
287
|
+
stem = word.slice(0, -4);
|
|
288
|
+
return stem + 'ie';
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Undo consonant doubling: stopping → stop, running → run
|
|
292
|
+
if (
|
|
293
|
+
stem.length >= 2 &&
|
|
294
|
+
stem[stem.length - 1] === stem[stem.length - 2] &&
|
|
295
|
+
!/[aeiou]/.test(stem[stem.length - 1])
|
|
296
|
+
) {
|
|
297
|
+
stem = stem.slice(0, -1);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// DO NOT blindly add 'e' — this is the source of "walke", "runne", etc.
|
|
301
|
+
// Only add 'e' in known safe cases — or just don't do it.
|
|
302
|
+
// Here: we add 'e' only if the word is in a small whitelist of common cases
|
|
303
|
+
const restoreECases = ['dancing', 'making', 'taking', 'giving', 'living'];
|
|
304
|
+
if (restoreECases.includes(word)) {
|
|
305
|
+
stem += 'e';
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return stem;
|
|
309
|
+
}
|
|
310
|
+
// ------------------------------------------------------------
|
|
311
|
+
// 4. Present 3rd-person singular
|
|
312
|
+
// ------------------------------------------------------------
|
|
100
313
|
if (word.endsWith('ies') && word.length > 3) {
|
|
101
|
-
// flies → fly
|
|
102
|
-
return word.slice(0, -3) + 'y';
|
|
314
|
+
return word.slice(0, -3) + 'y'; // flies → fly
|
|
103
315
|
}
|
|
104
|
-
|
|
105
316
|
if (word.endsWith('es') && word.length > 3) {
|
|
106
317
|
const stem = word.slice(0, -2);
|
|
107
|
-
// boxes → box, watches → watch, goes → go
|
|
108
318
|
if (/[sxz]$/.test(stem) || /[cs]h$/.test(stem) || stem.endsWith('o')) {
|
|
109
|
-
return stem;
|
|
319
|
+
return stem; // watches → watch
|
|
110
320
|
}
|
|
111
321
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// moves → move, walks → walk
|
|
115
|
-
return word.slice(0, -1);
|
|
322
|
+
if (word.endsWith('s') && !word.endsWith('ss') && word.length > 2) {
|
|
323
|
+
return word.slice(0, -1); // walks → walk
|
|
116
324
|
}
|
|
117
325
|
|
|
118
|
-
//
|
|
326
|
+
// ------------------------------------------------------------
|
|
327
|
+
// 5. Nothing matched → return as-is
|
|
328
|
+
// ------------------------------------------------------------
|
|
119
329
|
return word;
|
|
120
330
|
}
|
|
121
331
|
|