@mooloo-ai/eutaxy 0.1.0 → 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/README.md +1 -1
- package/dist/aws.d.mts +15464 -0
- package/dist/aws.d.mts.map +1 -0
- package/dist/aws.mjs +24057 -0
- package/dist/aws.mjs.map +1 -0
- package/dist/bin.mjs +2 -2
- package/dist/checksum-DhS6ofSm.mjs +6049 -0
- package/dist/checksum-DhS6ofSm.mjs.map +1 -0
- package/dist/cli-DnPkIL8h.mjs +2 -0
- package/dist/cli.mjs +2 -2
- package/dist/cloudflare.d.mts +17 -1
- package/dist/cloudflare.d.mts.map +1 -1
- package/dist/cloudflare.mjs +41 -9
- package/dist/cloudflare.mjs.map +1 -1
- package/dist/es5-DtZuPEgt.mjs +1721 -0
- package/dist/es5-DtZuPEgt.mjs.map +1 -0
- package/dist/event-streams-BANyO9xt.mjs +801 -0
- package/dist/event-streams-BANyO9xt.mjs.map +1 -0
- package/dist/explore-C5fDFOoY.d.mts +63 -0
- package/dist/explore-C5fDFOoY.d.mts.map +1 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -2
- package/dist/{explore-BB77_V0x.d.mts → platform-CGVkTa16.d.mts} +30 -65
- package/dist/platform-CGVkTa16.d.mts.map +1 -0
- package/dist/rolldown-runtime-C1I3wEg2.mjs +43 -0
- package/dist/{src-dP-0Apun.mjs → src-B66we2mG.mjs} +3 -2
- package/dist/{src-dP-0Apun.mjs.map → src-B66we2mG.mjs.map} +1 -1
- package/dist/{src-Bef00JwK.mjs → src-BP6Iqc_9.mjs} +3 -88
- package/dist/src-BP6Iqc_9.mjs.map +1 -0
- package/dist/{src-Dn3Lm5Us.mjs → src-BrCsF5RZ.mjs} +223 -28
- package/dist/src-BrCsF5RZ.mjs.map +1 -0
- package/dist/src-s6uYyC0B.mjs +89 -0
- package/dist/src-s6uYyC0B.mjs.map +1 -0
- package/dist/verdict-evEM5Gxx.mjs +12 -0
- package/dist/verdict-evEM5Gxx.mjs.map +1 -0
- package/package.json +20 -3
- package/dist/cli-DTuDOgGM.mjs +0 -2
- package/dist/explore-BB77_V0x.d.mts.map +0 -1
- package/dist/src-Bef00JwK.mjs.map +0 -1
- package/dist/src-Dn3Lm5Us.mjs.map +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// packages/core/src/canonical-json.ts
|
|
2
|
+
function canonicalJson(value) {
|
|
3
|
+
if (value === null) return "null";
|
|
4
|
+
switch (typeof value) {
|
|
5
|
+
case "boolean": return value ? "true" : "false";
|
|
6
|
+
case "number":
|
|
7
|
+
if (!Number.isFinite(value)) throw new TypeError(`non-finite number: ${value}`);
|
|
8
|
+
return Object.is(value, -0) ? "0" : JSON.stringify(value);
|
|
9
|
+
case "string": return JSON.stringify(value);
|
|
10
|
+
case "object": {
|
|
11
|
+
if (Array.isArray(value)) {
|
|
12
|
+
const items = [];
|
|
13
|
+
for (let i = 0; i < value.length; i++) {
|
|
14
|
+
const v = value[i];
|
|
15
|
+
if (v === void 0) throw new TypeError(`hole or undefined at index ${i}`);
|
|
16
|
+
items.push(canonicalJson(v));
|
|
17
|
+
}
|
|
18
|
+
return `[${items.join(",")}]`;
|
|
19
|
+
}
|
|
20
|
+
const keys = Object.keys(value).sort();
|
|
21
|
+
const parts = [];
|
|
22
|
+
for (const k of keys) {
|
|
23
|
+
const v = value[k];
|
|
24
|
+
if (v === void 0) throw new TypeError(`undefined at key ${JSON.stringify(k)}`);
|
|
25
|
+
parts.push(`${JSON.stringify(k)}:${canonicalJson(v)}`);
|
|
26
|
+
}
|
|
27
|
+
return `{${parts.join(",")}}`;
|
|
28
|
+
}
|
|
29
|
+
default: throw new TypeError(`not JSON data: ${typeof value}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// packages/core/src/utf8.ts
|
|
33
|
+
/**
|
|
34
|
+
* UTF-8 encode a string, with no runtime dependency on TextEncoder. An unpaired
|
|
35
|
+
* surrogate becomes U+FFFD, exactly as TextEncoder does, so the output is
|
|
36
|
+
* always valid UTF-8.
|
|
37
|
+
*/
|
|
38
|
+
function utf8Encode(s) {
|
|
39
|
+
const out = [];
|
|
40
|
+
for (const ch of s) {
|
|
41
|
+
let cp = ch.codePointAt(0) ?? 0;
|
|
42
|
+
if (cp >= 55296 && cp <= 57343) cp = 65533;
|
|
43
|
+
if (cp < 128) out.push(cp);
|
|
44
|
+
else if (cp < 2048) out.push(192 | cp >> 6, 128 | cp & 63);
|
|
45
|
+
else if (cp < 65536) out.push(224 | cp >> 12, 128 | cp >> 6 & 63, 128 | cp & 63);
|
|
46
|
+
else out.push(240 | cp >> 18, 128 | cp >> 12 & 63, 128 | cp >> 6 & 63, 128 | cp & 63);
|
|
47
|
+
}
|
|
48
|
+
return Uint8Array.from(out);
|
|
49
|
+
}
|
|
50
|
+
// packages/core/src/effect-log.ts
|
|
51
|
+
/**
|
|
52
|
+
* The effect log: the complete, ordered record of what a simulated run did at
|
|
53
|
+
* its effect boundaries. It is plain data, appended immutably, and has one
|
|
54
|
+
* canonical serialisation, so two runs are identical exactly when their
|
|
55
|
+
* serialised logs are byte-identical.
|
|
56
|
+
*/
|
|
57
|
+
const emptyLog = Object.freeze({ entries: Object.freeze([]) });
|
|
58
|
+
/** Append one effect, assigning its sequence number. The input log is unchanged. */
|
|
59
|
+
function appendEffect(log, effect) {
|
|
60
|
+
const record = {
|
|
61
|
+
...effect,
|
|
62
|
+
seq: log.entries.length
|
|
63
|
+
};
|
|
64
|
+
return { entries: [...log.entries, record] };
|
|
65
|
+
}
|
|
66
|
+
/** One canonical JSON object per line, in sequence order. */
|
|
67
|
+
function serializeLog(log) {
|
|
68
|
+
return log.entries.map((e) => canonicalJson({
|
|
69
|
+
seq: e.seq,
|
|
70
|
+
kind: e.kind,
|
|
71
|
+
invocation: e.invocation,
|
|
72
|
+
target: e.target,
|
|
73
|
+
op: e.op,
|
|
74
|
+
payload: e.payload
|
|
75
|
+
})).join("\n");
|
|
76
|
+
}
|
|
77
|
+
/** A 64-bit FNV-1a digest of the serialised log, as 16 hex digits. Not cryptographic. */
|
|
78
|
+
function digestLog(log) {
|
|
79
|
+
const bytes = utf8Encode(serializeLog(log));
|
|
80
|
+
let h = 14695981039346656037n;
|
|
81
|
+
for (const b of bytes) {
|
|
82
|
+
h ^= BigInt(b);
|
|
83
|
+
h = h * 1099511628211n & 18446744073709551615n;
|
|
84
|
+
}
|
|
85
|
+
return h.toString(16).padStart(16, "0");
|
|
86
|
+
}
|
|
87
|
+
export { canonicalJson as i, digestLog as n, emptyLog as r, appendEffect as t };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=src-s6uYyC0B.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-s6uYyC0B.mjs","names":[],"sources":["../../core/src/canonical-json.ts","../../core/src/utf8.ts","../../core/src/effect-log.ts"],"sourcesContent":["/**\n * Canonical JSON: the one serialisation of a value, so that equal data always\n * produces equal bytes. Object keys are sorted; numbers must be finite; there\n * is no whitespace. Anything that is not plain JSON data is rejected.\n */\n\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | readonly JsonValue[]\n | { readonly [key: string]: JsonValue };\n\nexport function canonicalJson(value: JsonValue): string {\n if (value === null) return \"null\";\n switch (typeof value) {\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"number\":\n if (!Number.isFinite(value)) throw new TypeError(`non-finite number: ${value}`);\n return Object.is(value, -0) ? \"0\" : JSON.stringify(value);\n case \"string\":\n return JSON.stringify(value);\n case \"object\": {\n if (Array.isArray(value)) {\n const items: string[] = [];\n for (let i = 0; i < value.length; i++) {\n const v = value[i];\n if (v === undefined) throw new TypeError(`hole or undefined at index ${i}`);\n items.push(canonicalJson(v));\n }\n return `[${items.join(\",\")}]`;\n }\n const keys = Object.keys(value).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const v = (value as { readonly [key: string]: JsonValue | undefined })[k];\n if (v === undefined) throw new TypeError(`undefined at key ${JSON.stringify(k)}`);\n parts.push(`${JSON.stringify(k)}:${canonicalJson(v)}`);\n }\n return `{${parts.join(\",\")}}`;\n }\n default:\n throw new TypeError(`not JSON data: ${typeof value}`);\n }\n}\n","/**\n * UTF-8 encode a string, with no runtime dependency on TextEncoder. An unpaired\n * surrogate becomes U+FFFD, exactly as TextEncoder does, so the output is\n * always valid UTF-8.\n */\nexport function utf8Encode(s: string): Uint8Array {\n const out: number[] = [];\n for (const ch of s) {\n let cp = ch.codePointAt(0) ?? 0;\n if (cp >= 0xd800 && cp <= 0xdfff) cp = 0xfffd;\n if (cp < 0x80) out.push(cp);\n else if (cp < 0x800) out.push(0xc0 | (cp >> 6), 0x80 | (cp & 0x3f));\n else if (cp < 0x10000)\n out.push(0xe0 | (cp >> 12), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));\n else\n out.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f),\n );\n }\n return Uint8Array.from(out);\n}\n\n/** True when two byte arrays are identical in length and content. */\nexport function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n","/**\n * The effect log: the complete, ordered record of what a simulated run did at\n * its effect boundaries. It is plain data, appended immutably, and has one\n * canonical serialisation, so two runs are identical exactly when their\n * serialised logs are byte-identical.\n */\n\nimport { canonicalJson, type JsonValue } from \"./canonical-json.ts\";\nimport { utf8Encode } from \"./utf8.ts\";\n\n/** `snapshot` records platform state (e.g. D1 tables) captured at the end of a run; it is not an effect point. */\nexport type EffectKind = \"call\" | \"result\" | \"fault\" | \"snapshot\";\n\nexport interface EffectRecord {\n /** Position in the log, dense from 0. */\n readonly seq: number;\n readonly kind: EffectKind;\n /** The invocation (request, message, alarm) this effect belongs to. */\n readonly invocation: string;\n /** The binding or global the effect went through, e.g. \"D1:DB\". */\n readonly target: string;\n /** The operation, e.g. \"run\", \"batch\", \"send\". */\n readonly op: string;\n /** Operation-specific data: arguments, results, or the injected fault. */\n readonly payload: JsonValue;\n}\n\nexport interface EffectLog {\n readonly entries: readonly EffectRecord[];\n}\n\nexport const emptyLog: EffectLog = Object.freeze({ entries: Object.freeze([]) });\n\n/** Append one effect, assigning its sequence number. The input log is unchanged. */\nexport function appendEffect(log: EffectLog, effect: Omit<EffectRecord, \"seq\">): EffectLog {\n const record: EffectRecord = { ...effect, seq: log.entries.length };\n return { entries: [...log.entries, record] };\n}\n\n/** One canonical JSON object per line, in sequence order. */\nexport function serializeLog(log: EffectLog): string {\n return log.entries\n .map((e) =>\n canonicalJson({\n seq: e.seq,\n kind: e.kind,\n invocation: e.invocation,\n target: e.target,\n op: e.op,\n payload: e.payload,\n }),\n )\n .join(\"\\n\");\n}\n\n/** A 64-bit FNV-1a digest of the serialised log, as 16 hex digits. Not cryptographic. */\nexport function digestLog(log: EffectLog): string {\n const bytes = utf8Encode(serializeLog(log));\n let h = 0xcbf29ce484222325n;\n for (const b of bytes) {\n h ^= BigInt(b);\n h = (h * 0x100000001b3n) & 0xffffffffffffffffn;\n }\n return h.toString(16).padStart(16, \"0\");\n}\n"],"mappings":";AAcA,SAAgB,cAAc,OAA0B;CACtD,IAAI,UAAU,MAAM,OAAO;CAC3B,QAAQ,OAAO,OAAf;EACE,KAAK,WACH,OAAO,QAAQ,SAAS;EAC1B,KAAK;GACH,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,UAAU,sBAAsB,OAAO;GAC9E,OAAO,OAAO,GAAG,OAAO,EAAE,IAAI,MAAM,KAAK,UAAU,KAAK;EAC1D,KAAK,UACH,OAAO,KAAK,UAAU,KAAK;EAC7B,KAAK,UAAU;GACb,IAAI,MAAM,QAAQ,KAAK,GAAG;IACxB,MAAM,QAAkB,CAAC;IACzB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;KACrC,MAAM,IAAI,MAAM;KAChB,IAAI,MAAM,KAAA,GAAW,MAAM,IAAI,UAAU,8BAA8B,GAAG;KAC1E,MAAM,KAAK,cAAc,CAAC,CAAC;IAC7B;IACA,OAAO,IAAI,MAAM,KAAK,GAAG,EAAE;GAC7B;GACA,MAAM,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,KAAK;GACrC,MAAM,QAAkB,CAAC;GACzB,KAAK,MAAM,KAAK,MAAM;IACpB,MAAM,IAAK,MAA4D;IACvE,IAAI,MAAM,KAAA,GAAW,MAAM,IAAI,UAAU,oBAAoB,KAAK,UAAU,CAAC,GAAG;IAChF,MAAM,KAAK,GAAG,KAAK,UAAU,CAAC,EAAE,GAAG,cAAc,CAAC,GAAG;GACvD;GACA,OAAO,IAAI,MAAM,KAAK,GAAG,EAAE;EAC7B;EACA,SACE,MAAM,IAAI,UAAU,kBAAkB,OAAO,OAAO;CACxD;AACF;;;;;;;ACzCA,SAAgB,WAAW,GAAuB;CAChD,MAAM,MAAgB,CAAC;CACvB,KAAK,MAAM,MAAM,GAAG;EAClB,IAAI,KAAK,GAAG,YAAY,CAAC,KAAK;EAC9B,IAAI,MAAM,SAAU,MAAM,OAAQ,KAAK;EACvC,IAAI,KAAK,KAAM,IAAI,KAAK,EAAE;OACrB,IAAI,KAAK,MAAO,IAAI,KAAK,MAAQ,MAAM,GAAI,MAAQ,KAAK,EAAK;OAC7D,IAAI,KAAK,OACZ,IAAI,KAAK,MAAQ,MAAM,IAAK,MAAS,MAAM,IAAK,IAAO,MAAQ,KAAK,EAAK;OAEzE,IAAI,KACF,MAAQ,MAAM,IACd,MAAS,MAAM,KAAM,IACrB,MAAS,MAAM,IAAK,IACpB,MAAQ,KAAK,EACf;CACJ;CACA,OAAO,WAAW,KAAK,GAAG;AAC5B;;;;;;;;ACQA,MAAa,WAAsB,OAAO,OAAO,EAAE,SAAS,OAAO,OAAO,CAAC,CAAC,EAAE,CAAC;;AAG/E,SAAgB,aAAa,KAAgB,QAA8C;CACzF,MAAM,SAAuB;EAAE,GAAG;EAAQ,KAAK,IAAI,QAAQ;CAAO;CAClE,OAAO,EAAE,SAAS,CAAC,GAAG,IAAI,SAAS,MAAM,EAAE;AAC7C;;AAGA,SAAgB,aAAa,KAAwB;CACnD,OAAO,IAAI,QACR,KAAK,MACJ,cAAc;EACZ,KAAK,EAAE;EACP,MAAM,EAAE;EACR,YAAY,EAAE;EACd,QAAQ,EAAE;EACV,IAAI,EAAE;EACN,SAAS,EAAE;CACb,CAAC,CACH,CAAC,CACA,KAAK,IAAI;AACd;;AAGA,SAAgB,UAAU,KAAwB;CAChD,MAAM,QAAQ,WAAW,aAAa,GAAG,CAAC;CAC1C,IAAI,IAAI;CACR,KAAK,MAAM,KAAK,OAAO;EACrB,KAAK,OAAO,CAAC;EACb,IAAK,IAAI,iBAAkB;CAC7B;CACA,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,GAAG;AACxC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// packages/core/src/verdict.ts
|
|
2
|
+
/** One line per verdict, for error messages; full rendering lives in `report`. */
|
|
3
|
+
function describeVerdict(v) {
|
|
4
|
+
switch (v.kind) {
|
|
5
|
+
case "VIOLATED": return `VIOLATED ${v.scenario}: ${v.violation.message} (seed ${v.schedule.seed}, ${v.reached.runs} run(s))`;
|
|
6
|
+
case "BOUNDED": return `BOUNDED ${v.scenario}: no violation in ${v.reached.runs} run(s), ${v.reached.effectPoints} effect point(s), ${v.reached.faultsInjected} fault(s)`;
|
|
7
|
+
case "UNSUPPORTED": return `UNSUPPORTED ${v.scenario}: ${v.cause}: ${v.reason}`;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export { describeVerdict as t };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=verdict-evEM5Gxx.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-evEM5Gxx.mjs","names":[],"sources":["../../core/src/verdict.ts"],"sourcesContent":["/** Simulation verdicts, with what each one rests on. */\n\nimport type { EffectLog } from \"./effect-log.ts\";\nimport type { Schedule } from \"./faults.ts\";\nimport type { Violation } from \"./invariants.ts\";\nimport type { Bounds } from \"./scenario.ts\";\n\nexport interface BoundsReached {\n readonly runs: number;\n readonly effectPoints: number;\n readonly faultsInjected: number;\n readonly elapsedMs: number;\n}\n\ninterface VerdictBase {\n readonly scenario: string;\n readonly seed: number | string;\n readonly reached: BoundsReached;\n readonly assumptions: readonly string[];\n}\n\nexport interface Shrunk {\n readonly faultsRemoved: number;\n readonly eventsRemoved: number;\n readonly runs: number;\n}\n\nexport interface Violated extends VerdictBase {\n readonly kind: \"VIOLATED\";\n readonly violation: Violation;\n /** The replayed, shrunk trace that breaks the invariant. */\n readonly trace: EffectLog;\n readonly schedule: Schedule;\n /** Ids of the drive's events that remain after shrinking. */\n readonly keptEvents: readonly string[];\n readonly shrunk: Shrunk;\n}\n\nexport interface Bounded extends VerdictBase {\n readonly kind: \"BOUNDED\";\n readonly bounds: Bounds;\n}\n\nexport type UnsupportedCause =\n | \"unsupported_api\"\n | \"not_replayable\"\n | \"module_state_leak\"\n | \"unsupported_bounds\";\n\nexport interface Unsupported extends VerdictBase {\n readonly kind: \"UNSUPPORTED\";\n readonly cause: UnsupportedCause;\n readonly reason: string;\n}\n\nexport type ScenarioVerdict = Violated | Bounded | Unsupported;\n\n/** One line per verdict, for error messages; full rendering lives in `report`. */\nexport function describeVerdict(v: ScenarioVerdict): string {\n switch (v.kind) {\n case \"VIOLATED\":\n return `VIOLATED ${v.scenario}: ${v.violation.message} (seed ${v.schedule.seed}, ${v.reached.runs} run(s))`;\n case \"BOUNDED\":\n return `BOUNDED ${v.scenario}: no violation in ${v.reached.runs} run(s), ${v.reached.effectPoints} effect point(s), ${v.reached.faultsInjected} fault(s)`;\n case \"UNSUPPORTED\":\n return `UNSUPPORTED ${v.scenario}: ${v.cause}: ${v.reason}`;\n }\n}\n"],"mappings":";;AA0DA,SAAgB,gBAAgB,GAA4B;CAC1D,QAAQ,EAAE,MAAV;EACE,KAAK,YACH,OAAO,YAAY,EAAE,SAAS,IAAI,EAAE,UAAU,QAAQ,SAAS,EAAE,SAAS,KAAK,IAAI,EAAE,QAAQ,KAAK;EACpG,KAAK,WACH,OAAO,WAAW,EAAE,SAAS,oBAAoB,EAAE,QAAQ,KAAK,WAAW,EAAE,QAAQ,aAAa,oBAAoB,EAAE,QAAQ,eAAe;EACjJ,KAAK,eACH,OAAO,eAAe,EAAE,SAAS,IAAI,EAAE,MAAM,IAAI,EAAE;CACvD;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mooloo-ai/eutaxy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Deterministic simulation and formal proof for TypeScript on Cloudflare Workers",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"./cloudflare": {
|
|
21
21
|
"types": "./dist/cloudflare.d.mts",
|
|
22
22
|
"default": "./dist/cloudflare.mjs"
|
|
23
|
+
},
|
|
24
|
+
"./aws": {
|
|
25
|
+
"types": "./dist/aws.d.mts",
|
|
26
|
+
"default": "./dist/aws.mjs"
|
|
23
27
|
}
|
|
24
28
|
},
|
|
25
29
|
"bin": {
|
|
@@ -36,11 +40,23 @@
|
|
|
36
40
|
"peerDependencies": {
|
|
37
41
|
"@cloudflare/vitest-plugin": ">=1.4.0",
|
|
38
42
|
"@cloudflare/workers-types": ">=4.0.0",
|
|
39
|
-
"vitest": ">=4.1.0"
|
|
43
|
+
"vitest": ">=4.1.0",
|
|
44
|
+
"@aws-sdk/client-dynamodb": ">=3.0.0",
|
|
45
|
+
"@aws-sdk/util-dynamodb": ">=3.0.0",
|
|
46
|
+
"@smithy/smithy-client": ">=3.0.0"
|
|
40
47
|
},
|
|
41
48
|
"peerDependenciesMeta": {
|
|
42
49
|
"@cloudflare/workers-types": {
|
|
43
50
|
"optional": true
|
|
51
|
+
},
|
|
52
|
+
"@aws-sdk/client-dynamodb": {
|
|
53
|
+
"optional": true
|
|
54
|
+
},
|
|
55
|
+
"@aws-sdk/util-dynamodb": {
|
|
56
|
+
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"@smithy/smithy-client": {
|
|
59
|
+
"optional": true
|
|
44
60
|
}
|
|
45
61
|
},
|
|
46
62
|
"devDependencies": {
|
|
@@ -54,7 +70,8 @@
|
|
|
54
70
|
"@eutaxy/prover-lemmascript": "0.0.0",
|
|
55
71
|
"@eutaxy/report": "0.0.0",
|
|
56
72
|
"@eutaxy/cli": "0.0.0",
|
|
57
|
-
"@types/node": "24.19.2"
|
|
73
|
+
"@types/node": "24.19.2",
|
|
74
|
+
"@eutaxy/aws": "0.0.0"
|
|
58
75
|
},
|
|
59
76
|
"scripts": {
|
|
60
77
|
"build": "pnpm -w run build"
|
package/dist/cli-DTuDOgGM.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"explore-BB77_V0x.d.mts","names":[],"sources":["../../core/src/canonical-json.ts","../../core/src/effect-log.ts","../../core/src/faults.ts","../../core/src/invariants.ts","../../core/src/scenario.ts","../../core/src/platform.d.ts","../../core/src/verdict.ts","../../engine/src/explore.ts"],"mappings":";;;;;KAMY,wDAKC;YACG,cAAc;;;KCDlB;UAEK;;WAEN;WACA,MAAM;;WAEN;;WAEA;;WAEA;;WAEA,SAAS;;UAGH;WACN,kBAAkB;;;;;;;KChBjB;UAUK;;WAEN;;WAEA;WACA,OAAO;;WAEP;WACA;;UAGM;;WAEN;WACA,iBAAiB;;;UC1BX;WACN;WACA;WACA,OAAO;;WAEP;cAAoB,eAAe;;;WAEnC;cAAsB;;;;UAIhB;WACN;WACA;WACA,QAAQ;;WAER;;;UAIM;WACN;WACA;WACA,QAAQ;WACR;WACA,mBAAmB;;WAEnB;aAAwB;;;;KAqBvB;WACG;WAAyB;WAA2B,OAAO;;WAC3D;WAAyB;WAA0C;;WACnE;WAAyB;WAAmB,gBAAgB;;WAC5D;WAAyB;;;UAGvB;;WAEN;WACA;WACA,iBAAiB;;;UAIX;WACN;WACA;WACA,OAAO;WACP,gBAAgB;;;;;;;UAQV;WACN;WACA;WACA,MAAM;;WAEN;WACA,OAAO;WACP;;KAGC,YAAY,mBAAmB,cAAc,WAAW;UA2DnD;WACN;WACA;;WAEA;;WAEA;;iBA4EK,eAAe,KAAK,WAAW,KAAK,YAAY;iBAiGhD,gBACd,KAAK,WACL,qBAAqB,uBACX;;UCrUK;WACN;YACC,cAAc;;;UAIT;WACN;WACA;;;UAIM;WACN;;WAEA;WACA;;aAEE;;;;UAKI;WACN;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA,QAAQ;;WAER,OAAO;;WAEP,gBAAgB;WAChB,oBAAoB;WACpB,qBAAqB;WACrB,QAAQ;;;iBAeH,iBAAiB,MAAM;;UCxDtB;WACN;;WAEA;WACA,MAAM;;;UAGA;WACN;WACA;WACA;WACA,MAAM;;WAEN,kBAAkB;;;UAGZ;WACN;;WAEA,SAAS;EAClB;;;UAGe;EACf,gBAAgB,aAAa;;EAE7B,OAAO,GACL,OAAO,aACP,eAAe,QAAQ,IACvB,YAAY,OAAO,MAAM,YACxB,QAAQ;;EAEX,WAAW,GAAG,OAAO,aAAa,eAAe,GAAG,YAAY,OAAO,MAAM,YAAY;;EAEzF,YAAY;;EAEZ,SAAS,oBAAoB,gBAAgB,SAAS;;;;;;;EAOtD,OAAO,GAAG,SAAS,QAAQ,IAAI,qBAAqB,QAAQ;;UAE7C;WACN;;WAEA,oBAAoB;;UAEd;WACN;;WAEA;;EAET,MAAM,MAAM,eAAe;;EAE3B,cAAc,MAAM,wBAAwB;;EAE5C,QAAQ,OAAO,UAAU,OAAO,UAAU,MAAM,eAAe,QAAQ;;EAEvE,eAAe,MAAM,cAAc,6BAA6B;;EAEhE,QAAQ,MAAM,cAAc,OAAO,WAAW;;UClE/B;WACN;WACA;WACA;WACA;;UAGD;WACC;WACA;WACA,SAAS;WACT;;UAGM;WACN;WACA;WACA;;UAGM,iBAAiB;WACvB;WACA,WAAW;;WAEX,OAAO;WACP,UAAU;;WAEV;WACA,QAAQ;;UAGF,gBAAgB;WACtB;WACA,QAAQ;;KAGP;UAMK,oBAAoB;WAC1B;WACA,OAAO;WACP;;KAGC,kBAAkB,WAAW,UAAU;;iBAGnC,gBAAgB,GAAG;UCnClB;WACN;;WAEA;;WAEA;;WAEA;;WAEA;;;;;;WAMA;;;iBA8CW,OACpB,MAAM,cACN,UAAU,UACV,UAAU,WACT,QAAQ;iBAIW,QACpB,MAAM,cACN,UAAU,UACV,SAAS,iBACR,QAAQ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"src-Bef00JwK.mjs","names":[],"sources":["../../core/src/canonical-json.ts","../../core/src/utf8.ts","../../core/src/effect-log.ts","../../report/src/regression.ts","../../report/src/render.ts"],"sourcesContent":["/**\n * Canonical JSON: the one serialisation of a value, so that equal data always\n * produces equal bytes. Object keys are sorted; numbers must be finite; there\n * is no whitespace. Anything that is not plain JSON data is rejected.\n */\n\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | readonly JsonValue[]\n | { readonly [key: string]: JsonValue };\n\nexport function canonicalJson(value: JsonValue): string {\n if (value === null) return \"null\";\n switch (typeof value) {\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"number\":\n if (!Number.isFinite(value)) throw new TypeError(`non-finite number: ${value}`);\n return Object.is(value, -0) ? \"0\" : JSON.stringify(value);\n case \"string\":\n return JSON.stringify(value);\n case \"object\": {\n if (Array.isArray(value)) {\n const items: string[] = [];\n for (let i = 0; i < value.length; i++) {\n const v = value[i];\n if (v === undefined) throw new TypeError(`hole or undefined at index ${i}`);\n items.push(canonicalJson(v));\n }\n return `[${items.join(\",\")}]`;\n }\n const keys = Object.keys(value).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const v = (value as { readonly [key: string]: JsonValue | undefined })[k];\n if (v === undefined) throw new TypeError(`undefined at key ${JSON.stringify(k)}`);\n parts.push(`${JSON.stringify(k)}:${canonicalJson(v)}`);\n }\n return `{${parts.join(\",\")}}`;\n }\n default:\n throw new TypeError(`not JSON data: ${typeof value}`);\n }\n}\n","/**\n * UTF-8 encode a string, with no runtime dependency on TextEncoder. An unpaired\n * surrogate becomes U+FFFD, exactly as TextEncoder does, so the output is\n * always valid UTF-8.\n */\nexport function utf8Encode(s: string): Uint8Array {\n const out: number[] = [];\n for (const ch of s) {\n let cp = ch.codePointAt(0) ?? 0;\n if (cp >= 0xd800 && cp <= 0xdfff) cp = 0xfffd;\n if (cp < 0x80) out.push(cp);\n else if (cp < 0x800) out.push(0xc0 | (cp >> 6), 0x80 | (cp & 0x3f));\n else if (cp < 0x10000)\n out.push(0xe0 | (cp >> 12), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));\n else\n out.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f),\n );\n }\n return Uint8Array.from(out);\n}\n\n/** True when two byte arrays are identical in length and content. */\nexport function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n","/**\n * The effect log: the complete, ordered record of what a simulated run did at\n * its effect boundaries. It is plain data, appended immutably, and has one\n * canonical serialisation, so two runs are identical exactly when their\n * serialised logs are byte-identical.\n */\n\nimport { canonicalJson, type JsonValue } from \"./canonical-json.ts\";\nimport { utf8Encode } from \"./utf8.ts\";\n\n/** `snapshot` records platform state (e.g. D1 tables) captured at the end of a run; it is not an effect point. */\nexport type EffectKind = \"call\" | \"result\" | \"fault\" | \"snapshot\";\n\nexport interface EffectRecord {\n /** Position in the log, dense from 0. */\n readonly seq: number;\n readonly kind: EffectKind;\n /** The invocation (request, message, alarm) this effect belongs to. */\n readonly invocation: string;\n /** The binding or global the effect went through, e.g. \"D1:DB\". */\n readonly target: string;\n /** The operation, e.g. \"run\", \"batch\", \"send\". */\n readonly op: string;\n /** Operation-specific data: arguments, results, or the injected fault. */\n readonly payload: JsonValue;\n}\n\nexport interface EffectLog {\n readonly entries: readonly EffectRecord[];\n}\n\nexport const emptyLog: EffectLog = Object.freeze({ entries: Object.freeze([]) });\n\n/** Append one effect, assigning its sequence number. The input log is unchanged. */\nexport function appendEffect(log: EffectLog, effect: Omit<EffectRecord, \"seq\">): EffectLog {\n const record: EffectRecord = { ...effect, seq: log.entries.length };\n return { entries: [...log.entries, record] };\n}\n\n/** One canonical JSON object per line, in sequence order. */\nexport function serializeLog(log: EffectLog): string {\n return log.entries\n .map((e) =>\n canonicalJson({\n seq: e.seq,\n kind: e.kind,\n invocation: e.invocation,\n target: e.target,\n op: e.op,\n payload: e.payload,\n }),\n )\n .join(\"\\n\");\n}\n\n/** A 64-bit FNV-1a digest of the serialised log, as 16 hex digits. Not cryptographic. */\nexport function digestLog(log: EffectLog): string {\n const bytes = utf8Encode(serializeLog(log));\n let h = 0xcbf29ce484222325n;\n for (const b of bytes) {\n h ^= BigInt(b);\n h = (h * 0x100000001b3n) & 0xffffffffffffffffn;\n }\n return h.toString(16).padStart(16, \"0\");\n}\n","/**\n * The Vitest regression emitter. Given a violation, produce a test file that\n * replays its shrunk schedule on the restricted scenario. By default the\n * test expects the invariants to hold, so it fails while the bug exists and\n * passes once it is fixed. With `expect: \"violates\"` it asserts the recorded\n * violation instead, which is how Eutaxy's own corpus exercises the emitter.\n *\n * The emitter knows nothing about any platform: the caller supplies the\n * import lines and the expression that builds the platform.\n */\n\nimport { canonicalJson, type JsonValue, type Violated } from \"@eutaxy/core\";\n\nexport interface RegressionTestOptions {\n /** Import lines for the scenario, the platform's dependencies, and anything the platform expression needs. */\n readonly imports: readonly string[];\n /** An expression evaluating to the `Platform` (may reference the imports). */\n readonly platform: string;\n /** An expression evaluating to the `ScenarioSpec`. */\n readonly scenario: string;\n /** Module that exports `replay`, `restrictSpec` and `checkInvariants`; the public facade by default. */\n readonly engineModule?: string;\n readonly expect?: \"holds\" | \"violates\";\n}\n\nexport function emitRegressionTest(verdict: Violated, options: RegressionTestOptions): string {\n const engineModule = options.engineModule ?? \"@mooloo-ai/eutaxy\";\n const mode = options.expect ?? \"holds\";\n const schedule = canonicalJson(verdict.schedule as unknown as JsonValue);\n const kept = canonicalJson([...verdict.keptEvents]);\n const keys = canonicalJson([...verdict.violation.keys]);\n const title =\n mode === \"holds\"\n ? `${verdict.scenario}: ${verdict.violation.invariant} holds on the recorded schedule`\n : `${verdict.scenario}: ${verdict.violation.invariant} is still violated on the recorded schedule`;\n const assertion =\n mode === \"holds\"\n ? ` expect(violations.map((v) => \\`\\${v.invariant}: \\${v.message}\\`)).toEqual([]);`\n : ` expect(violations.map((v) => [v.invariant, v.keys])).toContainEqual([${JSON.stringify(verdict.violation.invariant)}, ${keys}]);`;\n const lines = [\n \"// Generated by Eutaxy. Replays a recorded violation; regenerate rather than edit.\",\n `// Scenario ${verdict.scenario}, seed ${String(verdict.seed)}: ${verdict.violation.message}`,\n `import { checkInvariants, replay, restrictSpec } from ${JSON.stringify(engineModule)};`,\n ...options.imports,\n 'import { expect, test } from \"vitest\";',\n \"\",\n `const schedule = ${schedule} as const;`,\n `const keptEvents = ${kept} as const;`,\n \"\",\n `test(${JSON.stringify(title)}, async () => {`,\n ` const platform = ${options.platform};`,\n ` const spec = restrictSpec(platform, ${options.scenario}, keptEvents);`,\n \" const log = await replay(spec, platform, schedule);\",\n \" const violations = checkInvariants(log, spec.invariants);\",\n assertion,\n \"});\",\n \"\",\n ];\n return lines.join(\"\\n\");\n}\n","/**\n * Rendering verdicts: a text form for people and a versioned JSON form for\n * CI and coding agents. Both are pure functions over the verdict data.\n */\n\nimport { canonicalJson, type EffectLog, type JsonValue, type ScenarioVerdict } from \"@eutaxy/core\";\n\nexport const reportSchemaVersion = 1;\n\n/** The JSON report: one object, canonical, with a schema version at the top. */\nexport function renderJson(verdict: ScenarioVerdict): string {\n return canonicalJson({\n schemaVersion: reportSchemaVersion,\n generator: \"eutaxy\",\n verdict: verdict as unknown as JsonValue,\n });\n}\n\nfunction clip(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, max - 1)}…`;\n}\n\nfunction pad(s: string, width: number): string {\n return s.length >= width ? s : s + \" \".repeat(width - s.length);\n}\n\n/** The trace as a fixed-width table; evidence rows are marked with `*`. */\nexport function renderTrace(log: EffectLog, evidence: readonly number[] = []): string {\n const rows = log.entries.map((e) => [\n evidence.includes(e.seq) ? \"*\" : \" \",\n String(e.seq),\n e.invocation,\n e.kind,\n e.target,\n e.op,\n clip(canonicalJson(e.payload), 72),\n ]);\n const header = [\" \", \"seq\", \"invocation\", \"kind\", \"target\", \"op\", \"payload\"];\n const widths = header.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => (r[i] as string).length)),\n );\n const line = (cells: readonly string[]) =>\n cells\n .map((c, i) => (i === cells.length - 1 ? c : pad(c, widths[i] as number)))\n .join(\" \")\n .trimEnd();\n return [line(header), ...rows.map(line)].join(\"\\n\");\n}\n\n/** A readable report: verdict, what it rests on, and for a violation the schedule and trace. */\nexport function renderText(verdict: ScenarioVerdict): string {\n const out: string[] = [];\n const r = verdict.reached;\n out.push(`${verdict.kind} ${verdict.scenario} (seed ${String(verdict.seed)})`);\n switch (verdict.kind) {\n case \"VIOLATED\": {\n out.push(\"\");\n out.push(\n `Invariant ${verdict.violation.invariant} is violated: ${verdict.violation.message}`,\n );\n out.push(`Keys: ${verdict.violation.keys.join(\", \")}`);\n out.push(\"\");\n out.push(\n `Schedule (run seed ${verdict.schedule.seed}), events kept: ${verdict.keptEvents.join(\", \")}`,\n );\n if (verdict.schedule.faults.length === 0) out.push(\" no injected faults\");\n for (const f of verdict.schedule.faults) {\n out.push(` ${f.fault} at ${f.invocation} effect #${f.ordinal} (${f.target} ${f.op})`);\n }\n out.push(\n `Shrunk: ${verdict.shrunk.eventsRemoved} event(s) and ${verdict.shrunk.faultsRemoved} fault(s) removed in ${verdict.shrunk.runs} run(s)`,\n );\n out.push(\"\");\n out.push(\"Trace:\");\n out.push(renderTrace(verdict.trace, verdict.violation.evidence));\n break;\n }\n case \"BOUNDED\": {\n const b = verdict.bounds;\n out.push(\"\");\n out.push(\"No violation found within the stated bounds. This is not a proof.\");\n out.push(\n `Bounds: faults per run ≤ ${b.maxFaultsPerRun}, redeliveries ≤ ${b.maxRedeliveries}, concurrent invocations ≤ ${b.maxConcurrentInvocations}, budget ${b.budgetMs} ms`,\n );\n break;\n }\n case \"UNSUPPORTED\": {\n out.push(\"\");\n out.push(`Eutaxy could not decide this scenario (${verdict.cause}): ${verdict.reason}`);\n break;\n }\n }\n out.push(\"\");\n out.push(\n `Explored: ${r.runs} run(s), ${r.effectPoints} effect point(s), ${r.faultsInjected} fault(s) injected, ${r.elapsedMs} ms`,\n );\n out.push(\"Assumptions:\");\n for (const a of verdict.assumptions) out.push(` - ${a}`);\n return out.join(\"\\n\");\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"src-Dn3Lm5Us.mjs","names":[],"sources":["../../core/src/prng.ts","../../core/src/faults.ts","../../core/src/invariants.ts","../../core/src/scenario.ts","../../core/src/shrink.ts","../../core/src/verdict.ts","../../engine/src/clock.ts","../../engine/src/run.ts","../../engine/src/shrink.ts","../../engine/src/explore.ts"],"sourcesContent":["/**\n * A pure, seedable pseudo-random generator (xoshiro128**).\n *\n * State is an immutable tuple of four 32-bit words. Every operation returns a\n * value and the next state; nothing is mutated, so a schedule can be replayed\n * from any state and two explorations can never interfere with each other.\n * Not cryptographic.\n */\n\nexport type PrngState = readonly [number, number, number, number];\n\nfunction rotl(x: number, k: number): number {\n return ((x << k) | (x >>> (32 - k))) >>> 0;\n}\n\n/** splitmix32: expands a 32-bit seed into well-mixed words for seeding. */\nfunction splitmix32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x9e3779b9) >>> 0;\n let t = a;\n t = Math.imul(t ^ (t >>> 16), 0x21f0aaad);\n t = Math.imul(t ^ (t >>> 15), 0x735a2d97);\n return (t ^ (t >>> 15)) >>> 0;\n };\n}\n\n/** FNV-1a over UTF-16 code units, so string seeds are stable across runtimes. */\nfunction hashString(s: string): number {\n let h = 0x811c9dc5;\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return h >>> 0;\n}\n\n/** Derive an initial state from a number (taken modulo 2^32) or a string. */\nexport function seedPrng(seed: number | string): PrngState {\n const word = typeof seed === \"string\" ? hashString(seed) : seed >>> 0;\n const next = splitmix32(word);\n const s: [number, number, number, number] = [next(), next(), next(), next()];\n if (s[0] === 0 && s[1] === 0 && s[2] === 0 && s[3] === 0) {\n s[0] = 1; // xoshiro must never hold the all-zero state\n }\n return s;\n}\n\n/** Next 32-bit unsigned integer and the state that follows it. */\nexport function nextU32(state: PrngState): readonly [number, PrngState] {\n const [s0, s1, s2, s3] = state;\n const result = Math.imul(rotl(Math.imul(s1, 5) >>> 0, 7), 9) >>> 0;\n const t = (s1 << 9) >>> 0;\n let n2 = (s2 ^ s0) >>> 0;\n let n3 = (s3 ^ s1) >>> 0;\n const n1 = (s1 ^ n2) >>> 0;\n const n0 = (s0 ^ n3) >>> 0;\n n2 = (n2 ^ t) >>> 0;\n n3 = rotl(n3, 11);\n return [result, [n0, n1, n2, n3]];\n}\n\n/** Next float in [0, 1) with 24 bits of precision. */\nexport function nextFloat(state: PrngState): readonly [number, PrngState] {\n const [u, next] = nextU32(state);\n return [(u >>> 8) * 2 ** -24, next];\n}\n\n/**\n * Next integer in [0, bound). Uses rejection sampling, so every value is\n * equally likely; a bound of 1 always yields 0 without consuming state.\n */\nexport function nextInt(state: PrngState, bound: number): readonly [number, PrngState] {\n if (!Number.isInteger(bound) || bound < 1 || bound > 0x1_0000_0000) {\n throw new RangeError(`nextInt bound must be an integer in [1, 2^32], got ${bound}`);\n }\n if (bound === 1) return [0, state];\n const limit = 0x1_0000_0000 - (0x1_0000_0000 % bound);\n let s = state;\n for (;;) {\n const [u, next] = nextU32(s);\n s = next;\n if (u < limit) return [u % bound, s];\n }\n}\n\n/**\n * Split one generator into two independent streams: the first element is the\n * continuation of the parent, the second a freshly seeded child.\n */\nexport function fork(state: PrngState): readonly [PrngState, PrngState] {\n const [a, s1] = nextU32(state);\n const [b, s2] = nextU32(s1);\n const next = splitmix32((a ^ Math.imul(b, 0x9e3779b1)) >>> 0);\n const child: [number, number, number, number] = [next(), next(), next(), next()];\n if (child[0] === 0 && child[1] === 0 && child[2] === 0 && child[3] === 0) child[0] = 1;\n return [s2, child];\n}\n","/**\n * The fault model and the schedule. A schedule is the complete, replayable\n * record of which fault was injected at which effect point in one run.\n */\n\nimport { nextFloat, nextInt, type PrngState } from \"./prng.ts\";\n\n/**\n * `cut_off` is a crash that happens after a response or acknowledgement was\n * already sent, so only background work (ctx.waitUntil) is lost; platforms\n * offer it at the point where that work would start.\n */\nexport type FaultKind = \"crash_before\" | \"crash_after\" | \"ambiguous\" | \"error\" | \"cut_off\";\n\nexport const allFaults: readonly FaultKind[] = [\n \"crash_before\",\n \"crash_after\",\n \"ambiguous\",\n \"error\",\n \"cut_off\",\n];\n\nexport interface FaultDecision {\n /** The invocation the effect belongs to, e.g. \"msg-1#2\". */\n readonly invocation: string;\n /** Position of the effect within that invocation, from 0. Stable when other invocations are removed. */\n readonly ordinal: number;\n readonly fault: FaultKind;\n /** What the effect was, for people reading the schedule. */\n readonly target: string;\n readonly op: string;\n}\n\nexport interface Schedule {\n /** The per-run seed the decisions were drawn from. */\n readonly seed: number;\n readonly faults: readonly FaultDecision[];\n}\n\nexport interface FaultPolicy {\n readonly maxFaultsPerRun: number;\n /** Probability of injecting at an eligible effect point, in [0, 1]. */\n readonly faultProbability: number;\n}\n\n/**\n * Decide whether to inject a fault at an effect point during exploration.\n * Pure: the same state and inputs always give the same decision. The PRNG is\n * only consumed when a fault is possible, so adding an ineligible point does\n * not perturb later decisions.\n */\nexport function decideFault(\n state: PrngState,\n allowed: readonly FaultKind[],\n faultsSoFar: number,\n policy: FaultPolicy,\n): readonly [FaultKind | null, PrngState] {\n if (allowed.length === 0 || faultsSoFar >= policy.maxFaultsPerRun) return [null, state];\n const [p, s1] = nextFloat(state);\n if (p >= policy.faultProbability) return [null, s1];\n const [i, s2] = nextInt(s1, allowed.length);\n return [allowed[i] ?? null, s2];\n}\n","/**\n * Invariants are plain data describing a property of the effect log; checkers\n * are pure functions from (log, invariant) to a violation or null. The\n * library starts with what the first planted bug needs and grows from there.\n */\n\nimport { canonicalJson, type JsonValue } from \"./canonical-json.ts\";\nimport type { EffectKind, EffectLog, EffectRecord } from \"./effect-log.ts\";\n\n/** Picks effect records by target, op, kind and payload fields. */\nexport interface EffectSelector {\n readonly target: string;\n readonly op?: string;\n readonly kind?: EffectKind;\n /** Dot paths into the payload that must equal the given values. */\n readonly where?: { readonly [path: string]: JsonValue };\n /** Dot paths into the payload whose numeric value must be at least the given bound. */\n readonly atLeast?: { readonly [path: string]: number };\n}\n\n/** No two selected effects share the same key. Catches duplicate writes. */\nexport interface AtMostOncePerKey {\n readonly kind: \"atMostOncePerKey\";\n readonly name: string;\n readonly effect: EffectSelector;\n /** Dot path into the payload that identifies the key. */\n readonly key: string;\n}\n\n/** Every expected key appears in at least one selected effect. Catches lost work. */\nexport interface AtLeastOnce {\n readonly kind: \"atLeastOnce\";\n readonly name: string;\n readonly effect: EffectSelector;\n readonly key: string;\n readonly expected: readonly JsonValue[];\n /** Set when `expected` was derived from the drive's message bodies, so it can be re-derived when messages are removed. */\n readonly perMessage?: { readonly bodyKey: string };\n}\n\n/** Re-derive `expected` for per-message invariants from the bodies that remain. */\nexport function recomputePerMessageExpected(\n invariants: readonly Invariant[],\n bodies: readonly JsonValue[],\n): readonly Invariant[] {\n return invariants.map((inv) => {\n if (inv.kind !== \"atLeastOnce\" || !inv.perMessage) return inv;\n const bodyKey = inv.perMessage.bodyKey;\n const expected: JsonValue[] = [];\n for (const b of bodies) {\n const v = getPath(b, bodyKey);\n if (v !== undefined) expected.push(v);\n }\n return { ...inv, expected };\n });\n}\n\n/** A condition on one column of a row. */\nexport type RowCondition =\n | { readonly column: string; readonly op: \"eq\" | \"neq\"; readonly value: JsonValue }\n | { readonly column: string; readonly op: \"gt\" | \"gte\" | \"lt\" | \"lte\"; readonly value: number }\n | { readonly column: string; readonly op: \"in\"; readonly value: readonly JsonValue[] }\n | { readonly column: string; readonly op: \"notNull\" };\n\n/** Rows of a table in the last snapshot of a target, optionally filtered. */\nexport interface StateQuery {\n /** The snapshot target, e.g. \"D1:DB\". */\n readonly target: string;\n readonly table: string;\n readonly where?: readonly RowCondition[];\n}\n\n/** Every row the query returns satisfies all of `holds`. */\nexport interface EveryRow {\n readonly kind: \"everyRow\";\n readonly name: string;\n readonly query: StateQuery;\n readonly holds: readonly RowCondition[];\n}\n\n/**\n * For every selected effect, a row exists whose `column` equals the effect's\n * key. Ties what the shell did to what the state says, e.g. \"every acked\n * message has its payment row\".\n */\nexport interface Implies {\n readonly kind: \"implies\";\n readonly name: string;\n readonly when: EffectSelector;\n /** Dot path into the effect payload that yields the key. */\n readonly key: string;\n readonly state: StateQuery;\n readonly column: string;\n}\n\nexport type Invariant = AtMostOncePerKey | AtLeastOnce | EveryRow | Implies;\n\nexport type Row = { readonly [column: string]: JsonValue };\n\n/** The tables in the last snapshot recorded for a target, or undefined when none was. */\nexport function lastSnapshot(\n log: EffectLog,\n target: string,\n): { readonly [table: string]: readonly Row[] } | undefined {\n for (let i = log.entries.length - 1; i >= 0; i--) {\n const e = log.entries[i] as EffectRecord;\n if (e.kind === \"snapshot\" && e.target === target) {\n const tables = getPath(e.payload, \"tables\");\n if (tables && typeof tables === \"object\" && !Array.isArray(tables)) {\n return tables as { readonly [table: string]: readonly Row[] };\n }\n return {};\n }\n }\n return undefined;\n}\n\nexport function rowMatches(row: Row, condition: RowCondition): boolean {\n const v = row[condition.column];\n switch (condition.op) {\n case \"eq\":\n return v !== undefined && jsonEqual(v, condition.value);\n case \"neq\":\n return v === undefined || !jsonEqual(v, condition.value);\n case \"gt\":\n return typeof v === \"number\" && v > condition.value;\n case \"gte\":\n return typeof v === \"number\" && v >= condition.value;\n case \"lt\":\n return typeof v === \"number\" && v < condition.value;\n case \"lte\":\n return typeof v === \"number\" && v <= condition.value;\n case \"in\":\n return v !== undefined && condition.value.some((c) => jsonEqual(v, c));\n case \"notNull\":\n return v !== undefined && v !== null;\n }\n}\n\n/** Rows a state query selects from the log's last snapshot; undefined when there is no snapshot. */\nexport function queryRows(log: EffectLog, query: StateQuery): readonly Row[] | undefined {\n const tables = lastSnapshot(log, query.target);\n if (!tables) return undefined;\n const rows = tables[query.table] ?? [];\n const where = query.where ?? [];\n return rows.filter((r) => where.every((c) => rowMatches(r, c)));\n}\n\nfunction snapshotSeq(log: EffectLog, target: string): number[] {\n let last: number | undefined;\n for (const e of log.entries) if (e.kind === \"snapshot\" && e.target === target) last = e.seq;\n return last === undefined ? [] : [last];\n}\n\nexport interface Violation {\n readonly invariant: string;\n readonly message: string;\n /** The keys involved, in canonical JSON, so two violations can be compared across runs. */\n readonly keys: readonly string[];\n /** Sequence numbers of the effects that witness the violation. */\n readonly evidence: readonly number[];\n}\n\n/** True when two violations are of the same invariant for the same keys, whatever the traces. */\nexport function sameViolation(a: Violation, b: Violation): boolean {\n return (\n a.invariant === b.invariant &&\n a.keys.length === b.keys.length &&\n a.keys.every((k, i) => k === b.keys[i])\n );\n}\n\n/** Read a dot path such as \"args.params.0\" out of JSON data; undefined when absent. */\nexport function getPath(value: JsonValue, path: string): JsonValue | undefined {\n let cur: JsonValue | undefined = value;\n if (path === \"\") return cur;\n for (const part of path.split(\".\")) {\n if (cur === null || typeof cur !== \"object\") return undefined;\n if (Array.isArray(cur)) {\n const i = Number(part);\n if (!Number.isInteger(i) || i < 0) return undefined;\n cur = cur[i];\n } else {\n cur = (cur as { readonly [k: string]: JsonValue })[part];\n }\n if (cur === undefined) return undefined;\n }\n return cur;\n}\n\nfunction jsonEqual(a: JsonValue | undefined, b: JsonValue): boolean {\n if (a === undefined) return false;\n if (a === b) return true;\n if (a === null || b === null || typeof a !== \"object\" || typeof b !== \"object\") return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((x, i) => jsonEqual(x, b[i] as JsonValue));\n }\n const ao = a as { readonly [k: string]: JsonValue };\n const bo = b as { readonly [k: string]: JsonValue };\n const ak = Object.keys(ao).sort();\n const bk = Object.keys(bo).sort();\n return (\n ak.length === bk.length &&\n ak.every((k, i) => k === bk[i] && jsonEqual(ao[k], bo[k] as JsonValue))\n );\n}\n\nexport function matches(record: EffectRecord, sel: EffectSelector): boolean {\n if (record.target !== sel.target) return false;\n if (sel.op !== undefined && record.op !== sel.op) return false;\n if (sel.kind !== undefined && record.kind !== sel.kind) return false;\n if (sel.where) {\n for (const [path, want] of Object.entries(sel.where)) {\n if (!jsonEqual(getPath(record.payload, path), want)) return false;\n }\n }\n if (sel.atLeast) {\n for (const [path, min] of Object.entries(sel.atLeast)) {\n const v = getPath(record.payload, path);\n if (typeof v !== \"number\" || v < min) return false;\n }\n }\n return true;\n}\n\nexport function selectEffects(log: EffectLog, sel: EffectSelector): readonly EffectRecord[] {\n return log.entries.filter((e) => matches(e, sel));\n}\n\n/** Canonical form of a key, so equal JSON values compare equal whatever their key order. */\nfunction keyOf(record: EffectRecord, path: string): string | undefined {\n const v = getPath(record.payload, path);\n return v === undefined ? undefined : canonicalJson(v);\n}\n\nexport function checkInvariant(log: EffectLog, inv: Invariant): Violation | null {\n switch (inv.kind) {\n case \"everyRow\":\n return checkEveryRow(log, inv);\n case \"implies\":\n return checkImplies(log, inv);\n case \"atMostOncePerKey\": {\n const seen = new Map<string, number>();\n for (const e of selectEffects(log, inv.effect)) {\n const k = keyOf(e, inv.key);\n if (k === undefined) continue;\n const first = seen.get(k);\n if (first !== undefined) {\n return {\n invariant: inv.name,\n message: `${inv.effect.target} ${inv.effect.op ?? \"*\"} happened twice for key ${k} (seq ${first} and ${e.seq})`,\n keys: [k],\n evidence: [first, e.seq],\n };\n }\n seen.set(k, e.seq);\n }\n return null;\n }\n case \"atLeastOnce\": {\n const present = new Set<string>();\n const selected = selectEffects(log, inv.effect);\n for (const e of selected) {\n const k = keyOf(e, inv.key);\n if (k !== undefined) present.add(k);\n }\n const missing = inv.expected.map((v) => canonicalJson(v)).filter((k) => !present.has(k));\n if (missing.length === 0) return null;\n return {\n invariant: inv.name,\n message: `${inv.effect.target} ${inv.effect.op ?? \"*\"} never happened for key(s) ${missing.join(\", \")}`,\n keys: missing,\n evidence: selected.map((e) => e.seq),\n };\n }\n }\n}\n\nfunction checkEveryRow(log: EffectLog, inv: EveryRow): Violation | null {\n const rows = queryRows(log, inv.query);\n if (rows === undefined) {\n return {\n invariant: inv.name,\n message: `no snapshot of ${inv.query.target} was recorded`,\n keys: [],\n evidence: [],\n };\n }\n const failing = rows.filter((r) => !inv.holds.every((c) => rowMatches(r, c)));\n if (failing.length === 0) return null;\n const keys = failing.map((r) => canonicalJson(r));\n const shown = keys.slice(0, 3).join(\", \") + (failing.length > 3 ? \", …\" : \"\");\n return {\n invariant: inv.name,\n message: `${failing.length} row(s) of ${inv.query.table} in ${inv.query.target} violate the condition: ${shown}`,\n keys,\n evidence: snapshotSeq(log, inv.query.target),\n };\n}\n\nfunction checkImplies(log: EffectLog, inv: Implies): Violation | null {\n const rows = queryRows(log, inv.state);\n if (rows === undefined) {\n return {\n invariant: inv.name,\n message: `no snapshot of ${inv.state.target} was recorded`,\n keys: [],\n evidence: [],\n };\n }\n const present = new Set<string>();\n for (const r of rows) {\n const v = r[inv.column];\n if (v !== undefined) present.add(canonicalJson(v));\n }\n const missing: string[] = [];\n const evidence: number[] = [];\n for (const e of selectEffects(log, inv.when)) {\n const k = keyOf(e, inv.key);\n if (k === undefined || present.has(k)) continue;\n if (!missing.includes(k)) missing.push(k);\n evidence.push(e.seq);\n }\n if (missing.length === 0) return null;\n return {\n invariant: inv.name,\n message: `${inv.when.target} ${inv.when.op ?? \"*\"} happened for key(s) ${missing.join(\", \")} but ${inv.state.table}.${inv.column} in ${inv.state.target} has no such row`,\n keys: missing,\n evidence,\n };\n}\n\nexport function checkInvariants(\n log: EffectLog,\n invariants: readonly Invariant[],\n): readonly Violation[] {\n const out: Violation[] = [];\n for (const inv of invariants) {\n const v = checkInvariant(log, inv);\n if (v) out.push(v);\n }\n return out;\n}\n","/**\n * The scenario spec: everything Eutaxy needs to run one scenario, as plain\n * data. The platform-neutral parts are typed here; what a platform needs to\n * drive the Worker and set up its state travels as `PlatformData`, which only\n * that platform's package knows how to build and interpret.\n */\n\nimport type { JsonValue } from \"./canonical-json.ts\";\nimport type { Invariant } from \"./invariants.ts\";\n\n/** Opaque, JSON-shaped data owned by a platform package. `kind` names its shape. */\nexport interface PlatformData {\n readonly kind: string;\n readonly [key: string]: JsonValue;\n}\n\n/** Where the Worker under test lives, relative to the scenario file. */\nexport interface WorkerRef {\n readonly entry: string;\n readonly config: string;\n}\n\n/** An external service the Worker talks to, and what it promises. */\nexport interface ExternalDecl {\n readonly name: string;\n /** Host pattern for outbound requests, e.g. \"api.stripe.com\". */\n readonly host: string;\n readonly guarantees: {\n /** Header whose value makes repeated requests idempotent, if any. */\n readonly dedupeBy?: string;\n };\n}\n\n/** Exploration bounds. Every verdict reports the bounds actually reached. */\nexport interface Bounds {\n readonly maxFaultsPerRun: number;\n readonly maxRedeliveries: number;\n readonly maxConcurrentInvocations: number;\n readonly budgetMs: number;\n}\n\nexport interface ScenarioSpec {\n readonly version: 1;\n readonly name: string;\n readonly worker: WorkerRef;\n /** How the scenario drives the Worker (which events, with what payloads). */\n readonly drive: PlatformData;\n /** State to establish before each run, in order. */\n readonly setup: readonly PlatformData[];\n readonly externals: readonly ExternalDecl[];\n readonly invariants: readonly Invariant[];\n readonly bounds: Bounds;\n}\n\nexport const defaultBounds: Bounds = {\n maxFaultsPerRun: 1,\n maxRedeliveries: 2,\n maxConcurrentInvocations: 1,\n budgetMs: 2000,\n};\n\nfunction isPositiveInt(n: unknown): n is number {\n return typeof n === \"number\" && Number.isInteger(n) && n > 0;\n}\n\n/** Every reason a spec is not usable; empty when it is. */\nexport function validateScenario(spec: ScenarioSpec): readonly string[] {\n const errors: string[] = [];\n if (spec.version !== 1) errors.push(`version must be 1, got ${String(spec.version)}`);\n if (!spec.name.trim()) errors.push(\"name must not be empty\");\n if (!/^[a-z0-9][a-z0-9-]*$/.test(spec.name))\n errors.push(`name must be lowercase letters, digits and dashes: ${JSON.stringify(spec.name)}`);\n if (!spec.worker.entry) errors.push(\"worker.entry must not be empty\");\n if (!spec.worker.config) errors.push(\"worker.config must not be empty\");\n if (!spec.drive.kind) errors.push(\"drive.kind must not be empty\");\n spec.setup.forEach((s, i) => {\n if (!s.kind) errors.push(`setup[${i}].kind must not be empty`);\n });\n if (spec.invariants.length === 0) errors.push(\"at least one invariant is required\");\n const names = new Set<string>();\n for (const inv of spec.invariants) {\n if (!inv.name) errors.push(\"every invariant needs a name\");\n else if (names.has(inv.name))\n errors.push(`duplicate invariant name ${JSON.stringify(inv.name)}`);\n names.add(inv.name);\n }\n const ext = new Set<string>();\n for (const e of spec.externals) {\n if (ext.has(e.name)) errors.push(`duplicate external ${JSON.stringify(e.name)}`);\n ext.add(e.name);\n }\n for (const k of [\n \"maxFaultsPerRun\",\n \"maxRedeliveries\",\n \"maxConcurrentInvocations\",\n \"budgetMs\",\n ] as const) {\n if (k === \"maxFaultsPerRun\" || k === \"maxRedeliveries\") {\n const v = spec.bounds[k];\n if (!(Number.isInteger(v) && v >= 0))\n errors.push(`bounds.${k} must be a non-negative integer`);\n } else if (!isPositiveInt(spec.bounds[k]))\n errors.push(`bounds.${k} must be a positive integer`);\n }\n return errors;\n}\n","/**\n * Shrinking, the pure part: given a violating schedule and the ids of the\n * events that drove it, the candidates to try next, smallest change first.\n * The engine replays each candidate and keeps it when the same invariant is\n * still violated for the same keys.\n */\n\nimport type { Schedule } from \"./faults.ts\";\n\nexport interface ShrinkState {\n readonly schedule: Schedule;\n readonly keepIds: readonly string[];\n}\n\n/** One-step candidates: each single fault removed, then each single event removed. */\nexport function shrinkCandidates(state: ShrinkState): readonly ShrinkState[] {\n const out: ShrinkState[] = [];\n state.schedule.faults.forEach((_, i) => {\n out.push({\n schedule: {\n seed: state.schedule.seed,\n faults: state.schedule.faults.filter((_, j) => j !== i),\n },\n keepIds: state.keepIds,\n });\n });\n if (state.keepIds.length > 1) {\n state.keepIds.forEach((id) => {\n out.push({\n schedule: {\n seed: state.schedule.seed,\n // Faults that belonged to the removed event's invocations can no longer fire.\n faults: state.schedule.faults.filter((f) => !f.invocation.startsWith(`${id}#`)),\n },\n keepIds: state.keepIds.filter((k) => k !== id),\n });\n });\n }\n return out;\n}\n\n/** Fewer events, then fewer faults: the order that keeps shrinking monotone. */\nexport function shrinkSize(state: ShrinkState): number {\n return state.keepIds.length * 1000 + state.schedule.faults.length;\n}\n","/** Simulation verdicts, with what each one rests on. */\n\nimport type { EffectLog } from \"./effect-log.ts\";\nimport type { Schedule } from \"./faults.ts\";\nimport type { Violation } from \"./invariants.ts\";\nimport type { Bounds } from \"./scenario.ts\";\n\nexport interface BoundsReached {\n readonly runs: number;\n readonly effectPoints: number;\n readonly faultsInjected: number;\n readonly elapsedMs: number;\n}\n\ninterface VerdictBase {\n readonly scenario: string;\n readonly seed: number | string;\n readonly reached: BoundsReached;\n readonly assumptions: readonly string[];\n}\n\nexport interface Shrunk {\n readonly faultsRemoved: number;\n readonly eventsRemoved: number;\n readonly runs: number;\n}\n\nexport interface Violated extends VerdictBase {\n readonly kind: \"VIOLATED\";\n readonly violation: Violation;\n /** The replayed, shrunk trace that breaks the invariant. */\n readonly trace: EffectLog;\n readonly schedule: Schedule;\n /** Ids of the drive's events that remain after shrinking. */\n readonly keptEvents: readonly string[];\n readonly shrunk: Shrunk;\n}\n\nexport interface Bounded extends VerdictBase {\n readonly kind: \"BOUNDED\";\n readonly bounds: Bounds;\n}\n\nexport type UnsupportedCause =\n | \"unsupported_api\"\n | \"not_replayable\"\n | \"module_state_leak\"\n | \"unsupported_bounds\";\n\nexport interface Unsupported extends VerdictBase {\n readonly kind: \"UNSUPPORTED\";\n readonly cause: UnsupportedCause;\n readonly reason: string;\n}\n\nexport type ScenarioVerdict = Violated | Bounded | Unsupported;\n\n/** One line per verdict, for error messages; full rendering lives in `report`. */\nexport function describeVerdict(v: ScenarioVerdict): string {\n switch (v.kind) {\n case \"VIOLATED\":\n return `VIOLATED ${v.scenario}: ${v.violation.message} (seed ${v.schedule.seed}, ${v.reached.runs} run(s))`;\n case \"BOUNDED\":\n return `BOUNDED ${v.scenario}: no violation in ${v.reached.runs} run(s), ${v.reached.effectPoints} effect point(s), ${v.reached.faultsInjected} fault(s)`;\n case \"UNSUPPORTED\":\n return `UNSUPPORTED ${v.scenario}: ${v.cause}: ${v.reason}`;\n }\n}\n","/**\n * The virtual clock and the globals patch. Within a run, Date, Math.random,\n * crypto.randomUUID, crypto.getRandomValues, performance.now and the timer\n * functions are replaced by deterministic versions driven by the run's seed\n * and by a clock that starts at a fixed epoch and advances only when the\n * engine says so: one millisecond per effect, and to each timer's due time\n * when the timer fires. Timers fire only while the invocation is idle (no\n * effect in flight), in due order, so they never race real I/O.\n */\n\nimport { nextFloat, nextU32, type PrngState, seedPrng } from \"@eutaxy/core\";\n\n/** 2026-01-01T00:00:00.000Z. Every run starts here. */\nexport const virtualEpoch = Date.UTC(2026, 0, 1);\n\n/** Virtual time advances this much at each effect completion. */\nexport const effectLatencyMs = 1;\n\n// Captured before any patching, so the engine can yield to the real event loop.\nconst realSetTimeout = globalThis.setTimeout.bind(globalThis);\n\ninterface Timer {\n readonly id: number;\n due: number;\n readonly callback: (...args: unknown[]) => void;\n readonly args: readonly unknown[];\n readonly interval: number | null;\n /** The invocation that scheduled it; cancelled with that invocation when it crashes. */\n readonly owner: string | null;\n}\n\nexport class VirtualClock {\n private time = virtualEpoch;\n private timers: Timer[] = [];\n private nextId = 1;\n /** The invocation whose code is running; timers scheduled now belong to it. */\n owner: string | null = null;\n\n now(): number {\n return this.time;\n }\n\n advance(ms: number): void {\n if (ms > 0) this.time += ms;\n }\n\n private schedule(\n callback: (...args: unknown[]) => void,\n delay: number,\n args: readonly unknown[],\n interval: number | null,\n ): number {\n const ms = Number.isFinite(delay) && delay > 0 ? Math.floor(delay) : 0;\n const timer: Timer = {\n id: this.nextId++,\n due: this.time + ms,\n callback,\n args,\n interval,\n owner: this.owner,\n };\n this.timers.push(timer);\n return timer.id;\n }\n\n setTimeout(callback: (...args: unknown[]) => void, delay = 0, ...args: unknown[]): number {\n return this.schedule(callback, delay, args, null);\n }\n\n setInterval(callback: (...args: unknown[]) => void, delay = 0, ...args: unknown[]): number {\n return this.schedule(callback, delay, args, Math.max(1, Math.floor(delay)));\n }\n\n clear(id: number): void {\n this.timers = this.timers.filter((t) => t.id !== id);\n }\n\n pendingTimers(): number {\n return this.timers.length;\n }\n\n /** Drop every timer an invocation scheduled: a crashed invocation's code must never run again. */\n cancelOwner(owner: string): void {\n this.timers = this.timers.filter((t) => t.owner !== owner);\n }\n\n /** Advance to the earliest due timer and run it. False when none is pending. */\n fireNext(): boolean {\n if (this.timers.length === 0) return false;\n let earliest = this.timers[0] as Timer;\n for (const t of this.timers)\n if (t.due < earliest.due || (t.due === earliest.due && t.id < earliest.id)) earliest = t;\n if (earliest.due > this.time) this.time = earliest.due;\n if (earliest.interval === null) this.timers = this.timers.filter((t) => t !== earliest);\n else earliest.due = this.time + earliest.interval;\n try {\n earliest.callback(...earliest.args);\n } catch {\n // An exception in a timer callback is uncaught in the real runtime too; it does not stop the run.\n }\n return true;\n }\n}\n\n/** Deterministic randomness for a run: Math.random, UUIDs and random bytes from one seeded stream. */\nexport class VirtualRandom {\n private state: PrngState;\n\n constructor(seed: number | string) {\n this.state = seedPrng(`random:${seed}`);\n }\n\n float(): number {\n const [f, next] = nextFloat(this.state);\n this.state = next;\n return f;\n }\n\n u32(): number {\n const [u, next] = nextU32(this.state);\n this.state = next;\n return u;\n }\n\n fill<T extends ArrayBufferView>(view: T): T {\n const bytes = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n for (let i = 0; i < bytes.length; i += 4) {\n const u = this.u32();\n for (let j = 0; j < 4 && i + j < bytes.length; j++) bytes[i + j] = (u >>> (8 * j)) & 0xff;\n }\n return view;\n }\n\n /** A version-4 UUID from the stream. */\n uuid(): string {\n const b = this.fill(new Uint8Array(16));\n b[6] = ((b[6] as number) & 0x0f) | 0x40;\n b[8] = ((b[8] as number) & 0x3f) | 0x80;\n const hex = [...b].map((x) => x.toString(16).padStart(2, \"0\")).join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n }\n}\n\nexport interface Patched {\n readonly clock: VirtualClock;\n readonly random: VirtualRandom;\n /** Put every global back. Safe to call twice. */\n restore(): void;\n}\n\ntype Global = Record<string, unknown>;\n\n/** Replace the nondeterministic globals for one run. Returns the handle that restores them. */\nexport function patchGlobals(seed: number | string): Patched {\n const clock = new VirtualClock();\n const random = new VirtualRandom(seed);\n const g = globalThis as unknown as Global;\n const saved = new Map<string, PropertyDescriptor | undefined>();\n const define = (target: object, key: string, value: unknown): void => {\n const owner = target === g ? g : target;\n saved.set(key, Object.getOwnPropertyDescriptor(owner, key));\n Object.defineProperty(owner, key, {\n value,\n configurable: true,\n writable: true,\n enumerable: false,\n });\n };\n\n const RealDate = Date;\n const VirtualDate = function (this: unknown, ...args: unknown[]): unknown {\n if (new.target === undefined) return new RealDate(clock.now()).toString();\n return Reflect.construct(RealDate, args.length === 0 ? [clock.now()] : args, new.target);\n } as unknown as DateConstructor;\n Object.setPrototypeOf(VirtualDate, RealDate);\n Object.defineProperty(VirtualDate, \"prototype\", { value: RealDate.prototype, writable: false });\n Object.defineProperty(VirtualDate, \"now\", {\n value: () => clock.now(),\n configurable: true,\n writable: true,\n });\n Object.defineProperty(VirtualDate, \"name\", { value: \"Date\" });\n\n define(g, \"Date\", VirtualDate);\n define(Math, \"random\", () => random.float());\n define(g, \"setTimeout\", (cb: (...a: unknown[]) => void, ms?: number, ...args: unknown[]) =>\n clock.setTimeout(cb, ms, ...args),\n );\n define(g, \"setInterval\", (cb: (...a: unknown[]) => void, ms?: number, ...args: unknown[]) =>\n clock.setInterval(cb, ms, ...args),\n );\n define(g, \"clearTimeout\", (id?: number) => id !== undefined && clock.clear(id));\n define(g, \"clearInterval\", (id?: number) => id !== undefined && clock.clear(id));\n const perf = g[\"performance\"];\n if (perf && typeof perf === \"object\") define(perf, \"now\", () => clock.now() - virtualEpoch);\n const cryptoObj = g[\"crypto\"];\n if (cryptoObj && typeof cryptoObj === \"object\") {\n define(cryptoObj, \"randomUUID\", () => random.uuid());\n define(cryptoObj, \"getRandomValues\", <T extends ArrayBufferView>(view: T) => random.fill(view));\n }\n\n let restored = false;\n const targets: Record<string, object> = {\n Date: g,\n random: Math,\n setTimeout: g,\n setInterval: g,\n clearTimeout: g,\n clearInterval: g,\n };\n if (perf && typeof perf === \"object\") targets[\"now\"] = perf;\n if (cryptoObj && typeof cryptoObj === \"object\") {\n targets[\"randomUUID\"] = cryptoObj;\n targets[\"getRandomValues\"] = cryptoObj;\n }\n return {\n clock,\n random,\n restore() {\n if (restored) return;\n restored = true;\n for (const [key, descriptor] of saved) {\n const target = targets[key] as object;\n if (descriptor) Object.defineProperty(target, key, descriptor);\n else delete (target as Global)[key];\n }\n },\n };\n}\n\n/** Yield to the real event loop so microtasks and pending I/O can make progress. */\nexport function realTick(): Promise<void> {\n return new Promise((resolve) => realSetTimeout(() => resolve(), 0));\n}\n\nexport interface SettleContext {\n readonly clock: VirtualClock;\n /** Effects currently performing real I/O. */\n readonly inFlight: () => number;\n /** True once the invocation has been crashed; the promise is then abandoned. */\n readonly crashed: () => boolean;\n /** Called when nothing can make progress: no I/O, no timers, not done. */\n readonly stuck: () => void;\n}\n\n/**\n * Wait for a promise under the virtual clock: while it is pending, let real\n * I/O complete, and when the invocation is idle fire the next due timer.\n */\nexport async function settleOn<T>(promise: Promise<T>, ctx: SettleContext): Promise<T> {\n let done = false;\n let failed = false;\n let value: T | undefined;\n let error: unknown;\n const tracked = promise.then(\n (v) => {\n done = true;\n value = v;\n },\n (e: unknown) => {\n done = true;\n failed = true;\n error = e;\n },\n );\n for (;;) {\n await Promise.race([tracked, realTick()]);\n if (done) {\n if (failed) throw error;\n return value as T;\n }\n if (ctx.crashed()) return new Promise<T>(() => {});\n if (ctx.inFlight() > 0) continue;\n if (ctx.clock.fireNext()) continue;\n ctx.stuck();\n return new Promise<T>(() => {});\n }\n}\n","/**\n * One run of a scenario: the effect log being built, the fault decisions\n * (drawn during exploration, looked up during replay), and the invocations\n * in flight. Proxies in the platform package call `effect`/`effectSync`\n * around every real effect; everything else is engine-internal.\n */\n\nimport {\n appendEffect,\n type Bounds,\n decideFault,\n type EffectLog,\n type EffectPoint,\n emptyLog,\n type FaultDecision,\n type FaultKind,\n type Invocation,\n type JsonValue,\n type PrngState,\n type RunHooks,\n type Schedule,\n seedPrng,\n} from \"@eutaxy/core\";\nimport { effectLatencyMs, type Patched, patchGlobals, settleOn } from \"./clock.ts\";\n\n/** Thrown into user code by a synchronous effect that crashes the invocation. */\nexport class CrashSignal extends Error {\n override readonly name = \"CrashSignal\";\n readonly invocation: string;\n constructor(invocation: string) {\n super(`invocation ${invocation} crashed by an injected fault`);\n this.invocation = invocation;\n }\n}\n\n/** The error user code sees for an injected `error` or `ambiguous` fault. */\nexport class InjectedEffectError extends Error {\n override readonly name = \"InjectedEffectError\";\n readonly point: EffectPoint;\n readonly fault: FaultKind;\n constructor(point: EffectPoint, fault: FaultKind) {\n super(`${point.target} ${point.op} failed (injected ${fault})`);\n this.point = point;\n this.fault = fault;\n }\n}\n\nexport interface RunOptions {\n readonly mode: \"explore\" | \"replay\";\n readonly schedule: Schedule;\n readonly bounds: Bounds;\n readonly faultProbability: number;\n}\n\nclass InvocationState implements Invocation {\n readonly crashed: Promise<void>;\n private readonly onCrash: () => void;\n /** Effect points seen so far in this invocation; the next effect's ordinal. */\n ordinal = 0;\n private crashedFlag = false;\n private resolveCrashed: () => void = () => {};\n readonly id: string;\n\n constructor(id: string, onCrash: () => void) {\n this.id = id;\n this.onCrash = onCrash;\n this.crashed = new Promise<void>((resolve) => {\n this.resolveCrashed = resolve;\n });\n }\n\n isCrashed(): boolean {\n return this.crashedFlag;\n }\n\n crash(): void {\n if (this.crashedFlag) return;\n this.crashedFlag = true;\n this.onCrash();\n this.resolveCrashed();\n }\n}\n\n/** A promise that never settles: how an abandoned invocation experiences a crash. */\nfunction hang<T>(): Promise<T> {\n return new Promise<T>(() => {});\n}\n\nexport class Run implements RunHooks {\n private logState: EffectLog = emptyLog;\n private readonly faults: FaultDecision[] = [];\n private effectIndex = 0;\n private prng: PrngState;\n private readonly invocations = new Map<string, InvocationState>();\n private readonly reasons: string[] = [];\n private inFlight = 0;\n private patched: Patched | null = null;\n\n readonly options: RunOptions;\n\n constructor(options: RunOptions) {\n this.options = options;\n this.prng = seedPrng(options.schedule.seed);\n }\n\n get log(): EffectLog {\n return this.logState;\n }\n\n /** The schedule as actually executed: input decisions during replay, drawn ones during exploration. */\n get schedule(): Schedule {\n return { seed: this.options.schedule.seed, faults: [...this.faults] };\n }\n\n get effectPoints(): number {\n return this.effectIndex;\n }\n\n get faultsInjected(): number {\n return this.faults.length;\n }\n\n get unsupportedReasons(): readonly string[] {\n return this.reasons;\n }\n\n /** Replace the nondeterministic globals for this run. Call `uninstall` in a finally. */\n install(): void {\n if (!this.patched) this.patched = patchGlobals(this.options.schedule.seed);\n }\n\n uninstall(): void {\n this.patched?.restore();\n this.patched = null;\n }\n\n /** Virtual milliseconds since the epoch, or the real clock when the globals are not installed. */\n now(): number {\n return this.patched ? this.patched.clock.now() : Date.now();\n }\n\n /** Timers scheduled and not yet fired or cancelled (0 when the globals are not installed). */\n pendingTimers(): number {\n return this.patched?.clock.pendingTimers() ?? 0;\n }\n\n startInvocation(id: string): Invocation {\n if (this.invocations.has(id)) throw new Error(`invocation ${id} already started`);\n const inv = new InvocationState(id, () => this.patched?.clock.cancelOwner(id));\n this.invocations.set(id, inv);\n if (this.patched) this.patched.clock.owner = id;\n return inv;\n }\n\n private invocation(id: string): InvocationState {\n const inv = this.invocations.get(id);\n if (!inv) throw new Error(`effect from unknown invocation ${id}`);\n return inv;\n }\n\n private decide(point: EffectPoint, ordinal: number): FaultKind | null {\n if (this.options.mode === \"replay\") {\n const d = this.options.schedule.faults.find(\n (f) => f.invocation === point.invocation && f.ordinal === ordinal,\n );\n return d && point.allowed.includes(d.fault) ? d.fault : null;\n }\n const [fault, next] = decideFault(this.prng, point.allowed, this.faults.length, {\n maxFaultsPerRun: this.options.bounds.maxFaultsPerRun,\n faultProbability: this.options.faultProbability,\n });\n this.prng = next;\n return fault;\n }\n\n private record(point: EffectPoint, kind: \"call\" | \"result\" | \"fault\", payload: JsonValue): void {\n this.logState = appendEffect(this.logState, {\n kind,\n invocation: point.invocation,\n target: point.target,\n op: point.op,\n payload,\n });\n }\n\n /** Open an effect point: record the call and decide the fault. */\n private open(point: EffectPoint, inv: InvocationState): FaultKind | null {\n this.effectIndex++;\n const ordinal = inv.ordinal++;\n this.record(point, \"call\", { args: point.args });\n const fault = this.decide(point, ordinal);\n if (fault) {\n this.faults.push({\n invocation: point.invocation,\n ordinal,\n fault,\n target: point.target,\n op: point.op,\n });\n }\n return fault;\n }\n\n async effect<T>(\n point: EffectPoint,\n perform: () => Promise<T>,\n summarize: (value: T) => JsonValue,\n ): Promise<T> {\n const inv = this.invocation(point.invocation);\n if (inv.isCrashed()) return hang();\n const fault = this.open(point, inv);\n if (fault === \"crash_before\" || fault === \"cut_off\") {\n this.record(point, \"fault\", { args: point.args, fault });\n inv.crash();\n return hang();\n }\n if (fault === \"error\") {\n this.record(point, \"fault\", { args: point.args, fault });\n throw new InjectedEffectError(point, fault);\n }\n let value: T;\n this.inFlight++;\n try {\n value = await perform();\n } catch (err) {\n this.record(point, \"result\", { args: point.args, result: null, error: String(err) });\n throw err;\n } finally {\n this.inFlight--;\n this.patched?.clock.advance(effectLatencyMs);\n }\n this.record(point, \"result\", { args: point.args, result: summarize(value) });\n // The effect committed while the invocation was dying: nothing after it runs.\n if (inv.isCrashed()) return hang();\n if (fault === \"crash_after\") {\n this.record(point, \"fault\", { args: point.args, fault });\n inv.crash();\n return hang();\n }\n if (fault === \"ambiguous\") {\n this.record(point, \"fault\", { args: point.args, fault });\n throw new InjectedEffectError(point, fault);\n }\n return value;\n }\n\n effectSync<T>(point: EffectPoint, perform: () => T, summarize: (value: T) => JsonValue): T {\n const inv = this.invocation(point.invocation);\n if (inv.isCrashed()) throw new CrashSignal(inv.id);\n const fault = this.open(point, inv);\n if (fault === \"crash_before\" || fault === \"cut_off\") {\n this.record(point, \"fault\", { args: point.args, fault });\n inv.crash();\n throw new CrashSignal(inv.id);\n }\n if (fault === \"error\") {\n this.record(point, \"fault\", { args: point.args, fault });\n throw new InjectedEffectError(point, fault);\n }\n let value: T;\n try {\n value = perform();\n } catch (err) {\n this.record(point, \"result\", { args: point.args, result: null, error: String(err) });\n throw err;\n }\n this.record(point, \"result\", { args: point.args, result: summarize(value) });\n if (fault === \"crash_after\") {\n this.record(point, \"fault\", { args: point.args, fault });\n inv.crash();\n throw new CrashSignal(inv.id);\n }\n if (fault === \"ambiguous\") {\n this.record(point, \"fault\", { args: point.args, fault });\n throw new InjectedEffectError(point, fault);\n }\n return value;\n }\n\n unsupported(reason: string): void {\n this.reasons.push(reason);\n }\n\n settle<T>(promise: Promise<T>, invocation: string): Promise<T> {\n const inv = this.invocation(invocation);\n const patched = this.patched;\n if (patched) patched.clock.owner = invocation;\n if (!patched) {\n // Globals not installed (direct use outside runOnce): just wait, abandoning on crash.\n return Promise.race([promise, inv.crashed.then(() => new Promise<T>(() => {}))]);\n }\n return settleOn(promise, {\n clock: patched.clock,\n inFlight: () => this.inFlight,\n crashed: () => inv.isCrashed(),\n stuck: () => {\n // Nothing can make progress: report it and abandon the invocation so the run can end.\n this.unsupported(\n `invocation ${invocation} is waiting on something Eutaxy cannot see (no effect in flight, no timer due)`,\n );\n inv.crash();\n },\n });\n }\n\n snapshot(invocation: string, target: string, payload: JsonValue): void {\n this.logState = appendEffect(this.logState, {\n kind: \"snapshot\",\n invocation,\n target,\n op: \"snapshot\",\n payload,\n });\n }\n}\n","/**\n * Shrinking, the loop: try the pure candidates in order, replay each, keep\n * the first that still violates the same invariant for the same keys, and\n * repeat from there until nothing smaller works or the budget is spent.\n */\n\nimport {\n checkInvariants,\n type EffectLog,\n type Platform,\n recomputePerMessageExpected,\n type ScenarioSpec,\n type Schedule,\n type ShrinkState,\n sameViolation,\n shrinkCandidates,\n type Violation,\n} from \"@eutaxy/core\";\nimport { replayRun } from \"./explore.ts\";\n\nexport interface ShrinkOptions {\n readonly maxRuns: number;\n readonly deadline: number;\n readonly now: () => number;\n}\n\nexport interface ShrinkResult {\n readonly spec: ScenarioSpec;\n readonly schedule: Schedule;\n readonly keptEvents: readonly string[];\n readonly trace: EffectLog;\n readonly violation: Violation;\n readonly runs: number;\n readonly faultsRemoved: number;\n readonly eventsRemoved: number;\n}\n\n/** The scenario restricted to the kept events, with per-message invariants re-derived. */\nexport function restrictSpec(\n platform: Platform,\n spec: ScenarioSpec,\n keepIds: readonly string[],\n): ScenarioSpec {\n const restricted = platform.restrictEvents(spec, keepIds);\n const bodies = platform.initialEvents(restricted).map((e) => e.data);\n return { ...restricted, invariants: recomputePerMessageExpected(restricted.invariants, bodies) };\n}\n\nexport async function shrink(\n spec: ScenarioSpec,\n platform: Platform,\n schedule: Schedule,\n violation: Violation,\n trace: EffectLog,\n options: ShrinkOptions,\n): Promise<ShrinkResult> {\n const allIds = platform.initialEvents(spec).map((e) => e.id);\n let state: ShrinkState = { schedule, keepIds: allIds };\n let best = { trace, violation };\n let runs = 0;\n\n let improved = true;\n while (improved && runs < options.maxRuns && options.now() < options.deadline) {\n improved = false;\n for (const candidate of shrinkCandidates(state)) {\n if (runs >= options.maxRuns || options.now() >= options.deadline) break;\n const candidateSpec = restrictSpec(platform, spec, candidate.keepIds);\n const run = await replayRun(candidateSpec, platform, candidate.schedule);\n const log = run.log;\n runs++;\n // A smaller run that touches something Eutaxy cannot control is not a valid counterexample.\n if (run.unsupportedReasons.length > 0) continue;\n const found = checkInvariants(log, candidateSpec.invariants).find((v) =>\n sameViolation(v, violation),\n );\n if (found) {\n state = candidate;\n best = { trace: log, violation: found };\n improved = true;\n break;\n }\n }\n }\n return {\n spec: restrictSpec(platform, spec, state.keepIds),\n schedule: state.schedule,\n keptEvents: state.keepIds,\n trace: best.trace,\n violation: best.violation,\n runs,\n faultsRemoved: schedule.faults.length - state.schedule.faults.length,\n eventsRemoved: allIds.length - state.keepIds.length,\n };\n}\n","/**\n * The exploration loop: run the scenario under seeded fault injection until\n * an invariant breaks or the budget is spent; replay any violation before\n * reporting it.\n */\n\nimport {\n type BoundsReached,\n checkInvariants,\n digestLog,\n type EffectLog,\n type EventRef,\n nextU32,\n type Platform,\n type PrngState,\n type ScenarioSpec,\n type ScenarioVerdict,\n type Schedule,\n seedPrng,\n} from \"@eutaxy/core\";\nimport { Run } from \"./run.ts\";\nimport { shrink } from \"./shrink.ts\";\n\nexport interface ExploreOptions {\n readonly seed: number | string;\n /** Hard cap on runs, in addition to the scenario's time budget. */\n readonly maxRuns?: number;\n /** Probability of injecting at an eligible effect point. */\n readonly faultProbability?: number;\n /** Clock for the time budget; injectable for tests. */\n readonly now?: () => number;\n /** Hard cap on replay runs spent shrinking a violation. */\n readonly maxShrinkRuns?: number;\n /**\n * How many of the first exploration runs to replay in reverse order\n * before reporting BOUNDED, to detect module-level state leaking between\n * runs. 0 disables the pass.\n */\n readonly leakCheckRuns?: number;\n}\n\nconst engineAssumptions: readonly string[] = [\n \"schedule points are effect boundaries: proxied bindings, patched timers and fetch; other awaits run in program order\",\n \"faults: crash_before, crash_after, ambiguous, error at any effect point; redelivery per the platform's queue model\",\n \"one invocation at a time (maxConcurrentInvocations = 1)\",\n \"Date, Math.random, crypto.randomUUID, crypto.getRandomValues, performance.now and timers are virtualised per run from the seed; time starts at 2026-01-01T00:00:00Z and advances 1 ms per effect and to each timer's due time\",\n \"timers fire only while the invocation is idle (no effect in flight), in due order; an invocation waiting on something outside Eutaxy makes the run UNSUPPORTED\",\n \"module-level state cannot be reset between runs; before BOUNDED the first runs are replayed in reverse order and any difference makes the run UNSUPPORTED (module_state_leak)\",\n];\n\n/** Run the scenario once under the given run's fault decisions and return its log. */\nexport async function runOnce(\n spec: ScenarioSpec,\n platform: Platform,\n run: Run,\n): Promise<EffectLog> {\n run.install();\n try {\n await platform.reset(spec);\n const pending: EventRef[] = [...platform.initialEvents(spec)];\n while (pending.length > 0) {\n const event = pending.shift() as EventRef;\n const result = await platform.deliver(event, run, spec);\n pending.push(...result.followUps);\n }\n await platform.finish?.(spec, run);\n } finally {\n run.uninstall();\n }\n return run.log;\n}\n\n/** Re-run a recorded schedule exactly and return the whole run (log and support status). */\nexport async function replayRun(\n spec: ScenarioSpec,\n platform: Platform,\n schedule: Schedule,\n): Promise<Run> {\n const run = new Run({ mode: \"replay\", schedule, bounds: spec.bounds, faultProbability: 0 });\n await runOnce(spec, platform, run);\n return run;\n}\n\n/** Re-run a recorded schedule exactly. */\nexport async function replay(\n spec: ScenarioSpec,\n platform: Platform,\n schedule: Schedule,\n): Promise<EffectLog> {\n return (await replayRun(spec, platform, schedule)).log;\n}\n\nexport async function explore(\n spec: ScenarioSpec,\n platform: Platform,\n options: ExploreOptions,\n): Promise<ScenarioVerdict> {\n const now = options.now ?? (() => Date.now());\n const maxRuns = options.maxRuns ?? 100;\n const faultProbability = options.faultProbability ?? 0.5;\n const assumptions = [...engineAssumptions, ...platform.assumptions];\n const start = now();\n const reached = { runs: 0, effectPoints: 0, faultsInjected: 0 };\n const done = (): BoundsReached => ({ ...reached, elapsedMs: now() - start });\n const base = { scenario: spec.name, seed: options.seed, assumptions };\n\n if (spec.bounds.maxConcurrentInvocations !== 1) {\n return {\n ...base,\n kind: \"UNSUPPORTED\",\n cause: \"unsupported_bounds\",\n reason: \"maxConcurrentInvocations above 1 is not supported yet\",\n reached: done(),\n };\n }\n\n const leakCheckRuns = options.leakCheckRuns ?? 2;\n /** The first runs' schedules and digests, replayed in reverse order before BOUNDED. */\n const witnesses: { schedule: Schedule; digest: string }[] = [];\n\n let master: PrngState = seedPrng(options.seed);\n while (reached.runs < maxRuns && now() - start < spec.bounds.budgetMs) {\n const [runSeed, next] = nextU32(master);\n master = next;\n const run = new Run({\n mode: \"explore\",\n schedule: { seed: runSeed, faults: [] },\n bounds: spec.bounds,\n faultProbability,\n });\n const log = await runOnce(spec, platform, run);\n reached.runs++;\n reached.effectPoints += run.effectPoints;\n reached.faultsInjected += run.faultsInjected;\n if (witnesses.length < leakCheckRuns)\n witnesses.push({ schedule: run.schedule, digest: digestLog(log) });\n\n if (run.unsupportedReasons.length > 0) {\n return {\n ...base,\n kind: \"UNSUPPORTED\",\n cause: \"unsupported_api\",\n reason: run.unsupportedReasons.join(\"; \"),\n reached: done(),\n };\n }\n\n const violations = checkInvariants(log, spec.invariants);\n const violation = violations[0];\n if (violation) {\n const schedule = run.schedule;\n const replayedRun = await replayRun(spec, platform, schedule);\n const replayed = replayedRun.log;\n reached.runs++;\n if (replayedRun.unsupportedReasons.length > 0 || digestLog(replayed) !== digestLog(log)) {\n return {\n ...base,\n kind: \"UNSUPPORTED\",\n cause: \"not_replayable\",\n reason: `the violating run of seed ${schedule.seed} did not reproduce on replay`,\n reached: done(),\n };\n }\n // Shrink within the scenario's budget (a second budget's worth at most), then report.\n const shrunk = await shrink(spec, platform, schedule, violation, replayed, {\n maxRuns: options.maxShrinkRuns ?? 200,\n deadline: now() + spec.bounds.budgetMs,\n now,\n });\n reached.runs += shrunk.runs;\n return {\n ...base,\n kind: \"VIOLATED\",\n violation: shrunk.violation,\n trace: shrunk.trace,\n schedule: shrunk.schedule,\n keptEvents: shrunk.keptEvents,\n shrunk: {\n faultsRemoved: shrunk.faultsRemoved,\n eventsRemoved: shrunk.eventsRemoved,\n runs: shrunk.runs,\n },\n reached: done(),\n };\n }\n }\n // Module-state leak detection: the same schedules, in the opposite order, must give the same logs.\n for (const witness of [...witnesses].reverse()) {\n const again = await replayRun(spec, platform, witness.schedule);\n reached.runs++;\n if (again.unsupportedReasons.length > 0 || digestLog(again.log) !== witness.digest) {\n return {\n ...base,\n kind: \"UNSUPPORTED\",\n cause: \"module_state_leak\",\n reason: `run seed ${witness.schedule.seed} produced a different log when replayed after other runs: state is leaking between runs (module-level variables, or a binding Eutaxy does not reset)`,\n reached: done(),\n };\n }\n }\n return { ...base, kind: \"BOUNDED\", bounds: spec.bounds, reached: done() };\n}\n"],"mappings":";;AAWA,SAAS,KAAK,GAAW,GAAmB;CAC1C,QAAS,KAAK,IAAM,MAAO,KAAK,OAAS;AAC3C;;AAGA,SAAS,WAAW,MAA4B;CAC9C,IAAI,IAAI,SAAS;CACjB,aAAa;EACX,IAAK,IAAI,eAAgB;EACzB,IAAI,IAAI;EACR,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,SAAU;EACxC,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,UAAU;EACxC,QAAQ,IAAK,MAAM,QAAS;CAC9B;AACF;;AAGA,SAAS,WAAW,GAAmB;CACrC,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;EACjC,KAAK,EAAE,WAAW,CAAC;EACnB,IAAI,KAAK,KAAK,GAAG,QAAU;CAC7B;CACA,OAAO,MAAM;AACf;;AAGA,SAAgB,SAAS,MAAkC;CAEzD,MAAM,OAAO,WADA,OAAO,SAAS,WAAW,WAAW,IAAI,IAAI,SAAS,CACxC;CAC5B,MAAM,IAAsC;EAAC,KAAK;EAAG,KAAK;EAAG,KAAK;EAAG,KAAK;CAAC;CAC3E,IAAI,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,OAAO,GACrD,EAAE,KAAK;CAET,OAAO;AACT;;AAGA,SAAgB,QAAQ,OAAgD;CACtE,MAAM,CAAC,IAAI,IAAI,IAAI,MAAM;CACzB,MAAM,SAAS,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM;CACjE,MAAM,IAAK,MAAM,MAAO;CACxB,IAAI,MAAM,KAAK,QAAQ;CACvB,IAAI,MAAM,KAAK,QAAQ;CACvB,MAAM,MAAM,KAAK,QAAQ;CACzB,MAAM,MAAM,KAAK,QAAQ;CACzB,MAAM,KAAK,OAAO;CAClB,KAAK,KAAK,IAAI,EAAE;CAChB,OAAO,CAAC,QAAQ;EAAC;EAAI;EAAI;EAAI;CAAE,CAAC;AAClC;;AAGA,SAAgB,UAAU,OAAgD;CACxE,MAAM,CAAC,GAAG,QAAQ,QAAQ,KAAK;CAC/B,OAAO,EAAE,MAAM,KAAK,KAAK,KAAK,IAAI;AACpC;;;;;AAMA,SAAgB,QAAQ,OAAkB,OAA6C;CACrF,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,YACnD,MAAM,IAAI,WAAW,sDAAsD,OAAO;CAEpF,IAAI,UAAU,GAAG,OAAO,CAAC,GAAG,KAAK;CACjC,MAAM,QAAQ,aAAiB,aAAgB;CAC/C,IAAI,IAAI;CACR,SAAS;EACP,MAAM,CAAC,GAAG,QAAQ,QAAQ,CAAC;EAC3B,IAAI;EACJ,IAAI,IAAI,OAAO,OAAO,CAAC,IAAI,OAAO,CAAC;CACrC;AACF;;;;;;;;;;;;ACjCA,SAAgB,YACd,OACA,SACA,aACA,QACwC;CACxC,IAAI,QAAQ,WAAW,KAAK,eAAe,OAAO,iBAAiB,OAAO,CAAC,MAAM,KAAK;CACtF,MAAM,CAAC,GAAG,MAAM,UAAU,KAAK;CAC/B,IAAI,KAAK,OAAO,kBAAkB,OAAO,CAAC,MAAM,EAAE;CAClD,MAAM,CAAC,GAAG,MAAM,QAAQ,IAAI,QAAQ,MAAM;CAC1C,OAAO,CAAC,QAAQ,MAAM,MAAM,EAAE;AAChC;;;;;;;;ACrBA,SAAgB,4BACd,YACA,QACsB;CACtB,OAAO,WAAW,KAAK,QAAQ;EAC7B,IAAI,IAAI,SAAS,iBAAiB,CAAC,IAAI,YAAY,OAAO;EAC1D,MAAM,UAAU,IAAI,WAAW;EAC/B,MAAM,WAAwB,CAAC;EAC/B,KAAK,MAAM,KAAK,QAAQ;GACtB,MAAM,IAAI,QAAQ,GAAG,OAAO;GAC5B,IAAI,MAAM,KAAA,GAAW,SAAS,KAAK,CAAC;EACtC;EACA,OAAO;GAAE,GAAG;GAAK;EAAS;CAC5B,CAAC;AACH;;AA6CA,SAAgB,aACd,KACA,QAC0D;CAC1D,KAAK,IAAI,IAAI,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;EAChD,MAAM,IAAI,IAAI,QAAQ;EACtB,IAAI,EAAE,SAAS,cAAc,EAAE,WAAW,QAAQ;GAChD,MAAM,SAAS,QAAQ,EAAE,SAAS,QAAQ;GAC1C,IAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,GAC/D,OAAO;GAET,OAAO,CAAC;EACV;CACF;AAEF;AAEA,SAAgB,WAAW,KAAU,WAAkC;CACrE,MAAM,IAAI,IAAI,UAAU;CACxB,QAAQ,UAAU,IAAlB;EACE,KAAK,MACH,OAAO,MAAM,KAAA,KAAa,UAAU,GAAG,UAAU,KAAK;EACxD,KAAK,OACH,OAAO,MAAM,KAAA,KAAa,CAAC,UAAU,GAAG,UAAU,KAAK;EACzD,KAAK,MACH,OAAO,OAAO,MAAM,YAAY,IAAI,UAAU;EAChD,KAAK,OACH,OAAO,OAAO,MAAM,YAAY,KAAK,UAAU;EACjD,KAAK,MACH,OAAO,OAAO,MAAM,YAAY,IAAI,UAAU;EAChD,KAAK,OACH,OAAO,OAAO,MAAM,YAAY,KAAK,UAAU;EACjD,KAAK,MACH,OAAO,MAAM,KAAA,KAAa,UAAU,MAAM,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC;EACvE,KAAK,WACH,OAAO,MAAM,KAAA,KAAa,MAAM;CACpC;AACF;;AAGA,SAAgB,UAAU,KAAgB,OAA+C;CACvF,MAAM,SAAS,aAAa,KAAK,MAAM,MAAM;CAC7C,IAAI,CAAC,QAAQ,OAAO,KAAA;CACpB,MAAM,OAAO,OAAO,MAAM,UAAU,CAAC;CACrC,MAAM,QAAQ,MAAM,SAAS,CAAC;CAC9B,OAAO,KAAK,QAAQ,MAAM,MAAM,OAAO,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC;AAChE;AAEA,SAAS,YAAY,KAAgB,QAA0B;CAC7D,IAAI;CACJ,KAAK,MAAM,KAAK,IAAI,SAAS,IAAI,EAAE,SAAS,cAAc,EAAE,WAAW,QAAQ,OAAO,EAAE;CACxF,OAAO,SAAS,KAAA,IAAY,CAAC,IAAI,CAAC,IAAI;AACxC;;AAYA,SAAgB,cAAc,GAAc,GAAuB;CACjE,OACE,EAAE,cAAc,EAAE,aAClB,EAAE,KAAK,WAAW,EAAE,KAAK,UACzB,EAAE,KAAK,OAAO,GAAG,MAAM,MAAM,EAAE,KAAK,EAAE;AAE1C;;AAGA,SAAgB,QAAQ,OAAkB,MAAqC;CAC7E,IAAI,MAA6B;CACjC,IAAI,SAAS,IAAI,OAAO;CACxB,KAAK,MAAM,QAAQ,KAAK,MAAM,GAAG,GAAG;EAClC,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU,OAAO,KAAA;EACpD,IAAI,MAAM,QAAQ,GAAG,GAAG;GACtB,MAAM,IAAI,OAAO,IAAI;GACrB,IAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,GAAG,OAAO,KAAA;GAC1C,MAAM,IAAI;EACZ,OACE,MAAO,IAA4C;EAErD,IAAI,QAAQ,KAAA,GAAW,OAAO,KAAA;CAChC;CACA,OAAO;AACT;AAEA,SAAS,UAAU,GAA0B,GAAuB;CAClE,IAAI,MAAM,KAAA,GAAW,OAAO;CAC5B,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,MAAM,QAAQ,MAAM,QAAQ,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU,OAAO;CACvF,IAAI,MAAM,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,GAAG,OAAO;CAClD,IAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GACrC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,UAAU,GAAG,EAAE,EAAe,CAAC;CAEnF,MAAM,KAAK;CACX,MAAM,KAAK;CACX,MAAM,KAAK,OAAO,KAAK,EAAE,CAAC,CAAC,KAAK;CAChC,MAAM,KAAK,OAAO,KAAK,EAAE,CAAC,CAAC,KAAK;CAChC,OACE,GAAG,WAAW,GAAG,UACjB,GAAG,OAAO,GAAG,MAAM,MAAM,GAAG,MAAM,UAAU,GAAG,IAAI,GAAG,EAAe,CAAC;AAE1E;AAEA,SAAgB,QAAQ,QAAsB,KAA8B;CAC1E,IAAI,OAAO,WAAW,IAAI,QAAQ,OAAO;CACzC,IAAI,IAAI,OAAO,KAAA,KAAa,OAAO,OAAO,IAAI,IAAI,OAAO;CACzD,IAAI,IAAI,SAAS,KAAA,KAAa,OAAO,SAAS,IAAI,MAAM,OAAO;CAC/D,IAAI,IAAI,OACD;OAAA,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,IAAI,KAAK,GACjD,IAAI,CAAC,UAAU,QAAQ,OAAO,SAAS,IAAI,GAAG,IAAI,GAAG,OAAO;CAAA;CAGhE,IAAI,IAAI,SACN,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,IAAI,OAAO,GAAG;EACrD,MAAM,IAAI,QAAQ,OAAO,SAAS,IAAI;EACtC,IAAI,OAAO,MAAM,YAAY,IAAI,KAAK,OAAO;CAC/C;CAEF,OAAO;AACT;AAEA,SAAgB,cAAc,KAAgB,KAA8C;CAC1F,OAAO,IAAI,QAAQ,QAAQ,MAAM,QAAQ,GAAG,GAAG,CAAC;AAClD;;AAGA,SAAS,MAAM,QAAsB,MAAkC;CACrE,MAAM,IAAI,QAAQ,OAAO,SAAS,IAAI;CACtC,OAAO,MAAM,KAAA,IAAY,KAAA,IAAY,cAAc,CAAC;AACtD;AAEA,SAAgB,eAAe,KAAgB,KAAkC;CAC/E,QAAQ,IAAI,MAAZ;EACE,KAAK,YACH,OAAO,cAAc,KAAK,GAAG;EAC/B,KAAK,WACH,OAAO,aAAa,KAAK,GAAG;EAC9B,KAAK,oBAAoB;GACvB,MAAM,uBAAO,IAAI,IAAoB;GACrC,KAAK,MAAM,KAAK,cAAc,KAAK,IAAI,MAAM,GAAG;IAC9C,MAAM,IAAI,MAAM,GAAG,IAAI,GAAG;IAC1B,IAAI,MAAM,KAAA,GAAW;IACrB,MAAM,QAAQ,KAAK,IAAI,CAAC;IACxB,IAAI,UAAU,KAAA,GACZ,OAAO;KACL,WAAW,IAAI;KACf,SAAS,GAAG,IAAI,OAAO,OAAO,GAAG,IAAI,OAAO,MAAM,IAAI,0BAA0B,EAAE,QAAQ,MAAM,OAAO,EAAE,IAAI;KAC7G,MAAM,CAAC,CAAC;KACR,UAAU,CAAC,OAAO,EAAE,GAAG;IACzB;IAEF,KAAK,IAAI,GAAG,EAAE,GAAG;GACnB;GACA,OAAO;EACT;EACA,KAAK,eAAe;GAClB,MAAM,0BAAU,IAAI,IAAY;GAChC,MAAM,WAAW,cAAc,KAAK,IAAI,MAAM;GAC9C,KAAK,MAAM,KAAK,UAAU;IACxB,MAAM,IAAI,MAAM,GAAG,IAAI,GAAG;IAC1B,IAAI,MAAM,KAAA,GAAW,QAAQ,IAAI,CAAC;GACpC;GACA,MAAM,UAAU,IAAI,SAAS,KAAK,MAAM,cAAc,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;GACvF,IAAI,QAAQ,WAAW,GAAG,OAAO;GACjC,OAAO;IACL,WAAW,IAAI;IACf,SAAS,GAAG,IAAI,OAAO,OAAO,GAAG,IAAI,OAAO,MAAM,IAAI,6BAA6B,QAAQ,KAAK,IAAI;IACpG,MAAM;IACN,UAAU,SAAS,KAAK,MAAM,EAAE,GAAG;GACrC;EACF;CACF;AACF;AAEA,SAAS,cAAc,KAAgB,KAAiC;CACtE,MAAM,OAAO,UAAU,KAAK,IAAI,KAAK;CACrC,IAAI,SAAS,KAAA,GACX,OAAO;EACL,WAAW,IAAI;EACf,SAAS,kBAAkB,IAAI,MAAM,OAAO;EAC5C,MAAM,CAAC;EACP,UAAU,CAAC;CACb;CAEF,MAAM,UAAU,KAAK,QAAQ,MAAM,CAAC,IAAI,MAAM,OAAO,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC;CAC5E,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,MAAM,OAAO,QAAQ,KAAK,MAAM,cAAc,CAAC,CAAC;CAChD,MAAM,QAAQ,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,QAAQ,SAAS,IAAI,QAAQ;CAC1E,OAAO;EACL,WAAW,IAAI;EACf,SAAS,GAAG,QAAQ,OAAO,aAAa,IAAI,MAAM,MAAM,MAAM,IAAI,MAAM,OAAO,0BAA0B;EACzG;EACA,UAAU,YAAY,KAAK,IAAI,MAAM,MAAM;CAC7C;AACF;AAEA,SAAS,aAAa,KAAgB,KAAgC;CACpE,MAAM,OAAO,UAAU,KAAK,IAAI,KAAK;CACrC,IAAI,SAAS,KAAA,GACX,OAAO;EACL,WAAW,IAAI;EACf,SAAS,kBAAkB,IAAI,MAAM,OAAO;EAC5C,MAAM,CAAC;EACP,UAAU,CAAC;CACb;CAEF,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,IAAI,EAAE,IAAI;EAChB,IAAI,MAAM,KAAA,GAAW,QAAQ,IAAI,cAAc,CAAC,CAAC;CACnD;CACA,MAAM,UAAoB,CAAC;CAC3B,MAAM,WAAqB,CAAC;CAC5B,KAAK,MAAM,KAAK,cAAc,KAAK,IAAI,IAAI,GAAG;EAC5C,MAAM,IAAI,MAAM,GAAG,IAAI,GAAG;EAC1B,IAAI,MAAM,KAAA,KAAa,QAAQ,IAAI,CAAC,GAAG;EACvC,IAAI,CAAC,QAAQ,SAAS,CAAC,GAAG,QAAQ,KAAK,CAAC;EACxC,SAAS,KAAK,EAAE,GAAG;CACrB;CACA,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,OAAO;EACL,WAAW,IAAI;EACf,SAAS,GAAG,IAAI,KAAK,OAAO,GAAG,IAAI,KAAK,MAAM,IAAI,uBAAuB,QAAQ,KAAK,IAAI,EAAE,OAAO,IAAI,MAAM,MAAM,GAAG,IAAI,OAAO,MAAM,IAAI,MAAM,OAAO;EACxJ,MAAM;EACN;CACF;AACF;AAEA,SAAgB,gBACd,KACA,YACsB;CACtB,MAAM,MAAmB,CAAC;CAC1B,KAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,IAAI,eAAe,KAAK,GAAG;EACjC,IAAI,GAAG,IAAI,KAAK,CAAC;CACnB;CACA,OAAO;AACT;;ACjSA,MAAa,gBAAwB;CACnC,iBAAiB;CACjB,iBAAiB;CACjB,0BAA0B;CAC1B,UAAU;AACZ;AAEA,SAAS,cAAc,GAAyB;CAC9C,OAAO,OAAO,MAAM,YAAY,OAAO,UAAU,CAAC,KAAK,IAAI;AAC7D;;AAGA,SAAgB,iBAAiB,MAAuC;CACtE,MAAM,SAAmB,CAAC;CAC1B,IAAI,KAAK,YAAY,GAAG,OAAO,KAAK,0BAA0B,OAAO,KAAK,OAAO,GAAG;CACpF,IAAI,CAAC,KAAK,KAAK,KAAK,GAAG,OAAO,KAAK,wBAAwB;CAC3D,IAAI,CAAC,uBAAuB,KAAK,KAAK,IAAI,GACxC,OAAO,KAAK,sDAAsD,KAAK,UAAU,KAAK,IAAI,GAAG;CAC/F,IAAI,CAAC,KAAK,OAAO,OAAO,OAAO,KAAK,gCAAgC;CACpE,IAAI,CAAC,KAAK,OAAO,QAAQ,OAAO,KAAK,iCAAiC;CACtE,IAAI,CAAC,KAAK,MAAM,MAAM,OAAO,KAAK,8BAA8B;CAChE,KAAK,MAAM,SAAS,GAAG,MAAM;EAC3B,IAAI,CAAC,EAAE,MAAM,OAAO,KAAK,SAAS,EAAE,yBAAyB;CAC/D,CAAC;CACD,IAAI,KAAK,WAAW,WAAW,GAAG,OAAO,KAAK,oCAAoC;CAClF,MAAM,wBAAQ,IAAI,IAAY;CAC9B,KAAK,MAAM,OAAO,KAAK,YAAY;EACjC,IAAI,CAAC,IAAI,MAAM,OAAO,KAAK,8BAA8B;OACpD,IAAI,MAAM,IAAI,IAAI,IAAI,GACzB,OAAO,KAAK,4BAA4B,KAAK,UAAU,IAAI,IAAI,GAAG;EACpE,MAAM,IAAI,IAAI,IAAI;CACpB;CACA,MAAM,sBAAM,IAAI,IAAY;CAC5B,KAAK,MAAM,KAAK,KAAK,WAAW;EAC9B,IAAI,IAAI,IAAI,EAAE,IAAI,GAAG,OAAO,KAAK,sBAAsB,KAAK,UAAU,EAAE,IAAI,GAAG;EAC/E,IAAI,IAAI,EAAE,IAAI;CAChB;CACA,KAAK,MAAM,KAAK;EACd;EACA;EACA;EACA;CACF,GACE,IAAI,MAAM,qBAAqB,MAAM,mBAAmB;EACtD,MAAM,IAAI,KAAK,OAAO;EACtB,IAAI,EAAE,OAAO,UAAU,CAAC,KAAK,KAAK,IAChC,OAAO,KAAK,UAAU,EAAE,gCAAgC;CAC5D,OAAO,IAAI,CAAC,cAAc,KAAK,OAAO,EAAE,GACtC,OAAO,KAAK,UAAU,EAAE,4BAA4B;CAExD,OAAO;AACT;;;AC1FA,SAAgB,iBAAiB,OAA4C;CAC3E,MAAM,MAAqB,CAAC;CAC5B,MAAM,SAAS,OAAO,SAAS,GAAG,MAAM;EACtC,IAAI,KAAK;GACP,UAAU;IACR,MAAM,MAAM,SAAS;IACrB,QAAQ,MAAM,SAAS,OAAO,QAAQ,GAAG,MAAM,MAAM,CAAC;GACxD;GACA,SAAS,MAAM;EACjB,CAAC;CACH,CAAC;CACD,IAAI,MAAM,QAAQ,SAAS,GACzB,MAAM,QAAQ,SAAS,OAAO;EAC5B,IAAI,KAAK;GACP,UAAU;IACR,MAAM,MAAM,SAAS;IAErB,QAAQ,MAAM,SAAS,OAAO,QAAQ,MAAM,CAAC,EAAE,WAAW,WAAW,GAAG,GAAG,EAAE,CAAC;GAChF;GACA,SAAS,MAAM,QAAQ,QAAQ,MAAM,MAAM,EAAE;EAC/C,CAAC;CACH,CAAC;CAEH,OAAO;AACT;;;ACmBA,SAAgB,gBAAgB,GAA4B;CAC1D,QAAQ,EAAE,MAAV;EACE,KAAK,YACH,OAAO,YAAY,EAAE,SAAS,IAAI,EAAE,UAAU,QAAQ,SAAS,EAAE,SAAS,KAAK,IAAI,EAAE,QAAQ,KAAK;EACpG,KAAK,WACH,OAAO,WAAW,EAAE,SAAS,oBAAoB,EAAE,QAAQ,KAAK,WAAW,EAAE,QAAQ,aAAa,oBAAoB,EAAE,QAAQ,eAAe;EACjJ,KAAK,eACH,OAAO,eAAe,EAAE,SAAS,IAAI,EAAE,MAAM,IAAI,EAAE;CACvD;AACF;;;;;;;;;;;;ACtDA,MAAa,eAAe,KAAK,IAAI,MAAM,GAAG,CAAC;AAM/C,MAAM,iBAAiB,WAAW,WAAW,KAAK,UAAU;AAY5D,IAAa,eAAb,MAA0B;CACxB,OAAe;CACf,SAA0B,CAAC;CAC3B,SAAiB;;CAEjB,QAAuB;CAEvB,MAAc;EACZ,OAAO,KAAK;CACd;CAEA,QAAQ,IAAkB;EACxB,IAAI,KAAK,GAAG,KAAK,QAAQ;CAC3B;CAEA,SACE,UACA,OACA,MACA,UACQ;EACR,MAAM,KAAK,OAAO,SAAS,KAAK,KAAK,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI;EACrE,MAAM,QAAe;GACnB,IAAI,KAAK;GACT,KAAK,KAAK,OAAO;GACjB;GACA;GACA;GACA,OAAO,KAAK;EACd;EACA,KAAK,OAAO,KAAK,KAAK;EACtB,OAAO,MAAM;CACf;CAEA,WAAW,UAAwC,QAAQ,GAAG,GAAG,MAAyB;EACxF,OAAO,KAAK,SAAS,UAAU,OAAO,MAAM,IAAI;CAClD;CAEA,YAAY,UAAwC,QAAQ,GAAG,GAAG,MAAyB;EACzF,OAAO,KAAK,SAAS,UAAU,OAAO,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,CAAC;CAC5E;CAEA,MAAM,IAAkB;EACtB,KAAK,SAAS,KAAK,OAAO,QAAQ,MAAM,EAAE,OAAO,EAAE;CACrD;CAEA,gBAAwB;EACtB,OAAO,KAAK,OAAO;CACrB;;CAGA,YAAY,OAAqB;EAC/B,KAAK,SAAS,KAAK,OAAO,QAAQ,MAAM,EAAE,UAAU,KAAK;CAC3D;;CAGA,WAAoB;EAClB,IAAI,KAAK,OAAO,WAAW,GAAG,OAAO;EACrC,IAAI,WAAW,KAAK,OAAO;EAC3B,KAAK,MAAM,KAAK,KAAK,QACnB,IAAI,EAAE,MAAM,SAAS,OAAQ,EAAE,QAAQ,SAAS,OAAO,EAAE,KAAK,SAAS,IAAK,WAAW;EACzF,IAAI,SAAS,MAAM,KAAK,MAAM,KAAK,OAAO,SAAS;EACnD,IAAI,SAAS,aAAa,MAAM,KAAK,SAAS,KAAK,OAAO,QAAQ,MAAM,MAAM,QAAQ;OACjF,SAAS,MAAM,KAAK,OAAO,SAAS;EACzC,IAAI;GACF,SAAS,SAAS,GAAG,SAAS,IAAI;EACpC,QAAQ,CAER;EACA,OAAO;CACT;AACF;;AAGA,IAAa,gBAAb,MAA2B;CACzB;CAEA,YAAY,MAAuB;EACjC,KAAK,QAAQ,SAAS,UAAU,MAAM;CACxC;CAEA,QAAgB;EACd,MAAM,CAAC,GAAG,QAAQ,UAAU,KAAK,KAAK;EACtC,KAAK,QAAQ;EACb,OAAO;CACT;CAEA,MAAc;EACZ,MAAM,CAAC,GAAG,QAAQ,QAAQ,KAAK,KAAK;EACpC,KAAK,QAAQ;EACb,OAAO;CACT;CAEA,KAAgC,MAAY;EAC1C,MAAM,QAAQ,IAAI,WAAW,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;EAC1E,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;GACxC,MAAM,IAAI,KAAK,IAAI;GACnB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,IAAI,MAAM,QAAQ,KAAK,MAAM,IAAI,KAAM,MAAO,IAAI,IAAM;EACvF;EACA,OAAO;CACT;;CAGA,OAAe;EACb,MAAM,IAAI,KAAK,qBAAK,IAAI,WAAW,EAAE,CAAC;EACtC,EAAE,KAAO,EAAE,KAAgB,KAAQ;EACnC,EAAE,KAAO,EAAE,KAAgB,KAAQ;EACnC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;EACtE,OAAO,GAAG,IAAI,MAAM,GAAG,CAAC,EAAE,GAAG,IAAI,MAAM,GAAG,EAAE,EAAE,GAAG,IAAI,MAAM,IAAI,EAAE,EAAE,GAAG,IAAI,MAAM,IAAI,EAAE,EAAE,GAAG,IAAI,MAAM,EAAE;CACzG;AACF;;AAYA,SAAgB,aAAa,MAAgC;CAC3D,MAAM,QAAQ,IAAI,aAAa;CAC/B,MAAM,SAAS,IAAI,cAAc,IAAI;CACrC,MAAM,IAAI;CACV,MAAM,wBAAQ,IAAI,IAA4C;CAC9D,MAAM,UAAU,QAAgB,KAAa,UAAyB;EACpE,MAAM,QAAQ,WAAW,IAAI,IAAI;EACjC,MAAM,IAAI,KAAK,OAAO,yBAAyB,OAAO,GAAG,CAAC;EAC1D,OAAO,eAAe,OAAO,KAAK;GAChC;GACA,cAAc;GACd,UAAU;GACV,YAAY;EACd,CAAC;CACH;CAEA,MAAM,WAAW;CACjB,MAAM,cAAc,SAAyB,GAAG,MAA0B;EACxE,IAAI,eAAe,KAAA,GAAW,OAAO,IAAI,SAAS,MAAM,IAAI,CAAC,CAAC,CAAC,SAAS;EACxE,OAAO,QAAQ,UAAU,UAAU,KAAK,WAAW,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,UAAU;CACzF;CACA,OAAO,eAAe,aAAa,QAAQ;CAC3C,OAAO,eAAe,aAAa,aAAa;EAAE,OAAO,SAAS;EAAW,UAAU;CAAM,CAAC;CAC9F,OAAO,eAAe,aAAa,OAAO;EACxC,aAAa,MAAM,IAAI;EACvB,cAAc;EACd,UAAU;CACZ,CAAC;CACD,OAAO,eAAe,aAAa,QAAQ,EAAE,OAAO,OAAO,CAAC;CAE5D,OAAO,GAAG,QAAQ,WAAW;CAC7B,OAAO,MAAM,gBAAgB,OAAO,MAAM,CAAC;CAC3C,OAAO,GAAG,eAAe,IAA+B,IAAa,GAAG,SACtE,MAAM,WAAW,IAAI,IAAI,GAAG,IAAI,CAClC;CACA,OAAO,GAAG,gBAAgB,IAA+B,IAAa,GAAG,SACvE,MAAM,YAAY,IAAI,IAAI,GAAG,IAAI,CACnC;CACA,OAAO,GAAG,iBAAiB,OAAgB,OAAO,KAAA,KAAa,MAAM,MAAM,EAAE,CAAC;CAC9E,OAAO,GAAG,kBAAkB,OAAgB,OAAO,KAAA,KAAa,MAAM,MAAM,EAAE,CAAC;CAC/E,MAAM,OAAO,EAAE;CACf,IAAI,QAAQ,OAAO,SAAS,UAAU,OAAO,MAAM,aAAa,MAAM,IAAI,IAAI,YAAY;CAC1F,MAAM,YAAY,EAAE;CACpB,IAAI,aAAa,OAAO,cAAc,UAAU;EAC9C,OAAO,WAAW,oBAAoB,OAAO,KAAK,CAAC;EACnD,OAAO,WAAW,oBAA+C,SAAY,OAAO,KAAK,IAAI,CAAC;CAChG;CAEA,IAAI,WAAW;CACf,MAAM,UAAkC;EACtC,MAAM;EACN,QAAQ;EACR,YAAY;EACZ,aAAa;EACb,cAAc;EACd,eAAe;CACjB;CACA,IAAI,QAAQ,OAAO,SAAS,UAAU,QAAQ,SAAS;CACvD,IAAI,aAAa,OAAO,cAAc,UAAU;EAC9C,QAAQ,gBAAgB;EACxB,QAAQ,qBAAqB;CAC/B;CACA,OAAO;EACL;EACA;EACA,UAAU;GACR,IAAI,UAAU;GACd,WAAW;GACX,KAAK,MAAM,CAAC,KAAK,eAAe,OAAO;IACrC,MAAM,SAAS,QAAQ;IACvB,IAAI,YAAY,OAAO,eAAe,QAAQ,KAAK,UAAU;SACxD,OAAQ,OAAkB;GACjC;EACF;CACF;AACF;;AAGA,SAAgB,WAA0B;CACxC,OAAO,IAAI,SAAS,YAAY,qBAAqB,QAAQ,GAAG,CAAC,CAAC;AACpE;;;;;AAgBA,eAAsB,SAAY,SAAqB,KAAgC;CACrF,IAAI,OAAO;CACX,IAAI,SAAS;CACb,IAAI;CACJ,IAAI;CACJ,MAAM,UAAU,QAAQ,MACrB,MAAM;EACL,OAAO;EACP,QAAQ;CACV,IACC,MAAe;EACd,OAAO;EACP,SAAS;EACT,QAAQ;CACV,CACF;CACA,SAAS;EACP,MAAM,QAAQ,KAAK,CAAC,SAAS,SAAS,CAAC,CAAC;EACxC,IAAI,MAAM;GACR,IAAI,QAAQ,MAAM;GAClB,OAAO;EACT;EACA,IAAI,IAAI,QAAQ,GAAG,OAAO,IAAI,cAAiB,CAAC,CAAC;EACjD,IAAI,IAAI,SAAS,IAAI,GAAG;EACxB,IAAI,IAAI,MAAM,SAAS,GAAG;EAC1B,IAAI,MAAM;EACV,OAAO,IAAI,cAAiB,CAAC,CAAC;CAChC;AACF;;;;;;;;;AC3PA,IAAa,cAAb,cAAiC,MAAM;CACrC,OAAyB;CACzB;CACA,YAAY,YAAoB;EAC9B,MAAM,cAAc,WAAW,8BAA8B;EAC7D,KAAK,aAAa;CACpB;AACF;;AAGA,IAAa,sBAAb,cAAyC,MAAM;CAC7C,OAAyB;CACzB;CACA;CACA,YAAY,OAAoB,OAAkB;EAChD,MAAM,GAAG,MAAM,OAAO,GAAG,MAAM,GAAG,oBAAoB,MAAM,EAAE;EAC9D,KAAK,QAAQ;EACb,KAAK,QAAQ;CACf;AACF;AASA,IAAM,kBAAN,MAA4C;CAC1C;CACA;;CAEA,UAAU;CACV,cAAsB;CACtB,uBAA2C,CAAC;CAC5C;CAEA,YAAY,IAAY,SAAqB;EAC3C,KAAK,KAAK;EACV,KAAK,UAAU;EACf,KAAK,UAAU,IAAI,SAAe,YAAY;GAC5C,KAAK,iBAAiB;EACxB,CAAC;CACH;CAEA,YAAqB;EACnB,OAAO,KAAK;CACd;CAEA,QAAc;EACZ,IAAI,KAAK,aAAa;EACtB,KAAK,cAAc;EACnB,KAAK,QAAQ;EACb,KAAK,eAAe;CACtB;AACF;;AAGA,SAAS,OAAsB;CAC7B,OAAO,IAAI,cAAiB,CAAC,CAAC;AAChC;AAEA,IAAa,MAAb,MAAqC;CACnC,WAA8B;CAC9B,SAA2C,CAAC;CAC5C,cAAsB;CACtB;CACA,8BAA+B,IAAI,IAA6B;CAChE,UAAqC,CAAC;CACtC,WAAmB;CACnB,UAAkC;CAElC;CAEA,YAAY,SAAqB;EAC/B,KAAK,UAAU;EACf,KAAK,OAAO,SAAS,QAAQ,SAAS,IAAI;CAC5C;CAEA,IAAI,MAAiB;EACnB,OAAO,KAAK;CACd;;CAGA,IAAI,WAAqB;EACvB,OAAO;GAAE,MAAM,KAAK,QAAQ,SAAS;GAAM,QAAQ,CAAC,GAAG,KAAK,MAAM;EAAE;CACtE;CAEA,IAAI,eAAuB;EACzB,OAAO,KAAK;CACd;CAEA,IAAI,iBAAyB;EAC3B,OAAO,KAAK,OAAO;CACrB;CAEA,IAAI,qBAAwC;EAC1C,OAAO,KAAK;CACd;;CAGA,UAAgB;EACd,IAAI,CAAC,KAAK,SAAS,KAAK,UAAU,aAAa,KAAK,QAAQ,SAAS,IAAI;CAC3E;CAEA,YAAkB;EAChB,KAAK,SAAS,QAAQ;EACtB,KAAK,UAAU;CACjB;;CAGA,MAAc;EACZ,OAAO,KAAK,UAAU,KAAK,QAAQ,MAAM,IAAI,IAAI,KAAK,IAAI;CAC5D;;CAGA,gBAAwB;EACtB,OAAO,KAAK,SAAS,MAAM,cAAc,KAAK;CAChD;CAEA,gBAAgB,IAAwB;EACtC,IAAI,KAAK,YAAY,IAAI,EAAE,GAAG,MAAM,IAAI,MAAM,cAAc,GAAG,iBAAiB;EAChF,MAAM,MAAM,IAAI,gBAAgB,UAAU,KAAK,SAAS,MAAM,YAAY,EAAE,CAAC;EAC7E,KAAK,YAAY,IAAI,IAAI,GAAG;EAC5B,IAAI,KAAK,SAAS,KAAK,QAAQ,MAAM,QAAQ;EAC7C,OAAO;CACT;CAEA,WAAmB,IAA6B;EAC9C,MAAM,MAAM,KAAK,YAAY,IAAI,EAAE;EACnC,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,kCAAkC,IAAI;EAChE,OAAO;CACT;CAEA,OAAe,OAAoB,SAAmC;EACpE,IAAI,KAAK,QAAQ,SAAS,UAAU;GAClC,MAAM,IAAI,KAAK,QAAQ,SAAS,OAAO,MACpC,MAAM,EAAE,eAAe,MAAM,cAAc,EAAE,YAAY,OAC5D;GACA,OAAO,KAAK,MAAM,QAAQ,SAAS,EAAE,KAAK,IAAI,EAAE,QAAQ;EAC1D;EACA,MAAM,CAAC,OAAO,QAAQ,YAAY,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,QAAQ;GAC9E,iBAAiB,KAAK,QAAQ,OAAO;GACrC,kBAAkB,KAAK,QAAQ;EACjC,CAAC;EACD,KAAK,OAAO;EACZ,OAAO;CACT;CAEA,OAAe,OAAoB,MAAmC,SAA0B;EAC9F,KAAK,WAAW,aAAa,KAAK,UAAU;GAC1C;GACA,YAAY,MAAM;GAClB,QAAQ,MAAM;GACd,IAAI,MAAM;GACV;EACF,CAAC;CACH;;CAGA,KAAa,OAAoB,KAAwC;EACvE,KAAK;EACL,MAAM,UAAU,IAAI;EACpB,KAAK,OAAO,OAAO,QAAQ,EAAE,MAAM,MAAM,KAAK,CAAC;EAC/C,MAAM,QAAQ,KAAK,OAAO,OAAO,OAAO;EACxC,IAAI,OACF,KAAK,OAAO,KAAK;GACf,YAAY,MAAM;GAClB;GACA;GACA,QAAQ,MAAM;GACd,IAAI,MAAM;EACZ,CAAC;EAEH,OAAO;CACT;CAEA,MAAM,OACJ,OACA,SACA,WACY;EACZ,MAAM,MAAM,KAAK,WAAW,MAAM,UAAU;EAC5C,IAAI,IAAI,UAAU,GAAG,OAAO,KAAK;EACjC,MAAM,QAAQ,KAAK,KAAK,OAAO,GAAG;EAClC,IAAI,UAAU,kBAAkB,UAAU,WAAW;GACnD,KAAK,OAAO,OAAO,SAAS;IAAE,MAAM,MAAM;IAAM;GAAM,CAAC;GACvD,IAAI,MAAM;GACV,OAAO,KAAK;EACd;EACA,IAAI,UAAU,SAAS;GACrB,KAAK,OAAO,OAAO,SAAS;IAAE,MAAM,MAAM;IAAM;GAAM,CAAC;GACvD,MAAM,IAAI,oBAAoB,OAAO,KAAK;EAC5C;EACA,IAAI;EACJ,KAAK;EACL,IAAI;GACF,QAAQ,MAAM,QAAQ;EACxB,SAAS,KAAK;GACZ,KAAK,OAAO,OAAO,UAAU;IAAE,MAAM,MAAM;IAAM,QAAQ;IAAM,OAAO,OAAO,GAAG;GAAE,CAAC;GACnF,MAAM;EACR,UAAU;GACR,KAAK;GACL,KAAK,SAAS,MAAM,QAAA,CAAuB;EAC7C;EACA,KAAK,OAAO,OAAO,UAAU;GAAE,MAAM,MAAM;GAAM,QAAQ,UAAU,KAAK;EAAE,CAAC;EAE3E,IAAI,IAAI,UAAU,GAAG,OAAO,KAAK;EACjC,IAAI,UAAU,eAAe;GAC3B,KAAK,OAAO,OAAO,SAAS;IAAE,MAAM,MAAM;IAAM;GAAM,CAAC;GACvD,IAAI,MAAM;GACV,OAAO,KAAK;EACd;EACA,IAAI,UAAU,aAAa;GACzB,KAAK,OAAO,OAAO,SAAS;IAAE,MAAM,MAAM;IAAM;GAAM,CAAC;GACvD,MAAM,IAAI,oBAAoB,OAAO,KAAK;EAC5C;EACA,OAAO;CACT;CAEA,WAAc,OAAoB,SAAkB,WAAuC;EACzF,MAAM,MAAM,KAAK,WAAW,MAAM,UAAU;EAC5C,IAAI,IAAI,UAAU,GAAG,MAAM,IAAI,YAAY,IAAI,EAAE;EACjD,MAAM,QAAQ,KAAK,KAAK,OAAO,GAAG;EAClC,IAAI,UAAU,kBAAkB,UAAU,WAAW;GACnD,KAAK,OAAO,OAAO,SAAS;IAAE,MAAM,MAAM;IAAM;GAAM,CAAC;GACvD,IAAI,MAAM;GACV,MAAM,IAAI,YAAY,IAAI,EAAE;EAC9B;EACA,IAAI,UAAU,SAAS;GACrB,KAAK,OAAO,OAAO,SAAS;IAAE,MAAM,MAAM;IAAM;GAAM,CAAC;GACvD,MAAM,IAAI,oBAAoB,OAAO,KAAK;EAC5C;EACA,IAAI;EACJ,IAAI;GACF,QAAQ,QAAQ;EAClB,SAAS,KAAK;GACZ,KAAK,OAAO,OAAO,UAAU;IAAE,MAAM,MAAM;IAAM,QAAQ;IAAM,OAAO,OAAO,GAAG;GAAE,CAAC;GACnF,MAAM;EACR;EACA,KAAK,OAAO,OAAO,UAAU;GAAE,MAAM,MAAM;GAAM,QAAQ,UAAU,KAAK;EAAE,CAAC;EAC3E,IAAI,UAAU,eAAe;GAC3B,KAAK,OAAO,OAAO,SAAS;IAAE,MAAM,MAAM;IAAM;GAAM,CAAC;GACvD,IAAI,MAAM;GACV,MAAM,IAAI,YAAY,IAAI,EAAE;EAC9B;EACA,IAAI,UAAU,aAAa;GACzB,KAAK,OAAO,OAAO,SAAS;IAAE,MAAM,MAAM;IAAM;GAAM,CAAC;GACvD,MAAM,IAAI,oBAAoB,OAAO,KAAK;EAC5C;EACA,OAAO;CACT;CAEA,YAAY,QAAsB;EAChC,KAAK,QAAQ,KAAK,MAAM;CAC1B;CAEA,OAAU,SAAqB,YAAgC;EAC7D,MAAM,MAAM,KAAK,WAAW,UAAU;EACtC,MAAM,UAAU,KAAK;EACrB,IAAI,SAAS,QAAQ,MAAM,QAAQ;EACnC,IAAI,CAAC,SAEH,OAAO,QAAQ,KAAK,CAAC,SAAS,IAAI,QAAQ,WAAW,IAAI,cAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;EAEjF,OAAO,SAAS,SAAS;GACvB,OAAO,QAAQ;GACf,gBAAgB,KAAK;GACrB,eAAe,IAAI,UAAU;GAC7B,aAAa;IAEX,KAAK,YACH,cAAc,WAAW,+EAC3B;IACA,IAAI,MAAM;GACZ;EACF,CAAC;CACH;CAEA,SAAS,YAAoB,QAAgB,SAA0B;EACrE,KAAK,WAAW,aAAa,KAAK,UAAU;GAC1C,MAAM;GACN;GACA;GACA,IAAI;GACJ;EACF,CAAC;CACH;AACF;;;;;;;;ACpRA,SAAgB,aACd,UACA,MACA,SACc;CACd,MAAM,aAAa,SAAS,eAAe,MAAM,OAAO;CACxD,MAAM,SAAS,SAAS,cAAc,UAAU,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;CACnE,OAAO;EAAE,GAAG;EAAY,YAAY,4BAA4B,WAAW,YAAY,MAAM;CAAE;AACjG;AAEA,eAAsB,OACpB,MACA,UACA,UACA,WACA,OACA,SACuB;CACvB,MAAM,SAAS,SAAS,cAAc,IAAI,CAAC,CAAC,KAAK,MAAM,EAAE,EAAE;CAC3D,IAAI,QAAqB;EAAE;EAAU,SAAS;CAAO;CACrD,IAAI,OAAO;EAAE;EAAO;CAAU;CAC9B,IAAI,OAAO;CAEX,IAAI,WAAW;CACf,OAAO,YAAY,OAAO,QAAQ,WAAW,QAAQ,IAAI,IAAI,QAAQ,UAAU;EAC7E,WAAW;EACX,KAAK,MAAM,aAAa,iBAAiB,KAAK,GAAG;GAC/C,IAAI,QAAQ,QAAQ,WAAW,QAAQ,IAAI,KAAK,QAAQ,UAAU;GAClE,MAAM,gBAAgB,aAAa,UAAU,MAAM,UAAU,OAAO;GACpE,MAAM,MAAM,MAAM,UAAU,eAAe,UAAU,UAAU,QAAQ;GACvE,MAAM,MAAM,IAAI;GAChB;GAEA,IAAI,IAAI,mBAAmB,SAAS,GAAG;GACvC,MAAM,QAAQ,gBAAgB,KAAK,cAAc,UAAU,CAAC,CAAC,MAAM,MACjE,cAAc,GAAG,SAAS,CAC5B;GACA,IAAI,OAAO;IACT,QAAQ;IACR,OAAO;KAAE,OAAO;KAAK,WAAW;IAAM;IACtC,WAAW;IACX;GACF;EACF;CACF;CACA,OAAO;EACL,MAAM,aAAa,UAAU,MAAM,MAAM,OAAO;EAChD,UAAU,MAAM;EAChB,YAAY,MAAM;EAClB,OAAO,KAAK;EACZ,WAAW,KAAK;EAChB;EACA,eAAe,SAAS,OAAO,SAAS,MAAM,SAAS,OAAO;EAC9D,eAAe,OAAO,SAAS,MAAM,QAAQ;CAC/C;AACF;;;;;;;ACpDA,MAAM,oBAAuC;CAC3C;CACA;CACA;CACA;CACA;CACA;AACF;;AAGA,eAAsB,QACpB,MACA,UACA,KACoB;CACpB,IAAI,QAAQ;CACZ,IAAI;EACF,MAAM,SAAS,MAAM,IAAI;EACzB,MAAM,UAAsB,CAAC,GAAG,SAAS,cAAc,IAAI,CAAC;EAC5D,OAAO,QAAQ,SAAS,GAAG;GACzB,MAAM,QAAQ,QAAQ,MAAM;GAC5B,MAAM,SAAS,MAAM,SAAS,QAAQ,OAAO,KAAK,IAAI;GACtD,QAAQ,KAAK,GAAG,OAAO,SAAS;EAClC;EACA,MAAM,SAAS,SAAS,MAAM,GAAG;CACnC,UAAU;EACR,IAAI,UAAU;CAChB;CACA,OAAO,IAAI;AACb;;AAGA,eAAsB,UACpB,MACA,UACA,UACc;CACd,MAAM,MAAM,IAAI,IAAI;EAAE,MAAM;EAAU;EAAU,QAAQ,KAAK;EAAQ,kBAAkB;CAAE,CAAC;CAC1F,MAAM,QAAQ,MAAM,UAAU,GAAG;CACjC,OAAO;AACT;;AAGA,eAAsB,OACpB,MACA,UACA,UACoB;CACpB,QAAQ,MAAM,UAAU,MAAM,UAAU,QAAQ,EAAA,CAAG;AACrD;AAEA,eAAsB,QACpB,MACA,UACA,SAC0B;CAC1B,MAAM,MAAM,QAAQ,cAAc,KAAK,IAAI;CAC3C,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,mBAAmB,QAAQ,oBAAoB;CACrD,MAAM,cAAc,CAAC,GAAG,mBAAmB,GAAG,SAAS,WAAW;CAClE,MAAM,QAAQ,IAAI;CAClB,MAAM,UAAU;EAAE,MAAM;EAAG,cAAc;EAAG,gBAAgB;CAAE;CAC9D,MAAM,cAA6B;EAAE,GAAG;EAAS,WAAW,IAAI,IAAI;CAAM;CAC1E,MAAM,OAAO;EAAE,UAAU,KAAK;EAAM,MAAM,QAAQ;EAAM;CAAY;CAEpE,IAAI,KAAK,OAAO,6BAA6B,GAC3C,OAAO;EACL,GAAG;EACH,MAAM;EACN,OAAO;EACP,QAAQ;EACR,SAAS,KAAK;CAChB;CAGF,MAAM,gBAAgB,QAAQ,iBAAiB;;CAE/C,MAAM,YAAsD,CAAC;CAE7D,IAAI,SAAoB,SAAS,QAAQ,IAAI;CAC7C,OAAO,QAAQ,OAAO,WAAW,IAAI,IAAI,QAAQ,KAAK,OAAO,UAAU;EACrE,MAAM,CAAC,SAAS,QAAQ,QAAQ,MAAM;EACtC,SAAS;EACT,MAAM,MAAM,IAAI,IAAI;GAClB,MAAM;GACN,UAAU;IAAE,MAAM;IAAS,QAAQ,CAAC;GAAE;GACtC,QAAQ,KAAK;GACb;EACF,CAAC;EACD,MAAM,MAAM,MAAM,QAAQ,MAAM,UAAU,GAAG;EAC7C,QAAQ;EACR,QAAQ,gBAAgB,IAAI;EAC5B,QAAQ,kBAAkB,IAAI;EAC9B,IAAI,UAAU,SAAS,eACrB,UAAU,KAAK;GAAE,UAAU,IAAI;GAAU,QAAQ,UAAU,GAAG;EAAE,CAAC;EAEnE,IAAI,IAAI,mBAAmB,SAAS,GAClC,OAAO;GACL,GAAG;GACH,MAAM;GACN,OAAO;GACP,QAAQ,IAAI,mBAAmB,KAAK,IAAI;GACxC,SAAS,KAAK;EAChB;EAIF,MAAM,YADa,gBAAgB,KAAK,KAAK,UAClB,CAAC,CAAC;EAC7B,IAAI,WAAW;GACb,MAAM,WAAW,IAAI;GACrB,MAAM,cAAc,MAAM,UAAU,MAAM,UAAU,QAAQ;GAC5D,MAAM,WAAW,YAAY;GAC7B,QAAQ;GACR,IAAI,YAAY,mBAAmB,SAAS,KAAK,UAAU,QAAQ,MAAM,UAAU,GAAG,GACpF,OAAO;IACL,GAAG;IACH,MAAM;IACN,OAAO;IACP,QAAQ,6BAA6B,SAAS,KAAK;IACnD,SAAS,KAAK;GAChB;GAGF,MAAM,SAAS,MAAM,OAAO,MAAM,UAAU,UAAU,WAAW,UAAU;IACzE,SAAS,QAAQ,iBAAiB;IAClC,UAAU,IAAI,IAAI,KAAK,OAAO;IAC9B;GACF,CAAC;GACD,QAAQ,QAAQ,OAAO;GACvB,OAAO;IACL,GAAG;IACH,MAAM;IACN,WAAW,OAAO;IAClB,OAAO,OAAO;IACd,UAAU,OAAO;IACjB,YAAY,OAAO;IACnB,QAAQ;KACN,eAAe,OAAO;KACtB,eAAe,OAAO;KACtB,MAAM,OAAO;IACf;IACA,SAAS,KAAK;GAChB;EACF;CACF;CAEA,KAAK,MAAM,WAAW,CAAC,GAAG,SAAS,CAAC,CAAC,QAAQ,GAAG;EAC9C,MAAM,QAAQ,MAAM,UAAU,MAAM,UAAU,QAAQ,QAAQ;EAC9D,QAAQ;EACR,IAAI,MAAM,mBAAmB,SAAS,KAAK,UAAU,MAAM,GAAG,MAAM,QAAQ,QAC1E,OAAO;GACL,GAAG;GACH,MAAM;GACN,OAAO;GACP,QAAQ,YAAY,QAAQ,SAAS,KAAK;GAC1C,SAAS,KAAK;EAChB;CAEJ;CACA,OAAO;EAAE,GAAG;EAAM,MAAM;EAAW,QAAQ,KAAK;EAAQ,SAAS,KAAK;CAAE;AAC1E"}
|