@cavelang/canonical 0.32.3 → 0.33.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.
- package/README.md +6 -2
- package/dist/src/emit.d.ts +9 -4
- package/dist/src/emit.d.ts.map +1 -1
- package/dist/src/emit.js +26 -25
- package/dist/src/emit.js.map +1 -1
- package/package.json +3 -3
- package/src/emit.ts +28 -30
package/README.md
CHANGED
|
@@ -73,7 +73,10 @@ preserves direction and makes reverse reads return the preferred opposite name.
|
|
|
73
73
|
- primary verb direction (§5.5);
|
|
74
74
|
- `WHEN NOT x`, never `UNLESS` (§8.2);
|
|
75
75
|
- §3.2 anatomy order: payload, `+/- delta`, `(Nσ)`, contexts, tags,
|
|
76
|
-
`@ N%` (omitted at 100%), `!`, `; comment`.
|
|
76
|
+
`@ N%` (omitted at 100%), `!`, `; comment`. A multi-line comment (§6.4)
|
|
77
|
+
opens as full-line `;` comments directly above the claim line, its last
|
|
78
|
+
line riding on the claim, so `emitClaim` may return several lines; a
|
|
79
|
+
§28.4 annotation stays the line directly above the claim.
|
|
77
80
|
- recursive factoring of adjacent sibling claims through shared incomplete
|
|
78
81
|
prefixes, stopping before a header would itself parse as a complete claim.
|
|
79
82
|
|
|
@@ -121,7 +124,8 @@ parseable.
|
|
|
121
124
|
qualifier-level `NOT`, and `UNLESS` each flip the condition's negation.
|
|
122
125
|
- **Comments do not fan out from headers**: a prefix header comment is
|
|
123
126
|
documentary only. Persisted comments stay on leaf claims, preventing one
|
|
124
|
-
comment from silently becoming metadata on several rows.
|
|
127
|
+
comment from silently becoming metadata on several rows. A leaf's
|
|
128
|
+
multi-line comment block is emitted at the leaf's indentation.
|
|
125
129
|
|
|
126
130
|
## Tests
|
|
127
131
|
|
package/dist/src/emit.d.ts
CHANGED
|
@@ -9,14 +9,19 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { Claim } from '@cavelang/core';
|
|
11
11
|
import type * as Canonicalize from './canonicalize.ts';
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* @returns the canonical text of one claim (no indentation): a single line,
|
|
14
|
+
* or — when the comment spans several lines (§6.4) — its leading comment
|
|
15
|
+
* lines above the claim line, the last comment line riding on the claim.
|
|
16
|
+
*/
|
|
13
17
|
export declare const emitClaim: (claim: Claim.t) => string;
|
|
14
18
|
/**
|
|
15
19
|
* A transaction annotation (spec §28.4): the full-line comment placed
|
|
16
20
|
* immediately above a claim line to carry its transaction id through
|
|
17
|
-
* canonical text.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
21
|
+
* canonical text. Annotation lines are transparent to the grammar (§8) and
|
|
22
|
+
* to the comment block above a claim (§6.4), so annotated text reads
|
|
23
|
+
* unchanged everywhere; sync-aware readers pair each annotation with the
|
|
24
|
+
* claim line below it.
|
|
20
25
|
*/
|
|
21
26
|
export declare const txComment: (tx: string) => string;
|
|
22
27
|
/**
|
package/dist/src/emit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAA0B,MAAM,gBAAgB,CAAA;AAE9D,OAAO,KAAK,KAAK,YAAY,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAA0B,MAAM,gBAAgB,CAAA;AAE9D,OAAO,KAAK,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAoDtD;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,CAAC,CAAC,KAAG,MACS,CAAA;AAgBpD;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GAAI,IAAI,MAAM,KAAG,MAC3B,CAAA;AAEZ;;;;GAIG;AACH,eAAO,MAAM,QAAQ,qCAAiB,CAAA;AAEtC,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,GAAG,MAAM,CAAA;CAC1D,CAAA;AAkHD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,IAAI,GAAI,QAAQ,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,UAAS,WAAgB,KAAG,MAoDvG,CAAA"}
|
package/dist/src/emit.js
CHANGED
|
@@ -41,13 +41,10 @@ const metaText = (claim) => {
|
|
|
41
41
|
if (claim.importance) {
|
|
42
42
|
parts.push('!');
|
|
43
43
|
}
|
|
44
|
-
if (claim.comment !== undefined) {
|
|
45
|
-
parts.push(`; ${claim.comment}`);
|
|
46
|
-
}
|
|
47
44
|
return parts;
|
|
48
45
|
};
|
|
49
|
-
/** @returns
|
|
50
|
-
|
|
46
|
+
/** @returns the canonical claim line without its comment. */
|
|
47
|
+
const claimLine = (claim) => {
|
|
51
48
|
const parts = [Claim.formatTerm(claim.subject), claim.verb];
|
|
52
49
|
if (claim.negated) {
|
|
53
50
|
parts.push('NOT');
|
|
@@ -59,6 +56,12 @@ export const emitClaim = (claim) => {
|
|
|
59
56
|
parts.push(...metaText(claim));
|
|
60
57
|
return parts.join(' ');
|
|
61
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* @returns the canonical text of one claim (no indentation): a single line,
|
|
61
|
+
* or — when the comment spans several lines (§6.4) — its leading comment
|
|
62
|
+
* lines above the claim line, the last comment line riding on the claim.
|
|
63
|
+
*/
|
|
64
|
+
export const emitClaim = (claim) => Token.joinComment(claimLine(claim), claim.comment);
|
|
62
65
|
/**
|
|
63
66
|
* @returns the qualifier-payload text of a condition claim. Negation always
|
|
64
67
|
* emits as a `NOT` *prefix* — the §8.2 canonical `WHEN NOT x` shape — never
|
|
@@ -69,24 +72,24 @@ export const emitClaim = (claim) => {
|
|
|
69
72
|
const conditionText = (claim) => {
|
|
70
73
|
const body = claim.verb === 'EXISTS' && claim.payload.kind === 'none' ?
|
|
71
74
|
[Claim.formatTerm(claim.subject), ...metaText(claim)].join(' ') :
|
|
72
|
-
|
|
75
|
+
claimLine({ ...claim, negated: false });
|
|
73
76
|
return claim.negated ? `NOT ${body}` : body;
|
|
74
77
|
};
|
|
75
78
|
/**
|
|
76
79
|
* A transaction annotation (spec §28.4): the full-line comment placed
|
|
77
80
|
* immediately above a claim line to carry its transaction id through
|
|
78
|
-
* canonical text.
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
+
* canonical text. Annotation lines are transparent to the grammar (§8) and
|
|
82
|
+
* to the comment block above a claim (§6.4), so annotated text reads
|
|
83
|
+
* unchanged everywhere; sync-aware readers pair each annotation with the
|
|
84
|
+
* claim line below it.
|
|
81
85
|
*/
|
|
82
86
|
export const txComment = (tx) => `;@ ${tx}`;
|
|
83
|
-
const txLineRe = /^\s*;@\s+(\S+)\s*$/;
|
|
84
87
|
/**
|
|
85
88
|
* @returns the transaction id carried by a raw line when it is a §28.4
|
|
86
89
|
* annotation (`;@ <tx>`), `undefined` otherwise. Purely lexical — the
|
|
87
90
|
* caller validates the id shape.
|
|
88
91
|
*/
|
|
89
|
-
export const txOfLine =
|
|
92
|
+
export const txOfLine = Token.txOfLine;
|
|
90
93
|
const tokenText = (token) => {
|
|
91
94
|
switch (token.kind) {
|
|
92
95
|
case 'text':
|
|
@@ -97,13 +100,6 @@ const tokenText = (token) => {
|
|
|
97
100
|
return token.text;
|
|
98
101
|
}
|
|
99
102
|
};
|
|
100
|
-
const renderParts = (text) => {
|
|
101
|
-
const split = Token.splitComment(text);
|
|
102
|
-
return {
|
|
103
|
-
tokens: Token.tokenize(split.head).map(tokenText),
|
|
104
|
-
...split.comment === undefined ? {} : { comment: split.comment }
|
|
105
|
-
};
|
|
106
|
-
};
|
|
107
103
|
const commonPrefixLength = (items) => {
|
|
108
104
|
const shortest = Math.min(...items.map(item => item.tokens.length));
|
|
109
105
|
let length = 0;
|
|
@@ -155,10 +151,15 @@ const emitForest = (forest, depth, topLevel, inherited, lines) => {
|
|
|
155
151
|
}
|
|
156
152
|
const item = forest[at];
|
|
157
153
|
const indent = ' '.repeat(depth);
|
|
154
|
+
// A multi-line comment (§6.4) opens above the claim line; the §28.4
|
|
155
|
+
// annotation stays the line directly above the claim.
|
|
156
|
+
const rendered = Token.joinComment(item.tokens.join(' '), item.node.comment).split('\n');
|
|
157
|
+
const last = rendered.pop();
|
|
158
|
+
lines.push(...rendered.map(line => `${indent}${line}`));
|
|
158
159
|
if (item.node.annotation !== undefined) {
|
|
159
160
|
lines.push(`${indent}${item.node.annotation}`);
|
|
160
161
|
}
|
|
161
|
-
lines.push(`${indent}${
|
|
162
|
+
lines.push(`${indent}${last}`);
|
|
162
163
|
emitForest(item.node.children.map(node => ({ node, tokens: node.tokens })), depth + 1, false, [], lines);
|
|
163
164
|
at += 1;
|
|
164
165
|
}
|
|
@@ -194,15 +195,15 @@ export const emit = (result, options = {}) => {
|
|
|
194
195
|
const nodeAt = (index, role) => {
|
|
195
196
|
const { claim } = result.claims[index];
|
|
196
197
|
const text = role === undefined || role === 'QUALIFIES' ?
|
|
197
|
-
|
|
198
|
+
claimLine(claim) :
|
|
198
199
|
`${role} ${conditionText(claim)}`;
|
|
199
|
-
const
|
|
200
|
+
const tokens = Token.tokenize(text).map(tokenText);
|
|
200
201
|
const annotation = options.annotate?.(index);
|
|
201
202
|
if (expanded.has(index)) {
|
|
202
203
|
return {
|
|
203
204
|
index,
|
|
204
|
-
tokens
|
|
205
|
-
...
|
|
205
|
+
tokens,
|
|
206
|
+
...claim.comment === undefined ? {} : { comment: claim.comment },
|
|
206
207
|
...annotation === undefined ? {} : { annotation },
|
|
207
208
|
children: []
|
|
208
209
|
};
|
|
@@ -210,8 +211,8 @@ export const emit = (result, options = {}) => {
|
|
|
210
211
|
expanded.add(index);
|
|
211
212
|
return {
|
|
212
213
|
index,
|
|
213
|
-
tokens
|
|
214
|
-
...
|
|
214
|
+
tokens,
|
|
215
|
+
...claim.comment === undefined ? {} : { comment: claim.comment },
|
|
215
216
|
...annotation === undefined ? {} : { annotation },
|
|
216
217
|
children: (childEdges.get(index) ?? []).map(edge => nodeAt(edge.child, edge.role))
|
|
217
218
|
};
|
package/dist/src/emit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAGvD,MAAM,WAAW,GAAG,CAAC,OAAsB,EAAsB,EAAE;IACjE,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,UAAU;YACb,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QACzC,KAAK,WAAW;YACd,OAAO,GAAG,OAAO,CAAC,SAAS,KAAK,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAA;QAC/D,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QACpC,KAAK,MAAM;YACT,OAAO,SAAS,CAAA;IACpB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAY,EAAE;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAChD,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,CAAA;IACtC,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC,CAAA;IAC3B,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7B,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClD,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACjB,CAAC;IACD,
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/emit.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cavelang/canonical",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CAVE canonicalization — verb lifecycle and inverse registry, continuation expansion, canonical emitter.",
|
|
6
6
|
"keywords": [
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@cavelang/core": "0.
|
|
47
|
-
"@cavelang/parser": "0.
|
|
46
|
+
"@cavelang/core": "0.33.0",
|
|
47
|
+
"@cavelang/parser": "0.33.0"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsc -b",
|
package/src/emit.ts
CHANGED
|
@@ -45,14 +45,11 @@ const metaText = (claim: Claim.t): string[] => {
|
|
|
45
45
|
if (claim.importance) {
|
|
46
46
|
parts.push('!')
|
|
47
47
|
}
|
|
48
|
-
if (claim.comment !== undefined) {
|
|
49
|
-
parts.push(`; ${claim.comment}`)
|
|
50
|
-
}
|
|
51
48
|
return parts
|
|
52
49
|
}
|
|
53
50
|
|
|
54
|
-
/** @returns
|
|
55
|
-
|
|
51
|
+
/** @returns the canonical claim line without its comment. */
|
|
52
|
+
const claimLine = (claim: Claim.t): string => {
|
|
56
53
|
const parts = [Claim.formatTerm(claim.subject), claim.verb]
|
|
57
54
|
if (claim.negated) {
|
|
58
55
|
parts.push('NOT')
|
|
@@ -65,6 +62,14 @@ export const emitClaim = (claim: Claim.t): string => {
|
|
|
65
62
|
return parts.join(' ')
|
|
66
63
|
}
|
|
67
64
|
|
|
65
|
+
/**
|
|
66
|
+
* @returns the canonical text of one claim (no indentation): a single line,
|
|
67
|
+
* or — when the comment spans several lines (§6.4) — its leading comment
|
|
68
|
+
* lines above the claim line, the last comment line riding on the claim.
|
|
69
|
+
*/
|
|
70
|
+
export const emitClaim = (claim: Claim.t): string =>
|
|
71
|
+
Token.joinComment(claimLine(claim), claim.comment)
|
|
72
|
+
|
|
68
73
|
/**
|
|
69
74
|
* @returns the qualifier-payload text of a condition claim. Negation always
|
|
70
75
|
* emits as a `NOT` *prefix* — the §8.2 canonical `WHEN NOT x` shape — never
|
|
@@ -75,29 +80,27 @@ export const emitClaim = (claim: Claim.t): string => {
|
|
|
75
80
|
const conditionText = (claim: Claim.t): string => {
|
|
76
81
|
const body = claim.verb === 'EXISTS' && claim.payload.kind === 'none' ?
|
|
77
82
|
[Claim.formatTerm(claim.subject), ...metaText(claim)].join(' ') :
|
|
78
|
-
|
|
83
|
+
claimLine({ ...claim, negated: false })
|
|
79
84
|
return claim.negated ? `NOT ${body}` : body
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
/**
|
|
83
88
|
* A transaction annotation (spec §28.4): the full-line comment placed
|
|
84
89
|
* immediately above a claim line to carry its transaction id through
|
|
85
|
-
* canonical text.
|
|
86
|
-
*
|
|
87
|
-
*
|
|
90
|
+
* canonical text. Annotation lines are transparent to the grammar (§8) and
|
|
91
|
+
* to the comment block above a claim (§6.4), so annotated text reads
|
|
92
|
+
* unchanged everywhere; sync-aware readers pair each annotation with the
|
|
93
|
+
* claim line below it.
|
|
88
94
|
*/
|
|
89
95
|
export const txComment = (tx: string): string =>
|
|
90
96
|
`;@ ${tx}`
|
|
91
97
|
|
|
92
|
-
const txLineRe = /^\s*;@\s+(\S+)\s*$/
|
|
93
|
-
|
|
94
98
|
/**
|
|
95
99
|
* @returns the transaction id carried by a raw line when it is a §28.4
|
|
96
100
|
* annotation (`;@ <tx>`), `undefined` otherwise. Purely lexical — the
|
|
97
101
|
* caller validates the id shape.
|
|
98
102
|
*/
|
|
99
|
-
export const txOfLine =
|
|
100
|
-
txLineRe.exec(raw)?.[1]
|
|
103
|
+
export const txOfLine = Token.txOfLine
|
|
101
104
|
|
|
102
105
|
export type EmitOptions = {
|
|
103
106
|
/**
|
|
@@ -133,14 +136,6 @@ const tokenText = (token: Token.t): string => {
|
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
138
|
|
|
136
|
-
const renderParts = (text: string): { tokens: readonly string[], comment?: string } => {
|
|
137
|
-
const split = Token.splitComment(text)
|
|
138
|
-
return {
|
|
139
|
-
tokens: Token.tokenize(split.head).map(tokenText),
|
|
140
|
-
...split.comment === undefined ? {} : { comment: split.comment }
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
139
|
const commonPrefixLength = (items: readonly RenderItem[]): number => {
|
|
145
140
|
const shortest = Math.min(...items.map(item => item.tokens.length))
|
|
146
141
|
let length = 0
|
|
@@ -209,12 +204,15 @@ const emitForest = (
|
|
|
209
204
|
|
|
210
205
|
const item = forest[at]!
|
|
211
206
|
const indent = ' '.repeat(depth)
|
|
207
|
+
// A multi-line comment (§6.4) opens above the claim line; the §28.4
|
|
208
|
+
// annotation stays the line directly above the claim.
|
|
209
|
+
const rendered = Token.joinComment(item.tokens.join(' '), item.node.comment).split('\n')
|
|
210
|
+
const last = rendered.pop()!
|
|
211
|
+
lines.push(...rendered.map(line => `${indent}${line}`))
|
|
212
212
|
if (item.node.annotation !== undefined) {
|
|
213
213
|
lines.push(`${indent}${item.node.annotation}`)
|
|
214
214
|
}
|
|
215
|
-
lines.push(
|
|
216
|
-
`${indent}${item.tokens.join(' ')}${item.node.comment === undefined ? '' : ` ; ${item.node.comment}`}`
|
|
217
|
-
)
|
|
215
|
+
lines.push(`${indent}${last}`)
|
|
218
216
|
emitForest(
|
|
219
217
|
item.node.children.map(node => ({ node, tokens: node.tokens })),
|
|
220
218
|
depth + 1,
|
|
@@ -256,15 +254,15 @@ export const emit = (result: Pick<Canonicalize.Result, 'claims' | 'edges'>, opti
|
|
|
256
254
|
const nodeAt = (index: number, role: undefined | Canonicalize.EdgeRole): RenderNode => {
|
|
257
255
|
const { claim } = result.claims[index]!
|
|
258
256
|
const text = role === undefined || role === 'QUALIFIES' ?
|
|
259
|
-
|
|
257
|
+
claimLine(claim) :
|
|
260
258
|
`${role} ${conditionText(claim)}`
|
|
261
|
-
const
|
|
259
|
+
const tokens = Token.tokenize(text).map(tokenText)
|
|
262
260
|
const annotation = options.annotate?.(index)
|
|
263
261
|
if (expanded.has(index)) {
|
|
264
262
|
return {
|
|
265
263
|
index,
|
|
266
|
-
tokens
|
|
267
|
-
...
|
|
264
|
+
tokens,
|
|
265
|
+
...claim.comment === undefined ? {} : { comment: claim.comment },
|
|
268
266
|
...annotation === undefined ? {} : { annotation },
|
|
269
267
|
children: []
|
|
270
268
|
}
|
|
@@ -272,8 +270,8 @@ export const emit = (result: Pick<Canonicalize.Result, 'claims' | 'edges'>, opti
|
|
|
272
270
|
expanded.add(index)
|
|
273
271
|
return {
|
|
274
272
|
index,
|
|
275
|
-
tokens
|
|
276
|
-
...
|
|
273
|
+
tokens,
|
|
274
|
+
...claim.comment === undefined ? {} : { comment: claim.comment },
|
|
277
275
|
...annotation === undefined ? {} : { annotation },
|
|
278
276
|
children: (childEdges.get(index) ?? []).map(edge => nodeAt(edge.child, edge.role))
|
|
279
277
|
}
|