@axtary/ledger 0.0.1 → 0.2.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/LICENSE +202 -0
- package/README.md +82 -3
- package/dist/behavior.d.ts +81 -0
- package/dist/behavior.d.ts.map +1 -0
- package/dist/behavior.js +0 -0
- package/dist/behavior.js.map +1 -0
- package/dist/forensics.d.ts +52 -0
- package/dist/forensics.d.ts.map +1 -0
- package/dist/forensics.js +249 -0
- package/dist/forensics.js.map +1 -0
- package/dist/index.d.ts +663 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +928 -29
- package/dist/index.js.map +1 -1
- package/dist/merkle.d.ts +42 -0
- package/dist/merkle.d.ts.map +1 -0
- package/dist/merkle.js +213 -0
- package/dist/merkle.js.map +1 -0
- package/package.json +6 -6
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
// Offline forensic reconstruction of a delegation+execution incident from the
|
|
2
|
+
// decision ledger alone (spec/actionpass-v0.md §9.5).
|
|
3
|
+
//
|
|
4
|
+
// Given an ordered list of verified ledger records, this rebuilds the delegation
|
|
5
|
+
// forest and execution timeline and deterministically asserts three properties:
|
|
6
|
+
//
|
|
7
|
+
// - delegation_attenuation — the recorded delegation structure is a
|
|
8
|
+
// well-formed, depth-monotonic, single-root tree (the ledger-visible
|
|
9
|
+
// evidence of attenuated delegation; strict scope-subset attenuation is
|
|
10
|
+
// enforced at issuance/verification in @axtary/actionpass, not re-derivable
|
|
11
|
+
// from the ledger because passes carry scope, the ledger carries hashes).
|
|
12
|
+
// - forensic_reconstructibility — every execution is attributable to a pass
|
|
13
|
+
// with a prior authorizing decision in the same chain; no orphan execution.
|
|
14
|
+
// - cascade_containment — once a pass is revoked (a deny record naming
|
|
15
|
+
// it with an `actionpass_revoked` reason), neither it nor any descendant
|
|
16
|
+
// records a later successful execution.
|
|
17
|
+
//
|
|
18
|
+
// This is a deterministic, read-only auditor primitive — not anomaly detection,
|
|
19
|
+
// scoring, or monitoring (PRD §4 non-goals). It reads records and reports facts.
|
|
20
|
+
export const LEDGER_FORENSICS_VERSION = "axtary.ledger_forensics.v0";
|
|
21
|
+
/** A reason token marking a record as a revocation denial for its pass. */
|
|
22
|
+
const REVOCATION_REASON = /(^|_)actionpass_revoked($|_)|(^|\b)actionpass_revoked\b/;
|
|
23
|
+
function ensureNode(nodes, passId) {
|
|
24
|
+
let node = nodes.get(passId);
|
|
25
|
+
if (!node) {
|
|
26
|
+
node = {
|
|
27
|
+
passId,
|
|
28
|
+
parentPassId: null,
|
|
29
|
+
rootPassId: passId,
|
|
30
|
+
depth: 0,
|
|
31
|
+
recordIndices: [],
|
|
32
|
+
executions: [],
|
|
33
|
+
revokedAtIndex: null,
|
|
34
|
+
};
|
|
35
|
+
nodes.set(passId, node);
|
|
36
|
+
}
|
|
37
|
+
return node;
|
|
38
|
+
}
|
|
39
|
+
/** Rebuild the delegation forest and execution timeline from ledger records. */
|
|
40
|
+
export function reconstructIncident(records) {
|
|
41
|
+
const nodes = new Map();
|
|
42
|
+
const edges = [];
|
|
43
|
+
const timeline = [];
|
|
44
|
+
records.forEach((record, index) => {
|
|
45
|
+
const passId = record.actionPassId ?? null;
|
|
46
|
+
if (record.delegation) {
|
|
47
|
+
edges.push(record.delegation);
|
|
48
|
+
const child = ensureNode(nodes, record.delegation.childPassId);
|
|
49
|
+
child.parentPassId = record.delegation.parentPassId;
|
|
50
|
+
child.rootPassId = record.delegation.rootPassId;
|
|
51
|
+
child.depth = record.delegation.depth;
|
|
52
|
+
// Surface the parent so a parent that only appears inside a child's edge
|
|
53
|
+
// still becomes a reconstructable node.
|
|
54
|
+
const parent = ensureNode(nodes, record.delegation.parentPassId);
|
|
55
|
+
parent.rootPassId = record.delegation.rootPassId;
|
|
56
|
+
if (record.delegation.parentPassId === record.delegation.rootPassId) {
|
|
57
|
+
parent.depth = 0;
|
|
58
|
+
parent.parentPassId = null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (passId) {
|
|
62
|
+
const node = ensureNode(nodes, passId);
|
|
63
|
+
node.recordIndices.push(index);
|
|
64
|
+
if (record.executionOutcome) {
|
|
65
|
+
node.executions.push({
|
|
66
|
+
recordIndex: index,
|
|
67
|
+
recordId: record.id,
|
|
68
|
+
status: record.executionOutcome.status,
|
|
69
|
+
occurredAt: record.occurredAt,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (node.revokedAtIndex === null &&
|
|
73
|
+
record.reasons.some((reason) => REVOCATION_REASON.test(reason))) {
|
|
74
|
+
node.revokedAtIndex = index;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
timeline.push({
|
|
78
|
+
recordIndex: index,
|
|
79
|
+
recordId: record.id,
|
|
80
|
+
occurredAt: record.occurredAt,
|
|
81
|
+
passId,
|
|
82
|
+
decision: record.decision,
|
|
83
|
+
reasons: record.reasons,
|
|
84
|
+
executionStatus: record.executionOutcome?.status ?? null,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
const childIds = new Set(edges.map((edge) => edge.childPassId));
|
|
88
|
+
const roots = [...nodes.keys()].filter((id) => !childIds.has(id)).sort();
|
|
89
|
+
return {
|
|
90
|
+
nodes: [...nodes.values()].sort((a, b) => a.passId.localeCompare(b.passId)),
|
|
91
|
+
edges,
|
|
92
|
+
roots,
|
|
93
|
+
timeline,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** All descendants (inclusive) of `passId` following parent->child edges. */
|
|
97
|
+
function subtree(passId, childrenOf) {
|
|
98
|
+
const out = new Set([passId]);
|
|
99
|
+
const stack = [passId];
|
|
100
|
+
while (stack.length > 0) {
|
|
101
|
+
const current = stack.pop();
|
|
102
|
+
for (const child of childrenOf.get(current) ?? []) {
|
|
103
|
+
if (!out.has(child)) {
|
|
104
|
+
out.add(child);
|
|
105
|
+
stack.push(child);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
/** Reconstruct the incident and assert the three forensic properties. */
|
|
112
|
+
export function analyzeForensics(records) {
|
|
113
|
+
const incident = reconstructIncident(records);
|
|
114
|
+
const byId = new Map(incident.nodes.map((node) => [node.passId, node]));
|
|
115
|
+
const childrenOf = new Map();
|
|
116
|
+
for (const edge of incident.edges) {
|
|
117
|
+
const list = childrenOf.get(edge.parentPassId) ?? [];
|
|
118
|
+
list.push(edge.childPassId);
|
|
119
|
+
childrenOf.set(edge.parentPassId, list);
|
|
120
|
+
}
|
|
121
|
+
// 1. delegation_attenuation — depth-monotonic, single-root, acyclic tree.
|
|
122
|
+
const attenuation = [];
|
|
123
|
+
const edgeByChild = new Map();
|
|
124
|
+
for (const edge of incident.edges) {
|
|
125
|
+
const prior = edgeByChild.get(edge.childPassId);
|
|
126
|
+
if (prior && prior.parentPassId !== edge.parentPassId) {
|
|
127
|
+
attenuation.push(`multiple_parents:${edge.childPassId}`);
|
|
128
|
+
}
|
|
129
|
+
if (prior &&
|
|
130
|
+
(prior.rootPassId !== edge.rootPassId || prior.depth !== edge.depth)) {
|
|
131
|
+
attenuation.push(`edge_metadata_inconsistent:${edge.childPassId}`);
|
|
132
|
+
}
|
|
133
|
+
edgeByChild.set(edge.childPassId, prior ?? edge);
|
|
134
|
+
}
|
|
135
|
+
for (const edge of incident.edges) {
|
|
136
|
+
const parentEdge = edgeByChild.get(edge.parentPassId);
|
|
137
|
+
const expectedDepth = edge.parentPassId === edge.rootPassId
|
|
138
|
+
? 1
|
|
139
|
+
: parentEdge
|
|
140
|
+
? parentEdge.depth + 1
|
|
141
|
+
: null;
|
|
142
|
+
if (expectedDepth === null) {
|
|
143
|
+
attenuation.push(`root_unreachable:${edge.childPassId}:root=${edge.rootPassId}`);
|
|
144
|
+
}
|
|
145
|
+
else if (edge.depth !== expectedDepth) {
|
|
146
|
+
attenuation.push(`depth_not_monotonic:${edge.childPassId}:edge=${edge.depth}:expected=${expectedDepth}`);
|
|
147
|
+
}
|
|
148
|
+
if (parentEdge && parentEdge.rootPassId !== edge.rootPassId) {
|
|
149
|
+
attenuation.push(`root_inconsistent:${edge.childPassId}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Walking the first recorded parent edge from any node must terminate at the
|
|
153
|
+
// declared root. Multiple-parent/metadata conflicts are reported above.
|
|
154
|
+
for (const node of incident.nodes) {
|
|
155
|
+
const visited = new Set();
|
|
156
|
+
let cursor = node.passId;
|
|
157
|
+
while (cursor) {
|
|
158
|
+
if (visited.has(cursor)) {
|
|
159
|
+
attenuation.push(`cycle_detected:${node.passId}`);
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
visited.add(cursor);
|
|
163
|
+
cursor = edgeByChild.get(cursor)?.parentPassId ?? null;
|
|
164
|
+
}
|
|
165
|
+
const incoming = edgeByChild.get(node.passId);
|
|
166
|
+
if (incoming &&
|
|
167
|
+
!visited.has(incoming.rootPassId)) {
|
|
168
|
+
attenuation.push(`root_inconsistent:${node.passId}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// 2. forensic_reconstructibility — every execution points to the exact,
|
|
172
|
+
// earlier authorizing allow record for the same pass.
|
|
173
|
+
const reconstructibility = [];
|
|
174
|
+
const recordIndexById = new Map(records.map((record, index) => [record.id, index]));
|
|
175
|
+
records.forEach((record, index) => {
|
|
176
|
+
if (!record.executionOutcome)
|
|
177
|
+
return;
|
|
178
|
+
if (!record.actionPassId) {
|
|
179
|
+
reconstructibility.push(`execution_without_pass:${record.id}`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (!record.correlationId) {
|
|
183
|
+
reconstructibility.push(`execution_without_correlation:${record.actionPassId}:${record.id}`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const authorizationIndex = recordIndexById.get(record.correlationId);
|
|
187
|
+
if (authorizationIndex === undefined) {
|
|
188
|
+
reconstructibility.push(`execution_authorization_missing:${record.actionPassId}:${record.id}`);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (authorizationIndex >= index) {
|
|
192
|
+
reconstructibility.push(`execution_authorization_not_prior:${record.actionPassId}:${record.id}`);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const authorization = records[authorizationIndex];
|
|
196
|
+
if (authorization.actionPassId !== record.actionPassId) {
|
|
197
|
+
reconstructibility.push(`execution_authorization_pass_mismatch:${record.actionPassId}:${record.id}`);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (authorization.decision !== "allow") {
|
|
201
|
+
reconstructibility.push(`execution_without_authorization:${record.actionPassId}:${record.id}`);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
// 3. cascade_containment — no descendant of a revoked pass succeeds afterward.
|
|
205
|
+
const containment = [];
|
|
206
|
+
for (const node of incident.nodes) {
|
|
207
|
+
if (node.revokedAtIndex === null)
|
|
208
|
+
continue;
|
|
209
|
+
const affected = subtree(node.passId, childrenOf);
|
|
210
|
+
for (const descendantId of affected) {
|
|
211
|
+
const descendant = byId.get(descendantId);
|
|
212
|
+
if (!descendant)
|
|
213
|
+
continue;
|
|
214
|
+
for (const execution of descendant.executions) {
|
|
215
|
+
if (execution.status === "succeeded" &&
|
|
216
|
+
execution.recordIndex > node.revokedAtIndex) {
|
|
217
|
+
containment.push(`post_revocation_success:revoked=${node.passId}:descendant=${descendantId}:record=${execution.recordId}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const properties = [
|
|
223
|
+
{
|
|
224
|
+
property: "delegation_attenuation",
|
|
225
|
+
holds: attenuation.length === 0,
|
|
226
|
+
violations: attenuation,
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
property: "forensic_reconstructibility",
|
|
230
|
+
holds: reconstructibility.length === 0,
|
|
231
|
+
violations: reconstructibility,
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
property: "cascade_containment",
|
|
235
|
+
holds: containment.length === 0,
|
|
236
|
+
violations: containment,
|
|
237
|
+
},
|
|
238
|
+
];
|
|
239
|
+
return {
|
|
240
|
+
schemaVersion: LEDGER_FORENSICS_VERSION,
|
|
241
|
+
recordCount: records.length,
|
|
242
|
+
roots: incident.roots,
|
|
243
|
+
nodeCount: incident.nodes.length,
|
|
244
|
+
edgeCount: incident.edges.length,
|
|
245
|
+
properties,
|
|
246
|
+
valid: properties.every((property) => property.holds),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=forensics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forensics.js","sourceRoot":"","sources":["../src/forensics.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,sDAAsD;AACtD,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,4EAA4E;AAC5E,gFAAgF;AAChF,8EAA8E;AAC9E,8EAA8E;AAC9E,gFAAgF;AAChF,gFAAgF;AAChF,6EAA6E;AAC7E,4CAA4C;AAC5C,EAAE;AACF,gFAAgF;AAChF,iFAAiF;AAIjF,MAAM,CAAC,MAAM,wBAAwB,GAAG,4BAA4B,CAAC;AAErE,2EAA2E;AAC3E,MAAM,iBAAiB,GAAG,yDAAyD,CAAC;AAwDpF,SAAS,UAAU,CACjB,KAAgC,EAChC,MAAc;IAEd,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG;YACL,MAAM;YACN,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,MAAM;YAClB,KAAK,EAAE,CAAC;YACR,aAAa,EAAE,EAAE;YACjB,UAAU,EAAE,EAAE;YACd,cAAc,EAAE,IAAI;SACrB,CAAC;QACF,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,mBAAmB,CAAC,OAAuB;IACzD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC9C,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAE7C,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC;QAE3C,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC9B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YAC/D,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC;YACpD,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;YAChD,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;YACtC,yEAAyE;YACzE,wCAAwC;YACxC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACjE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;YACjD,IAAI,MAAM,CAAC,UAAU,CAAC,YAAY,KAAK,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;gBACpE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;gBACjB,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACvC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;gBAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;oBACnB,WAAW,EAAE,KAAK;oBAClB,QAAQ,EAAE,MAAM,CAAC,EAAE;oBACnB,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC,MAAM;oBACtC,UAAU,EAAE,MAAM,CAAC,UAAU;iBAC9B,CAAC,CAAC;YACL,CAAC;YACD,IACE,IAAI,CAAC,cAAc,KAAK,IAAI;gBAC5B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAC/D,CAAC;gBACD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC;YACZ,WAAW,EAAE,KAAK;YAClB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,MAAM;YACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,eAAe,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,IAAI,IAAI;SACzD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAEzE,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC3E,KAAK;QACL,KAAK;QACL,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,SAAS,OAAO,CAAC,MAAc,EAAE,UAAiC;IAChE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,OAAuB;IACtD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5B,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,0EAA0E;IAC1E,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAgC,CAAC;IAC5D,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChD,IAAI,KAAK,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACtD,WAAW,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,IACE,KAAK;YACL,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,EACpE,CAAC;YACD,WAAW,CAAC,IAAI,CAAC,8BAA8B,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACtD,MAAM,aAAa,GACjB,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,UAAU;YACnC,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,UAAU;gBACV,CAAC,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC;gBACtB,CAAC,CAAC,IAAI,CAAC;QACb,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC3B,WAAW,CAAC,IAAI,CACd,oBAAoB,IAAI,CAAC,WAAW,SAAS,IAAI,CAAC,UAAU,EAAE,CAC/D,CAAC;QACJ,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;YACxC,WAAW,CAAC,IAAI,CACd,uBAAuB,IAAI,CAAC,WAAW,SAAS,IAAI,CAAC,KAAK,aAAa,aAAa,EAAE,CACvF,CAAC;QACJ,CAAC;QAED,IAAI,UAAU,IAAI,UAAU,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5D,WAAW,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,wEAAwE;IACxE,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,IAAI,MAAM,GAAkB,IAAI,CAAC,MAAM,CAAC;QACxC,OAAO,MAAM,EAAE,CAAC;YACd,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxB,WAAW,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBAClD,MAAM;YACR,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,IAAI,IAAI,CAAC;QACzD,CAAC;QACD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,IACE,QAAQ;YACR,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EACjC,CAAC;YACD,WAAW,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,yDAAyD;IACzD,MAAM,kBAAkB,GAAa,EAAE,CAAC;IACxC,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAU,CAAC,CAC5D,CAAC;IACF,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAChC,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAAE,OAAO;QACrC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YACzB,kBAAkB,CAAC,IAAI,CAAC,0BAA0B,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC1B,kBAAkB,CAAC,IAAI,CACrB,iCAAiC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,EAAE,EAAE,CACpE,CAAC;YACF,OAAO;QACT,CAAC;QAED,MAAM,kBAAkB,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACrE,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACrC,kBAAkB,CAAC,IAAI,CACrB,mCAAmC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,EAAE,EAAE,CACtE,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,kBAAkB,IAAI,KAAK,EAAE,CAAC;YAChC,kBAAkB,CAAC,IAAI,CACrB,qCAAqC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,EAAE,EAAE,CACxE,CAAC;YACF,OAAO;QACT,CAAC;QAED,MAAM,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAE,CAAC;QACnD,IAAI,aAAa,CAAC,YAAY,KAAK,MAAM,CAAC,YAAY,EAAE,CAAC;YACvD,kBAAkB,CAAC,IAAI,CACrB,yCAAyC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,EAAE,EAAE,CAC5E,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,aAAa,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACvC,kBAAkB,CAAC,IAAI,CACrB,mCAAmC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,EAAE,EAAE,CACtE,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI;YAAE,SAAS;QAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAClD,KAAK,MAAM,YAAY,IAAI,QAAQ,EAAE,CAAC;YACpC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC1C,IAAI,CAAC,UAAU;gBAAE,SAAS;YAC1B,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;gBAC9C,IACE,SAAS,CAAC,MAAM,KAAK,WAAW;oBAChC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,EAC3C,CAAC;oBACD,WAAW,CAAC,IAAI,CACd,mCAAmC,IAAI,CAAC,MAAM,eAAe,YAAY,WAAW,SAAS,CAAC,QAAQ,EAAE,CACzG,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAuB;QACrC;YACE,QAAQ,EAAE,wBAAwB;YAClC,KAAK,EAAE,WAAW,CAAC,MAAM,KAAK,CAAC;YAC/B,UAAU,EAAE,WAAW;SACxB;QACD;YACE,QAAQ,EAAE,6BAA6B;YACvC,KAAK,EAAE,kBAAkB,CAAC,MAAM,KAAK,CAAC;YACtC,UAAU,EAAE,kBAAkB;SAC/B;QACD;YACE,QAAQ,EAAE,qBAAqB;YAC/B,KAAK,EAAE,WAAW,CAAC,MAAM,KAAK,CAAC;YAC/B,UAAU,EAAE,WAAW;SACxB;KACF,CAAC;IAEF,OAAO;QACL,aAAa,EAAE,wBAAwB;QACvC,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;QAChC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;QAChC,UAAU;QACV,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;KACtD,CAAC;AACJ,CAAC"}
|