@openauditmodel/cli 0.1.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.
Files changed (134) hide show
  1. package/LICENSE +215 -0
  2. package/README.md +647 -0
  3. package/dist/conformance/src/cli.d.ts +20 -0
  4. package/dist/conformance/src/cli.js +560 -0
  5. package/dist/conformance/src/cli.js.map +1 -0
  6. package/dist/conformance/src/format-errors.d.ts +20 -0
  7. package/dist/conformance/src/format-errors.js +116 -0
  8. package/dist/conformance/src/format-errors.js.map +1 -0
  9. package/dist/conformance/src/integrity/canonicalize.d.ts +25 -0
  10. package/dist/conformance/src/integrity/canonicalize.js +100 -0
  11. package/dist/conformance/src/integrity/canonicalize.js.map +1 -0
  12. package/dist/conformance/src/integrity/digest.d.ts +54 -0
  13. package/dist/conformance/src/integrity/digest.js +126 -0
  14. package/dist/conformance/src/integrity/digest.js.map +1 -0
  15. package/dist/conformance/src/integrity/types.d.ts +86 -0
  16. package/dist/conformance/src/integrity/types.js +36 -0
  17. package/dist/conformance/src/integrity/types.js.map +1 -0
  18. package/dist/conformance/src/integrity/verify-chain.d.ts +23 -0
  19. package/dist/conformance/src/integrity/verify-chain.js +235 -0
  20. package/dist/conformance/src/integrity/verify-chain.js.map +1 -0
  21. package/dist/conformance/src/integrity/verify-event.d.ts +29 -0
  22. package/dist/conformance/src/integrity/verify-event.js +140 -0
  23. package/dist/conformance/src/integrity/verify-event.js.map +1 -0
  24. package/dist/conformance/src/privacy/entropy.d.ts +14 -0
  25. package/dist/conformance/src/privacy/entropy.js +86 -0
  26. package/dist/conformance/src/privacy/entropy.js.map +1 -0
  27. package/dist/conformance/src/privacy/field-names.d.ts +36 -0
  28. package/dist/conformance/src/privacy/field-names.js +121 -0
  29. package/dist/conformance/src/privacy/field-names.js.map +1 -0
  30. package/dist/conformance/src/privacy/lint-event.d.ts +18 -0
  31. package/dist/conformance/src/privacy/lint-event.js +272 -0
  32. package/dist/conformance/src/privacy/lint-event.js.map +1 -0
  33. package/dist/conformance/src/privacy/rules.d.ts +44 -0
  34. package/dist/conformance/src/privacy/rules.js +161 -0
  35. package/dist/conformance/src/privacy/rules.js.map +1 -0
  36. package/dist/conformance/src/privacy/safe-formats.d.ts +32 -0
  37. package/dist/conformance/src/privacy/safe-formats.js +118 -0
  38. package/dist/conformance/src/privacy/safe-formats.js.map +1 -0
  39. package/dist/conformance/src/privacy/size-analysis.d.ts +36 -0
  40. package/dist/conformance/src/privacy/size-analysis.js +87 -0
  41. package/dist/conformance/src/privacy/size-analysis.js.map +1 -0
  42. package/dist/conformance/src/privacy/token-patterns.d.ts +24 -0
  43. package/dist/conformance/src/privacy/token-patterns.js +126 -0
  44. package/dist/conformance/src/privacy/token-patterns.js.map +1 -0
  45. package/dist/conformance/src/privacy/traverse.d.ts +33 -0
  46. package/dist/conformance/src/privacy/traverse.js +61 -0
  47. package/dist/conformance/src/privacy/traverse.js.map +1 -0
  48. package/dist/conformance/src/privacy/types.d.ts +58 -0
  49. package/dist/conformance/src/privacy/types.js +32 -0
  50. package/dist/conformance/src/privacy/types.js.map +1 -0
  51. package/dist/conformance/src/privacy/url-analysis.d.ts +40 -0
  52. package/dist/conformance/src/privacy/url-analysis.js +148 -0
  53. package/dist/conformance/src/privacy/url-analysis.js.map +1 -0
  54. package/dist/conformance/src/profiles/check-profile.d.ts +22 -0
  55. package/dist/conformance/src/profiles/check-profile.js +72 -0
  56. package/dist/conformance/src/profiles/check-profile.js.map +1 -0
  57. package/dist/conformance/src/profiles/evaluate-rule.d.ts +27 -0
  58. package/dist/conformance/src/profiles/evaluate-rule.js +87 -0
  59. package/dist/conformance/src/profiles/evaluate-rule.js.map +1 -0
  60. package/dist/conformance/src/profiles/load-profile.d.ts +30 -0
  61. package/dist/conformance/src/profiles/load-profile.js +95 -0
  62. package/dist/conformance/src/profiles/load-profile.js.map +1 -0
  63. package/dist/conformance/src/profiles/resolve-pointer.d.ts +44 -0
  64. package/dist/conformance/src/profiles/resolve-pointer.js +123 -0
  65. package/dist/conformance/src/profiles/resolve-pointer.js.map +1 -0
  66. package/dist/conformance/src/profiles/select-rules.d.ts +13 -0
  67. package/dist/conformance/src/profiles/select-rules.js +42 -0
  68. package/dist/conformance/src/profiles/select-rules.js.map +1 -0
  69. package/dist/conformance/src/profiles/types.d.ts +101 -0
  70. package/dist/conformance/src/profiles/types.js +31 -0
  71. package/dist/conformance/src/profiles/types.js.map +1 -0
  72. package/dist/conformance/src/profiles/validate-profile-definition.d.ts +12 -0
  73. package/dist/conformance/src/profiles/validate-profile-definition.js +47 -0
  74. package/dist/conformance/src/profiles/validate-profile-definition.js.map +1 -0
  75. package/dist/conformance/src/sources.d.ts +53 -0
  76. package/dist/conformance/src/sources.js +153 -0
  77. package/dist/conformance/src/sources.js.map +1 -0
  78. package/dist/conformance/src/validate-core.d.ts +30 -0
  79. package/dist/conformance/src/validate-core.js +62 -0
  80. package/dist/conformance/src/validate-core.js.map +1 -0
  81. package/dist/conformance/src/validate.d.ts +34 -0
  82. package/dist/conformance/src/validate.js +62 -0
  83. package/dist/conformance/src/validate.js.map +1 -0
  84. package/dist/conformance/src/validator-interface.d.ts +35 -0
  85. package/dist/conformance/src/validator-interface.js +19 -0
  86. package/dist/conformance/src/validator-interface.js.map +1 -0
  87. package/package.json +85 -0
  88. package/profiles/README.md +201 -0
  89. package/profiles/api-and-integration-management/README.md +271 -0
  90. package/profiles/api-and-integration-management/profile.json +258 -0
  91. package/profiles/backup-and-recovery/README.md +318 -0
  92. package/profiles/backup-and-recovery/profile.json +178 -0
  93. package/profiles/customer-and-account-management/README.md +340 -0
  94. package/profiles/customer-and-account-management/profile.json +237 -0
  95. package/profiles/deployment-and-change-management/README.md +359 -0
  96. package/profiles/deployment-and-change-management/profile.json +298 -0
  97. package/profiles/document-management/README.md +120 -0
  98. package/profiles/document-management/profile.json +170 -0
  99. package/profiles/financial-transaction-management/README.md +339 -0
  100. package/profiles/financial-transaction-management/profile.json +247 -0
  101. package/profiles/identity-and-access-management/README.md +112 -0
  102. package/profiles/identity-and-access-management/profile.json +120 -0
  103. package/profiles/incident-management/README.md +338 -0
  104. package/profiles/incident-management/profile.json +256 -0
  105. package/profiles/message-broker-management/README.md +344 -0
  106. package/profiles/message-broker-management/profile.json +399 -0
  107. package/profiles/profile-definition.schema.json +213 -0
  108. package/profiles/secrets-and-key-management/README.md +331 -0
  109. package/profiles/secrets-and-key-management/profile.json +219 -0
  110. package/schemas/v0.1/audit-event.schema.json +911 -0
  111. package/semantic-conventions/README.md +52 -0
  112. package/semantic-conventions/authentication.md +111 -0
  113. package/semantic-conventions/configuration-and-change.md +122 -0
  114. package/semantic-conventions/correlation-and-tracing.md +387 -0
  115. package/semantic-conventions/data-access.md +115 -0
  116. package/semantic-conventions/event-naming.md +114 -0
  117. package/semantic-conventions/identity-and-access.md +112 -0
  118. package/semantic-conventions/privileged-operations.md +110 -0
  119. package/semantic-conventions/workflow-and-approval.md +109 -0
  120. package/specification/actor-model.md +135 -0
  121. package/specification/approval-and-delegation.md +150 -0
  122. package/specification/authentication.md +116 -0
  123. package/specification/authorization.md +117 -0
  124. package/specification/change-model.md +134 -0
  125. package/specification/delivery.md +136 -0
  126. package/specification/design-principles.md +137 -0
  127. package/specification/event-model.md +387 -0
  128. package/specification/evidence-model.md +109 -0
  129. package/specification/extension-model.md +159 -0
  130. package/specification/integrity.md +314 -0
  131. package/specification/overview.md +172 -0
  132. package/specification/privacy.md +386 -0
  133. package/specification/resource-model.md +116 -0
  134. package/specification/terminology.md +135 -0
