@clossys/writer 0.3.2

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 (115) hide show
  1. package/CHANGELOG.md +196 -0
  2. package/LICENSE +21 -0
  3. package/README.md +593 -0
  4. package/dist/addressability.d.ts +245 -0
  5. package/dist/addressability.d.ts.map +1 -0
  6. package/dist/addressability.js +567 -0
  7. package/dist/addressability.js.map +1 -0
  8. package/dist/checker.d.ts +159 -0
  9. package/dist/checker.d.ts.map +1 -0
  10. package/dist/checker.js +177 -0
  11. package/dist/checker.js.map +1 -0
  12. package/dist/cli.d.ts +149 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +1049 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/copy-gate.d.ts +107 -0
  17. package/dist/copy-gate.d.ts.map +1 -0
  18. package/dist/copy-gate.js +132 -0
  19. package/dist/copy-gate.js.map +1 -0
  20. package/dist/fingerprint.d.ts +61 -0
  21. package/dist/fingerprint.d.ts.map +1 -0
  22. package/dist/fingerprint.js +64 -0
  23. package/dist/fingerprint.js.map +1 -0
  24. package/dist/index.d.ts +47 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +63 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/locale-coverage.d.ts +227 -0
  29. package/dist/locale-coverage.d.ts.map +1 -0
  30. package/dist/locale-coverage.js +414 -0
  31. package/dist/locale-coverage.js.map +1 -0
  32. package/dist/passage.d.ts +294 -0
  33. package/dist/passage.d.ts.map +1 -0
  34. package/dist/passage.js +463 -0
  35. package/dist/passage.js.map +1 -0
  36. package/dist/path-exclusions.d.ts +114 -0
  37. package/dist/path-exclusions.d.ts.map +1 -0
  38. package/dist/path-exclusions.js +213 -0
  39. package/dist/path-exclusions.js.map +1 -0
  40. package/dist/registry.d.ts +61 -0
  41. package/dist/registry.d.ts.map +1 -0
  42. package/dist/registry.js +64 -0
  43. package/dist/registry.js.map +1 -0
  44. package/dist/resolve.d.ts +33 -0
  45. package/dist/resolve.d.ts.map +1 -0
  46. package/dist/resolve.js +133 -0
  47. package/dist/resolve.js.map +1 -0
  48. package/dist/scan.d.ts +457 -0
  49. package/dist/scan.d.ts.map +1 -0
  50. package/dist/scan.js +1698 -0
  51. package/dist/scan.js.map +1 -0
  52. package/dist/schema.d.ts +81 -0
  53. package/dist/schema.d.ts.map +1 -0
  54. package/dist/schema.js +482 -0
  55. package/dist/schema.js.map +1 -0
  56. package/dist/types.d.ts +268 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +40 -0
  59. package/dist/types.js.map +1 -0
  60. package/dist/voice/checker.d.ts +186 -0
  61. package/dist/voice/checker.d.ts.map +1 -0
  62. package/dist/voice/checker.js +483 -0
  63. package/dist/voice/checker.js.map +1 -0
  64. package/dist/voice/derivation-coverage.d.ts +168 -0
  65. package/dist/voice/derivation-coverage.d.ts.map +1 -0
  66. package/dist/voice/derivation-coverage.js +181 -0
  67. package/dist/voice/derivation-coverage.js.map +1 -0
  68. package/dist/voice/fields.d.ts +107 -0
  69. package/dist/voice/fields.d.ts.map +1 -0
  70. package/dist/voice/fields.js +144 -0
  71. package/dist/voice/fields.js.map +1 -0
  72. package/dist/voice/index.d.ts +19 -0
  73. package/dist/voice/index.d.ts.map +1 -0
  74. package/dist/voice/index.js +24 -0
  75. package/dist/voice/index.js.map +1 -0
  76. package/dist/voice/internal/parse-template.d.ts +27 -0
  77. package/dist/voice/internal/parse-template.d.ts.map +1 -0
  78. package/dist/voice/internal/parse-template.js +111 -0
  79. package/dist/voice/internal/parse-template.js.map +1 -0
  80. package/dist/voice/internal/pattern-safety.d.ts +111 -0
  81. package/dist/voice/internal/pattern-safety.d.ts.map +1 -0
  82. package/dist/voice/internal/pattern-safety.js +278 -0
  83. package/dist/voice/internal/pattern-safety.js.map +1 -0
  84. package/dist/voice/schema.d.ts +65 -0
  85. package/dist/voice/schema.d.ts.map +1 -0
  86. package/dist/voice/schema.js +535 -0
  87. package/dist/voice/schema.js.map +1 -0
  88. package/dist/voice/types.d.ts +282 -0
  89. package/dist/voice/types.d.ts.map +1 -0
  90. package/dist/voice/types.js +37 -0
  91. package/dist/voice/types.js.map +1 -0
  92. package/package.json +72 -0
  93. package/src/addressability.ts +664 -0
  94. package/src/checker.ts +293 -0
  95. package/src/cli.ts +1166 -0
  96. package/src/copy-gate.ts +197 -0
  97. package/src/fingerprint.ts +66 -0
  98. package/src/index.ts +163 -0
  99. package/src/locale-coverage.ts +512 -0
  100. package/src/passage.ts +644 -0
  101. package/src/path-exclusions.ts +265 -0
  102. package/src/registry.ts +103 -0
  103. package/src/resolve.ts +172 -0
  104. package/src/scan.ts +1959 -0
  105. package/src/schema.ts +528 -0
  106. package/src/types.ts +301 -0
  107. package/src/voice/checker.ts +590 -0
  108. package/src/voice/derivation-coverage.ts +217 -0
  109. package/src/voice/fields.ts +160 -0
  110. package/src/voice/index.ts +55 -0
  111. package/src/voice/internal/parse-template.ts +114 -0
  112. package/src/voice/internal/pattern-safety.ts +336 -0
  113. package/src/voice/schema.ts +585 -0
  114. package/src/voice/types.ts +329 -0
  115. package/templates/voice-record.template.jsonc +135 -0
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Structural validation for a candidate `VoiceRecord`, in the same plain
3
+ * type-guard style as `@example/policy`'s `validate.ts` — no
4
+ * schema library. See `types.ts`'s doc comment for why: this package's
5
+ * entire job is dependency-free data validation, and a public package
6
+ * should not force every consumer onto one schema library's major version
7
+ * for the sake of shape-checking a handful of nested objects.
8
+ */
9
+ import type { VoiceFinding, VoiceRecord } from "./types.js";
10
+ /**
11
+ * Validates that `value` conforms to the `VoiceRecord` shape. Returns a
12
+ * `VoiceFinding[]`; empty means `value` is a well-formed `VoiceRecord`
13
+ * (once defaults are applied — see `parseVoiceRecord`). Never throws — any
14
+ * input, including `null`, a string, or a wildly malformed object,
15
+ * produces findings rather than an exception, the same discipline
16
+ * `@example/policy`'s `validateBindingShape` holds to.
17
+ *
18
+ * `glossary`, `claims`, and `patterns` (top level) and `forbiddenPronouns`/
19
+ * `forbiddenMarkers`/`tone`/`matchPhrases` (nested) may all be omitted —
20
+ * a default of `[]` applies to each in `parseVoiceRecord`. Omitting one is
21
+ * therefore not itself a finding; providing one of the wrong shape is.
22
+ *
23
+ * Every object this function (and its helpers) inspects has its fields
24
+ * read exactly once into local variables before any check runs, and only
25
+ * those locals are used from then on — mirroring
26
+ * `@example/policy`'s own `validateBindingShape`. Without this, a
27
+ * hostile `value` (a field implemented as a getter, or a Proxy) could
28
+ * return a different result on each property read, passing a check on one
29
+ * read and disagreeing with itself on the next.
30
+ */
31
+ export declare function validateVoiceRecordShape(value: unknown): VoiceFinding[];
32
+ /**
33
+ * Parses `value` as a `VoiceRecord`, throwing a plain `Error` (never a
34
+ * `VoiceFinding[]`) if it does not conform. For a caller that wants
35
+ * fail-fast construction — a config-loading step, say — rather than
36
+ * `validateVoiceRecordShape`'s "collect every problem and keep going"
37
+ * shape. The thrown message includes every issue `validateVoiceRecordShape`
38
+ * would have reported, joined, so nothing is lost by throwing instead of
39
+ * returning.
40
+ *
41
+ * Calls `validateVoiceRecordShape(value)` and, only if it reports zero
42
+ * findings, makes one further pass over `value` (`buildVoiceRecord`) to
43
+ * apply this schema's defaults (`glossary: []`, `claims: []`, `tone: []`,
44
+ * `forbiddenPronouns: []`, `forbiddenMarkers: []`, `matchPhrases: []`,
45
+ * `caseSensitive: false`, `requiresSupport: true` — and, ONLY if `value`
46
+ * declared a `patterns` array at all, `patterns` is carried through
47
+ * as-given; if `value` never declared `patterns`, the built record omits
48
+ * the field entirely rather than defaulting it to `[]`, so a caller reading
49
+ * `record.patterns === undefined` can still tell "never touched this
50
+ * feature" apart from "declared it, empty" — see `buildVoiceRecord`) and
51
+ * produce a fully
52
+ * populated `VoiceRecord`. This is a deliberate two-pass design, not an
53
+ * oversight: `@example/policy`'s own TOCTOU-safety comments (see
54
+ * `verifyBinding`) explain why reading the same object's fields twice can
55
+ * matter for a hostile `value` (a getter returning a different result on
56
+ * each read). That package's shape is flat enough to snapshot once and
57
+ * reuse for both validation and use; this package's is nested arrays of
58
+ * objects deep enough that a full single-pass snapshot-then-build would
59
+ * add real complexity for a caller-input-shape concern this package's
60
+ * actual threat model (a consumer's own in-memory config object, not a
61
+ * value crossing a real trust boundary) does not call for. Documented here
62
+ * rather than silently accepted.
63
+ */
64
+ export declare function parseVoiceRecord(value: unknown): VoiceRecord;
65
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/voice/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EASV,YAAY,EAEZ,WAAW,EAGZ,MAAM,YAAY,CAAC;AAoVpB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,EAAE,CAgEvE;AA6FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAS5D"}
@@ -0,0 +1,535 @@
1
+ /**
2
+ * Structural validation for a candidate `VoiceRecord`, in the same plain
3
+ * type-guard style as `@example/policy`'s `validate.ts` — no
4
+ * schema library. See `types.ts`'s doc comment for why: this package's
5
+ * entire job is dependency-free data validation, and a public package
6
+ * should not force every consumer onto one schema library's major version
7
+ * for the sake of shape-checking a handful of nested objects.
8
+ */
9
+ import { checkPatternSafety } from "./internal/pattern-safety.js";
10
+ import { FORMALITY_LEVELS, GLOSSARY_STATUSES, VOICE_SEVERITIES } from "./types.js";
11
+ function isPlainObject(value) {
12
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13
+ }
14
+ function isOneOf(value, list) {
15
+ return typeof value === "string" && list.includes(value);
16
+ }
17
+ function isNonEmptyString(value) {
18
+ return typeof value === "string" && value.length > 0;
19
+ }
20
+ /**
21
+ * Shape-only validation for an optional `VoiceChannel` field, shared by
22
+ * `validateGlossaryEntryShape` and `validatePatternRuleShape` — see
23
+ * `types.ts`'s `VoiceChannel` doc comment for why this package validates
24
+ * SHAPE only (a non-empty, non-whitespace-only string) and never a closed
25
+ * enum of "valid" channels, exactly mirroring how `registry-locale-shape`
26
+ * (the sibling `../schema.ts`, i.e. this package's root `CopyLocale`
27
+ * validation) treats `locale`.
28
+ */
29
+ function validateChannelShape(value, rule, path) {
30
+ if (value === undefined)
31
+ return [];
32
+ if (typeof value !== "string" || value.trim().length === 0) {
33
+ return [
34
+ {
35
+ rule,
36
+ severity: "error",
37
+ message: `${path} must be a non-empty string when present, got ${JSON.stringify(value)}.`,
38
+ path,
39
+ },
40
+ ];
41
+ }
42
+ return [];
43
+ }
44
+ /**
45
+ * Validates a field that is a list of words/phrases — `forbiddenPronouns`,
46
+ * `forbiddenMarkers`, `tone`, `matchPhrases`: every "plain string list"
47
+ * field in this schema shares this exact shape and this exact validation.
48
+ * `undefined` is valid here (a default of `[]` applies later, in
49
+ * `buildVoiceRecord`) — only a present-but-wrong-shaped value is a finding.
50
+ */
51
+ function validateStringListShape(value, rule, path) {
52
+ if (value === undefined)
53
+ return [];
54
+ if (!Array.isArray(value)) {
55
+ return [
56
+ {
57
+ rule,
58
+ severity: "error",
59
+ message: `${path} must be an array of non-empty strings when present, got ${JSON.stringify(value)}.`,
60
+ path,
61
+ },
62
+ ];
63
+ }
64
+ const findings = [];
65
+ value.forEach((item, i) => {
66
+ if (!isNonEmptyString(item)) {
67
+ findings.push({
68
+ rule,
69
+ severity: "error",
70
+ message: `${path}.${i} must be a non-empty string, got ${JSON.stringify(item)}.`,
71
+ path: `${path}.${i}`,
72
+ });
73
+ }
74
+ });
75
+ return findings;
76
+ }
77
+ // Rules: person-present, person-description-shape, person-forbidden-pronouns-shape
78
+ function validatePersonRuleShape(value, path) {
79
+ if (!isPlainObject(value)) {
80
+ return [{ rule: "person-present", severity: "error", message: `${path} must be an object.`, path }];
81
+ }
82
+ // Snapshot every field this function reads, exactly once, before any
83
+ // check runs — see validateVoiceRecordShape's own doc comment for why.
84
+ const description = value.description;
85
+ const forbiddenPronouns = value.forbiddenPronouns;
86
+ const findings = [];
87
+ if (!isNonEmptyString(description)) {
88
+ findings.push({
89
+ rule: "person-description-shape",
90
+ severity: "error",
91
+ message: `${path}.description must be a non-empty string, got ${JSON.stringify(description)}.`,
92
+ path: `${path}.description`,
93
+ });
94
+ }
95
+ findings.push(...validateStringListShape(forbiddenPronouns, "person-forbidden-pronouns-shape", `${path}.forbiddenPronouns`));
96
+ return findings;
97
+ }
98
+ // Rules: tense-present, tense-description-shape, tense-forbidden-markers-shape
99
+ function validateTenseRuleShape(value, path) {
100
+ if (!isPlainObject(value)) {
101
+ return [{ rule: "tense-present", severity: "error", message: `${path} must be an object.`, path }];
102
+ }
103
+ const description = value.description;
104
+ const forbiddenMarkers = value.forbiddenMarkers;
105
+ const findings = [];
106
+ if (!isNonEmptyString(description)) {
107
+ findings.push({
108
+ rule: "tense-description-shape",
109
+ severity: "error",
110
+ message: `${path}.description must be a non-empty string, got ${JSON.stringify(description)}.`,
111
+ path: `${path}.description`,
112
+ });
113
+ }
114
+ findings.push(...validateStringListShape(forbiddenMarkers, "tense-forbidden-markers-shape", `${path}.forbiddenMarkers`));
115
+ return findings;
116
+ }
117
+ // Rules: rules-present, formality-shape, tone-shape (+ person-*, tense-* above)
118
+ function validateVoiceRulesShape(value, path) {
119
+ if (!isPlainObject(value)) {
120
+ return [{ rule: "rules-present", severity: "error", message: `${path} must be an object.`, path }];
121
+ }
122
+ const person = value.person;
123
+ const tense = value.tense;
124
+ const formality = value.formality;
125
+ const tone = value.tone;
126
+ const findings = [];
127
+ findings.push(...validatePersonRuleShape(person, `${path}.person`));
128
+ findings.push(...validateTenseRuleShape(tense, `${path}.tense`));
129
+ if (!isOneOf(formality, FORMALITY_LEVELS)) {
130
+ findings.push({
131
+ rule: "formality-shape",
132
+ severity: "error",
133
+ message: `${path}.formality must be one of ${FORMALITY_LEVELS.join(", ")}, got ${JSON.stringify(formality)}.`,
134
+ path: `${path}.formality`,
135
+ });
136
+ }
137
+ findings.push(...validateStringListShape(tone, "tone-shape", `${path}.tone`));
138
+ return findings;
139
+ }
140
+ // Rules: glossary-entry-shape, glossary-term-shape, glossary-status-shape,
141
+ // glossary-reason-shape, glossary-alternative-shape, glossary-case-sensitive-shape,
142
+ // glossary-channel-shape
143
+ function validateGlossaryEntryShape(value, path) {
144
+ if (!isPlainObject(value)) {
145
+ return [{ rule: "glossary-entry-shape", severity: "error", message: `${path} must be an object.`, path }];
146
+ }
147
+ const term = value.term;
148
+ const status = value.status;
149
+ const reason = value.reason;
150
+ const alternative = value.alternative;
151
+ const caseSensitive = value.caseSensitive;
152
+ const channel = value.channel;
153
+ const findings = [];
154
+ if (!isNonEmptyString(term)) {
155
+ findings.push({
156
+ rule: "glossary-term-shape",
157
+ severity: "error",
158
+ message: `${path}.term must be a non-empty string, got ${JSON.stringify(term)}.`,
159
+ path: `${path}.term`,
160
+ });
161
+ }
162
+ if (!isOneOf(status, GLOSSARY_STATUSES)) {
163
+ findings.push({
164
+ rule: "glossary-status-shape",
165
+ severity: "error",
166
+ message: `${path}.status must be one of ${GLOSSARY_STATUSES.join(", ")}, got ${JSON.stringify(status)}.`,
167
+ path: `${path}.status`,
168
+ });
169
+ }
170
+ if (!isNonEmptyString(reason)) {
171
+ findings.push({
172
+ rule: "glossary-reason-shape",
173
+ severity: "error",
174
+ message: `${path}.reason must be a non-empty string, got ${JSON.stringify(reason)}.`,
175
+ path: `${path}.reason`,
176
+ });
177
+ }
178
+ if (alternative !== undefined && !isNonEmptyString(alternative)) {
179
+ findings.push({
180
+ rule: "glossary-alternative-shape",
181
+ severity: "error",
182
+ message: `${path}.alternative must be a non-empty string when present, got ${JSON.stringify(alternative)}.`,
183
+ path: `${path}.alternative`,
184
+ });
185
+ }
186
+ if (caseSensitive !== undefined && typeof caseSensitive !== "boolean") {
187
+ findings.push({
188
+ rule: "glossary-case-sensitive-shape",
189
+ severity: "error",
190
+ message: `${path}.caseSensitive must be a boolean when present, got ${JSON.stringify(caseSensitive)}.`,
191
+ path: `${path}.caseSensitive`,
192
+ });
193
+ }
194
+ findings.push(...validateChannelShape(channel, "glossary-channel-shape", `${path}.channel`));
195
+ return findings;
196
+ }
197
+ // Rules: pattern-rule-shape, pattern-id-shape, pattern-description-shape,
198
+ // pattern-shape (pattern.source/pattern.flags, via checkPatternSafety —
199
+ // see internal/pattern-safety.ts), pattern-severity-shape,
200
+ // pattern-reason-shape, pattern-alternative-shape, pattern-channel-shape
201
+ function validatePatternRuleShape(value, path) {
202
+ if (!isPlainObject(value)) {
203
+ return [{ rule: "pattern-rule-shape", severity: "error", message: `${path} must be an object.`, path }];
204
+ }
205
+ const id = value.id;
206
+ const description = value.description;
207
+ const pattern = value.pattern;
208
+ const severity = value.severity;
209
+ const reason = value.reason;
210
+ const alternative = value.alternative;
211
+ const channel = value.channel;
212
+ const findings = [];
213
+ if (!isNonEmptyString(id)) {
214
+ findings.push({
215
+ rule: "pattern-id-shape",
216
+ severity: "error",
217
+ message: `${path}.id must be a non-empty string, got ${JSON.stringify(id)}.`,
218
+ path: `${path}.id`,
219
+ });
220
+ }
221
+ if (!isNonEmptyString(description)) {
222
+ findings.push({
223
+ rule: "pattern-description-shape",
224
+ severity: "error",
225
+ message: `${path}.description must be a non-empty string, got ${JSON.stringify(description)}.`,
226
+ path: `${path}.description`,
227
+ });
228
+ }
229
+ // The real safety gate — see internal/pattern-safety.ts's top doc comment
230
+ // for exactly what this rejects and why. A pattern that fails here is a
231
+ // real, unmissable finding: this is this file's mechanical enforcement of
232
+ // the core rule stated in types.ts's own header comment — a check that
233
+ // cannot run must fail, not pass, never a silently dropped rule.
234
+ if (!isPlainObject(pattern)) {
235
+ findings.push({
236
+ rule: "pattern-shape",
237
+ severity: "error",
238
+ message: `${path}.pattern must be an object with a "source" string (and optional "flags"), got ${JSON.stringify(pattern)}.`,
239
+ path: `${path}.pattern`,
240
+ });
241
+ }
242
+ else {
243
+ const safety = checkPatternSafety(pattern);
244
+ if (!safety.ok) {
245
+ findings.push({
246
+ rule: `pattern-shape:${safety.issue}`,
247
+ severity: "error",
248
+ message: `${path}.pattern is invalid or unsafe (${safety.issue}): ${safety.detail}`,
249
+ path: `${path}.pattern`,
250
+ });
251
+ }
252
+ }
253
+ if (!isOneOf(severity, VOICE_SEVERITIES)) {
254
+ findings.push({
255
+ rule: "pattern-severity-shape",
256
+ severity: "error",
257
+ message: `${path}.severity must be one of ${VOICE_SEVERITIES.join(", ")}, got ${JSON.stringify(severity)}.`,
258
+ path: `${path}.severity`,
259
+ });
260
+ }
261
+ if (!isNonEmptyString(reason)) {
262
+ findings.push({
263
+ rule: "pattern-reason-shape",
264
+ severity: "error",
265
+ message: `${path}.reason must be a non-empty string, got ${JSON.stringify(reason)}.`,
266
+ path: `${path}.reason`,
267
+ });
268
+ }
269
+ if (alternative !== undefined && !isNonEmptyString(alternative)) {
270
+ findings.push({
271
+ rule: "pattern-alternative-shape",
272
+ severity: "error",
273
+ message: `${path}.alternative must be a non-empty string when present, got ${JSON.stringify(alternative)}.`,
274
+ path: `${path}.alternative`,
275
+ });
276
+ }
277
+ findings.push(...validateChannelShape(channel, "pattern-channel-shape", `${path}.channel`));
278
+ return findings;
279
+ }
280
+ // Rules: claim-entry-shape, claim-id-shape, claim-text-shape,
281
+ // claim-match-phrases-shape, claim-fact-ref-shape, claim-requires-support-shape
282
+ function validateClaimShape(value, path) {
283
+ if (!isPlainObject(value)) {
284
+ return [{ rule: "claim-entry-shape", severity: "error", message: `${path} must be an object.`, path }];
285
+ }
286
+ const id = value.id;
287
+ const text = value.text;
288
+ const matchPhrases = value.matchPhrases;
289
+ const factRef = value.factRef;
290
+ const requiresSupport = value.requiresSupport;
291
+ const findings = [];
292
+ if (!isNonEmptyString(id)) {
293
+ findings.push({
294
+ rule: "claim-id-shape",
295
+ severity: "error",
296
+ message: `${path}.id must be a non-empty string, got ${JSON.stringify(id)}.`,
297
+ path: `${path}.id`,
298
+ });
299
+ }
300
+ if (!isNonEmptyString(text)) {
301
+ findings.push({
302
+ rule: "claim-text-shape",
303
+ severity: "error",
304
+ message: `${path}.text must be a non-empty string, got ${JSON.stringify(text)}.`,
305
+ path: `${path}.text`,
306
+ });
307
+ }
308
+ findings.push(...validateStringListShape(matchPhrases, "claim-match-phrases-shape", `${path}.matchPhrases`));
309
+ if (factRef !== undefined && !isNonEmptyString(factRef)) {
310
+ findings.push({
311
+ rule: "claim-fact-ref-shape",
312
+ severity: "error",
313
+ message: `${path}.factRef must be a non-empty string when present, got ${JSON.stringify(factRef)}.`,
314
+ path: `${path}.factRef`,
315
+ });
316
+ }
317
+ if (requiresSupport !== undefined && typeof requiresSupport !== "boolean") {
318
+ findings.push({
319
+ rule: "claim-requires-support-shape",
320
+ severity: "error",
321
+ message: `${path}.requiresSupport must be a boolean when present, got ${JSON.stringify(requiresSupport)}.`,
322
+ path: `${path}.requiresSupport`,
323
+ });
324
+ }
325
+ return findings;
326
+ }
327
+ /**
328
+ * Validates that `value` conforms to the `VoiceRecord` shape. Returns a
329
+ * `VoiceFinding[]`; empty means `value` is a well-formed `VoiceRecord`
330
+ * (once defaults are applied — see `parseVoiceRecord`). Never throws — any
331
+ * input, including `null`, a string, or a wildly malformed object,
332
+ * produces findings rather than an exception, the same discipline
333
+ * `@example/policy`'s `validateBindingShape` holds to.
334
+ *
335
+ * `glossary`, `claims`, and `patterns` (top level) and `forbiddenPronouns`/
336
+ * `forbiddenMarkers`/`tone`/`matchPhrases` (nested) may all be omitted —
337
+ * a default of `[]` applies to each in `parseVoiceRecord`. Omitting one is
338
+ * therefore not itself a finding; providing one of the wrong shape is.
339
+ *
340
+ * Every object this function (and its helpers) inspects has its fields
341
+ * read exactly once into local variables before any check runs, and only
342
+ * those locals are used from then on — mirroring
343
+ * `@example/policy`'s own `validateBindingShape`. Without this, a
344
+ * hostile `value` (a field implemented as a getter, or a Proxy) could
345
+ * return a different result on each property read, passing a check on one
346
+ * read and disagreeing with itself on the next.
347
+ */
348
+ export function validateVoiceRecordShape(value) {
349
+ if (!isPlainObject(value)) {
350
+ return [{ rule: "record-present", severity: "error", message: "A voice record must be an object.", path: "$" }];
351
+ }
352
+ const id = value.id;
353
+ const rules = value.rules;
354
+ const glossary = value.glossary;
355
+ const claims = value.claims;
356
+ const patterns = value.patterns;
357
+ const findings = [];
358
+ if (!isNonEmptyString(id)) {
359
+ findings.push({
360
+ rule: "id-shape",
361
+ severity: "error",
362
+ message: `id must be a non-empty string, got ${JSON.stringify(id)}.`,
363
+ path: "id",
364
+ });
365
+ }
366
+ findings.push(...validateVoiceRulesShape(rules, "rules"));
367
+ if (glossary !== undefined) {
368
+ if (!Array.isArray(glossary)) {
369
+ findings.push({
370
+ rule: "glossary-shape",
371
+ severity: "error",
372
+ message: `glossary must be an array when present, got ${JSON.stringify(glossary)}.`,
373
+ path: "glossary",
374
+ });
375
+ }
376
+ else {
377
+ glossary.forEach((entry, i) => findings.push(...validateGlossaryEntryShape(entry, `glossary.${i}`)));
378
+ }
379
+ }
380
+ if (claims !== undefined) {
381
+ if (!Array.isArray(claims)) {
382
+ findings.push({
383
+ rule: "claims-shape",
384
+ severity: "error",
385
+ message: `claims must be an array when present, got ${JSON.stringify(claims)}.`,
386
+ path: "claims",
387
+ });
388
+ }
389
+ else {
390
+ claims.forEach((entry, i) => findings.push(...validateClaimShape(entry, `claims.${i}`)));
391
+ }
392
+ }
393
+ if (patterns !== undefined) {
394
+ if (!Array.isArray(patterns)) {
395
+ findings.push({
396
+ rule: "patterns-shape",
397
+ severity: "error",
398
+ message: `patterns must be an array when present, got ${JSON.stringify(patterns)}.`,
399
+ path: "patterns",
400
+ });
401
+ }
402
+ else {
403
+ patterns.forEach((entry, i) => findings.push(...validatePatternRuleShape(entry, `patterns.${i}`)));
404
+ }
405
+ }
406
+ return findings;
407
+ }
408
+ /**
409
+ * Builds a fully-defaulted `VoiceRecord` from `value`, which the caller
410
+ * must already know passed `validateVoiceRecordShape` with zero findings —
411
+ * this function does no validation of its own and will throw or produce
412
+ * garbage on unvalidated input. Only called internally, from
413
+ * `parseVoiceRecord`, immediately after that check.
414
+ */
415
+ function buildVoiceRecord(value) {
416
+ const rules = value.rules;
417
+ const person = rules.person;
418
+ const tense = rules.tense;
419
+ const glossaryRaw = value.glossary ?? [];
420
+ const claimsRaw = value.claims ?? [];
421
+ // Deliberately NOT `?? []` like glossary/claims above — see this file's
422
+ // `buildVoiceRecord` return statement and `types.ts`'s `VoiceRecord` doc
423
+ // comment for why `patterns` preserves the distinction between "never
424
+ // declared" (stays `undefined`, all the way through) and "declared,
425
+ // currently empty" (`[]`), a distinction glossary/claims do not need
426
+ // because they are required fields with no "never declared" state to
427
+ // preserve.
428
+ const patternsDeclared = value.patterns !== undefined;
429
+ const patternsRaw = value.patterns ?? [];
430
+ const builtRules = {
431
+ person: {
432
+ description: person.description,
433
+ forbiddenPronouns: [...(person.forbiddenPronouns ?? [])],
434
+ },
435
+ tense: {
436
+ description: tense.description,
437
+ forbiddenMarkers: [...(tense.forbiddenMarkers ?? [])],
438
+ },
439
+ formality: rules.formality,
440
+ tone: [...(rules.tone ?? [])],
441
+ };
442
+ const builtGlossary = glossaryRaw.map((raw) => {
443
+ const entry = raw;
444
+ return {
445
+ term: entry.term,
446
+ status: entry.status,
447
+ reason: entry.reason,
448
+ alternative: entry.alternative,
449
+ caseSensitive: entry.caseSensitive ?? false,
450
+ channel: entry.channel,
451
+ };
452
+ });
453
+ const builtClaims = claimsRaw.map((raw) => {
454
+ const entry = raw;
455
+ return {
456
+ id: entry.id,
457
+ text: entry.text,
458
+ matchPhrases: [...(entry.matchPhrases ?? [])],
459
+ factRef: entry.factRef,
460
+ requiresSupport: entry.requiresSupport ?? true,
461
+ };
462
+ });
463
+ const builtPatterns = patternsRaw.map((raw) => {
464
+ const entry = raw;
465
+ const pattern = entry.pattern;
466
+ return {
467
+ id: entry.id,
468
+ description: entry.description,
469
+ pattern: {
470
+ source: pattern.source,
471
+ flags: pattern.flags,
472
+ },
473
+ severity: entry.severity,
474
+ reason: entry.reason,
475
+ alternative: entry.alternative,
476
+ channel: entry.channel,
477
+ };
478
+ });
479
+ return {
480
+ id: value.id,
481
+ rules: builtRules,
482
+ glossary: builtGlossary,
483
+ claims: builtClaims,
484
+ // Present (as `builtPatterns`, possibly `[]`) only when the input
485
+ // actually declared `patterns` — omitted entirely otherwise, so
486
+ // `record.patterns` stays `undefined` for a `VoiceRecord` built from
487
+ // input that never touched this feature, exactly matching a
488
+ // hand-written literal that omits the field. See the comment on
489
+ // `patternsDeclared` above.
490
+ ...(patternsDeclared ? { patterns: builtPatterns } : {}),
491
+ };
492
+ }
493
+ /**
494
+ * Parses `value` as a `VoiceRecord`, throwing a plain `Error` (never a
495
+ * `VoiceFinding[]`) if it does not conform. For a caller that wants
496
+ * fail-fast construction — a config-loading step, say — rather than
497
+ * `validateVoiceRecordShape`'s "collect every problem and keep going"
498
+ * shape. The thrown message includes every issue `validateVoiceRecordShape`
499
+ * would have reported, joined, so nothing is lost by throwing instead of
500
+ * returning.
501
+ *
502
+ * Calls `validateVoiceRecordShape(value)` and, only if it reports zero
503
+ * findings, makes one further pass over `value` (`buildVoiceRecord`) to
504
+ * apply this schema's defaults (`glossary: []`, `claims: []`, `tone: []`,
505
+ * `forbiddenPronouns: []`, `forbiddenMarkers: []`, `matchPhrases: []`,
506
+ * `caseSensitive: false`, `requiresSupport: true` — and, ONLY if `value`
507
+ * declared a `patterns` array at all, `patterns` is carried through
508
+ * as-given; if `value` never declared `patterns`, the built record omits
509
+ * the field entirely rather than defaulting it to `[]`, so a caller reading
510
+ * `record.patterns === undefined` can still tell "never touched this
511
+ * feature" apart from "declared it, empty" — see `buildVoiceRecord`) and
512
+ * produce a fully
513
+ * populated `VoiceRecord`. This is a deliberate two-pass design, not an
514
+ * oversight: `@example/policy`'s own TOCTOU-safety comments (see
515
+ * `verifyBinding`) explain why reading the same object's fields twice can
516
+ * matter for a hostile `value` (a getter returning a different result on
517
+ * each read). That package's shape is flat enough to snapshot once and
518
+ * reuse for both validation and use; this package's is nested arrays of
519
+ * objects deep enough that a full single-pass snapshot-then-build would
520
+ * add real complexity for a caller-input-shape concern this package's
521
+ * actual threat model (a consumer's own in-memory config object, not a
522
+ * value crossing a real trust boundary) does not call for. Documented here
523
+ * rather than silently accepted.
524
+ */
525
+ export function parseVoiceRecord(value) {
526
+ const findings = validateVoiceRecordShape(value);
527
+ if (findings.length > 0) {
528
+ const detail = findings.map((f) => ` - ${f.path ?? "(root)"}: ${f.message}`).join("\n");
529
+ throw new Error(`parseVoiceRecord: value is not a valid VoiceRecord:\n${detail}`);
530
+ }
531
+ // Safe: validateVoiceRecordShape returning no findings means every field
532
+ // buildVoiceRecord reads below is present and correctly typed.
533
+ return buildVoiceRecord(value);
534
+ }
535
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/voice/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAiBnF,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,OAAO,CAAmB,KAAc,EAAE,IAAkB;IACnE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,IAA0B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,oBAAoB,CAAC,KAAc,EAAE,IAAY,EAAE,IAAY;IACtE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,OAAO;YACL;gBACE,IAAI;gBACJ,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,GAAG,IAAI,iDAAiD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG;gBACzF,IAAI;aACL;SACF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,uBAAuB,CAAC,KAAc,EAAE,IAAY,EAAE,IAAY;IACzE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL;gBACE,IAAI;gBACJ,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,GAAG,IAAI,4DAA4D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG;gBACpG,IAAI;aACL;SACF,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACxB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,oCAAoC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;gBAChF,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,mFAAmF;AACnF,SAAS,uBAAuB,CAAC,KAAc,EAAE,IAAY;IAC3D,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC;IACtG,CAAC;IACD,qEAAqE;IACrE,uEAAuE;IACvE,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACtC,MAAM,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC;IAElD,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;QACnC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,0BAA0B;YAChC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,gDAAgD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG;YAC9F,IAAI,EAAE,GAAG,IAAI,cAAc;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,IAAI,CACX,GAAG,uBAAuB,CAAC,iBAAiB,EAAE,iCAAiC,EAAE,GAAG,IAAI,oBAAoB,CAAC,CAC9G,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,+EAA+E;AAC/E,SAAS,sBAAsB,CAAC,KAAc,EAAE,IAAY;IAC1D,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACtC,MAAM,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAEhD,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;QACnC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,yBAAyB;YAC/B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,gDAAgD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG;YAC9F,IAAI,EAAE,GAAG,IAAI,cAAc;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,IAAI,CACX,GAAG,uBAAuB,CAAC,gBAAgB,EAAE,+BAA+B,EAAE,GAAG,IAAI,mBAAmB,CAAC,CAC1G,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,gFAAgF;AAChF,SAAS,uBAAuB,CAAC,KAAc,EAAE,IAAY;IAC3D,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IAExB,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC;IACpE,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,KAAK,EAAE,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,gBAAgB,CAAC,EAAE,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,6BAA6B,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG;YAC7G,IAAI,EAAE,GAAG,IAAI,YAAY;SAC1B,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IAC9E,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,2EAA2E;AAC3E,oFAAoF;AACpF,yBAAyB;AACzB,SAAS,0BAA0B,CAAC,KAAc,EAAE,IAAY;IAC9D,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5G,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACtC,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAE9B,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,qBAAqB;YAC3B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,yCAAyC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;YAChF,IAAI,EAAE,GAAG,IAAI,OAAO;SACrB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,uBAAuB;YAC7B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,0BAA0B,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG;YACxG,IAAI,EAAE,GAAG,IAAI,SAAS;SACvB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,uBAAuB;YAC7B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,2CAA2C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG;YACpF,IAAI,EAAE,GAAG,IAAI,SAAS;SACvB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,WAAW,KAAK,SAAS,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;QAChE,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,4BAA4B;YAClC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,6DAA6D,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG;YAC3G,IAAI,EAAE,GAAG,IAAI,cAAc;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,IAAI,aAAa,KAAK,SAAS,IAAI,OAAO,aAAa,KAAK,SAAS,EAAE,CAAC;QACtE,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,+BAA+B;YACrC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,sDAAsD,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG;YACtG,IAAI,EAAE,GAAG,IAAI,gBAAgB;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,OAAO,EAAE,wBAAwB,EAAE,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC;IAC7F,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,0EAA0E;AAC1E,wEAAwE;AACxE,2DAA2D;AAC3D,yEAAyE;AACzE,SAAS,wBAAwB,CAAC,KAAc,EAAE,IAAY;IAC5D,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1G,CAAC;IACD,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpB,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAE9B,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,kBAAkB;YACxB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,uCAAuC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG;YAC5E,IAAI,EAAE,GAAG,IAAI,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;QACnC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,2BAA2B;YACjC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,gDAAgD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG;YAC9F,IAAI,EAAE,GAAG,IAAI,cAAc;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,0EAA0E;IAC1E,wEAAwE;IACxE,0EAA0E;IAC1E,uEAAuE;IACvE,iEAAiE;IACjE,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,iFAAiF,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG;YAC3H,IAAI,EAAE,GAAG,IAAI,UAAU;SACxB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAgD,CAAC,CAAC;QACpF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,iBAAiB,MAAM,CAAC,KAAK,EAAE;gBACrC,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,GAAG,IAAI,kCAAkC,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,MAAM,EAAE;gBACnF,IAAI,EAAE,GAAG,IAAI,UAAU;aACxB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,CAAC;QACzC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,wBAAwB;YAC9B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,4BAA4B,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG;YAC3G,IAAI,EAAE,GAAG,IAAI,WAAW;SACzB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,sBAAsB;YAC5B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,2CAA2C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG;YACpF,IAAI,EAAE,GAAG,IAAI,SAAS;SACvB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,WAAW,KAAK,SAAS,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;QAChE,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,2BAA2B;YACjC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,6DAA6D,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG;YAC3G,IAAI,EAAE,GAAG,IAAI,cAAc;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,EAAE,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC;IAE5F,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,8DAA8D;AAC9D,gFAAgF;AAChF,SAAS,kBAAkB,CAAC,KAAc,EAAE,IAAY;IACtD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC;IACzG,CAAC;IACD,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC;IAE9C,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,gBAAgB;YACtB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,uCAAuC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG;YAC5E,IAAI,EAAE,GAAG,IAAI,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,kBAAkB;YACxB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,yCAAyC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;YAChF,IAAI,EAAE,GAAG,IAAI,OAAO;SACrB,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,YAAY,EAAE,2BAA2B,EAAE,GAAG,IAAI,eAAe,CAAC,CAAC,CAAC;IAC7G,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,sBAAsB;YAC5B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,yDAAyD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG;YACnG,IAAI,EAAE,GAAG,IAAI,UAAU;SACxB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,eAAe,KAAK,SAAS,IAAI,OAAO,eAAe,KAAK,SAAS,EAAE,CAAC;QAC1E,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,8BAA8B;YACpC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,IAAI,wDAAwD,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG;YAC1G,IAAI,EAAE,GAAG,IAAI,kBAAkB;SAChC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,mCAAmC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IAClH,CAAC;IAED,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAEhC,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,sCAAsC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG;YACpE,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAE1D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,+CAA+C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG;gBACnF,IAAI,EAAE,UAAU;aACjB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,0BAA0B,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvG,CAAC;IACH,CAAC;IAED,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,cAAc;gBACpB,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,6CAA6C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG;gBAC/E,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,+CAA+C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG;gBACnF,IAAI,EAAE,UAAU;aACjB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrG,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,KAA8B;IACtD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAgC,CAAC;IACrD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAiC,CAAC;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAgC,CAAC;IACrD,MAAM,WAAW,GAAI,KAAK,CAAC,QAAkC,IAAI,EAAE,CAAC;IACpE,MAAM,SAAS,GAAI,KAAK,CAAC,MAAgC,IAAI,EAAE,CAAC;IAChE,wEAAwE;IACxE,yEAAyE;IACzE,sEAAsE;IACtE,oEAAoE;IACpE,qEAAqE;IACrE,qEAAqE;IACrE,YAAY;IACZ,MAAM,gBAAgB,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC;IACtD,MAAM,WAAW,GAAI,KAAK,CAAC,QAAkC,IAAI,EAAE,CAAC;IAEpE,MAAM,UAAU,GAAe;QAC7B,MAAM,EAAE;YACN,WAAW,EAAE,MAAM,CAAC,WAAqB;YACzC,iBAAiB,EAAE,CAAC,GAAG,CAAE,MAAM,CAAC,iBAA0C,IAAI,EAAE,CAAC,CAAC;SAC9D;QACtB,KAAK,EAAE;YACL,WAAW,EAAE,KAAK,CAAC,WAAqB;YACxC,gBAAgB,EAAE,CAAC,GAAG,CAAE,KAAK,CAAC,gBAAyC,IAAI,EAAE,CAAC,CAAC;SAC5D;QACrB,SAAS,EAAE,KAAK,CAAC,SAA2B;QAC5C,IAAI,EAAE,CAAC,GAAG,CAAE,KAAK,CAAC,IAA6B,IAAI,EAAE,CAAC,CAAC;KACxD,CAAC;IAEF,MAAM,aAAa,GAAoB,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7D,MAAM,KAAK,GAAG,GAA8B,CAAC;QAC7C,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAc;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAwB;YACtC,MAAM,EAAE,KAAK,CAAC,MAAgB;YAC9B,WAAW,EAAE,KAAK,CAAC,WAAiC;YACpD,aAAa,EAAG,KAAK,CAAC,aAAqC,IAAI,KAAK;YACpE,OAAO,EAAE,KAAK,CAAC,OAAmC;SACnD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAY,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACjD,MAAM,KAAK,GAAG,GAA8B,CAAC;QAC7C,OAAO;YACL,EAAE,EAAE,KAAK,CAAC,EAAY;YACtB,IAAI,EAAE,KAAK,CAAC,IAAc;YAC1B,YAAY,EAAE,CAAC,GAAG,CAAE,KAAK,CAAC,YAAqC,IAAI,EAAE,CAAC,CAAC;YACvE,OAAO,EAAE,KAAK,CAAC,OAA6B;YAC5C,eAAe,EAAG,KAAK,CAAC,eAAuC,IAAI,IAAI;SACxE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAkB,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3D,MAAM,KAAK,GAAG,GAA8B,CAAC;QAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAkC,CAAC;QACzD,OAAO;YACL,EAAE,EAAE,KAAK,CAAC,EAAY;YACtB,WAAW,EAAE,KAAK,CAAC,WAAqB;YACxC,OAAO,EAAE;gBACP,MAAM,EAAE,OAAO,CAAC,MAAgB;gBAChC,KAAK,EAAE,OAAO,CAAC,KAA2B;aACpB;YACxB,QAAQ,EAAE,KAAK,CAAC,QAAyB;YACzC,MAAM,EAAE,KAAK,CAAC,MAAgB;YAC9B,WAAW,EAAE,KAAK,CAAC,WAAiC;YACpD,OAAO,EAAE,KAAK,CAAC,OAAmC;SACnD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAY;QACtB,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE,aAAa;QACvB,MAAM,EAAE,WAAW;QACnB,kEAAkE;QAClE,gEAAgE;QAChE,qEAAqE;QACrE,4DAA4D;QAC5D,gEAAgE;QAChE,4BAA4B;QAC5B,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,MAAM,QAAQ,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzF,MAAM,IAAI,KAAK,CAAC,wDAAwD,MAAM,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,yEAAyE;IACzE,+DAA+D;IAC/D,OAAO,gBAAgB,CAAC,KAAgC,CAAC,CAAC;AAC5D,CAAC"}