theprogrammablemind 8.0.0-beta.0 → 8.0.0-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.
- package/client.js +43 -11
- package/package.json +12 -13
- package/src/config.js +84 -19
package/client.js
CHANGED
@@ -47,7 +47,13 @@ const getConfig_getObjectsCheck = (config, testConfig) => {
|
|
47
47
|
}
|
48
48
|
const checks = (testConfig.checks && testConfig.checks.objects) || []
|
49
49
|
if (Array.isArray(checks)) {
|
50
|
-
|
50
|
+
const kmToChecks = { [testConfigName]: checks.filter( (check) => !check.km ) }
|
51
|
+
for (const check of checks) {
|
52
|
+
if (check.km) {
|
53
|
+
kmToChecks[check.km] = config.km(check.km).testConfig.checks.objects
|
54
|
+
}
|
55
|
+
}
|
56
|
+
return kmToChecks
|
51
57
|
} else {
|
52
58
|
return checks
|
53
59
|
}
|
@@ -441,7 +447,7 @@ const setupContexts = (rawContexts) => {
|
|
441
447
|
return contexts
|
442
448
|
}
|
443
449
|
|
444
|
-
const processContextsB = ({ config, hierarchy, semantics, generators, json, isTest, isInstance, instance, query, data, retries, url, commandLineArgs }) => {
|
450
|
+
const processContextsB = ({ config, hierarchy, semantics, generators, json, isTest, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs }) => {
|
445
451
|
// TODO fix this name to contextsPrime
|
446
452
|
const contextsPrime = []
|
447
453
|
const generatedPrime = []
|
@@ -491,6 +497,9 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
491
497
|
reason: e.reason,
|
492
498
|
error: e.stack || e.error
|
493
499
|
})
|
500
|
+
if (rebuildingTemplate) {
|
501
|
+
throw e
|
502
|
+
}
|
494
503
|
}
|
495
504
|
}
|
496
505
|
if (contextPrime.controlRemove) {
|
@@ -764,7 +773,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
764
773
|
start = runtime.performance.performance.now()
|
765
774
|
}
|
766
775
|
const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
|
767
|
-
processContextsB({ isTest, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
776
|
+
processContextsB({ isTest, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
768
777
|
if (isTest) {
|
769
778
|
end = runtime.performance.performance.now()
|
770
779
|
clientSideTime = end - start
|
@@ -1557,19 +1566,16 @@ const knowledgeModuleImpl = async ({
|
|
1557
1566
|
}
|
1558
1567
|
|
1559
1568
|
if (isProcess) {
|
1560
|
-
const config = createConfig()
|
1561
|
-
setupConfig(config)
|
1562
|
-
processResults = processResults({ config, errorHandler })
|
1563
|
-
// setup();
|
1564
1569
|
const parser = new runtime.ArgumentParser({
|
1565
1570
|
description: 'Entodicton knowledge module'
|
1566
1571
|
})
|
1567
1572
|
|
1573
|
+
const helpDebugWord = 'In order to get a debug break when a specific word is created set the DEBUG_WORD environment variable to the JSON of the association to break on. For example DEBUG_WORD=\'"the"\''
|
1568
1574
|
const helpDebugAssociation = 'In order to get a debug break when a specific association is created set the DEBUG_ASSOCIATION environment variable to the JSON of the association to break on. For example DEBUG_ASSOCIATION=\'[["the", 0], ["mammal", 1]]\''
|
1569
1575
|
const helpDebugHierarchy = 'In order to get a debug break when a specific hierarchy is created set the DEBUG_HIERARCHY environment variable to the JSON of the child-parent pair to break on. For example DEBUG_HIERARCHY=\'[["cat", 1], ["mammel", 1]]\''
|
1570
1576
|
const helpDebugPriority = 'In order to get a debug break when a specific set of priorities is created set set DEBUG_PRIORITY environment variable to the JSON of the priorities that you want to break on. For example DEBUG_PRIORITY=\'[["verb", 0], ["article", 0]]\''
|
1571
1577
|
const helpDebugContextualPriority = 'In order to get a debug break when a specific set of contextual priorities is created set set DEBUG_CONTEXTUAL_PRIORITY environment variable to the JSON of the priorities that you want to break on. For example DEBUG_CONTEXTUAL_PRIORITY=\'{ context: [["verb", 0], ["article", 0], select: 1}\''
|
1572
|
-
const helpDebugBridge = 'In order to get a debug break when a specific bridge is created set the DEBUG_BRIDGE environment variable to id
|
1578
|
+
const helpDebugBridge = 'In order to get a debug break when a specific bridge is created set the DEBUG_BRIDGE environment variable to id to break on. For example DEBUG_BRIDGE=\'car\''
|
1573
1579
|
const helpDebugOperator = 'In order to get a debug break when a specific hierarcy is created set the DEBUG_OPERATOR environment variable to debug any config loaded. For example DEBUG_OPERATOR=\'([operator] ([arg]))\''
|
1574
1580
|
|
1575
1581
|
parser.add_argument('-tmn', '--testModuleName', { help: 'When running tests instead of using the current modules tests use the specified modules tests' })
|
@@ -1601,6 +1607,7 @@ const knowledgeModuleImpl = async ({
|
|
1601
1607
|
parser.add_argument('-dl', '--debugLoops', { action: 'store_true', help: 'When running with the --debugLoops flag the logs calls to semantics and generators will be immediately written to the console ' })
|
1602
1608
|
parser.add_argument('-d', '--debug', { action: 'store_true', help: 'When running with the --debug flag this set the debug flag in the config' })
|
1603
1609
|
parser.add_argument('-da', '--debugAssociation', { action: 'store_true', help: helpDebugAssociation })
|
1610
|
+
parser.add_argument('-dw', '--debugWord', { action: 'store_true', help: helpDebugWord })
|
1604
1611
|
parser.add_argument('-dh', '--debugHierarchy', { action: 'store_true', help: helpDebugHierarchy })
|
1605
1612
|
parser.add_argument('-dp', '--debugPriority', { action: 'store_true', help: helpDebugPriority })
|
1606
1613
|
parser.add_argument('-dcp', '--debugContextualPriority', { action: 'store_true', help: helpDebugContextualPriority })
|
@@ -1616,6 +1623,21 @@ const knowledgeModuleImpl = async ({
|
|
1616
1623
|
args.rebuildTemplate = true
|
1617
1624
|
}
|
1618
1625
|
|
1626
|
+
// dont debug the load of the KM's if rebuild template is on since we want to debug the template rebuild not the load
|
1627
|
+
if (args.rebuildTemplate) {
|
1628
|
+
global.pauseDebugging = true
|
1629
|
+
}
|
1630
|
+
|
1631
|
+
const config = createConfig()
|
1632
|
+
setupConfig(config)
|
1633
|
+
processResults = processResults({ config, errorHandler })
|
1634
|
+
|
1635
|
+
if (args.rebuildTemplate) {
|
1636
|
+
global.pauseDebugging = false
|
1637
|
+
}
|
1638
|
+
|
1639
|
+
// setup();
|
1640
|
+
|
1619
1641
|
if (args.parenthesized) {
|
1620
1642
|
config.parenthesized = true
|
1621
1643
|
}
|
@@ -1641,7 +1663,7 @@ const knowledgeModuleImpl = async ({
|
|
1641
1663
|
throw new Error('Error for the checkForLoop argument. Expected a JSON array of operator keys of the form "[<id>, <level>]"')
|
1642
1664
|
}
|
1643
1665
|
} catch (e) {
|
1644
|
-
throw new Error(
|
1666
|
+
throw new Error('Error for the checkForLoop argument. Expected a JSON array of operator keys of the form "[<id>, <level>]"')
|
1645
1667
|
}
|
1646
1668
|
} else {
|
1647
1669
|
if (process.argv.includes('--checkForLoop') || process.argv.includes('-cl')) {
|
@@ -1652,6 +1674,10 @@ const knowledgeModuleImpl = async ({
|
|
1652
1674
|
console.log(helpDebugAssociation)
|
1653
1675
|
runtime.process.exit(-1)
|
1654
1676
|
}
|
1677
|
+
if (args.debugWord) {
|
1678
|
+
console.log(helpDebugWord)
|
1679
|
+
runtime.process.exit(-1)
|
1680
|
+
}
|
1655
1681
|
if (args.debugHierarchy) {
|
1656
1682
|
console.log(helpDebugHierarchy)
|
1657
1683
|
runtime.process.exit(-1)
|
@@ -1744,8 +1770,14 @@ const knowledgeModuleImpl = async ({
|
|
1744
1770
|
}
|
1745
1771
|
}
|
1746
1772
|
if (args.print.includes('w')) {
|
1747
|
-
|
1748
|
-
|
1773
|
+
// { literals: Object, patterns: Array(2), hierarchy: Array(97) }
|
1774
|
+
console.log('literals')
|
1775
|
+
for (const word in config.config.words.literals) {
|
1776
|
+
console.log(' ' + word.concat(' ', ...config.config.words.literals[word].map((def) => JSON.stringify(def))))
|
1777
|
+
}
|
1778
|
+
console.log('patterns')
|
1779
|
+
for (const pattern of config.config.words.patterns) {
|
1780
|
+
console.log(' ' + JSON.stringify(pattern))
|
1749
1781
|
}
|
1750
1782
|
}
|
1751
1783
|
if (args.print.includes('b')) {
|
package/package.json
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
{
|
2
2
|
"devDependencies": {
|
3
|
-
"eslint-plugin-import": "^2.23.4",
|
4
|
-
"jest": "^29.7.0",
|
5
|
-
"@typescript-eslint/parser": "^4.28.4",
|
6
3
|
"@typescript-eslint/eslint-plugin": "^4.28.4",
|
7
|
-
"eslint
|
4
|
+
"@typescript-eslint/parser": "^4.28.4",
|
5
|
+
"eslint": "^7.31.0",
|
8
6
|
"eslint-config-standard": "^16.0.3",
|
7
|
+
"eslint-plugin-import": "^2.23.4",
|
8
|
+
"eslint-plugin-node": "^11.1.0",
|
9
9
|
"eslint-plugin-promise": "^5.1.0",
|
10
|
-
"
|
10
|
+
"jest": "^29.7.0"
|
11
11
|
},
|
12
12
|
"scripts": {
|
13
13
|
"to:debug": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
|
@@ -52,19 +52,18 @@
|
|
52
52
|
],
|
53
53
|
"author": "dev@thinktelligence.com",
|
54
54
|
"dependencies": {
|
55
|
+
"base-64": "^1.0.0",
|
55
56
|
"deep-equal": "^2.0.4",
|
56
|
-
"
|
57
|
+
"fs": "0.0.1-security",
|
57
58
|
"json-diff": "^1.0.3",
|
59
|
+
"json-stable-stringify": "^1.0.1",
|
58
60
|
"lodash": "^4.17.20",
|
59
|
-
"
|
60
|
-
"base-64": "^1.0.0",
|
61
|
-
"sort-json": "^2.0.0",
|
61
|
+
"node-fetch": "^2.6.1",
|
62
62
|
"readline": "^1.3.0",
|
63
63
|
"scriptjs": "^2.5.9",
|
64
|
-
"
|
65
|
-
"
|
66
|
-
"node-fetch": "^2.6.1"
|
64
|
+
"sort-json": "^2.0.0",
|
65
|
+
"uuid": "^8.3.2"
|
67
66
|
},
|
68
|
-
"version": "8.0.0-beta.
|
67
|
+
"version": "8.0.0-beta.10",
|
69
68
|
"license": "UNLICENSED"
|
70
69
|
}
|
package/src/config.js
CHANGED
@@ -40,6 +40,9 @@ const initWords = (words) => {
|
|
40
40
|
}
|
41
41
|
|
42
42
|
const debugPriority = (priority) => {
|
43
|
+
if (global.pauseDebugging) {
|
44
|
+
return
|
45
|
+
}
|
43
46
|
if (global.entodictonDebugPriority) {
|
44
47
|
if (helpers.subPriority(entodictonDebugPriority, priority)) {
|
45
48
|
debugger // debug hierarchy hit
|
@@ -48,6 +51,9 @@ const debugPriority = (priority) => {
|
|
48
51
|
}
|
49
52
|
|
50
53
|
const debugAssociation = (association) => {
|
54
|
+
if (global.pauseDebugging) {
|
55
|
+
return
|
56
|
+
}
|
51
57
|
if (global.entodictonDebugAssociation) {
|
52
58
|
if (helpers.safeEquals(global.entodictonDebugAssociation, association)) {
|
53
59
|
debugger // debug association hit
|
@@ -55,7 +61,21 @@ const debugAssociation = (association) => {
|
|
55
61
|
}
|
56
62
|
}
|
57
63
|
|
64
|
+
const debugWord = (word) => {
|
65
|
+
if (global.pauseDebugging) {
|
66
|
+
return
|
67
|
+
}
|
68
|
+
if (global.entodictonDebugWord) {
|
69
|
+
if (helpers.safeEquals(global.entodictonDebugWord, word)) {
|
70
|
+
debugger // debug word hit
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
58
75
|
const debugHierarchy = (pair) => {
|
76
|
+
if (global.pauseDebugging) {
|
77
|
+
return
|
78
|
+
}
|
59
79
|
if (global.entodictonDebugHierarchy) {
|
60
80
|
if (helpers.safeEquals(global.entodictonDebugHierarchy, pair)) {
|
61
81
|
debugger // debug hierarchy hit
|
@@ -64,14 +84,20 @@ const debugHierarchy = (pair) => {
|
|
64
84
|
}
|
65
85
|
|
66
86
|
const debugBridge = (bridge) => {
|
87
|
+
if (global.pauseDebugging) {
|
88
|
+
return
|
89
|
+
}
|
67
90
|
if (global.entodictonDebugBridge) {
|
68
|
-
if (global.entodictonDebugBridge
|
91
|
+
if (global.entodictonDebugBridge == bridge.id) {
|
69
92
|
debugger // debug hierarchy hit
|
70
93
|
}
|
71
94
|
}
|
72
95
|
}
|
73
96
|
|
74
97
|
const debugOperator = (operator) => {
|
98
|
+
if (global.pauseDebugging) {
|
99
|
+
return
|
100
|
+
}
|
75
101
|
if (global.entodictonDebugOperator) {
|
76
102
|
if ((operator.pattern || operator) === global.entodictonDebugOperator) {
|
77
103
|
debugger // debug operator hit
|
@@ -80,18 +106,29 @@ const debugOperator = (operator) => {
|
|
80
106
|
}
|
81
107
|
|
82
108
|
const debugConfigProps = (config) => {
|
109
|
+
if (global.pauseDebugging) {
|
110
|
+
return
|
111
|
+
}
|
83
112
|
if (!config) {
|
84
113
|
return
|
85
114
|
}
|
86
115
|
const checkProps = [
|
87
116
|
{ property: 'priorities', check: (v) => debugPriority(v) },
|
88
117
|
{ property: 'association', check: (v) => debugAssociation(v) },
|
118
|
+
{ property: 'words', check: (v) => debugAssociation(v) },
|
89
119
|
{ property: 'hierarchy', check: (v) => debugHierarchy(v) },
|
90
120
|
{ property: 'operators', check: (v) => debugOperator(v) },
|
91
121
|
{ property: 'bridges', check: (v) => debugBridge(v) }
|
92
122
|
]
|
93
123
|
for (const { property, check } of checkProps) {
|
94
|
-
if (
|
124
|
+
if (property == 'words') {
|
125
|
+
if (config[property]) {
|
126
|
+
for (const value in config[property].literals) {
|
127
|
+
check(value)
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
else if (config[property]) {
|
95
132
|
for (const value of config[property]) {
|
96
133
|
check(value)
|
97
134
|
}
|
@@ -225,7 +262,12 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
225
262
|
}
|
226
263
|
if (bridge.children) {
|
227
264
|
for (const child of bridge.children) {
|
228
|
-
config.addHierarchy(child, bridge.id)
|
265
|
+
// config.addHierarchy(child, bridge.id)
|
266
|
+
if (child.child) {
|
267
|
+
config.addHierarchy(child.child, bridge.id, child.instance)
|
268
|
+
} else {
|
269
|
+
config.addHierarchy(child, bridge.id)
|
270
|
+
}
|
229
271
|
}
|
230
272
|
}
|
231
273
|
if (bridge.operator) {
|
@@ -233,12 +275,20 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
233
275
|
}
|
234
276
|
if (bridge.parents) {
|
235
277
|
for (const parent of bridge.parents) {
|
236
|
-
|
278
|
+
if (parent.parent) {
|
279
|
+
config.addHierarchy(bridge.id, parent.parent, parent.instance)
|
280
|
+
} else {
|
281
|
+
config.addHierarchy(bridge.id, parent)
|
282
|
+
}
|
237
283
|
}
|
238
284
|
}
|
239
285
|
if (bridge.isA) {
|
240
286
|
for (const parent of bridge.isA) {
|
241
|
-
|
287
|
+
if (parent.parent) {
|
288
|
+
config.addHierarchy(bridge.id, parent.parent, parent.instance)
|
289
|
+
} else {
|
290
|
+
config.addHierarchy(bridge.id, parent)
|
291
|
+
}
|
242
292
|
}
|
243
293
|
}
|
244
294
|
if (bridge.before) {
|
@@ -260,7 +310,7 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
260
310
|
if (bridge.words) {
|
261
311
|
for (let def of bridge.words) {
|
262
312
|
if (typeof def === 'string') {
|
263
|
-
config.addWordInternal(def, { id: bridge.id, initial: `{ value: "${
|
313
|
+
config.addWordInternal(def, { id: bridge.id, initial: `{ value: "${bridge.id}"}` })
|
264
314
|
} else {
|
265
315
|
const word = def.word
|
266
316
|
def = { initial: JSON.stringify(def), id: bridge.id, word }
|
@@ -404,13 +454,13 @@ if (runtime.process.env.DEBUG_ASSOCIATION) {
|
|
404
454
|
global.entodictonDebugAssociation = JSON.parse(runtime.process.env.DEBUG_ASSOCIATION)
|
405
455
|
}
|
406
456
|
|
457
|
+
if (runtime.process.env.DEBUG_WORD) {
|
458
|
+
global.entodictonDebugWord = runtime.process.env.DEBUG_WORD
|
459
|
+
}
|
460
|
+
|
407
461
|
if (runtime.process.env.DEBUG_BRIDGE) {
|
408
|
-
// id
|
409
|
-
global.entodictonDebugBridge = runtime.process.env.DEBUG_BRIDGE
|
410
|
-
if (global.entodictonDebugBridge.length !== 2) {
|
411
|
-
console.log('Expected DEBUG_BRIDGE to be of the form "id/level"')
|
412
|
-
process.exit(-1)
|
413
|
-
}
|
462
|
+
// id
|
463
|
+
global.entodictonDebugBridge = runtime.process.env.DEBUG_BRIDGE
|
414
464
|
global.entodictonDebugBridge[1] = parseInt(global.entodictonDebugBridge[1])
|
415
465
|
}
|
416
466
|
|
@@ -1272,9 +1322,9 @@ class Config {
|
|
1272
1322
|
}
|
1273
1323
|
}
|
1274
1324
|
|
1275
|
-
addHierarchy (child, parent) {
|
1325
|
+
addHierarchy (child, parent, instance) {
|
1276
1326
|
if (child && parent || !child || Array.isArray(child) || (typeof child === 'string' && !parent)) {
|
1277
|
-
this.addHierarchyChildParent(child, parent)
|
1327
|
+
this.addHierarchyChildParent(child, parent, instance)
|
1278
1328
|
// this.addHierarchyProperties ({ child, parent })
|
1279
1329
|
} else {
|
1280
1330
|
this.addHierarchyProperties(child)
|
@@ -1282,26 +1332,32 @@ class Config {
|
|
1282
1332
|
}
|
1283
1333
|
|
1284
1334
|
addHierarchyProperties (edge) {
|
1285
|
-
const { child, parent } = edge
|
1335
|
+
const { child, parent, instance } = edge
|
1286
1336
|
if (typeof child !== 'string') {
|
1287
1337
|
throw new Error(`addHierarchy expected child property to be a string. got ${JSON.stringify(child)}`)
|
1288
1338
|
}
|
1289
1339
|
if (typeof parent !== 'string') {
|
1290
1340
|
throw new Error(`addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`)
|
1291
1341
|
}
|
1342
|
+
if (instance && typeof instance !== 'boolean') {
|
1343
|
+
throw new Error(`addHierarchy expected instance property to be a boolean or undefined. got ${JSON.stringify(instance)}`)
|
1344
|
+
}
|
1292
1345
|
debugHierarchy([child, parent])
|
1293
1346
|
this.config.hierarchy.push(edge)
|
1294
1347
|
// TODO greg11 this.hierarchy.addEdge(edge)
|
1295
|
-
this._delta.json.hierarchy.push([child, parent])
|
1348
|
+
this._delta.json.hierarchy.push([child, parent, instance || false])
|
1296
1349
|
}
|
1297
1350
|
|
1298
|
-
addHierarchyChildParent (child, parent) {
|
1351
|
+
addHierarchyChildParent (child, parent, instance) {
|
1299
1352
|
if (typeof child !== 'string') {
|
1300
1353
|
throw new Error(`addHierarchy expected child to be a string. got ${JSON.stringify(child)}`)
|
1301
1354
|
}
|
1302
1355
|
if (typeof parent !== 'string') {
|
1303
1356
|
throw new Error(`addHierarchy expected parent to be a string. got ${JSON.stringify(parent)}`)
|
1304
1357
|
}
|
1358
|
+
if (instance && typeof instance !== 'boolean') {
|
1359
|
+
throw new Error(`addHierarchy expected instance property to be a boolean or undefined. got ${JSON.stringify(instance)}`)
|
1360
|
+
}
|
1305
1361
|
debugHierarchy([child, parent])
|
1306
1362
|
if (this.config.hierarchy.find((element) => {
|
1307
1363
|
const hc = hierarchyCanonical(element)
|
@@ -1312,9 +1368,9 @@ class Config {
|
|
1312
1368
|
return
|
1313
1369
|
}
|
1314
1370
|
|
1315
|
-
this.config.hierarchy.push([child, parent])
|
1371
|
+
this.config.hierarchy.push([child, parent, instance || false])
|
1316
1372
|
// this.hierarchy.addEdge([child, parent])
|
1317
|
-
this._delta.json.hierarchy.push([child, parent])
|
1373
|
+
this._delta.json.hierarchy.push([child, parent, instance || false])
|
1318
1374
|
}
|
1319
1375
|
|
1320
1376
|
getBridge (id, level) {
|
@@ -1458,6 +1514,7 @@ class Config {
|
|
1458
1514
|
hierarchy: [],
|
1459
1515
|
}
|
1460
1516
|
}
|
1517
|
+
debugWord(word)
|
1461
1518
|
|
1462
1519
|
const literals = this.config.words.literals
|
1463
1520
|
def = Object.assign({}, def, { uuid: uuid || this._uuid })
|
@@ -1582,6 +1639,14 @@ class Config {
|
|
1582
1639
|
return client.process(this, query, options)
|
1583
1640
|
}
|
1584
1641
|
|
1642
|
+
query (query, options) {
|
1643
|
+
return this.process(query, options)
|
1644
|
+
}
|
1645
|
+
|
1646
|
+
processQuery (query, options) {
|
1647
|
+
return this.process(query, options)
|
1648
|
+
}
|
1649
|
+
|
1585
1650
|
initDefaults () {
|
1586
1651
|
const init = (config) => {
|
1587
1652
|
if (!config.objects) {
|