@@ -0,0 +1,560 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `auditmodel` — the OpenAuditModel conformance command line interface.
4
+ *
5
+ * v0.1 implements three commands:
6
+ * validate check events against the canonical schema
7
+ * verify-integrity recalculate and compare each event's own digest
8
+ * verify-chain verify previous-hash chains across a set of events
9
+ *
10
+ * Exit codes:
11
+ * 0 a verdict was produced and it passed
12
+ * 1 a verdict was produced and it failed
13
+ * 2 the tool could not run: usage error, or a file could not be read or parsed
14
+ * 3 NO VERDICT was produced — nothing was evaluated
15
+ *
16
+ * 3 is the code that matters most, because it is the one that is easy to misread
17
+ * as success. `check-profile` returns it when no rule governs the event, and
18
+ * `lint-privacy` returns it when the input is not an audit event and was
19
+ * therefore never scanned. Neither is an approval of anything.
20
+ *
21
+ * The tooling is offline: it resolves no remote reference, fetches no evidence
22
+ * URL and executes nothing contained in an event.
23
+ */
24
+ import { readFileSync, realpathSync } from "node:fs";
25
+ import path from "node:path";
26
+ import { fileURLToPath } from "node:url";
27
+ import { parseArgs } from "node:util";
28
+ import { createValidator, SPEC_VERSION } from "./validate.js";
29
+ import { loadEventDocuments } from "./sources.js";
30
+ import { formatIssues } from "./format-errors.js";
31
+ import { verifyEventIntegrity } from "./integrity/verify-event.js";
32
+ import { verifyChains } from "./integrity/verify-chain.js";
33
+ import { lintEvent } from "./privacy/lint-event.js";
34
+ import { summarise } from "./privacy/types.js";
35
+ import { availableProfiles, loadProfile } from "./profiles/load-profile.js";
36
+ import { checkProfile } from "./profiles/check-profile.js";
37
+ import { summariseProfileResults } from "./profiles/types.js";
38
+ export const EXIT_OK = 0;
39
+ export const EXIT_INVALID = 1;
40
+ export const EXIT_ERROR = 2;
41
+ /**
42
+ * No verdict was produced for the input.
43
+ *
44
+ * `check-profile`: nothing checked was governed by the profile.
45
+ * `lint-privacy`: the input could not be evaluated as an audit event, so it was
46
+ * not scanned at all.
47
+ *
48
+ * Distinct from 0 in both cases for the same reason: a pipeline must not be able
49
+ * to read "the tool said nothing" as "the tool was satisfied". Distinct from 1
50
+ * because 1 means a real verdict was produced and it was negative, which is a
51
+ * different thing for an operator to act on.
52
+ */
53
+ export const EXIT_NO_VERDICT = 3;
54
+ /** Retained name for the `check-profile` reading of {@link EXIT_NO_VERDICT}. */
55
+ export const EXIT_NOT_APPLICABLE = EXIT_NO_VERDICT;
56
+ /** Commands that are specified as future work and deliberately not implemented in v0.1. */
57
+ const PLANNED_COMMANDS = new Set(["check-coverage"]);
58
+ const OUTPUT_FORMATS = new Set(["text", "json"]);
59
+ const USAGE = `auditmodel — OpenAuditModel conformance tooling (specification ${SPEC_VERSION}, experimental)
60
+
61
+ Usage:
62
+ auditmodel validate <path...> Validate events against the canonical schema
63
+ auditmodel verify-integrity <path...> Recalculate and compare each event's own digest
64
+ auditmodel verify-chain <path...> Verify previous-hash chains across a set of events
65
+ auditmodel lint-privacy <path...> Report suspected privacy and secret-exposure risks
66
+ auditmodel check-profile <path...> Check events against a domain profile
67
+ auditmodel --help Show this help
68
+ auditmodel --version Show the tool version
69
+
70
+ A path may be a JSON file holding one event, a JSON file holding an array of
71
+ events, a .jsonl or .ndjson file holding one event per line, or a directory of
72
+ those files.
73
+
74
+ Options:
75
+ -q, --quiet Only report failures
76
+ --format <text|json> Output format for lint-privacy and check-profile
77
+ --profile <name> Profile to check against (check-profile)
78
+
79
+ Exit codes:
80
+ 0 a verdict was produced and it passed
81
+ 1 a verdict was produced and it failed: invalid, unverified, a finding, or a
82
+ profile rule violation
83
+ 2 the tool could not run: usage error, or a file could not be read or parsed
84
+ 3 no verdict was produced, so nothing was approved:
85
+ check-profile no checked event is governed by the profile
86
+ lint-privacy the input is not an audit event and was NOT scanned
87
+
88
+ Verification is tamper-evident, not tamper-proof: it detects modification of the
89
+ events supplied to it. It cannot prove that events were never deleted, and it
90
+ makes no claim of immutability, legal weight or non-repudiation.
91
+
92
+ Privacy linting is deterministic local static analysis. It reports suspicions,
93
+ never proof: a finding does not confirm a credential, personal data or a breach,
94
+ and a clean result does not mean an event is safe or compliant. Findings never
95
+ contain the value that produced them.
96
+
97
+ A profile only ever adds requirements to the core model. Profile conformance is
98
+ not regulatory or legal compliance, and an event the profile does not govern is
99
+ reported as not-applicable rather than as conforming.
100
+
101
+ Planned commands (not implemented in v0.1):
102
+ check-coverage
103
+ `;
104
+ function toolVersion(schemaPath) {
105
+ // <root>/schemas/v0.1/audit-event.schema.json -> <root>/package.json
106
+ const root = path.dirname(path.dirname(path.dirname(schemaPath)));
107
+ try {
108
+ const manifest = JSON.parse(readFileSync(path.join(root, "package.json"), "utf8"));
109
+ return manifest.version ?? SPEC_VERSION;
110
+ }
111
+ catch {
112
+ return SPEC_VERSION;
113
+ }
114
+ }
115
+ function displayPath(file) {
116
+ return path.relative(process.cwd(), path.resolve(file)).split(path.sep).join("/") || file;
117
+ }
118
+ /** Report label for one event: its file, plus its position when the file holds several. */
119
+ function displayLabel(document) {
120
+ const base = displayPath(document.file);
121
+ return document.index === undefined ? base : `${base}#${document.index}`;
122
+ }
123
+ function write(text) {
124
+ process.stdout.write(text);
125
+ }
126
+ function writeFindings(findings, indent) {
127
+ for (const finding of findings) {
128
+ const where = finding.label === undefined ? "" : `${finding.label}: `;
129
+ write(`${indent}${where}${finding.message} [${finding.kind}]\n`);
130
+ for (const line of finding.detail ?? []) {
131
+ write(`${indent} ${line}\n`);
132
+ }
133
+ }
134
+ }
135
+ function writeProfileFindings(findings, indent) {
136
+ for (const finding of findings) {
137
+ write(`${indent}${finding.severity.toUpperCase()} ${finding.ruleId} ${finding.path}\n${indent} ${finding.message}\n`);
138
+ }
139
+ }
140
+ function writeChecks(checks, indent) {
141
+ for (const check of checks) {
142
+ write(`${indent}${check.message}\n`);
143
+ }
144
+ }
145
+ function writeNotes(notes, indent) {
146
+ for (const note of notes) {
147
+ write(`${indent}note: ${note.message}\n`);
148
+ for (const line of note.detail ?? []) {
149
+ write(`${indent} ${line}\n`);
150
+ }
151
+ }
152
+ }
153
+ /**
154
+ * Expands the given paths, reads every event they contain and compiles the
155
+ * schema. Returns an exit code when the command cannot proceed at all.
156
+ */
157
+ function loadInput(inputs, command, quiet) {
158
+ if (inputs.length === 0) {
159
+ process.stderr.write(`auditmodel: ${command} requires at least one file or directory\n\n`);
160
+ process.stderr.write(USAGE);
161
+ return EXIT_ERROR;
162
+ }
163
+ let loaded;
164
+ try {
165
+ loaded = loadEventDocuments(inputs);
166
+ }
167
+ catch (cause) {
168
+ process.stderr.write(`auditmodel: ${cause.message}\n`);
169
+ return EXIT_ERROR;
170
+ }
171
+ if (loaded.documents.length === 0 && loaded.failures.length === 0) {
172
+ process.stderr.write("auditmodel: no events found in the given paths\n");
173
+ return EXIT_ERROR;
174
+ }
175
+ let validator;
176
+ try {
177
+ validator = createValidator();
178
+ }
179
+ catch (cause) {
180
+ process.stderr.write(`auditmodel: ${cause.message}\n`);
181
+ return EXIT_ERROR;
182
+ }
183
+ if (!quiet) {
184
+ write(`schema: ${validator.schemaId} (${displayPath(validator.schemaPath)})\n\n`);
185
+ }
186
+ return { documents: loaded.documents, failures: loaded.failures, validator };
187
+ }
188
+ function reportLoadFailures(failures) {
189
+ for (const failure of failures) {
190
+ write(`ERROR ${displayPath(failure.file)}\n ${failure.error}\n`);
191
+ }
192
+ }
193
+ function runValidate(inputs, quiet) {
194
+ const loaded = loadInput(inputs, "validate", quiet);
195
+ if (typeof loaded === "number") {
196
+ return loaded;
197
+ }
198
+ reportLoadFailures(loaded.failures);
199
+ let valid = 0;
200
+ let invalid = 0;
201
+ for (const document of loaded.documents) {
202
+ const label = displayLabel(document);
203
+ const issues = loaded.validator.validateEvent(document.event);
204
+ if (issues.length === 0) {
205
+ valid += 1;
206
+ if (!quiet) {
207
+ write(`ok ${label}\n`);
208
+ }
209
+ }
210
+ else {
211
+ invalid += 1;
212
+ write(`FAIL ${label}\n${formatIssues(issues)}\n`);
213
+ }
214
+ }
215
+ const total = loaded.documents.length;
216
+ const noun = total === 1 ? "event" : "events";
217
+ write(`\n${total} ${noun} checked: ${valid} valid, ${invalid} invalid, ${loaded.failures.length} unreadable\n`);
218
+ if (loaded.failures.length > 0) {
219
+ return EXIT_ERROR;
220
+ }
221
+ return invalid > 0 ? EXIT_INVALID : EXIT_OK;
222
+ }
223
+ function runVerifyIntegrity(inputs, quiet) {
224
+ const loaded = loadInput(inputs, "verify-integrity", quiet);
225
+ if (typeof loaded === "number") {
226
+ return loaded;
227
+ }
228
+ reportLoadFailures(loaded.failures);
229
+ let verified = 0;
230
+ let failed = 0;
231
+ for (const document of loaded.documents) {
232
+ const label = displayLabel(document);
233
+ const result = verifyEventIntegrity(document.event, label, loaded.validator);
234
+ if (result.verified) {
235
+ verified += 1;
236
+ if (!quiet) {
237
+ write(`ok ${label}\n`);
238
+ writeChecks(result.checks, " ");
239
+ }
240
+ }
241
+ else {
242
+ failed += 1;
243
+ write(`FAIL ${label}\n`);
244
+ if (!quiet) {
245
+ writeChecks(result.checks, " ");
246
+ }
247
+ // The file name is already on the FAIL line, so the per-finding label
248
+ // would only repeat it.
249
+ writeFindings(result.findings.map((finding) => ({
250
+ kind: finding.kind,
251
+ message: finding.message,
252
+ ...(finding.detail === undefined ? {} : { detail: finding.detail }),
253
+ })), " ");
254
+ }
255
+ }
256
+ const total = loaded.documents.length;
257
+ const noun = total === 1 ? "event" : "events";
258
+ write(`\n${total} ${noun} checked: ${verified} verified, ${failed} failed\n`);
259
+ if (loaded.failures.length > 0) {
260
+ return EXIT_ERROR;
261
+ }
262
+ return failed > 0 ? EXIT_INVALID : EXIT_OK;
263
+ }
264
+ function runVerifyChain(inputs, quiet) {
265
+ const loaded = loadInput(inputs, "verify-chain", quiet);
266
+ if (typeof loaded === "number") {
267
+ return loaded;
268
+ }
269
+ reportLoadFailures(loaded.failures);
270
+ const events = loaded.documents.map((document) => ({
271
+ label: displayLabel(document),
272
+ event: document.event,
273
+ }));
274
+ const report = verifyChains(events, loaded.validator);
275
+ if (report.unassigned.length > 0) {
276
+ write("events that could not be assigned to a chain\n");
277
+ writeFindings(report.unassigned, " ");
278
+ write("\n");
279
+ }
280
+ for (const chain of report.chains) {
281
+ const range = chain.firstSequence === undefined || chain.lastSequence === undefined
282
+ ? "none"
283
+ : `${chain.firstSequence}..${chain.lastSequence}`;
284
+ write(`chain ${chain.chainId}\n`);
285
+ write(` events: ${chain.eventCount}\n`);
286
+ write(` sequences: ${range}\n`);
287
+ if (!quiet) {
288
+ writeChecks(chain.checks.map((check) => ({ message: `ok ${check.message}` })), " ");
289
+ }
290
+ if (chain.findings.length > 0) {
291
+ write(" FAIL\n");
292
+ writeFindings(chain.findings, " ");
293
+ }
294
+ if (!quiet) {
295
+ writeNotes(chain.notes, " ");
296
+ }
297
+ write("\n");
298
+ }
299
+ const intact = report.chains.filter((chain) => chain.intact).length;
300
+ const broken = report.chains.length - intact;
301
+ const chainNoun = report.chains.length === 1 ? "chain" : "chains";
302
+ write(`${report.chains.length} ${chainNoun} checked: ${intact} intact, ${broken} broken (${report.eventCount} events)\n`);
303
+ if (loaded.failures.length > 0) {
304
+ return EXIT_ERROR;
305
+ }
306
+ if (report.chains.length === 0 && report.unassigned.length === 0) {
307
+ process.stderr.write("auditmodel: no chains found in the given paths\n");
308
+ return EXIT_INVALID;
309
+ }
310
+ return report.intact ? EXIT_OK : EXIT_INVALID;
311
+ }
312
+ function runLintPrivacy(inputs, quiet, format) {
313
+ const loaded = loadInput(inputs, "lint-privacy", quiet || format === "json");
314
+ if (typeof loaded === "number") {
315
+ return loaded;
316
+ }
317
+ const results = loaded.documents.map((document) => lintEvent(document.event, displayLabel(document), loaded.validator));
318
+ const summary = summarise(results);
319
+ if (format === "json") {
320
+ const report = {
321
+ tool: "auditmodel lint-privacy",
322
+ specVersion: SPEC_VERSION,
323
+ schemaId: loaded.validator.schemaId,
324
+ summary,
325
+ unreadable: loaded.failures.map((failure) => ({
326
+ file: displayPath(failure.file),
327
+ error: failure.error,
328
+ })),
329
+ results: results.map((result) => ({
330
+ file: result.label,
331
+ ...(result.eventId === undefined ? {} : { eventId: result.eventId }),
332
+ status: result.status,
333
+ schemaIssues: result.schemaIssues,
334
+ // Findings never carry the value that produced them.
335
+ findings: result.findings.map((entry) => ({
336
+ ruleId: entry.ruleId,
337
+ severity: entry.severity,
338
+ confidence: entry.confidence,
339
+ category: entry.category,
340
+ path: entry.path,
341
+ message: entry.message,
342
+ recommendation: entry.recommendation,
343
+ })),
344
+ })),
345
+ };
346
+ write(`${JSON.stringify(report, null, 2)}\n`);
347
+ }
348
+ else {
349
+ reportLoadFailures(loaded.failures);
350
+ for (const result of results) {
351
+ if (result.status === "clean") {
352
+ if (!quiet) {
353
+ write(`ok ${result.label}\n`);
354
+ }
355
+ continue;
356
+ }
357
+ if (result.status === "schema-invalid") {
358
+ write(`FAIL ${result.label} (not an OpenAuditModel event: NOT scanned)\n`);
359
+ for (const issue of result.schemaIssues) {
360
+ write(` ${issue}\n`);
361
+ }
362
+ continue;
363
+ }
364
+ const noun = result.findings.length === 1 ? "finding" : "findings";
365
+ write(`FAIL ${result.label} (${result.findings.length} ${noun})\n`);
366
+ for (const entry of result.findings) {
367
+ write(` ${entry.severity.toUpperCase()} ${entry.ruleId} confidence ${entry.confidence} ${entry.path}\n`);
368
+ write(` ${entry.message}\n`);
369
+ if (entry.recommendation !== undefined) {
370
+ write(` recommendation: ${entry.recommendation}\n`);
371
+ }
372
+ }
373
+ }
374
+ const eventNoun = summary.events === 1 ? "event" : "events";
375
+ write(`\n${summary.events} ${eventNoun} checked: ${summary.clean} clean, ${summary.withFindings} with findings, ${summary.schemaInvalid} schema-invalid, ${loaded.failures.length} unreadable\n`);
376
+ const { critical, high, medium, low, info } = summary.bySeverity;
377
+ const findingNoun = summary.findings === 1 ? "finding" : "findings";
378
+ write(`${summary.findings} privacy ${findingNoun}: ${critical} critical, ${high} high, ${medium} medium, ${low} low, ${info} info\n`);
379
+ if (summary.schemaInvalid > 0) {
380
+ const noun = summary.schemaInvalid === 1 ? "input" : "inputs";
381
+ write(`\nPrivacy evaluation was not completed for ${summary.schemaInvalid} ${noun}: not a valid OpenAuditModel event. Those inputs were NOT scanned, and are not reported as clean.\n`);
382
+ }
383
+ }
384
+ if (loaded.failures.length > 0) {
385
+ return EXIT_ERROR;
386
+ }
387
+ // Findings win over schema-invalid: a real finding is the more actionable
388
+ // signal, and reporting "not evaluated" would bury it. With no findings, a
389
+ // schema-invalid input must never look clean — nothing was scanned.
390
+ if (summary.findings > 0) {
391
+ return EXIT_INVALID;
392
+ }
393
+ return summary.schemaInvalid > 0 ? EXIT_NO_VERDICT : EXIT_OK;
394
+ }
395
+ function runCheckProfile(inputs, quiet, format, profileName) {
396
+ if (profileName === undefined || profileName === "") {
397
+ process.stderr.write(`auditmodel: check-profile requires --profile <name>; available profiles: ${availableProfiles().join(", ")}\n`);
398
+ return EXIT_ERROR;
399
+ }
400
+ const loaded = loadProfile(profileName);
401
+ if (!loaded.ok) {
402
+ process.stderr.write(`auditmodel: ${loaded.error}\n`);
403
+ for (const issue of loaded.issues ?? []) {
404
+ process.stderr.write(` ${issue}\n`);
405
+ }
406
+ return EXIT_ERROR;
407
+ }
408
+ const input = loadInput(inputs, "check-profile", quiet || format === "json");
409
+ if (typeof input === "number") {
410
+ return input;
411
+ }
412
+ const { profile } = loaded;
413
+ const results = input.documents.map((document) => checkProfile(document.event, displayLabel(document), profile, input.validator));
414
+ const summary = summariseProfileResults(results);
415
+ if (format === "json") {
416
+ write(`${JSON.stringify({
417
+ tool: "auditmodel check-profile",
418
+ specVersion: SPEC_VERSION,
419
+ schemaId: input.validator.schemaId,
420
+ profile: { name: profile.name, version: profile.version, status: profile.status },
421
+ summary,
422
+ unreadable: input.failures.map((failure) => ({
423
+ file: displayPath(failure.file),
424
+ error: failure.error,
425
+ })),
426
+ results,
427
+ }, null, 2)}\n`);
428
+ }
429
+ else {
430
+ reportLoadFailures(input.failures);
431
+ if (!quiet) {
432
+ write(`profile: ${profile.name} ${profile.version} (${profile.status})\n\n`);
433
+ }
434
+ for (const result of results) {
435
+ if (result.status === "conforming") {
436
+ if (!quiet) {
437
+ write(`ok ${result.label} (${result.matchedRules.join(", ")})\n`);
438
+ writeProfileFindings(result.warnings, " ");
439
+ }
440
+ continue;
441
+ }
442
+ if (result.status === "not-applicable") {
443
+ if (!quiet) {
444
+ write(`n/a ${result.label} (no rule in this profile governs this event)\n`);
445
+ }
446
+ continue;
447
+ }
448
+ if (result.status === "core-invalid") {
449
+ write(`FAIL ${result.label} (core-invalid: profile rules not evaluated)\n`);
450
+ for (const issue of result.coreIssues) {
451
+ write(` ${issue}\n`);
452
+ }
453
+ continue;
454
+ }
455
+ const noun = result.errors.length === 1 ? "violation" : "violations";
456
+ write(`FAIL ${result.label} (${result.errors.length} ${noun})\n`);
457
+ if (!quiet && result.matchedRules.length > 0) {
458
+ write(` matched rules: ${result.matchedRules.join(", ")}\n`);
459
+ }
460
+ writeProfileFindings(result.errors, " ");
461
+ if (!quiet) {
462
+ writeProfileFindings(result.warnings, " ");
463
+ }
464
+ }
465
+ const noun = summary.events === 1 ? "event" : "events";
466
+ write(`\n${summary.events} ${noun} checked: ${summary.conforming} conforming, ${summary.violations} with violations, ${summary.notApplicable} not applicable, ${summary.coreInvalid} core-invalid, ${input.failures.length} unreadable\n`);
467
+ write(`${summary.errors} profile violations, ${summary.warnings} recommendations\n`);
468
+ }
469
+ if (input.failures.length > 0) {
470
+ return EXIT_ERROR;
471
+ }
472
+ if (summary.errors > 0 || summary.coreInvalid > 0) {
473
+ return EXIT_INVALID;
474
+ }
475
+ // Only when nothing at all was governed; a mix of conforming and
476
+ // not-applicable events is a pass.
477
+ return summary.conforming === 0 && summary.notApplicable > 0 ? EXIT_NOT_APPLICABLE : EXIT_OK;
478
+ }
479
+ export function run(argv) {
480
+ let parsed;
481
+ try {
482
+ parsed = parseArgs({
483
+ args: [...argv],
484
+ allowPositionals: true,
485
+ strict: true,
486
+ options: {
487
+ help: { type: "boolean", short: "h", default: false },
488
+ version: { type: "boolean", default: false },
489
+ quiet: { type: "boolean", short: "q", default: false },
490
+ format: { type: "string", default: "text" },
491
+ profile: { type: "string" },
492
+ },
493
+ });
494
+ }
495
+ catch (cause) {
496
+ process.stderr.write(`auditmodel: ${cause.message}\n\n`);
497
+ process.stderr.write(USAGE);
498
+ return EXIT_ERROR;
499
+ }
500
+ const { values, positionals } = parsed;
501
+ if (values.version === true) {
502
+ const validator = createValidator();
503
+ write(`auditmodel ${toolVersion(validator.schemaPath)} (specification ${SPEC_VERSION}, experimental)\n`);
504
+ return EXIT_OK;
505
+ }
506
+ const command = positionals[0];
507
+ if (values.help === true || command === undefined || command === "help") {
508
+ write(USAGE);
509
+ return command === undefined && values.help !== true ? EXIT_ERROR : EXIT_OK;
510
+ }
511
+ const rest = positionals.slice(1);
512
+ const quiet = values.quiet === true;
513
+ const format = typeof values.format === "string" ? values.format : "text";
514
+ if (!OUTPUT_FORMATS.has(format)) {
515
+ process.stderr.write(`auditmodel: unknown output format "${format}"; expected ${[...OUTPUT_FORMATS].join(" or ")}\n`);
516
+ return EXIT_ERROR;
517
+ }
518
+ if (command === "validate") {
519
+ return runValidate(rest, quiet);
520
+ }
521
+ if (command === "verify-integrity") {
522
+ return runVerifyIntegrity(rest, quiet);
523
+ }
524
+ if (command === "verify-chain") {
525
+ return runVerifyChain(rest, quiet);
526
+ }
527
+ if (command === "lint-privacy") {
528
+ return runLintPrivacy(rest, quiet, format);
529
+ }
530
+ if (command === "check-profile") {
531
+ return runCheckProfile(rest, quiet, format, typeof values.profile === "string" ? values.profile : undefined);
532
+ }
533
+ if (PLANNED_COMMANDS.has(command)) {
534
+ process.stderr.write(`auditmodel: "${command}" is planned for a future specification version and is not implemented in v${SPEC_VERSION}\n`);
535
+ return EXIT_ERROR;
536
+ }
537
+ process.stderr.write(`auditmodel: unknown command "${command}"\n\n`);
538
+ process.stderr.write(USAGE);
539
+ return EXIT_ERROR;
540
+ }
541
+ /**
542
+ * True when this module is the process entry point. Real paths are compared so
543
+ * that execution through a `node_modules/.bin` shim is still recognised.
544
+ */
545
+ function isDirectInvocation() {
546
+ const entry = process.argv[1];
547
+ if (entry === undefined) {
548
+ return false;
549
+ }
550
+ try {
551
+ return realpathSync(entry) === realpathSync(fileURLToPath(import.meta.url));
552
+ }
553
+ catch {
554
+ return true;
555
+ }
556
+ }
557
+ if (isDirectInvocation()) {
558
+ process.exitCode = run(process.argv.slice(2));
559
+ }
560
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../conformance/src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAkB,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAA+C,MAAM,cAAc,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAwB,MAAM,6BAA6B,CAAC;AAEjF,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAuB,MAAM,qBAAqB,CAAC;AAEnF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AACzB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5B;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC,gFAAgF;AAChF,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC;AAEnD,2FAA2F;AAC3F,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAErD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEjD,MAAM,KAAK,GAAG,kEAAkE,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4C3F,CAAC;AAEF,SAAS,WAAW,CAAC,UAAkB;IACrC,qEAAqE;IACrE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAClE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAEhF,CAAC;QACF,OAAO,QAAQ,CAAC,OAAO,IAAI,YAAY,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,YAAY,CAAC;IACtB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;AAC5F,CAAC;AAED,2FAA2F;AAC3F,SAAS,YAAY,CAAC,QAAuB;IAC3C,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;AAC3E,CAAC;AAED,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,aAAa,CAAC,QAA4B,EAAE,MAAc;IACjE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC;QACtE,KAAK,CAAC,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,OAAO,MAAM,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC;QAClE,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACxC,KAAK,CAAC,GAAG,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAmC,EAAE,MAAc;IAC/E,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,CACH,GAAG,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI,KAAK,MAAM,KAAK,OAAO,CAAC,OAAO,IAAI,CAClH,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,MAA8B,EAAE,MAAc;IACjE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAsB,EAAE,MAAc;IACxD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,GAAG,MAAM,SAAS,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QAC1C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACrC,KAAK,CAAC,GAAG,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;AACH,CAAC;AAQD;;;GAGG;AACH,SAAS,SAAS,CAChB,MAAyB,EACzB,OAAe,EACf,KAAc;IAEd,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,OAAO,8CAA8C,CAAC,CAAC;QAC3F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,MAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAgB,KAAe,CAAC,OAAO,IAAI,CAAC,CAAC;QAClE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACzE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,SAAoB,CAAC;IACzB,IAAI,CAAC;QACH,SAAS,GAAG,eAAe,EAAE,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAgB,KAAe,CAAC,OAAO,IAAI,CAAC,CAAC;QAClE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,CAAC,WAAW,SAAS,CAAC,QAAQ,KAAK,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC;AAC/E,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAwC;IAClE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,CAAC,SAAS,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,MAAyB,EAAE,KAAc;IAC5D,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IACpD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEpC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE9D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,KAAK,IAAI,CAAC,CAAC;YACX,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,CAAC;YACb,KAAK,CAAC,SAAS,KAAK,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;IACtC,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC9C,KAAK,CACH,KAAK,KAAK,IAAI,IAAI,aAAa,KAAK,WAAW,OAAO,aAAa,MAAM,CAAC,QAAQ,CAAC,MAAM,eAAe,CACzG,CAAC;IAEF,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9C,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAyB,EAAE,KAAc;IACnE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,CAAC,CAAC;IAC5D,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEpC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAE7E,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,QAAQ,IAAI,CAAC,CAAC;YACd,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC;gBAC1B,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,CAAC;YACZ,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YACzC,CAAC;YACD,sEAAsE;YACtE,wBAAwB;YACxB,aAAa,CACX,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAChC,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;aACpE,CAAC,CAAC,EACH,UAAU,CACX,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;IACtC,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC9C,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,aAAa,QAAQ,cAAc,MAAM,WAAW,CAAC,CAAC;IAE9E,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;AAC7C,CAAC;AAED,SAAS,cAAc,CAAC,MAAyB,EAAE,KAAc;IAC/D,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;IACxD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,MAAM,GAAsB,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACpE,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC;QAC7B,KAAK,EAAE,QAAQ,CAAC,KAAK;KACtB,CAAC,CAAC,CAAC;IAEJ,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAEtD,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACxD,aAAa,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,KAAK,GACT,KAAK,CAAC,aAAa,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;YACnE,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,GAAG,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,YAAY,EAAE,CAAC;QAEtD,KAAK,CAAC,SAAS,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;QAClC,KAAK,CAAC,gBAAgB,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;QAC5C,KAAK,CAAC,gBAAgB,KAAK,IAAI,CAAC,CAAC;QAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,WAAW,CACT,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EACpE,IAAI,CACL,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,CAAC,UAAU,CAAC,CAAC;YAClB,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAChC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IACpE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IAC7C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IAClE,KAAK,CACH,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,aAAa,MAAM,YAAY,MAAM,YAAY,MAAM,CAAC,UAAU,YAAY,CACnH,CAAC;IAEF,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACzE,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;AAChD,CAAC;AAED,SAAS,cAAc,CAAC,MAAyB,EAAE,KAAc,EAAE,MAAc;IAC/E,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,IAAI,MAAM,KAAK,MAAM,CAAC,CAAC;IAC7E,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAChD,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CACpE,CAAC;IACF,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAEnC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG;YACb,IAAI,EAAE,yBAAyB;YAC/B,WAAW,EAAE,YAAY;YACzB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ;YACnC,OAAO;YACP,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC5C,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;gBAC/B,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB,CAAC,CAAC;YACH,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAChC,IAAI,EAAE,MAAM,CAAC,KAAK;gBAClB,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpE,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,qDAAqD;gBACrD,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBACxC,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,cAAc,EAAE,KAAK,CAAC,cAAc;iBACrC,CAAC,CAAC;aACJ,CAAC,CAAC;SACJ,CAAC;QACF,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEpC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,KAAK,CAAC,SAAS,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;gBACnC,CAAC;gBACD,SAAS;YACX,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;gBACvC,KAAK,CAAC,SAAS,MAAM,CAAC,KAAK,gDAAgD,CAAC,CAAC;gBAC7E,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;oBACxC,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;gBAC9B,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;YACnE,KAAK,CAAC,SAAS,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC;YACtE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACpC,KAAK,CACH,WAAW,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,MAAM,gBAAgB,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,IAAI,IAAI,CAC5G,CAAC;gBACF,KAAK,CAAC,aAAa,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;gBACtC,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;oBACvC,KAAK,CAAC,6BAA6B,KAAK,CAAC,cAAc,IAAI,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC5D,KAAK,CACH,KAAK,OAAO,CAAC,MAAM,IAAI,SAAS,aAAa,OAAO,CAAC,KAAK,WAAW,OAAO,CAAC,YAAY,mBAAmB,OAAO,CAAC,aAAa,oBAAoB,MAAM,CAAC,QAAQ,CAAC,MAAM,eAAe,CAC3L,CAAC;QACF,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;QACjE,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;QACpE,KAAK,CACH,GAAG,OAAO,CAAC,QAAQ,YAAY,WAAW,KAAK,QAAQ,cAAc,IAAI,UAAU,MAAM,YAAY,GAAG,SAAS,IAAI,SAAS,CAC/H,CAAC;QAEF,IAAI,OAAO,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC9D,KAAK,CACH,8CAA8C,OAAO,CAAC,aAAa,IAAI,IAAI,qGAAqG,CACjL,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,0EAA0E;IAC1E,2EAA2E;IAC3E,oEAAoE;IACpE,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC;AAC/D,CAAC;AAED,SAAS,eAAe,CACtB,MAAyB,EACzB,KAAc,EACd,MAAc,EACd,WAA+B;IAE/B,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;QACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,4EAA4E,iBAAiB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAC/G,CAAC;QACF,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QACtD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,IAAI,MAAM,KAAK,MAAM,CAAC,CAAC;IAC7E,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC/C,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAC/E,CAAC;IACF,MAAM,OAAO,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAEjD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,KAAK,CACH,GAAG,IAAI,CAAC,SAAS,CACf;YACE,IAAI,EAAE,0BAA0B;YAChC,WAAW,EAAE,YAAY;YACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ;YAClC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;YACjF,OAAO;YACP,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC3C,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;gBAC/B,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB,CAAC,CAAC;YACH,OAAO;SACR,EACD,IAAI,EACJ,CAAC,CACF,IAAI,CACN,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAEnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,CAAC,YAAY,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC;QAC/E,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBACnC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,KAAK,CAAC,SAAS,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACtE,oBAAoB,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;gBACpD,CAAC;gBACD,SAAS;YACX,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;gBACvC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,KAAK,CAAC,SAAS,MAAM,CAAC,KAAK,kDAAkD,CAAC,CAAC;gBACjF,CAAC;gBACD,SAAS;YACX,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;gBACrC,KAAK,CAAC,SAAS,MAAM,CAAC,KAAK,iDAAiD,CAAC,CAAC;gBAC9E,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;oBACtC,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;gBAC9B,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;YACrE,KAAK,CAAC,SAAS,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC;YACpE,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7C,KAAK,CAAC,0BAA0B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtE,CAAC;YACD,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAChD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,oBAAoB,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;QACvD,KAAK,CACH,KAAK,OAAO,CAAC,MAAM,IAAI,IAAI,aAAa,OAAO,CAAC,UAAU,gBAAgB,OAAO,CAAC,UAAU,qBAAqB,OAAO,CAAC,aAAa,oBAAoB,OAAO,CAAC,WAAW,kBAAkB,KAAK,CAAC,QAAQ,CAAC,MAAM,eAAe,CACpO,CAAC;QACF,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,wBAAwB,OAAO,CAAC,QAAQ,oBAAoB,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;QAClD,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,iEAAiE;IACjE,mCAAmC;IACnC,OAAO,OAAO,CAAC,UAAU,KAAK,CAAC,IAAI,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC;AAC/F,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAuB;IACzC,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC;YACjB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;YACf,gBAAgB,EAAE,IAAI;YACtB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;gBACrD,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;gBAC5C,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;gBACtD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE;gBAC3C,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;aAC5B;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAgB,KAAe,CAAC,OAAO,MAAM,CAAC,CAAC;QACpE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;IAEvC,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;QACpC,KAAK,CACH,cAAc,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,mBAAmB,YAAY,mBAAmB,CAClG,CAAC;QACF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAE/B,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACxE,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,OAAO,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9E,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;IACpC,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAE1E,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sCAAsC,MAAM,eAAe,CAAC,GAAG,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAChG,CAAC;QACF,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,OAAO,KAAK,kBAAkB,EAAE,CAAC;QACnC,OAAO,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;QAC/B,OAAO,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;QAC/B,OAAO,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;QAChC,OAAO,eAAe,CACpB,IAAI,EACJ,KAAK,EACL,MAAM,EACN,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAChE,CAAC;IACJ,CAAC;IAED,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,gBAAgB,OAAO,8EAA8E,YAAY,IAAI,CACtH,CAAC;QACF,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,OAAO,OAAO,CAAC,CAAC;IACrE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB;IACzB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,IAAI,kBAAkB,EAAE,EAAE,CAAC;IACzB,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Translation of raw JSON Schema validation errors into stable, human readable
3
+ * issues. Every issue carries a JSON Pointer so that a reader can locate the
4
+ * offending value inside the audit event without guessing.
5
+ */
6
+ import type { ErrorObject } from "ajv";
7
+ export interface ValidationIssue {
8
+ /** JSON Pointer to the offending location inside the event. `/` is the event root. */
9
+ readonly path: string;
10
+ /** Human readable explanation of the failure. */
11
+ readonly message: string;
12
+ /** JSON Schema keyword that produced the failure. */
13
+ readonly keyword: string;
14
+ /** Additional context such as the allowed values or the expected pattern. */
15
+ readonly detail?: string;
16
+ }
17
+ /** Converts validator errors into issues, deduplicating identical entries. */
18
+ export declare function toIssues(errors: readonly ErrorObject[] | null | undefined): ValidationIssue[];
19
+ /** Renders issues as indented report lines. */
20
+ export declare function formatIssues(issues: readonly ValidationIssue[], indent?: string): string;