tpmkms 9.5.0 → 9.5.1-beta.10

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 (83) hide show
  1. package/common/animals.instance.json +21 -61
  2. package/common/asking.js +106 -104
  3. package/common/can.instance.json +17 -0
  4. package/common/can.js +188 -0
  5. package/common/characters.js +5 -5
  6. package/common/colors.instance.json +38 -10
  7. package/common/comparable.instance.json +2 -2
  8. package/common/concept.test.json +54 -40
  9. package/common/conjunction.js +13 -5
  10. package/common/crew.instance.json +71 -85
  11. package/common/crew.js +1 -1
  12. package/common/crew.test.json +4148 -3324
  13. package/common/currency.js +1 -1
  14. package/common/dates.instance.json +87 -3
  15. package/common/dialogues.js +12 -9
  16. package/common/dimension.instance.json +9 -9
  17. package/common/dimension.js +4 -4
  18. package/common/edible.instance.json +79 -23
  19. package/common/emotions.instance.json +29 -7
  20. package/common/emotions.js +1 -1
  21. package/common/emotions.test.json +242 -174
  22. package/common/english_helpers.js +336 -0
  23. package/common/errors.js +3 -3
  24. package/common/evaluate.js +2 -2
  25. package/common/events.js +8 -8
  26. package/common/fastfood.instance.json +205 -553
  27. package/common/fastfood.js +4 -4
  28. package/common/formulas.instance.json +1 -1
  29. package/common/formulas.js +1 -1
  30. package/common/gdefaults.js +58 -9
  31. package/common/help.js +3 -3
  32. package/common/helpers/concept.js +1 -1
  33. package/common/helpers/conjunction.js +54 -44
  34. package/common/helpers/dateTimeSelectors.js +2 -2
  35. package/common/helpers/dialogues.js +1 -1
  36. package/common/helpers/formulas.js +13 -11
  37. package/common/helpers/menus.js +12 -12
  38. package/common/helpers/meta.js +9 -9
  39. package/common/helpers/properties.js +158 -55
  40. package/common/helpers.js +135 -46
  41. package/common/hierarchy.js +3 -3
  42. package/common/kirk.instance.json +1 -1
  43. package/common/latin.instance.json +2 -2
  44. package/common/latin.js +4 -4
  45. package/common/length.instance.json +2 -2
  46. package/common/listener.js +1 -1
  47. package/common/math.instance.json +28 -28
  48. package/common/math.js +47 -46
  49. package/common/menus.instance.json +3 -3
  50. package/common/menus.js +1 -1
  51. package/common/meta.js +76 -60
  52. package/common/nameable.js +7 -7
  53. package/common/ordering.instance.json +85 -19
  54. package/common/ordering.js +1 -1
  55. package/common/ordering.test.json +786 -298
  56. package/common/people.instance.json +59 -56
  57. package/common/people.js +6 -4
  58. package/common/people.test.json +4135 -3606
  59. package/common/pipboy.instance.json +72 -16
  60. package/common/pipboy.js +2 -3
  61. package/common/pokemon.instance.json +8 -8
  62. package/common/pokemon.js +1 -1
  63. package/common/pressure.instance.json +2 -2
  64. package/common/properties.instance.json +1 -1
  65. package/common/properties.js +22 -4
  66. package/common/reminders.instance.json +4 -4
  67. package/common/reminders.js +3 -3
  68. package/common/reports.instance.json +3 -3
  69. package/common/reports.js +18 -16
  70. package/common/scorekeeper.js +6 -6
  71. package/common/sdefaults.js +22 -2
  72. package/common/spock.instance.json +1 -1
  73. package/common/stgame.js +1 -1
  74. package/common/stm.js +4 -4
  75. package/common/tell.js +1 -1
  76. package/common/temperature.instance.json +2 -2
  77. package/common/tester.js +3 -3
  78. package/common/time.js +3 -3
  79. package/common/tokenize.js +5 -2
  80. package/common/weight.instance.json +2 -2
  81. package/common/wp.instance.json +136 -8
  82. package/common/wp.js +4 -4
  83. package/package.json +6 -2
