@mcp-audit-gateway/core 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +37 -0
- package/.well-known/agent-governance.json +47 -0
- package/.well-known/security-insights-snippet.yml +9 -0
- package/CHANGELOG.md +32 -0
- package/README.md +31 -3
- package/dist/attestation/audit-log.d.ts +35 -3
- package/dist/attestation/audit-log.d.ts.map +1 -1
- package/dist/attestation/audit-log.js +303 -8
- package/dist/attestation/audit-log.js.map +1 -1
- package/dist/attestation/checkpoint.test.d.ts +2 -0
- package/dist/attestation/checkpoint.test.d.ts.map +1 -0
- package/dist/attestation/checkpoint.test.js +870 -0
- package/dist/attestation/checkpoint.test.js.map +1 -0
- package/dist/attestation/signer.d.ts +24 -9
- package/dist/attestation/signer.d.ts.map +1 -1
- package/dist/attestation/signer.js +151 -10
- package/dist/attestation/signer.js.map +1 -1
- package/dist/attestation/signer.test.js +83 -0
- package/dist/attestation/signer.test.js.map +1 -1
- package/dist/attestation/verify.d.ts +23 -2
- package/dist/attestation/verify.d.ts.map +1 -1
- package/dist/attestation/verify.js +219 -2
- package/dist/attestation/verify.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integration.test.js +1 -0
- package/dist/integration.test.js.map +1 -1
- package/dist/policy/engine.d.ts +12 -1
- package/dist/policy/engine.d.ts.map +1 -1
- package/dist/policy/engine.js +26 -4
- package/dist/policy/engine.js.map +1 -1
- package/dist/policy/engine.test.js +42 -1
- package/dist/policy/engine.test.js.map +1 -1
- package/dist/proxy/gateway.d.ts +4 -0
- package/dist/proxy/gateway.d.ts.map +1 -1
- package/dist/proxy/gateway.js +9 -2
- package/dist/proxy/gateway.js.map +1 -1
- package/dist/proxy/gateway.test.js +19 -0
- package/dist/proxy/gateway.test.js.map +1 -1
- package/dist/proxy/mcp-server-adapter.d.ts +1 -0
- package/dist/proxy/mcp-server-adapter.d.ts.map +1 -1
- package/dist/proxy/mcp-server-adapter.js +28 -1
- package/dist/proxy/mcp-server-adapter.js.map +1 -1
- package/dist/proxy/mcp-server-adapter.test.js +1 -0
- package/dist/proxy/mcp-server-adapter.test.js.map +1 -1
- package/dist/types.d.ts +81 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -1
- package/dist/wrap/proxy.test.js +2 -2
- package/dist/wrap/proxy.test.js.map +1 -1
- package/docs/BACKLOG.md +33 -0
- package/docs/SECURITY-DESIGN.md +126 -0
- package/docs/v0.4.0-patch-audit.md +115 -0
- package/package.json +1 -1
- package/src/attestation/audit-log.ts +357 -13
- package/src/attestation/checkpoint.test.ts +956 -0
- package/src/attestation/signer.test.ts +98 -0
- package/src/attestation/signer.ts +159 -19
- package/src/attestation/verify.ts +270 -4
- package/src/index.ts +1 -1
- package/src/integration.test.ts +1 -0
- package/src/policy/engine.test.ts +47 -1
- package/src/policy/engine.ts +38 -5
- package/src/proxy/gateway.test.ts +18 -0
- package/src/proxy/gateway.ts +10 -1
- package/src/proxy/mcp-server-adapter.test.ts +1 -0
- package/src/proxy/mcp-server-adapter.ts +26 -0
- package/src/types.ts +56 -0
- package/src/wrap/proxy.test.ts +2 -2
- package/test/vectors/README.md +44 -0
- package/test/vectors/aps-action-ref-v1-vectors.json +351 -0
- package/test/vectors/aps-action-ref-v1.mjs +145 -0
- package/test/vectors/canonicalization.json +764 -0
- package/test/vectors/checkpoint.json +450 -0
- package/test/vectors/generate.mjs +354 -0
- package/test/vectors/verify-checkpoint.mjs +344 -0
- package/test/vectors/verify-checkpoint.py +358 -0
- package/test/vectors/verify.mjs +346 -0
- package/test/vectors/verify.py +354 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
node-version: [20, 22]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: ${{ matrix.node-version }}
|
|
20
|
+
- run: npm ci
|
|
21
|
+
- run: npm run build
|
|
22
|
+
- run: npm test
|
|
23
|
+
|
|
24
|
+
vectors:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version: 20
|
|
31
|
+
- uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.12"
|
|
34
|
+
- run: npm ci
|
|
35
|
+
- run: node test/vectors/verify-checkpoint.mjs
|
|
36
|
+
- run: python3 test/vectors/verify-checkpoint.py
|
|
37
|
+
- run: node test/vectors/aps-action-ref-v1.mjs
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ossf.github.io/security-insights/governance-declaration/v0.1",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"framework": "mcp-audit-gateway",
|
|
5
|
+
"attestation": {
|
|
6
|
+
"predicate_type": "https://in-toto.io/attestation/ai-agent-action/v0.1",
|
|
7
|
+
"signing_algorithm": "ed25519",
|
|
8
|
+
"chain_algorithm": "sha256",
|
|
9
|
+
"tamper_evidence": "hash-chain",
|
|
10
|
+
"parties": [
|
|
11
|
+
{
|
|
12
|
+
"role": "witness",
|
|
13
|
+
"entity": "gateway",
|
|
14
|
+
"scope": [
|
|
15
|
+
"tool", "arguments", "result", "timing",
|
|
16
|
+
"principal", "namespace", "upstream",
|
|
17
|
+
"previousHash", "recordId", "method", "success"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"role": "asserter",
|
|
22
|
+
"entity": "policy-engine",
|
|
23
|
+
"scope": ["decisionContextDigest"]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"policy": {
|
|
28
|
+
"engine": "opa",
|
|
29
|
+
"bundle_digest_algorithm": "sha256",
|
|
30
|
+
"evaluation_record": true,
|
|
31
|
+
"human_approval_required": false
|
|
32
|
+
},
|
|
33
|
+
"observability": {
|
|
34
|
+
"otel_semconv": "mcp/v1.44.0",
|
|
35
|
+
"metrics": [
|
|
36
|
+
"mcp.client.operation.duration",
|
|
37
|
+
"mcp.server.operation.duration"
|
|
38
|
+
],
|
|
39
|
+
"traces": true,
|
|
40
|
+
"context_propagation": "w3c-traceparent"
|
|
41
|
+
},
|
|
42
|
+
"verification": {
|
|
43
|
+
"conformance_vectors": "https://github.com/elang2/mcp-audit-gateway/tree/main/test/vectors",
|
|
44
|
+
"cross_language": ["javascript", "python"],
|
|
45
|
+
"vector_count": 17
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Example security-insights.yml snippet demonstrating SIEP-171 integration
|
|
2
|
+
# This shows how governance-declaration works with a machine-readable target
|
|
3
|
+
|
|
4
|
+
repository:
|
|
5
|
+
url: https://github.com/elang2/mcp-audit-gateway
|
|
6
|
+
status: active
|
|
7
|
+
agent-assisted-production:
|
|
8
|
+
used: true
|
|
9
|
+
governance-declaration: https://github.com/elang2/mcp-audit-gateway/blob/main/.well-known/agent-governance.json
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.2.0] - 2026-08-22
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Multi-party attribution: each audit record now declares which entity (gateway, policy-engine) witnessed or asserted which fields via the `parties` array
|
|
8
|
+
- `decisionContextDigest` field: SHA-256 digest of the policy evaluation context, linking audit records to specific policy decisions
|
|
9
|
+
- Conformance test vectors: 17 vectors covering canonicalization (8), hash chain (3), and party attribution (6)
|
|
10
|
+
- Cross-language verifiers: JavaScript (`test/vectors/verify.mjs`) and Python (`test/vectors/verify.py`) both pass all 17 vectors byte-identical
|
|
11
|
+
- `.well-known/agent-governance.json`: machine-readable governance declaration implementing the OpenSSF SIEP-171 pattern
|
|
12
|
+
- Edge-case vectors for party attribution: empty array vs null, scope ordering significance, chain continuity with parties
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Canonical form now conditionally includes `decisionContextDigest` at position 10 and `parties` at the end when present
|
|
17
|
+
- Backward-compatible: records without these fields produce identical canonical hashes to v0.1.0
|
|
18
|
+
|
|
19
|
+
## [0.1.0] - 2026-08-16
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Initial release
|
|
24
|
+
- Transparent MCP proxy with `mcp-audit wrap` CLI
|
|
25
|
+
- HMAC-SHA256 and Ed25519 attestation signing
|
|
26
|
+
- SHA-256 hash-chained audit log (JSONL)
|
|
27
|
+
- Full gateway mode with multi-upstream routing and tool namespacing
|
|
28
|
+
- OPA-style policy engine with glob-based ACLs and per-principal rate limits
|
|
29
|
+
- OpenTelemetry traces and metrics export
|
|
30
|
+
- Chain verification CLI (`mcp-audit verify`)
|
|
31
|
+
- Live tail CLI (`mcp-audit tail`)
|
|
32
|
+
- Key generation CLI (`mcp-audit keygen`)
|
package/README.md
CHANGED
|
@@ -137,18 +137,46 @@ See [gateway configuration](gateway.config.example.json) for the full schema.
|
|
|
137
137
|
## Install
|
|
138
138
|
|
|
139
139
|
```bash
|
|
140
|
-
npm install -g @mcp-gateway/
|
|
140
|
+
npm install -g @mcp-audit-gateway/core
|
|
141
141
|
```
|
|
142
142
|
|
|
143
143
|
This installs the `mcp-audit` CLI globally. Or use without installing:
|
|
144
144
|
```bash
|
|
145
|
-
npx @mcp-gateway/
|
|
145
|
+
npx @mcp-audit-gateway/core wrap -- <your mcp server command>
|
|
146
146
|
```
|
|
147
147
|
|
|
148
|
+
## Attestation layer
|
|
149
|
+
|
|
150
|
+
The signing and verification subsystem goes beyond per-record HMAC. It provides tamper-evidence across log rotation, crash recovery, and multi-file chains.
|
|
151
|
+
|
|
152
|
+
Checkpoint records let a consumer detect tail truncation by stashing a single hash externally. The chain carries forward across file rotations (no silent resets). Forced restarts emit signed `chain_break` records instead of quietly starting fresh.
|
|
153
|
+
|
|
154
|
+
The canonical form is type-tagged and injective, avoids JCS's float-formatting problem by rejecting unsafe numbers entirely, and has proven cross-language parity via 46 conformance vectors (JS + Python). See [SECURITY-DESIGN.md](docs/SECURITY-DESIGN.md) for the full specification and threat model.
|
|
155
|
+
|
|
156
|
+
## Conformance
|
|
157
|
+
|
|
158
|
+
This implementation satisfies the following properties (verified by cross-language conformance vectors and unit tests):
|
|
159
|
+
|
|
160
|
+
- Injective canonical form (no cross-type digest collisions)
|
|
161
|
+
- Cross-language sort equivalence (UTF-16 code-unit order)
|
|
162
|
+
- Unpaired surrogate rejection
|
|
163
|
+
- Hash chain continuity across log rotation
|
|
164
|
+
- Planted state detection on startup
|
|
165
|
+
- No false-positive after legitimate chain break
|
|
166
|
+
- Fail-closed on corrupt or oversized input
|
|
167
|
+
- Segmented monotonicity at chain_break boundaries
|
|
168
|
+
- Consumer-anchored completeness via checkpoint records
|
|
169
|
+
- Memory-bounded init (1MB cap)
|
|
170
|
+
|
|
171
|
+
APS action-ref-v1 conformance: 51/51 vectors passing (JCS recomputation + fail-closed digest comparison).
|
|
172
|
+
|
|
148
173
|
## Testing
|
|
149
174
|
|
|
150
175
|
```bash
|
|
151
|
-
npm test
|
|
176
|
+
npm test # 149 unit tests
|
|
177
|
+
node test/vectors/verify-checkpoint.mjs # 46 JS conformance vectors
|
|
178
|
+
python3 test/vectors/verify-checkpoint.py # 46 Python conformance vectors
|
|
179
|
+
node test/vectors/aps-action-ref-v1.mjs # 51 APS vectors
|
|
152
180
|
```
|
|
153
181
|
|
|
154
182
|
## License
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import type { AuditRecord } from "../types.js";
|
|
1
|
+
import type { AuditRecord, CheckpointRecord, ChainBreakRecord } from "../types.js";
|
|
2
2
|
import type { Signer } from "./signer.js";
|
|
3
|
-
export declare function hashRecord(record: AuditRecord): string;
|
|
3
|
+
export declare function hashRecord(record: AuditRecord | CheckpointRecord | ChainBreakRecord): string;
|
|
4
|
+
export interface CheckpointConfig {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
intervalRecords: number;
|
|
7
|
+
intervalSeconds: number;
|
|
8
|
+
trigger: "records" | "time" | "whichever_first";
|
|
9
|
+
}
|
|
4
10
|
export declare class AuditLog {
|
|
5
11
|
private path;
|
|
6
12
|
private signer;
|
|
@@ -8,7 +14,13 @@ export declare class AuditLog {
|
|
|
8
14
|
private currentSize;
|
|
9
15
|
private lastHash;
|
|
10
16
|
private writeQueue;
|
|
17
|
+
private recordsSinceCheckpoint;
|
|
18
|
+
private lastCheckpointTime;
|
|
19
|
+
private checkpointSequence;
|
|
20
|
+
private totalRecordCount;
|
|
21
|
+
private checkpointConfig;
|
|
11
22
|
constructor(path: string, signer: Signer, rotateAfterBytes: number);
|
|
23
|
+
enableCheckpoints(config: CheckpointConfig): void;
|
|
12
24
|
record(method: string, opts: {
|
|
13
25
|
toolName?: string;
|
|
14
26
|
namespace?: string;
|
|
@@ -17,9 +29,29 @@ export declare class AuditLog {
|
|
|
17
29
|
durationMs: number;
|
|
18
30
|
success: boolean;
|
|
19
31
|
errorCode?: number;
|
|
32
|
+
decisionContextDigest?: string;
|
|
33
|
+
aiInvocation?: {
|
|
34
|
+
turnId?: string;
|
|
35
|
+
invocationReason?: string;
|
|
36
|
+
model?: string;
|
|
37
|
+
};
|
|
20
38
|
}): Promise<AuditRecord>;
|
|
21
39
|
private writeRecord;
|
|
40
|
+
private shouldEmitCheckpoint;
|
|
41
|
+
private writeCheckpoint;
|
|
42
|
+
emitCheckpoint(): Promise<CheckpointRecord>;
|
|
43
|
+
getLastHash(): string;
|
|
44
|
+
getCheckpointSequence(): number;
|
|
45
|
+
getRecordCount(): number;
|
|
22
46
|
private rotate;
|
|
23
|
-
|
|
47
|
+
private rotationBoundaryHash;
|
|
48
|
+
private persistState;
|
|
49
|
+
private persistChainState;
|
|
50
|
+
private recoverState;
|
|
51
|
+
init(opts?: {
|
|
52
|
+
forceNewChain?: boolean;
|
|
53
|
+
}): Promise<void>;
|
|
54
|
+
private emitChainBreak;
|
|
55
|
+
forceNewChain(reason: string): Promise<ChainBreakRecord>;
|
|
24
56
|
}
|
|
25
57
|
//# sourceMappingURL=audit-log.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-log.d.ts","sourceRoot":"","sources":["../../src/attestation/audit-log.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"audit-log.d.ts","sourceRoot":"","sources":["../../src/attestation/audit-log.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAiC,MAAM,aAAa,CAAC;AAElH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA6B1C,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,MAAM,CAG5F;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,SAAS,GAAG,MAAM,GAAG,iBAAiB,CAAC;CACjD;AAED,qBAAa,QAAQ;IAWjB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,gBAAgB;IAZ1B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,kBAAkB,CAAc;IACxC,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,gBAAgB,CAAiC;gBAG/C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM;IAGlC,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAI3C,MAAM,CACV,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;QACJ,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,YAAY,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/E,GACA,OAAO,CAAC,WAAW,CAAC;YAaT,WAAW;IA8CzB,OAAO,CAAC,oBAAoB;YAWd,eAAe;IAyBvB,cAAc,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAajD,WAAW,IAAI,MAAM;IAIrB,qBAAqB,IAAI,MAAM;IAI/B,cAAc,IAAI,MAAM;YAIV,MAAM;IAapB,OAAO,CAAC,oBAAoB,CAAqB;YAEnC,YAAY;YAaZ,iBAAiB;YAajB,YAAY;IAsBpB,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAqK/C,cAAc;IA+BtB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAY/D"}
|
|
@@ -1,5 +1,31 @@
|
|
|
1
|
-
import { appendFile, stat, rename, open } from "node:fs/promises";
|
|
1
|
+
import { appendFile, stat, rename, open, writeFile as fsWriteFile } from "node:fs/promises";
|
|
2
2
|
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
+
import { isCheckpoint } from "../types.js";
|
|
4
|
+
const GATEWAY_WITNESSED_FIELDS = [
|
|
5
|
+
"id", "timestamp", "method", "toolName", "namespace",
|
|
6
|
+
"upstream", "principal", "durationMs", "success", "errorCode",
|
|
7
|
+
"previousHash",
|
|
8
|
+
];
|
|
9
|
+
function buildParties(hasDecisionContext, hasAiInvocation) {
|
|
10
|
+
const parties = [
|
|
11
|
+
{ party: "gateway", role: "witness", scope: GATEWAY_WITNESSED_FIELDS },
|
|
12
|
+
];
|
|
13
|
+
if (hasDecisionContext) {
|
|
14
|
+
parties.push({
|
|
15
|
+
party: "policy-engine",
|
|
16
|
+
role: "asserter",
|
|
17
|
+
scope: ["decisionContextDigest"],
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (hasAiInvocation) {
|
|
21
|
+
parties.push({
|
|
22
|
+
party: "client",
|
|
23
|
+
role: "asserter",
|
|
24
|
+
scope: ["aiInvocation"],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return parties;
|
|
28
|
+
}
|
|
3
29
|
export function hashRecord(record) {
|
|
4
30
|
const json = JSON.stringify(record);
|
|
5
31
|
return createHash("sha256").update(json).digest("hex");
|
|
@@ -11,11 +37,19 @@ export class AuditLog {
|
|
|
11
37
|
currentSize = 0;
|
|
12
38
|
lastHash = "genesis";
|
|
13
39
|
writeQueue = Promise.resolve();
|
|
40
|
+
recordsSinceCheckpoint = 0;
|
|
41
|
+
lastCheckpointTime = Date.now();
|
|
42
|
+
checkpointSequence = 0;
|
|
43
|
+
totalRecordCount = 0;
|
|
44
|
+
checkpointConfig = null;
|
|
14
45
|
constructor(path, signer, rotateAfterBytes) {
|
|
15
46
|
this.path = path;
|
|
16
47
|
this.signer = signer;
|
|
17
48
|
this.rotateAfterBytes = rotateAfterBytes;
|
|
18
49
|
}
|
|
50
|
+
enableCheckpoints(config) {
|
|
51
|
+
this.checkpointConfig = config;
|
|
52
|
+
}
|
|
19
53
|
async record(method, opts) {
|
|
20
54
|
return new Promise((resolve, reject) => {
|
|
21
55
|
this.writeQueue = this.writeQueue.then(async () => {
|
|
@@ -30,11 +64,14 @@ export class AuditLog {
|
|
|
30
64
|
});
|
|
31
65
|
}
|
|
32
66
|
async writeRecord(method, opts) {
|
|
67
|
+
const { aiInvocation, ...rest } = opts;
|
|
33
68
|
const record = {
|
|
34
69
|
id: randomUUID(),
|
|
35
70
|
timestamp: new Date().toISOString(),
|
|
36
71
|
method,
|
|
37
|
-
...
|
|
72
|
+
...rest,
|
|
73
|
+
...(aiInvocation ? { aiInvocation } : {}),
|
|
74
|
+
parties: buildParties(opts.decisionContextDigest != null, aiInvocation != null),
|
|
38
75
|
previousHash: this.lastHash,
|
|
39
76
|
};
|
|
40
77
|
record.attestation = await this.signer.sign(record);
|
|
@@ -42,54 +79,312 @@ export class AuditLog {
|
|
|
42
79
|
await appendFile(this.path, line);
|
|
43
80
|
this.currentSize += Buffer.byteLength(line);
|
|
44
81
|
this.lastHash = hashRecord(record);
|
|
82
|
+
this.totalRecordCount++;
|
|
83
|
+
this.recordsSinceCheckpoint++;
|
|
84
|
+
if (this.shouldEmitCheckpoint()) {
|
|
85
|
+
await this.writeCheckpoint();
|
|
86
|
+
}
|
|
45
87
|
if (this.currentSize >= this.rotateAfterBytes) {
|
|
46
88
|
await this.rotate();
|
|
47
89
|
}
|
|
48
90
|
return record;
|
|
49
91
|
}
|
|
92
|
+
shouldEmitCheckpoint() {
|
|
93
|
+
if (!this.checkpointConfig?.enabled)
|
|
94
|
+
return false;
|
|
95
|
+
const { trigger, intervalRecords, intervalSeconds } = this.checkpointConfig;
|
|
96
|
+
const recordsHit = this.recordsSinceCheckpoint >= intervalRecords;
|
|
97
|
+
const timeHit = (Date.now() - this.lastCheckpointTime) >= intervalSeconds * 1000;
|
|
98
|
+
if (trigger === "records")
|
|
99
|
+
return recordsHit;
|
|
100
|
+
if (trigger === "time")
|
|
101
|
+
return timeHit;
|
|
102
|
+
return recordsHit || timeHit;
|
|
103
|
+
}
|
|
104
|
+
async writeCheckpoint() {
|
|
105
|
+
this.checkpointSequence++;
|
|
106
|
+
const checkpoint = {
|
|
107
|
+
id: `ckpt_${randomUUID()}`,
|
|
108
|
+
type: "checkpoint",
|
|
109
|
+
timestamp: new Date().toISOString(),
|
|
110
|
+
sequence: this.checkpointSequence,
|
|
111
|
+
recordCount: this.totalRecordCount,
|
|
112
|
+
previousHash: this.lastHash,
|
|
113
|
+
parties: [{ party: "gateway", role: "witness", scope: ["sequence", "recordCount", "previousHash"] }],
|
|
114
|
+
};
|
|
115
|
+
checkpoint.attestation = await this.signer.sign(checkpoint);
|
|
116
|
+
const line = JSON.stringify(checkpoint) + "\n";
|
|
117
|
+
await appendFile(this.path, line);
|
|
118
|
+
this.currentSize += Buffer.byteLength(line);
|
|
119
|
+
this.lastHash = hashRecord(checkpoint);
|
|
120
|
+
this.recordsSinceCheckpoint = 0;
|
|
121
|
+
this.lastCheckpointTime = Date.now();
|
|
122
|
+
return checkpoint;
|
|
123
|
+
}
|
|
124
|
+
async emitCheckpoint() {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
this.writeQueue = this.writeQueue.then(async () => {
|
|
127
|
+
try {
|
|
128
|
+
const result = await this.writeCheckpoint();
|
|
129
|
+
resolve(result);
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
reject(err);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
getLastHash() {
|
|
138
|
+
return this.lastHash;
|
|
139
|
+
}
|
|
140
|
+
getCheckpointSequence() {
|
|
141
|
+
return this.checkpointSequence;
|
|
142
|
+
}
|
|
143
|
+
getRecordCount() {
|
|
144
|
+
return this.totalRecordCount;
|
|
145
|
+
}
|
|
50
146
|
async rotate() {
|
|
51
147
|
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
52
148
|
const rotatedPath = this.path.replace(/\.jsonl$/, `-${ts}.jsonl`);
|
|
53
149
|
try {
|
|
54
150
|
await rename(this.path, rotatedPath);
|
|
55
151
|
this.currentSize = 0;
|
|
56
|
-
|
|
152
|
+
// Chain-global: lastHash, sequence, recordCount survive rotation.
|
|
153
|
+
// The first record in the new file chains to the last hash of the
|
|
154
|
+
// previous file. Resetting to "genesis" would allow truncation-via-rotation.
|
|
155
|
+
await this.persistState();
|
|
57
156
|
}
|
|
58
157
|
catch { }
|
|
59
158
|
}
|
|
60
|
-
|
|
159
|
+
rotationBoundaryHash = "genesis";
|
|
160
|
+
async persistState() {
|
|
161
|
+
const statePath = this.path.replace(/\.jsonl$/, ".state.json");
|
|
162
|
+
const tmpPath = statePath + ".tmp";
|
|
163
|
+
const state = {
|
|
164
|
+
lastHash: this.lastHash,
|
|
165
|
+
rotationBoundaryHash: this.lastHash,
|
|
166
|
+
checkpointSequence: this.checkpointSequence,
|
|
167
|
+
totalRecordCount: this.totalRecordCount,
|
|
168
|
+
};
|
|
169
|
+
await fsWriteFile(tmpPath, JSON.stringify(state));
|
|
170
|
+
await rename(tmpPath, statePath);
|
|
171
|
+
}
|
|
172
|
+
async persistChainState() {
|
|
173
|
+
const statePath = this.path.replace(/\.jsonl$/, ".state.json");
|
|
174
|
+
const tmpPath = statePath + ".tmp";
|
|
175
|
+
const state = {
|
|
176
|
+
lastHash: this.lastHash,
|
|
177
|
+
rotationBoundaryHash: this.rotationBoundaryHash,
|
|
178
|
+
checkpointSequence: this.checkpointSequence,
|
|
179
|
+
totalRecordCount: this.totalRecordCount,
|
|
180
|
+
};
|
|
181
|
+
await fsWriteFile(tmpPath, JSON.stringify(state));
|
|
182
|
+
await rename(tmpPath, statePath);
|
|
183
|
+
}
|
|
184
|
+
async recoverState() {
|
|
185
|
+
const statePath = this.path.replace(/\.jsonl$/, ".state.json");
|
|
186
|
+
try {
|
|
187
|
+
const { readFile } = await import("node:fs/promises");
|
|
188
|
+
const raw = await readFile(statePath, "utf-8");
|
|
189
|
+
const state = JSON.parse(raw);
|
|
190
|
+
if (typeof state.lastHash !== "string" || typeof state.checkpointSequence !== "number" ||
|
|
191
|
+
typeof state.rotationBoundaryHash !== "string") {
|
|
192
|
+
return "corrupt";
|
|
193
|
+
}
|
|
194
|
+
this.lastHash = state.lastHash;
|
|
195
|
+
this.rotationBoundaryHash = state.rotationBoundaryHash;
|
|
196
|
+
this.checkpointSequence = state.checkpointSequence ?? 0;
|
|
197
|
+
this.totalRecordCount = state.totalRecordCount ?? 0;
|
|
198
|
+
return "found";
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
const code = err?.code;
|
|
202
|
+
if (code === "ENOENT")
|
|
203
|
+
return "not_found";
|
|
204
|
+
return "corrupt";
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async init(opts) {
|
|
208
|
+
const stateResult = await this.recoverState();
|
|
209
|
+
let logExists = false;
|
|
61
210
|
let s;
|
|
62
211
|
try {
|
|
63
212
|
s = await stat(this.path);
|
|
213
|
+
logExists = true;
|
|
64
214
|
}
|
|
65
215
|
catch {
|
|
216
|
+
logExists = false;
|
|
217
|
+
}
|
|
218
|
+
// Three-way startup:
|
|
219
|
+
// (a) No state file, no log → genuine first run
|
|
220
|
+
if (stateResult === "not_found" && !logExists) {
|
|
221
|
+
this.currentSize = 0;
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
// (c) State file corrupt or exists but unparseable → refuse unless forced
|
|
225
|
+
if (stateResult === "corrupt") {
|
|
226
|
+
if (opts?.forceNewChain) {
|
|
227
|
+
await this.emitChainBreak("state_file_corrupt");
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
throw new Error("[audit-log] state file corrupt or inconsistent. " +
|
|
231
|
+
"Use --force-new-chain to start a new chain (emits a signed chain_break record).");
|
|
232
|
+
}
|
|
233
|
+
// (b) State file present and parseable → base+delta resume
|
|
234
|
+
if (!logExists) {
|
|
66
235
|
this.currentSize = 0;
|
|
67
236
|
return;
|
|
68
237
|
}
|
|
69
238
|
this.currentSize = s.size;
|
|
70
239
|
if (s.size > 0) {
|
|
71
|
-
const
|
|
240
|
+
const boundaryHash = stateResult === "found" ? this.rotationBoundaryHash : undefined;
|
|
72
241
|
const fh = await open(this.path, "r");
|
|
73
242
|
try {
|
|
243
|
+
let headBuf = Buffer.alloc(0);
|
|
244
|
+
let offset = 0;
|
|
245
|
+
const chunkSize = 4096;
|
|
246
|
+
const maxFirstLine = 1024 * 1024;
|
|
247
|
+
let firstLine = null;
|
|
248
|
+
while (offset < s.size) {
|
|
249
|
+
if (headBuf.length >= maxFirstLine) {
|
|
250
|
+
if (opts?.forceNewChain) {
|
|
251
|
+
await this.emitChainBreak("log_first_record_oversize");
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
throw new Error("[audit-log] first record exceeds 1MB cap (no newline found within limit). " +
|
|
255
|
+
"Use --force-new-chain to start a new chain.");
|
|
256
|
+
}
|
|
257
|
+
const readSize = Math.min(chunkSize, s.size - offset);
|
|
258
|
+
const chunk = Buffer.alloc(readSize);
|
|
259
|
+
await fh.read(chunk, 0, readSize, offset);
|
|
260
|
+
headBuf = Buffer.concat([headBuf, chunk]);
|
|
261
|
+
const text = headBuf.toString("utf-8");
|
|
262
|
+
const nlIdx = text.indexOf("\n");
|
|
263
|
+
if (nlIdx !== -1) {
|
|
264
|
+
firstLine = text.slice(0, nlIdx);
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
offset += readSize;
|
|
268
|
+
}
|
|
269
|
+
if (firstLine === null) {
|
|
270
|
+
const text = headBuf.toString("utf-8").trim();
|
|
271
|
+
if (text.length === 0) {
|
|
272
|
+
if (opts?.forceNewChain) {
|
|
273
|
+
await this.emitChainBreak("log_empty_no_newline");
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
throw new Error("[audit-log] log file exists but contains no parseable content. " +
|
|
277
|
+
"Use --force-new-chain to start a new chain.");
|
|
278
|
+
}
|
|
279
|
+
firstLine = text;
|
|
280
|
+
}
|
|
281
|
+
// Parse first record — if it doesn't parse, the log is corrupt
|
|
282
|
+
let firstRecordPrevHash;
|
|
283
|
+
let firstRecordIsBreak = false;
|
|
284
|
+
try {
|
|
285
|
+
const firstRecord = JSON.parse(firstLine);
|
|
286
|
+
if (firstRecord.type === "chain_break") {
|
|
287
|
+
firstRecordIsBreak = true;
|
|
288
|
+
firstRecordPrevHash = firstRecord.priorHead;
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
firstRecordPrevHash = firstRecord.previousHash;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
if (opts?.forceNewChain) {
|
|
296
|
+
await this.emitChainBreak("log_first_record_corrupt");
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
throw new Error("[audit-log] first record in log is corrupt (unparseable JSON). " +
|
|
300
|
+
"Use --force-new-chain to start a new chain.");
|
|
301
|
+
}
|
|
302
|
+
// Read tail: recover chain head and checkpoint state
|
|
303
|
+
const tailSize = Math.min(s.size, 8192);
|
|
74
304
|
const buf = Buffer.alloc(tailSize);
|
|
75
305
|
await fh.read(buf, 0, tailSize, s.size - tailSize);
|
|
76
306
|
const tail = buf.toString("utf-8");
|
|
77
307
|
const lines = tail.trimEnd().split("\n");
|
|
308
|
+
let foundLast = false;
|
|
309
|
+
let recordCountFromTail = 0;
|
|
310
|
+
let tailMaxSequence = 0;
|
|
78
311
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
79
312
|
try {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
313
|
+
const parsed = JSON.parse(lines[i]);
|
|
314
|
+
recordCountFromTail++;
|
|
315
|
+
if (!foundLast) {
|
|
316
|
+
this.lastHash = hashRecord(parsed);
|
|
317
|
+
foundLast = true;
|
|
318
|
+
}
|
|
319
|
+
if (isCheckpoint(parsed)) {
|
|
320
|
+
if (parsed.sequence > tailMaxSequence) {
|
|
321
|
+
tailMaxSequence = parsed.sequence;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
83
324
|
}
|
|
84
325
|
catch {
|
|
85
326
|
process.stderr.write(`[audit-log] warning: corrupt record in tail, skipping\n`);
|
|
86
327
|
}
|
|
87
328
|
}
|
|
329
|
+
if (tailMaxSequence > this.checkpointSequence) {
|
|
330
|
+
this.checkpointSequence = tailMaxSequence;
|
|
331
|
+
}
|
|
332
|
+
if (boundaryHash !== undefined && firstRecordPrevHash !== undefined &&
|
|
333
|
+
firstRecordPrevHash !== boundaryHash) {
|
|
334
|
+
if (opts?.forceNewChain) {
|
|
335
|
+
await this.emitChainBreak("state_log_inconsistent");
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
throw new Error("[audit-log] state file inconsistent with log: first record does not " +
|
|
339
|
+
"chain from rotationBoundaryHash. Use --force-new-chain to start a new chain.");
|
|
340
|
+
}
|
|
341
|
+
if (stateResult === "not_found") {
|
|
342
|
+
this.totalRecordCount = recordCountFromTail;
|
|
343
|
+
}
|
|
88
344
|
}
|
|
89
345
|
finally {
|
|
90
346
|
await fh.close();
|
|
91
347
|
}
|
|
92
348
|
}
|
|
93
349
|
}
|
|
350
|
+
async emitChainBreak(reason) {
|
|
351
|
+
const record = {
|
|
352
|
+
id: `break_${randomUUID()}`,
|
|
353
|
+
type: "chain_break",
|
|
354
|
+
timestamp: new Date().toISOString(),
|
|
355
|
+
reason,
|
|
356
|
+
priorHead: this.lastHash !== "genesis" ? this.lastHash : undefined,
|
|
357
|
+
priorSequence: this.checkpointSequence > 0 ? this.checkpointSequence : undefined,
|
|
358
|
+
priorRecordCount: this.totalRecordCount > 0 ? this.totalRecordCount : undefined,
|
|
359
|
+
};
|
|
360
|
+
record.attestation = await this.signer.sign(record);
|
|
361
|
+
const line = JSON.stringify(record) + "\n";
|
|
362
|
+
await appendFile(this.path, line);
|
|
363
|
+
this.currentSize += Buffer.byteLength(line);
|
|
364
|
+
// Reset chain state — this is a new chain.
|
|
365
|
+
// rotationBoundaryHash is NOT updated: it tracks the file boundary,
|
|
366
|
+
// not the chain boundary. The linkage check compares the first record
|
|
367
|
+
// of a file against rotationBoundaryHash, so mid-file breaks must not
|
|
368
|
+
// overwrite it.
|
|
369
|
+
this.lastHash = hashRecord(record);
|
|
370
|
+
this.checkpointSequence = 0;
|
|
371
|
+
this.totalRecordCount = 0;
|
|
372
|
+
this.recordsSinceCheckpoint = 0;
|
|
373
|
+
await this.persistChainState();
|
|
374
|
+
return record;
|
|
375
|
+
}
|
|
376
|
+
async forceNewChain(reason) {
|
|
377
|
+
return new Promise((resolve, reject) => {
|
|
378
|
+
this.writeQueue = this.writeQueue.then(async () => {
|
|
379
|
+
try {
|
|
380
|
+
const result = await this.emitChainBreak(reason);
|
|
381
|
+
resolve(result);
|
|
382
|
+
}
|
|
383
|
+
catch (err) {
|
|
384
|
+
reject(err);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
}
|
|
94
389
|
}
|
|
95
390
|
//# sourceMappingURL=audit-log.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-log.js","sourceRoot":"","sources":["../../src/attestation/audit-log.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"audit-log.js","sourceRoot":"","sources":["../../src/attestation/audit-log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,YAAY,EAAgB,MAAM,aAAa,CAAC;AAGzD,MAAM,wBAAwB,GAAG;IAC/B,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW;IACpD,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW;IAC7D,cAAc;CACf,CAAC;AAEF,SAAS,YAAY,CAAC,kBAA2B,EAAE,eAAwB;IACzE,MAAM,OAAO,GAAuB;QAClC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,wBAAwB,EAAE;KACvE,CAAC;IACF,IAAI,kBAAkB,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,CAAC,uBAAuB,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,CAAC,cAAc,CAAC;SACxB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAyD;IAClF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC;AASD,MAAM,OAAO,QAAQ;IAWT;IACA;IACA;IAZF,WAAW,GAAG,CAAC,CAAC;IAChB,QAAQ,GAAW,SAAS,CAAC;IAC7B,UAAU,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAC9C,sBAAsB,GAAG,CAAC,CAAC;IAC3B,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAChC,kBAAkB,GAAG,CAAC,CAAC;IACvB,gBAAgB,GAAG,CAAC,CAAC;IACrB,gBAAgB,GAA4B,IAAI,CAAC;IAEzD,YACU,IAAY,EACZ,MAAc,EACd,gBAAwB;QAFxB,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAQ;QACd,qBAAgB,GAAhB,gBAAgB,CAAQ;IAC/B,CAAC;IAEJ,iBAAiB,CAAC,MAAwB;QACxC,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,MAAM,CACV,MAAc,EACd,IAUC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;gBAChD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;oBACpD,OAAO,CAAC,MAAM,CAAC,CAAC;gBAClB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,WAAW,CACvB,MAAc,EACd,IAUC;QAED,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;QACvC,MAAM,MAAM,GAAgB;YAC1B,EAAE,EAAE,UAAU,EAAE;YAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM;YACN,GAAG,IAAI;YACP,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,qBAAqB,IAAI,IAAI,EAAE,YAAY,IAAI,IAAI,CAAC;YAC/E,YAAY,EAAE,IAAI,CAAC,QAAQ;SAC5B,CAAC;QAEF,MAAM,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QAE3C,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAE9B,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAChC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC/B,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC9C,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO;YAAE,OAAO,KAAK,CAAC;QAClD,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,sBAAsB,IAAI,eAAe,CAAC;QAClE,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,eAAe,GAAG,IAAI,CAAC;QAEjF,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,UAAU,CAAC;QAC7C,IAAI,OAAO,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC;QACvC,OAAO,UAAU,IAAI,OAAO,CAAC;IAC/B,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAqB;YACnC,EAAE,EAAE,QAAQ,UAAU,EAAE,EAAE;YAC1B,IAAI,EAAE,YAAY;YAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,QAAQ,EAAE,IAAI,CAAC,kBAAkB;YACjC,WAAW,EAAE,IAAI,CAAC,gBAAgB;YAClC,YAAY,EAAE,IAAI,CAAC,QAAQ;YAC3B,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,cAAc,CAAC,EAAE,CAAC;SACrG,CAAC;QAEF,UAAU,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;QAE/C,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,CAAC,sBAAsB,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAErC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;gBAChD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;oBAC5C,OAAO,CAAC,MAAM,CAAC,CAAC;gBAClB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,qBAAqB;QACnB,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAEO,KAAK,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;YACrB,kEAAkE;YAClE,kEAAkE;YAClE,6EAA6E;YAC7E,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAEO,oBAAoB,GAAW,SAAS,CAAC;IAEzC,KAAK,CAAC,YAAY;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;QACnC,MAAM,KAAK,GAAG;YACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,oBAAoB,EAAE,IAAI,CAAC,QAAQ;YACnC,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC;QACF,MAAM,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAClD,MAAM,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;QACnC,MAAM,KAAK,GAAG;YACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;YAC/C,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC;QACF,MAAM,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAClD,MAAM,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAC/D,IAAI,CAAC;YACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACtD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,kBAAkB,KAAK,QAAQ;gBAClF,OAAO,KAAK,CAAC,oBAAoB,KAAK,QAAQ,EAAE,CAAC;gBACnD,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YAC/B,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC,oBAAoB,CAAC;YACvD,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC,kBAAkB,IAAI,CAAC,CAAC;YACxD,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC;YACpD,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,IAAI,GAAI,GAA6B,EAAE,IAAI,CAAC;YAClD,IAAI,IAAI,KAAK,QAAQ;gBAAE,OAAO,WAAW,CAAC;YAC1C,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAkC;QAC3C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAE9C,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,CAAC;QACN,IAAI,CAAC;YACH,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,qBAAqB;QACrB,gDAAgD;QAChD,IAAI,WAAW,KAAK,WAAW,IAAI,CAAC,SAAS,EAAE,CAAC;YAC9C,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,0EAA0E;QAC1E,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,IAAI,EAAE,aAAa,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;gBAChD,OAAO;YACT,CAAC;YACD,MAAM,IAAI,KAAK,CACb,kDAAkD;gBAClD,iFAAiF,CAClF,CAAC;QACJ,CAAC;QAED,2DAA2D;QAC3D,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,CAAE,CAAC,IAAI,CAAC;QAE3B,IAAI,CAAE,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,YAAY,GAAG,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC;YACrF,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACtC,IAAI,CAAC;gBACH,IAAI,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC9B,IAAI,MAAM,GAAG,CAAC,CAAC;gBACf,MAAM,SAAS,GAAG,IAAI,CAAC;gBACvB,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC;gBACjC,IAAI,SAAS,GAAkB,IAAI,CAAC;gBACpC,OAAO,MAAM,GAAG,CAAE,CAAC,IAAI,EAAE,CAAC;oBACxB,IAAI,OAAO,CAAC,MAAM,IAAI,YAAY,EAAE,CAAC;wBACnC,IAAI,IAAI,EAAE,aAAa,EAAE,CAAC;4BACxB,MAAM,IAAI,CAAC,cAAc,CAAC,2BAA2B,CAAC,CAAC;4BACvD,OAAO;wBACT,CAAC;wBACD,MAAM,IAAI,KAAK,CACb,4EAA4E;4BAC5E,6CAA6C,CAC9C,CAAC;oBACJ,CAAC;oBACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAE,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;oBACvD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBACrC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;oBAC1C,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;oBAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;oBACvC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBACjC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;wBACjB,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;wBACjC,MAAM;oBACR,CAAC;oBACD,MAAM,IAAI,QAAQ,CAAC;gBACrB,CAAC;gBACD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;oBACvB,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC9C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACtB,IAAI,IAAI,EAAE,aAAa,EAAE,CAAC;4BACxB,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC;4BAClD,OAAO;wBACT,CAAC;wBACD,MAAM,IAAI,KAAK,CACb,iEAAiE;4BACjE,6CAA6C,CAC9C,CAAC;oBACJ,CAAC;oBACD,SAAS,GAAG,IAAI,CAAC;gBACnB,CAAC;gBAED,+DAA+D;gBAC/D,IAAI,mBAAuC,CAAC;gBAC5C,IAAI,kBAAkB,GAAG,KAAK,CAAC;gBAC/B,IAAI,CAAC;oBACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;oBAC1C,IAAI,WAAW,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;wBACvC,kBAAkB,GAAG,IAAI,CAAC;wBAC1B,mBAAmB,GAAG,WAAW,CAAC,SAAS,CAAC;oBAC9C,CAAC;yBAAM,CAAC;wBACN,mBAAmB,GAAG,WAAW,CAAC,YAAY,CAAC;oBACjD,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,IAAI,IAAI,EAAE,aAAa,EAAE,CAAC;wBACxB,MAAM,IAAI,CAAC,cAAc,CAAC,0BAA0B,CAAC,CAAC;wBACtD,OAAO;oBACT,CAAC;oBACD,MAAM,IAAI,KAAK,CACb,iEAAiE;wBACjE,6CAA6C,CAC9C,CAAC;gBACJ,CAAC;gBAED,qDAAqD;gBACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACzC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACnC,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAE,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC;gBACpD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACnC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzC,IAAI,SAAS,GAAG,KAAK,CAAC;gBACtB,IAAI,mBAAmB,GAAG,CAAC,CAAC;gBAC5B,IAAI,eAAe,GAAG,CAAC,CAAC;gBAExB,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3C,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;wBACpC,mBAAmB,EAAE,CAAC;wBAEtB,IAAI,CAAC,SAAS,EAAE,CAAC;4BACf,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;4BACnC,SAAS,GAAG,IAAI,CAAC;wBACnB,CAAC;wBAED,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;4BACzB,IAAI,MAAM,CAAC,QAAQ,GAAG,eAAe,EAAE,CAAC;gCACtC,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC;4BACpC,CAAC;wBACH,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yDAAyD,CAC1D,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,IAAI,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAC9C,IAAI,CAAC,kBAAkB,GAAG,eAAe,CAAC;gBAC5C,CAAC;gBAED,IAAI,YAAY,KAAK,SAAS,IAAI,mBAAmB,KAAK,SAAS;oBAC/D,mBAAmB,KAAK,YAAY,EAAE,CAAC;oBACzC,IAAI,IAAI,EAAE,aAAa,EAAE,CAAC;wBACxB,MAAM,IAAI,CAAC,cAAc,CAAC,wBAAwB,CAAC,CAAC;wBACpD,OAAO;oBACT,CAAC;oBACD,MAAM,IAAI,KAAK,CACb,sEAAsE;wBACtE,8EAA8E,CAC/E,CAAC;gBACJ,CAAC;gBAED,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;oBAChC,IAAI,CAAC,gBAAgB,GAAG,mBAAmB,CAAC;gBAC9C,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,MAAc;QACzC,MAAM,MAAM,GAAqB;YAC/B,EAAE,EAAE,SAAS,UAAU,EAAE,EAAE;YAC3B,IAAI,EAAE,aAAa;YACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YAClE,aAAa,EAAE,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS;YAChF,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS;SAChF,CAAC;QAEF,MAAM,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QAE3C,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAE5C,2CAA2C;QAC3C,oEAAoE;QACpE,sEAAsE;QACtE,sEAAsE;QACtE,gBAAgB;QAChB,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,sBAAsB,GAAG,CAAC,CAAC;QAEhC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,MAAc;QAChC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;gBAChD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;oBACjD,OAAO,CAAC,MAAM,CAAC,CAAC;gBAClB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|