@@ -1,8 +1,9 @@
1
1
  const pluralize = require('pluralize')
2
+ const { conjugateVerb } = require('../english_helpers')
2
3
  const { unflatten, flattens, Digraph } = require('../runtime').theprogrammablemind
3
4
  const _ = require('lodash')
4
5
  const deepEqual = require('deep-equal')
5
- const { chooseNumber } = require('../helpers.js')
6
+ const { chooseNumber, removeProp } = require('../helpers.js')
6
7
  const { Frankenhash } = require('./frankenhash.js')
7
8
  const { compose, translationMapping, translationMappingToInstantiatorMappings } = require('./meta.js')
8
9
 
@@ -28,7 +29,7 @@ class API {
28
29
  this._km = km
29
30
  this.__config = config
30
31
  this.digraph = new Digraph()
31
- const toJSON = (h) => {
32
+ function toJSON(h) {
32
33
  if (h.child && h.parent) {
33
34
  return h
34
35
  } else {
@@ -263,12 +264,35 @@ class API {
263
264
  // relation -> the semantics will be implements using relations
264
265
  // edable: "y is owned by x" edable = { operator: 'owned' }
265
266
  createActionPrefix(args, semanticApply) {
266
- const { operator, before=[], after=[], create=[], config, localHierarchy=[], relation, ordering, doAble, words = [], unflatten:unflattenArgs = [], focusable = [], edAble } = args;
267
- // const before = [...]
268
- // const after = [{tag: 'weapon', id: 'weapon'}]
269
- // const create = ['arm', 'weapon']
267
+ const {
268
+ operator,
269
+ before=[],
270
+ after=[],
271
+ create:createInit=[],
272
+ hierarchy=[],
273
+ config,
274
+ localHierarchy=[],
275
+ relation,
276
+ ordering,
277
+ doAble,
278
+ flatten,
279
+ can,
280
+ words = [],
281
+ unflatten:unflattenArgs = [],
282
+ focusable = [],
283
+ edAble } = args;
284
+
285
+ function createToCanonical(concept) {
286
+ if (typeof concept == 'string') {
287
+ return { id: concept, isA: [] }
288
+ } else {
289
+ return { isA: [], ...concept }
290
+ }
291
+ }
292
+
293
+ const create = createInit.map(createToCanonical)
270
294
 
271
- if (doAble) {
295
+ if (doAble) {
272
296
  if (before.length != 1) {
273
297
  throw "Expected exactly one before argument"
274
298
  }
@@ -323,9 +347,9 @@ class API {
323
347
  }
324
348
  }
325
349
 
326
- create.map( (id) => {
350
+ create.map( ({ id, isA }) => {
327
351
  if (id === operator) {
328
- const tagsToProps = (where, args, suffix='') => {
352
+ function tagsToProps(where, args, suffix='') {
329
353
  const i = 0;
330
354
  let r = ''
331
355
  for (const arg of args) {
@@ -341,13 +365,30 @@ class API {
341
365
  afterArgs = tagsToProps('after', after, '*')
342
366
  }
343
367
 
368
+ // const subjectContext = before[0].tag
369
+ // const interpolate = "[" + before.map((arg) => `{ property: '${arg.tag}' }`).concat(`{ ...operator, evaluateWord: true, number: ${subjectContext}.number }`).concat(after.map((arg) => `{ property: '${arg.tag}' }`)).join(',') + "]"
370
+ const imperative = (before.length == 0) ? "true" : "false"
371
+ // const interpolate = "[" + before.map((arg) => `{ property: '${arg.tag}' }`).concat(`{ ...operator, evaluateWord: true, imperative: ${imperative}, isVerb: true, number: 'one' }`).concat(after.map((arg) => `{ property: '${arg.tag}' }`)).join(',') + "]"
372
+ // const interpolateVerb = `{ property: "operator", context: { evaluateWord: true, imperative: ${imperative}, isVerb: true, number: 'one' } }`
373
+ let interpolateVerb
374
+ if (before.length > 0) {
375
+ interpolateVerb = `{ property: "operator", number: '${before[0].tag}' }`
376
+ } else {
377
+ interpolateVerb = `{ property: "operator" }`
378
+ }
379
+ const interpolate = "[" + before.map((arg) => `{ property: '${arg.tag}' }`).concat(interpolateVerb).concat(after.map((arg) => `{ property: '${arg.tag}' }`)).join(',') + "]"
380
+
344
381
  const unflattenArgs = [ ...before.map( (arg) => arg.tag ), ...after.map( (arg) => arg.tag ) ]
345
382
  const focusable = [ ...before.map( (arg) => arg.tag ), ...after.map( (arg) => arg.tag ) ]
383
+ let flattenProperty = ''
384
+ if (flatten) {
385
+ flattenProperty = ", flatten: true, relation: true "
386
+ }
346
387
  config.addBridge({
347
388
  id: operator,
348
389
  level: 0,
349
390
  localHierarchy: [...localHierarchy, ['object', 'unknown']],
350
- bridge: `{ ... next(operator) ${doParams} ${beforeArgs} ${afterArgs}, unflatten: ${JSON.stringify(unflattenArgs)}, focusable: ${JSON.stringify(focusable)} }`,
391
+ bridge: `{ ... next(operator) ${flattenProperty} ${doParams} ${beforeArgs} ${afterArgs}, operator: { ...operator, evaluateWord: true, imperative: ${imperative}, isVerb: true, number: 'one' }, unflatten: ${JSON.stringify(unflattenArgs)}, focusable: ${JSON.stringify(focusable)}, interpolate: ${interpolate} }`,
351
392
  allowDups: true
352
393
  })
353
394
  if (words.length > 0) {
@@ -360,15 +401,32 @@ class API {
360
401
  } else {
361
402
  config.addBridge({ id: id, allowDups: true })
362
403
  }
404
+
405
+ for (const parentId of isA) {
406
+ config.addHierarchy(id, parentId)
407
+ }
363
408
  })
364
409
 
365
410
  if (words.length == 0) {
411
+ const createDef = createInit.find((def) => def.id == operator)
412
+ if (createDef && createDef.infinitive) {
413
+ const conjugation = conjugateVerb(createDef.infinitive)
414
+ if (can) {
415
+ const def = conjugation.find((def) => def.form == "pastParticiple")
416
+ config.addWord(def.word, { id: operator, initial: `{ value: '${operator}', tense: '${def.tense}' }`})
417
+ }
418
+ }
419
+
366
420
  const operatorPlural = pluralize.singular(operator)
367
421
  const operatorSingular = pluralize.plural(operator)
368
422
  config.addWord(operatorSingular, { id: operator, initial: `{ value: '${operator}', number: 'one' }`})
369
423
  config.addWord(operatorPlural, { id: operator, initial: `{ value: '${operator}', number: 'many' }`})
370
424
  }
371
425
 
426
+ for (const { child, parent } of hierarchy) {
427
+ config.addHierarchy(child, parent)
428
+ }
429
+
372
430
  if (doAble) {
373
431
  config.addHierarchy(operator, 'canBeDoQuestion')
374
432
  }
@@ -376,49 +434,93 @@ class API {
376
434
  config.addPriority({ "context": [[operator, 0], ['means', 0], ], "choose": [0] })
377
435
  config.addPriority({ "context": [['article', 0], [operator, 0], ], "choose": [0] })
378
436
 
379
- config.addGenerator({
380
- notes: 'ordering generator for paraphrase',
381
- match: ({context}) => context.marker == operator && context.paraphrase && !context.query,
382
- apply: async ({context, gp, g}) => {
383
- const beforeGenerator = []
384
- for (const arg of before) {
385
- beforeGenerator.push(await g(context[arg.tag]))
386
- }
387
- const afterGenerator = []
388
- for (const arg of after) {
389
- afterGenerator.push(await gp(context[arg.tag]))
390
- }
391
- const word = context.word
392
- const sub = []
393
- if (context.subphrase) {
394
- sub.push(['that'])
395
- }
396
- return beforeGenerator.concat(sub).concat([word]).concat(afterGenerator).join(' ')
397
- }
398
- })
437
+ if (can) {
438
+ const beforeIds = before.map((def) => def.id)
439
+ const afterIds = after.map((def) => def.id)
440
+ config.addHierarchy(operator, 'canableAction')
441
+ config.addAssociation({ context: [[afterIds[0], 0], ['whatCanQuestion', 0], [beforeIds[0], 0], ['make', 0]], choose: 1 })
442
+ config.addAssociation({ context: [[afterIds[0], 1], ['whatCanQuestion', 0], [beforeIds[0], 0], ['make', 0]], choose: 1 })
443
+ config.addAssociation({ context: [[afterIds[0], 0], ['whatCanQuestionPassive', 0], [beforeIds[0], 0], ['beCanPassive', 0], ['make', 0], ['byCanPassive', 0]], choose: 1 })
444
+ config.addAssociation({ context: [[afterIds[0], 1], ['whatCanQuestionPassive', 0], [beforeIds[0], 0], ['beCanPassive', 0], ['make', 0], ['byCanPassive', 0]], choose: 1 })
445
+ config.addAssociation({ context: [[afterIds[0], 0], ['canPassive', 0], ['beCanPassive', 0], ['make', 0], ['byCanPassive', 0], [beforeIds[0], 0]], choose: 1 })
446
+ config.addAssociation({ context: [[afterIds[0], 1], ['canPassive', 0], ['beCanPassive', 0], ['make', 0], ['byCanPassive', 0], [beforeIds[0], 0]], choose: 1 })
447
+ }
399
448
 
400
- config.addGenerator({
401
- notes: 'ordering generator for response',
402
- match: ({context}) => context.marker == operator && context.evalue && context.isResponse,
403
- apply: async ({context, g, km}) => {
404
- const brief = km("dialogues").api.getBrief()
405
-
406
- const { evalue } = context
407
- let yesno = ''
408
- if (!context.do.query || evalue.truthValueOnly || brief) {
409
- if (evalue.truthValue) {
410
- yesno = 'yes'
411
- } else if (evalue.truthValue === false) {
412
- yesno = 'no'
449
+ if (false) {
450
+ config.addGenerator({
451
+ notes: 'ordering generator for paraphrase',
452
+ match: ({context}) => context.marker == operator && context.paraphrase && !context.query,
453
+ apply: async ({context, gp, g}) => {
454
+ const beforeGenerator = []
455
+ for (const arg of before) {
456
+ beforeGenerator.push(await g(context[arg.tag]))
457
+ }
458
+ const afterGenerator = []
459
+ for (const arg of after) {
460
+ afterGenerator.push(await gp(context[arg.tag]))
461
+ }
462
+ const word = context.word
463
+ const sub = []
464
+ if (context.subphrase) {
465
+ sub.push(['that'])
413
466
  }
467
+ return beforeGenerator.concat(sub).concat([word]).concat(afterGenerator).join(' ')
414
468
  }
415
- if (evalue.truthValueOnly || brief) {
416
- return `${yesno}`
417
- } else {
418
- return `${yesno} ${await g(Object.assign({}, evalue, { paraphrase: true }))}`
469
+ })
470
+ }
471
+
472
+ if (true) {
473
+ config.addGenerator({
474
+ notes: 'ordering generator for response',
475
+ match: ({context}) => context.marker == operator && context.evalue && context.isResponse,
476
+ apply: async ({context, g, km, flatten}) => {
477
+ const brief = km("dialogues").api.getBrief()
478
+
479
+ const { evalue } = context
480
+ let yesno = ''
481
+ let hasVariables = false
482
+ if (context.focusable) {
483
+ for (const f of context.focusable) {
484
+ if (context[f].query) {
485
+ hasVariables = true
486
+ break
487
+ }
488
+ }
489
+ }
490
+
491
+ // if (!context.do?.query || evalue.truthValueOnly || context.truthValueOnly || brief) {
492
+ if (evalue.truthValueOnly || context.truthValueOnly || context.wantsTruthValue || !hasVariables) {
493
+ function any(value, test) {
494
+ if (test(value)) {
495
+ return true
496
+ }
497
+ const values = flatten(['list'], value)[0]
498
+ for (const value of values) {
499
+ if (test(value)) {
500
+ return true
501
+ }
502
+ }
503
+ }
504
+ if (any(evalue, (value) => value.truthValue)) {
505
+ yesno = 'yes'
506
+ } else if (evalue.truthValue === false || context.truthValueOnly) {
507
+ yesno = 'no'
508
+ }
509
+ }
510
+ if (evalue.truthValueOnly) {
511
+ return `${yesno}`
512
+ } else {
513
+ const details = await g(Object.assign({}, evalue, { paraphrase: true }))
514
+ if (yesno) {
515
+ return `${yesno} ${details}`
516
+ }
517
+ else {
518
+ return details
519
+ }
520
+ }
419
521
  }
420
- }
421
- })
522
+ })
523
+ }
422
524
 
423
525
  if (ordering) {
424
526
  config.addSemantic({
@@ -515,9 +617,8 @@ class API {
515
617
  config.addSemantic({
516
618
  notes: `getter for ${operator}`,
517
619
  match: ({context}) => context.marker == operator && context.query,
518
- apply: ({context, km}) => {
620
+ apply: ({context, km, callId}) => {
519
621
  const api = km('properties').api
520
-
521
622
  context.evalue = {
522
623
  marker: 'list',
523
624
  value: unflatten(api.relation_get(context, before.concat(after).map( (arg) => arg.tag ) ))
@@ -527,8 +628,8 @@ class API {
527
628
  if (context.evalue.value.length == 0) {
528
629
  context.evalue.marker = 'answerNotKnown';
529
630
  context.evalue.value = [];
530
- context.evalue.marker = 'answerNotKnown';
531
- context.evalue.value = [];
631
+ } else {
632
+ // context.evalue.truthValue = true
532
633
  }
533
634
  }
534
635
  })
@@ -552,10 +653,13 @@ class API {
552
653
  }
553
654
 
554
655
  relation_add (relations) {
656
+ removeProp(relations, (val, prop, obj) => prop === 'range')
657
+
555
658
  if (!Array.isArray(relations)) {
556
659
  relations = [relations]
557
660
  }
558
661
  for (const relation of relations) {
662
+ relation.truthValue = true
559
663
  this._objects.relations.push(relation)
560
664
  }
561
665
  }
@@ -599,7 +703,7 @@ class API {
599
703
  return value
600
704
  }
601
705
 
602
- relation_get(context, args) {
706
+ relation_get (context, args) {
603
707
  const andTheAnswerIs = []
604
708
  for (const relation of this._objects.relations) {
605
709
  if (this.relation_match(args, context, relation)) {
@@ -703,7 +807,6 @@ class API {
703
807
  }
704
808
 
705
809
  setProperty(object, property, value, has, skipHandler) {
706
- // debugger
707
810
  if (!skipHandler) {
708
811
  const handler = this.propertiesFH.getHandler([object, property])
709
812
  if (handler) {
package/common/helpers.js CHANGED
@@ -1,13 +1,14 @@
1
1
  const pluralize = require('pluralize')
2
+ const { flatten } = require('./runtime').theprogrammablemind
2
3
 
3
- const unshiftL = (list, element, max) => {
4
+ function unshiftL(list, element, max) {
4
5
  if (list.length >= max) {
5
6
  list.pop()
6
7
  }
7
8
  list.unshift(element)
8
9
  }
9
10
 
10
- const pushL = (list, element, max) => {
11
+ function pushL(list, element, max) {
11
12
  if (list.length >= max) {
12
13
  list.shift()
13
14
  }
@@ -15,11 +16,11 @@ const pushL = (list, element, max) => {
15
16
  }
16
17
 
17
18
  // X pm today or tomorrow
18
- const millisecondsUntilHourOfDay = (newDate, hour) => {
19
+ function millisecondsUntilHourOfDay(newDate, hour) {
19
20
  const now = newDate()
20
21
  const target = newDate(now)
21
22
 
22
- const addHours = (date, h) => {
23
+ function addHours(date, h) {
23
24
  date.setTime(date.getTime() + (h*60*60*1000));
24
25
  }
25
26
  const hours = target.getHours()
@@ -34,11 +35,11 @@ const millisecondsUntilHourOfDay = (newDate, hour) => {
34
35
  return diff;
35
36
  }
36
37
 
37
- const indent = (string, indent) => {
38
+ function indent(string, indent) {
38
39
  return string.replace(/^/gm, ' '.repeat(indent));
39
40
  }
40
41
 
41
- const getCount = (context) => {
42
+ function getCount(context) {
42
43
  if (context.quantity) {
43
44
  return context.quantity.value
44
45
  }
@@ -47,13 +48,23 @@ const getCount = (context) => {
47
48
  }
48
49
  }
49
50
 
50
- const words = (word, additional = {}) => {
51
+ function words(word, additional = {}) {
51
52
  return [{ word: pluralize.singular(word), number: 'one', ...additional }, { word: pluralize.plural(word), number: 'many', ...additional }]
52
53
  }
53
54
 
54
- const isMany = (context) => {
55
- if (((context || {}).value || {}).marker == 'list' && (((context || {}).value || {}).value || []).length > 1) {
56
- return true
55
+ function isMany(context) {
56
+ if (!context) {
57
+ return
58
+ }
59
+ // if (((context || {}).value || {}).marker == 'list' && (((context || {}).value || {}).value || []).length > 1) {
60
+ const isList = context.marker == 'list' || context.value?.marker == 'list'
61
+ if (isList) {
62
+ if (context.value?.length > 1) {
63
+ return true
64
+ }
65
+ if (context.value?.value?.length > 1) {
66
+ return true
67
+ }
57
68
  }
58
69
 
59
70
  let number = context.number
@@ -77,13 +88,13 @@ const isMany = (context) => {
77
88
  return false
78
89
  }
79
90
 
80
- const requiredArgument = (value, name) => {
91
+ function requiredArgument(value, name) {
81
92
  if (!value) {
82
93
  throw new Error(`${name} is a required argument`)
83
94
  }
84
95
  }
85
96
 
86
- const chooseNumber = (context, one, many) => {
97
+ function chooseNumber(context, one, many) {
87
98
  if (isMany(context)) {
88
99
  return many;
89
100
  } else {
@@ -91,7 +102,7 @@ const chooseNumber = (context, one, many) => {
91
102
  }
92
103
  }
93
104
 
94
- const zip = (...arrays) => {
105
+ function zip(...arrays) {
95
106
  if (arrays == []) {
96
107
  return []
97
108
  }
@@ -107,15 +118,21 @@ const zip = (...arrays) => {
107
118
  }
108
119
 
109
120
 
110
- const focus = (context) => {
111
- const helper = (context) => {
121
+ function focus(context) {
122
+ function helper(context) {
112
123
  if (!context || !context.focusable) {
113
124
  return null
114
125
  }
115
126
  for (const property of context.focusable) {
116
127
  let focus = helper(context[property])
117
- if (!focus && (context[property] || {}).focus) {
118
- focus = context[property]
128
+ if (!focus) {
129
+ const flat = flatten(['list'], context[property])[0]
130
+ for (const element of flat) {
131
+ if (element.focus) {
132
+ focus = context[property]
133
+ break
134
+ }
135
+ }
119
136
  }
120
137
  return focus
121
138
  }
@@ -126,7 +143,7 @@ const focus = (context) => {
126
143
 
127
144
  // if property is a list make array of elements of the list, if not return an array with the property value
128
145
  // fromList
129
- const propertyToArray = (value) => {
146
+ function propertyToArray(value) {
130
147
  if (Array.isArray(value)) {
131
148
  return value
132
149
  } else if (value.marker == 'list') {
@@ -136,7 +153,23 @@ const propertyToArray = (value) => {
136
153
  }
137
154
  }
138
155
 
139
- wordNumber = (word, toPlural) => {
156
+ // values is marker: 'list' or some context
157
+ function concats(values) {
158
+ combined = []
159
+ for (const value of values) {
160
+ if (value.marker == 'list') {
161
+ combined = combined.concat(value.value)
162
+ } else {
163
+ combined.push(value)
164
+ }
165
+ }
166
+ return {
167
+ marker: 'list',
168
+ value: combined
169
+ }
170
+ }
171
+
172
+ function wordNumber(word, toPlural) {
140
173
  if (toPlural) {
141
174
  return pluralize.plural(word)
142
175
  } else {
@@ -144,14 +177,14 @@ wordNumber = (word, toPlural) => {
144
177
  }
145
178
  }
146
179
 
147
- const toEValue = (context) => {
180
+ function toEValue(context) {
148
181
  while( context.evalue ) {
149
182
  context = context.evalue
150
183
  }
151
184
  return context;
152
185
  }
153
186
 
154
- const defaultObjectCheck = (extra = []) => {
187
+ function defaultObjectCheck(extra = []) {
155
188
  return {
156
189
  objects: [
157
190
  {
@@ -162,11 +195,11 @@ const defaultObjectCheck = (extra = []) => {
162
195
  }
163
196
  }
164
197
 
165
- const defaultContextCheckProperties = (extra) => {
198
+ function defaultContextCheckProperties(extra) {
166
199
  return ['marker', 'text', 'verbatim', 'value', 'evalue', 'isResponse', { properties: 'modifiers' }, { properties: 'postModifiers' }, ...extra]
167
200
  }
168
201
 
169
- const defaultContextCheck = ({marker, extra = [], exported = false} = {}) => {
202
+ function defaultContextCheck({marker, extra = [], exported = false} = {}) {
170
203
  let match
171
204
  if (marker) {
172
205
  match = ({context}) => context.marker == marker
@@ -180,35 +213,37 @@ const defaultContextCheck = ({marker, extra = [], exported = false} = {}) => {
180
213
  }
181
214
  }
182
215
 
183
- const isA = (hierarchy) => (child, parent, { strict=false } = {}) => {
184
- if (!child || !parent) {
185
- return false
186
- }
187
-
188
- if (strict) {
189
- if (child.marker) {
190
- child = child.marker
191
- }
192
- if (parent.marker) {
193
- parent = parent.marker
194
- }
195
- return hierarchy.isA(child, parent)
196
- } else {
197
- if (hierarchy.isA(child.marker || child, parent.marker || parent)) {
198
- return true
216
+ function isA(hierarchy) {
217
+ return (child, parent, { strict=false } = {}) => {
218
+ if (!child || !parent) {
219
+ return false
199
220
  }
200
- for (const childT of child.types || [child]) {
201
- for (const parentT of parent.types || [parent]) {
202
- if (hierarchy.isA(childT, parentT)) {
203
- return true
221
+
222
+ if (strict) {
223
+ if (child.marker) {
224
+ child = child.marker
225
+ }
226
+ if (parent.marker) {
227
+ parent = parent.marker
228
+ }
229
+ return hierarchy.isA(child, parent)
230
+ } else {
231
+ if (hierarchy.isA(child.marker || child, parent.marker || parent)) {
232
+ return true
233
+ }
234
+ for (const childT of child.types || [child]) {
235
+ for (const parentT of parent.types || [parent]) {
236
+ if (hierarchy.isA(childT, parentT)) {
237
+ return true
238
+ }
204
239
  }
205
240
  }
241
+ return false
206
242
  }
207
- return false
208
243
  }
209
244
  }
210
245
 
211
- const getValue = (propertyPath, object) => {
246
+ function getValue(propertyPath, object) {
212
247
  if (!propertyPath) {
213
248
  return
214
249
  }
@@ -223,7 +258,7 @@ const getValue = (propertyPath, object) => {
223
258
  return value
224
259
  }
225
260
 
226
- const processTemplateString = async (template, evaluate) => {
261
+ async function processTemplateString(template, evaluate) {
227
262
  async function resolveWithCallback(strings, ...keys) {
228
263
  // const resolvedValues = await Promise.all(keys.map(key => lookupVariable(key)));
229
264
  const resolvedValues = await Promise.all(keys.map(async (key) => {
@@ -263,6 +298,58 @@ const processTemplateString = async (template, evaluate) => {
263
298
  return await processTemplateString(template)
264
299
  }
265
300
 
301
+ // removeProp.js
302
+ function removeProp(obj, testFn, { maxDepth = Infinity, seen = new WeakSet() } = {}) {
303
+ if (!obj || typeof obj !== 'object' || maxDepth <= 0) return obj;
304
+ if (seen.has(obj)) return obj;
305
+ seen.add(obj);
306
+
307
+ if (Array.isArray(obj)) {
308
+ // ---- ARRAY: process each element (but don't remove elements unless testFn says so)
309
+ let writeIdx = 0;
310
+ for (let i = 0; i < obj.length; i++) {
311
+ const element = obj[i];
312
+ const shouldRemoveElement = testFn(element, i, obj);
313
+
314
+ if (shouldRemoveElement) {
315
+ // Remove the whole array element
316
+ if (element && typeof element === 'object') {
317
+ // Still walk inside it in case testFn wants side effects
318
+ removeProp(element, testFn, { maxDepth: maxDepth - 1, seen });
319
+ }
320
+ // Skip writing it back
321
+ } else {
322
+ // Keep element, but walk into it to remove inner props
323
+ removeProp(element, testFn, { maxDepth: maxDepth - 1, seen });
324
+ if (writeIdx !== i) {
325
+ obj[writeIdx] = element;
326
+ }
327
+ writeIdx++;
328
+ }
329
+ }
330
+ obj.length = writeIdx;
331
+ return obj;
332
+ }
333
+
334
+ // ---- OBJECT: iterate over own keys
335
+ const keys = Reflect.ownKeys(obj);
336
+ for (const key of keys) {
337
+ const val = obj[key];
338
+ const shouldRemove = testFn(val, key, obj);
339
+
340
+ if (shouldRemove) {
341
+ delete obj[key];
342
+ if (val && typeof val === 'object') {
343
+ removeProp(val, testFn, { maxDepth: maxDepth - 1, seen });
344
+ }
345
+ } else {
346
+ removeProp(val, testFn, { maxDepth: maxDepth - 1, seen });
347
+ }
348
+ }
349
+
350
+ return obj;
351
+ }
352
+
266
353
  module.exports = {
267
354
  processTemplateString,
268
355
  unshiftL,
@@ -284,4 +371,6 @@ module.exports = {
284
371
  wordNumber,
285
372
  requiredArgument,
286
373
  isA,
374
+ removeProp,
375
+ concats
287
376
  }
@@ -6,11 +6,11 @@ const pluralize = require('pluralize')
6
6
  const _ = require('lodash')
7
7
  const { isMany } = require('./helpers')
8
8
 
9
- const getTypes = ( km, concept, instance ) => {
9
+ function getTypes( km, concept, instance ) {
10
10
  const propertiesAPI = km('properties').api;
11
11
  const conceptAPI = km('concept').api;
12
12
  const digraph = propertiesAPI.digraph;
13
- const intersect = (set1, set2) => {
13
+ function intersect(set1, set2) {
14
14
  return new Set([...set1].filter(x => set2.has(x)))
15
15
  }
16
16
  const descendants = digraph.descendants(concept.value)
@@ -286,7 +286,7 @@ const config = {
286
286
  ]
287
287
  };
288
288
 
289
- const initializer = ({apis, hierarchy}) => {
289
+ function initializer({apis, hierarchy}) {
290
290
  apis('stm').addIsA( (child, parent) => {
291
291
  return hierarchy.isA(child, parent)
292
292
  })
@@ -1666,7 +1666,7 @@
1666
1666
  "dead": true,
1667
1667
  "range": {
1668
1668
  "start": 0,
1669
- "end": 11
1669
+ "end": 2
1670
1670
  },
1671
1671
  "types": [
1672
1672
  "self"