@lovrozagar/oat 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +401 -0
- package/bin/oat.js +2 -0
- package/dist/cli.js +386 -0
- package/dist/config/define-config.d.ts +165 -0
- package/dist/config/define-config.d.ts.map +1 -0
- package/dist/config/define-config.js +24 -0
- package/dist/config/define-config.js.map +1 -0
- package/dist/config/load.d.ts +10 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +61 -0
- package/dist/config/load.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +9 -0
- package/dist/reference/defects.d.ts +254 -0
- package/dist/reference/defects.d.ts.map +1 -0
- package/dist/reference/defects.js +265 -0
- package/dist/reference/defects.js.map +1 -0
- package/dist/reference/dialect.d.ts +104 -0
- package/dist/reference/dialect.d.ts.map +1 -0
- package/dist/reference/dialect.js +174 -0
- package/dist/reference/dialect.js.map +1 -0
- package/dist/reference/http.d.ts +79 -0
- package/dist/reference/http.d.ts.map +1 -0
- package/dist/reference/http.js +889 -0
- package/dist/reference/http.js.map +1 -0
- package/dist/reference/model.d.ts +56 -0
- package/dist/reference/model.d.ts.map +1 -0
- package/dist/reference/model.js +156 -0
- package/dist/reference/model.js.map +1 -0
- package/dist/reference/query.d.ts +45 -0
- package/dist/reference/query.d.ts.map +1 -0
- package/dist/reference/query.js +353 -0
- package/dist/reference/query.js.map +1 -0
- package/dist/reference/spec.d.ts +13 -0
- package/dist/reference/spec.d.ts.map +1 -0
- package/dist/reference/spec.js +547 -0
- package/dist/reference/spec.js.map +1 -0
- package/dist/reference/store-api.d.ts +59 -0
- package/dist/reference/store-api.d.ts.map +1 -0
- package/dist/reference/store-api.js +76 -0
- package/dist/reference/store-api.js.map +1 -0
- package/dist/reference/stores/memory.d.ts +27 -0
- package/dist/reference/stores/memory.d.ts.map +1 -0
- package/dist/reference/stores/memory.js +97 -0
- package/dist/reference/stores/memory.js.map +1 -0
- package/dist/reference/stores/postgres.d.ts +61 -0
- package/dist/reference/stores/postgres.d.ts.map +1 -0
- package/dist/reference/stores/postgres.js +406 -0
- package/dist/reference/stores/postgres.js.map +1 -0
- package/dist/reference/stores/sqlite-driver.d.ts +54 -0
- package/dist/reference/stores/sqlite-driver.d.ts.map +1 -0
- package/dist/reference/stores/sqlite-driver.js +99 -0
- package/dist/reference/stores/sqlite-driver.js.map +1 -0
- package/dist/reference/stores/sqlite.d.ts +68 -0
- package/dist/reference/stores/sqlite.d.ts.map +1 -0
- package/dist/reference/stores/sqlite.js +464 -0
- package/dist/reference/stores/sqlite.js.map +1 -0
- package/dist/report/console.d.ts +33 -0
- package/dist/report/console.d.ts.map +1 -0
- package/dist/report/console.js +237 -0
- package/dist/report/console.js.map +1 -0
- package/dist/report/matrix.d.ts +131 -0
- package/dist/report/matrix.d.ts.map +1 -0
- package/dist/report/matrix.js +865 -0
- package/dist/report/matrix.js.map +1 -0
- package/dist/report/render.d.ts +66 -0
- package/dist/report/render.d.ts.map +1 -0
- package/dist/report/render.js +423 -0
- package/dist/report/render.js.map +1 -0
- package/dist/runtime/async.d.ts +34 -0
- package/dist/runtime/async.d.ts.map +1 -0
- package/dist/runtime/async.js +130 -0
- package/dist/runtime/async.js.map +1 -0
- package/dist/runtime/auth.d.ts +46 -0
- package/dist/runtime/auth.d.ts.map +1 -0
- package/dist/runtime/auth.js +236 -0
- package/dist/runtime/auth.js.map +1 -0
- package/dist/runtime/checks.d.ts +89 -0
- package/dist/runtime/checks.d.ts.map +1 -0
- package/dist/runtime/checks.js +3400 -0
- package/dist/runtime/checks.js.map +1 -0
- package/dist/runtime/client.d.ts +65 -0
- package/dist/runtime/client.d.ts.map +1 -0
- package/dist/runtime/client.js +122 -0
- package/dist/runtime/client.js.map +1 -0
- package/dist/runtime/finding.d.ts +50 -0
- package/dist/runtime/finding.d.ts.map +1 -0
- package/dist/runtime/finding.js +50 -0
- package/dist/runtime/finding.js.map +1 -0
- package/dist/runtime/fixture.d.ts +20 -0
- package/dist/runtime/fixture.d.ts.map +1 -0
- package/dist/runtime/fixture.js +175 -0
- package/dist/runtime/fixture.js.map +1 -0
- package/dist/runtime/progress.d.ts +41 -0
- package/dist/runtime/progress.d.ts.map +1 -0
- package/dist/runtime/progress.js +186 -0
- package/dist/runtime/progress.js.map +1 -0
- package/dist/runtime/run.d.ts +69 -0
- package/dist/runtime/run.d.ts.map +1 -0
- package/dist/runtime/run.js +575 -0
- package/dist/runtime/run.js.map +1 -0
- package/dist/runtime/teardown.d.ts +38 -0
- package/dist/runtime/teardown.d.ts.map +1 -0
- package/dist/runtime/teardown.js +129 -0
- package/dist/runtime/teardown.js.map +1 -0
- package/dist/runtime/validate.d.ts +31 -0
- package/dist/runtime/validate.d.ts.map +1 -0
- package/dist/runtime/validate.js +111 -0
- package/dist/runtime/validate.js.map +1 -0
- package/dist/runtime/world.d.ts +49 -0
- package/dist/runtime/world.d.ts.map +1 -0
- package/dist/runtime/world.js +119 -0
- package/dist/runtime/world.js.map +1 -0
- package/dist/spec/collection.d.ts +31 -0
- package/dist/spec/collection.d.ts.map +1 -0
- package/dist/spec/collection.js +121 -0
- package/dist/spec/collection.js.map +1 -0
- package/dist/spec/conventions.d.ts +103 -0
- package/dist/spec/conventions.d.ts.map +1 -0
- package/dist/spec/conventions.js +275 -0
- package/dist/spec/conventions.js.map +1 -0
- package/dist/spec/extensions.d.ts +74 -0
- package/dist/spec/extensions.d.ts.map +1 -0
- package/dist/spec/extensions.js +335 -0
- package/dist/spec/extensions.js.map +1 -0
- package/dist/spec/graph.d.ts +89 -0
- package/dist/spec/graph.d.ts.map +1 -0
- package/dist/spec/graph.js +318 -0
- package/dist/spec/graph.js.map +1 -0
- package/dist/spec/load.d.ts +36 -0
- package/dist/spec/load.d.ts.map +1 -0
- package/dist/spec/load.js +166 -0
- package/dist/spec/load.js.map +1 -0
- package/dist/spec/types.d.ts +57 -0
- package/dist/spec/types.d.ts.map +1 -0
- package/dist/spec/types.js +24 -0
- package/dist/spec/types.js.map +1 -0
- package/labs/README.md +130 -0
- package/labs/annotated-openapi.yaml +311 -0
- package/labs/anyrow.config.ts +107 -0
- package/labs/demo.mjs +124 -0
- package/labs/local.config.ts +41 -0
- package/labs/minimal.config.ts +32 -0
- package/package.json +80 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Findings carry their verdict, not a severity guess made at report time. The verdict is derived
|
|
3
|
+
* from what the evidence shows, which is what lets the report collapse cascades and lets the
|
|
4
|
+
* conformance suite assert "exactly this defect was detected".
|
|
5
|
+
*/
|
|
6
|
+
export class FindingCollector {
|
|
7
|
+
findings = [];
|
|
8
|
+
inconclusive = [];
|
|
9
|
+
/**
|
|
10
|
+
* Records that a check ran without reaching a verdict. Returns `undefined` so a check can
|
|
11
|
+
* `return ctx.findings.unresolved(...)` at the point it gives up, which keeps the reason
|
|
12
|
+
* beside the condition that caused it rather than in a comment.
|
|
13
|
+
*/
|
|
14
|
+
unresolved(check, entity, reason) {
|
|
15
|
+
this.inconclusive.push({ check, entity, reason });
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
report(finding) {
|
|
19
|
+
this.findings.push(finding);
|
|
20
|
+
}
|
|
21
|
+
backend(check, entity, summary, detail, evidence) {
|
|
22
|
+
this.report({ check, detail, entity, evidence, summary, verdict: "BACKEND_BUG" });
|
|
23
|
+
}
|
|
24
|
+
security(check, entity, summary, detail, evidence) {
|
|
25
|
+
this.report({ check, detail, entity, evidence, summary, verdict: "SECURITY" });
|
|
26
|
+
}
|
|
27
|
+
spec(check, entity, summary, detail, evidence) {
|
|
28
|
+
this.report({ check, detail, entity, evidence, summary, verdict: "SPEC_BUG" });
|
|
29
|
+
}
|
|
30
|
+
gap(check, entity, summary, detail) {
|
|
31
|
+
this.report({ check, detail, entity, evidence: [], summary, verdict: "COVERAGE_GAP" });
|
|
32
|
+
}
|
|
33
|
+
blocked(check, entity, summary, cause) {
|
|
34
|
+
this.report({
|
|
35
|
+
check,
|
|
36
|
+
detail: `blocked by ${cause}`,
|
|
37
|
+
entity,
|
|
38
|
+
evidence: [],
|
|
39
|
+
summary,
|
|
40
|
+
verdict: "BLOCKED",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
checks() {
|
|
44
|
+
return [...new Set(this.findings.map((f) => f.check))].sort();
|
|
45
|
+
}
|
|
46
|
+
byVerdict(verdict) {
|
|
47
|
+
return this.findings.filter((f) => f.verdict === verdict);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=finding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding.js","sourceRoot":"","sources":["../../src/runtime/finding.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsCH,MAAM,OAAO,gBAAgB;IACnB,QAAQ,GAAc,EAAE,CAAA;IACxB,YAAY,GAAmB,EAAE,CAAA;IAE1C;;;;OAIG;IACH,UAAU,CAAC,KAAa,EAAE,MAAc,EAAE,MAAc;QACvD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;QACjD,OAAO,SAAS,CAAA;IACjB,CAAC;IAED,MAAM,CAAC,OAAgB;QACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IAED,OAAO,CACN,KAAa,EACb,MAAc,EACd,OAAe,EACf,MAAc,EACd,QAAoB;QAEpB,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAA;IAClF,CAAC;IAED,QAAQ,CACP,KAAa,EACb,MAAc,EACd,OAAe,EACf,MAAc,EACd,QAAoB;QAEpB,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAA;IAC/E,CAAC;IAED,IAAI,CAAC,KAAa,EAAE,MAAc,EAAE,OAAe,EAAE,MAAc,EAAE,QAAoB;QACxF,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAA;IAC/E,CAAC;IAED,GAAG,CAAC,KAAa,EAAE,MAAc,EAAE,OAAe,EAAE,MAAc;QACjE,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAA;IACvF,CAAC;IAED,OAAO,CAAC,KAAa,EAAE,MAAc,EAAE,OAAe,EAAE,KAAa;QACpE,IAAI,CAAC,MAAM,CAAC;YACX,KAAK;YACL,MAAM,EAAE,cAAc,KAAK,EAAE;YAC7B,MAAM;YACN,QAAQ,EAAE,EAAE;YACZ,OAAO;YACP,OAAO,EAAE,SAAS;SAClB,CAAC,CAAA;IACH,CAAC;IAED,MAAM;QACL,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC9D,CAAC;IAED,SAAS,CAAC,OAAgB;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAA;IAC1D,CAAC;CACD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema-driven fixture generation.
|
|
3
|
+
*
|
|
4
|
+
* Valid-random data cannot test a query engine: `ilike` needs a substring, `order` needs a total
|
|
5
|
+
* order, escaping needs metacharacters. oat seeds a *discriminating cohort* — instances shaped so
|
|
6
|
+
* that every query assertion has signal — and derives everything from a seed so a failing run is
|
|
7
|
+
* exactly reproducible.
|
|
8
|
+
*/
|
|
9
|
+
export type Variant = "baseline" | "lexical-first" | "lexical-last" | "null-heavy" | "unicode" | "metacharacter" | "boundary";
|
|
10
|
+
export declare const COHORT: readonly Variant[];
|
|
11
|
+
/** Deterministic PRNG — same seed, same cohort, every run. */
|
|
12
|
+
export declare function mulberry32(seed: number): () => number;
|
|
13
|
+
type Schema = Record<string, unknown>;
|
|
14
|
+
export interface CohortMember {
|
|
15
|
+
variant: Variant;
|
|
16
|
+
body: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
export declare function buildCohort(bodySchema: Schema, seed: number, variants?: readonly Variant[]): CohortMember[];
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=fixture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture.d.ts","sourceRoot":"","sources":["../../src/runtime/fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,OAAO,GAChB,UAAU,GACV,eAAe,GACf,cAAc,GACd,YAAY,GACZ,SAAS,GACT,eAAe,GACf,UAAU,CAAA;AAEb,eAAO,MAAM,MAAM,EAAE,SAAS,OAAO,EAQpC,CAAA;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,MAAM,CAQrD;AAED,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAYrC,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC7B;AAED,wBAAgB,WAAW,CAC1B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,SAAS,OAAO,EAAW,GACnC,YAAY,EAAE,CAKhB"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema-driven fixture generation.
|
|
3
|
+
*
|
|
4
|
+
* Valid-random data cannot test a query engine: `ilike` needs a substring, `order` needs a total
|
|
5
|
+
* order, escaping needs metacharacters. oat seeds a *discriminating cohort* — instances shaped so
|
|
6
|
+
* that every query assertion has signal — and derives everything from a seed so a failing run is
|
|
7
|
+
* exactly reproducible.
|
|
8
|
+
*/
|
|
9
|
+
export const COHORT = [
|
|
10
|
+
"baseline",
|
|
11
|
+
"lexical-first",
|
|
12
|
+
"lexical-last",
|
|
13
|
+
"null-heavy",
|
|
14
|
+
"unicode",
|
|
15
|
+
"metacharacter",
|
|
16
|
+
"boundary",
|
|
17
|
+
];
|
|
18
|
+
/** Deterministic PRNG — same seed, same cohort, every run. */
|
|
19
|
+
export function mulberry32(seed) {
|
|
20
|
+
let a = seed >>> 0;
|
|
21
|
+
return () => {
|
|
22
|
+
a = (a + 0x6d2b79f5) >>> 0;
|
|
23
|
+
let t = Math.imul(a ^ (a >>> 15), 1 | a);
|
|
24
|
+
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
25
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const STRINGS = {
|
|
29
|
+
baseline: "Quarterly Report",
|
|
30
|
+
boundary: "",
|
|
31
|
+
"lexical-first": "aaa first alphabetically",
|
|
32
|
+
"lexical-last": "zzz last alphabetically",
|
|
33
|
+
metacharacter: "100% _off_ *everything*",
|
|
34
|
+
"null-heavy": "null heavy record",
|
|
35
|
+
unicode: "日本語 café ñandú",
|
|
36
|
+
};
|
|
37
|
+
export function buildCohort(bodySchema, seed, variants = COHORT) {
|
|
38
|
+
return variants.map((variant, index) => ({
|
|
39
|
+
body: generateObject(bodySchema, variant, mulberry32(seed + index * 7919), index),
|
|
40
|
+
variant,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
function generateObject(schema, variant, rand, index, depth = 0) {
|
|
44
|
+
if (depth > 4)
|
|
45
|
+
return {};
|
|
46
|
+
const properties = schema.properties;
|
|
47
|
+
if (properties === null || typeof properties !== "object")
|
|
48
|
+
return {};
|
|
49
|
+
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
50
|
+
const out = {};
|
|
51
|
+
for (const [name, raw] of Object.entries(properties)) {
|
|
52
|
+
if (raw === null || typeof raw !== "object")
|
|
53
|
+
continue;
|
|
54
|
+
if (raw.readOnly === true)
|
|
55
|
+
continue;
|
|
56
|
+
const value = generateValue(name, raw, variant, rand, index, depth);
|
|
57
|
+
if (value === undefined) {
|
|
58
|
+
if (required.includes(name))
|
|
59
|
+
out[name] = fallbackFor(raw);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
out[name] = value;
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
function generateValue(name, schema, variant, rand, index, depth = 0) {
|
|
67
|
+
/* Recursive schemas are shared objects after dereferencing, so generation must be bounded. */
|
|
68
|
+
if (depth > 4)
|
|
69
|
+
return undefined;
|
|
70
|
+
const nullable = isNullable(schema);
|
|
71
|
+
if (variant === "null-heavy" && nullable)
|
|
72
|
+
return null;
|
|
73
|
+
const concrete = concreteBranch(schema);
|
|
74
|
+
const type = typeOf(concrete);
|
|
75
|
+
if (Array.isArray(concrete.enum) && concrete.enum.length > 0) {
|
|
76
|
+
/* Walk the enum across the cohort so every value is represented and filters on it
|
|
77
|
+
* partition the set non-trivially. */
|
|
78
|
+
return concrete.enum[index % concrete.enum.length];
|
|
79
|
+
}
|
|
80
|
+
switch (type) {
|
|
81
|
+
case "string": {
|
|
82
|
+
const max = typeof concrete.maxLength === "number" ? concrete.maxLength : 64;
|
|
83
|
+
if (variant === "boundary")
|
|
84
|
+
return "B".repeat(Math.max(1, Math.min(max, 512)));
|
|
85
|
+
const base = STRINGS[variant];
|
|
86
|
+
/* Suffix keeps values distinct so equality filters select exactly one instance. */
|
|
87
|
+
const text = `${base} ${index}`;
|
|
88
|
+
return text.length > max ? text.slice(0, max) : text;
|
|
89
|
+
}
|
|
90
|
+
case "integer":
|
|
91
|
+
case "number": {
|
|
92
|
+
if (variant === "boundary" && typeof concrete.maximum === "number")
|
|
93
|
+
return concrete.maximum;
|
|
94
|
+
const min = typeof concrete.minimum === "number" ? concrete.minimum : 0;
|
|
95
|
+
/*
|
|
96
|
+
* A ladder whose lexical order differs from its numeric order: as text these sort
|
|
97
|
+
* 1, 10, 100, 2, 20, 5, 50 — nothing like their numeric order.
|
|
98
|
+
*
|
|
99
|
+
* An evenly spaced sequence (10, 20, 30…) sorts identically either way, so a backend
|
|
100
|
+
* comparing numbers as strings would look correct. Values have to disagree for the
|
|
101
|
+
* assertion to carry any signal.
|
|
102
|
+
*/
|
|
103
|
+
const ladder = [1, 2, 5, 10, 20, 50, 100];
|
|
104
|
+
const step = ladder[index % ladder.length] ?? 1;
|
|
105
|
+
return type === "integer" ? min + step : min + step + Math.round(rand() * 9) / 10;
|
|
106
|
+
}
|
|
107
|
+
case "boolean":
|
|
108
|
+
return index % 2 === 0;
|
|
109
|
+
case "array": {
|
|
110
|
+
/* An empty array is not a safe default: `minItems` is common on required collections
|
|
111
|
+
* (column definitions, line items), and sending [] fails validation on exactly the
|
|
112
|
+
* endpoints most worth testing. */
|
|
113
|
+
const min = typeof concrete.minItems === "number" ? concrete.minItems : 0;
|
|
114
|
+
const count = Math.max(min, 1);
|
|
115
|
+
const items = concrete.items;
|
|
116
|
+
if (items === null || typeof items !== "object")
|
|
117
|
+
return [];
|
|
118
|
+
return Array.from({ length: count }, (_, position) => generateValue(`${name}_item`, items, variant, rand, index + position, depth + 1));
|
|
119
|
+
}
|
|
120
|
+
case "object":
|
|
121
|
+
return generateObject(concrete, variant, rand, index, depth + 1);
|
|
122
|
+
default:
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function fallbackFor(schema) {
|
|
127
|
+
switch (typeOf(concreteBranch(schema))) {
|
|
128
|
+
case "integer":
|
|
129
|
+
case "number":
|
|
130
|
+
return 0;
|
|
131
|
+
case "boolean":
|
|
132
|
+
return false;
|
|
133
|
+
case "array":
|
|
134
|
+
return [];
|
|
135
|
+
case "object":
|
|
136
|
+
return {};
|
|
137
|
+
default:
|
|
138
|
+
return "value";
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** `oneOf: [{type: string}, {type: null}]` is the nullable idiom; pick the non-null branch. */
|
|
142
|
+
function concreteBranch(schema) {
|
|
143
|
+
const union = schema.oneOf ?? schema.anyOf;
|
|
144
|
+
if (!Array.isArray(union))
|
|
145
|
+
return schema;
|
|
146
|
+
const branch = union.find((candidate) => candidate !== null && typeof candidate === "object" && candidate.type !== "null");
|
|
147
|
+
return branch ?? schema;
|
|
148
|
+
}
|
|
149
|
+
function isNullable(schema) {
|
|
150
|
+
if (schema.nullable === true)
|
|
151
|
+
return true;
|
|
152
|
+
const type = schema.type;
|
|
153
|
+
if (Array.isArray(type))
|
|
154
|
+
return type.includes("null");
|
|
155
|
+
const union = schema.oneOf ?? schema.anyOf;
|
|
156
|
+
if (!Array.isArray(union))
|
|
157
|
+
return false;
|
|
158
|
+
return union.some((candidate) => candidate !== null && typeof candidate === "object" && candidate.type === "null");
|
|
159
|
+
}
|
|
160
|
+
function typeOf(schema) {
|
|
161
|
+
const type = schema.type;
|
|
162
|
+
if (typeof type === "string")
|
|
163
|
+
return type;
|
|
164
|
+
if (Array.isArray(type)) {
|
|
165
|
+
const concrete = type.find((t) => t !== "null");
|
|
166
|
+
if (typeof concrete === "string")
|
|
167
|
+
return concrete;
|
|
168
|
+
}
|
|
169
|
+
if (schema.properties !== undefined)
|
|
170
|
+
return "object";
|
|
171
|
+
if (schema.items !== undefined)
|
|
172
|
+
return "array";
|
|
173
|
+
return "string";
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=fixture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture.js","sourceRoot":"","sources":["../../src/runtime/fixture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live run status.
|
|
3
|
+
*
|
|
4
|
+
* Logs are logfmt (key=value, one event per line) — the usual shape for
|
|
5
|
+
* machines and people. Values are never truncated: a fixed-width table
|
|
6
|
+
* forced "…" on check names and URLs, and wrapped the header in a normal
|
|
7
|
+
* editor so the columns stopped lining up.
|
|
8
|
+
*
|
|
9
|
+
* stderr and progress.log are the same format. progress.jsonl is the same
|
|
10
|
+
* events as JSON. progress.tsv is the same columns, tab-separated.
|
|
11
|
+
*/
|
|
12
|
+
export interface ProgressLast {
|
|
13
|
+
method: string;
|
|
14
|
+
url: string;
|
|
15
|
+
status: number;
|
|
16
|
+
durationMs: number;
|
|
17
|
+
at: number;
|
|
18
|
+
}
|
|
19
|
+
export interface ProgressSnapshot {
|
|
20
|
+
phase: "load" | "auth" | "seed" | "test" | "teardown" | "done";
|
|
21
|
+
entity?: string;
|
|
22
|
+
entityIndex?: number;
|
|
23
|
+
entityTotal?: number;
|
|
24
|
+
check?: string;
|
|
25
|
+
requests: number;
|
|
26
|
+
findings: number;
|
|
27
|
+
last?: ProgressLast;
|
|
28
|
+
message?: string;
|
|
29
|
+
elapsedMs: number;
|
|
30
|
+
}
|
|
31
|
+
export type ProgressHandler = (snap: ProgressSnapshot) => void;
|
|
32
|
+
export declare const PROGRESS_TSV_HEADER: string;
|
|
33
|
+
export declare const PROGRESS_GLOSSARY: string;
|
|
34
|
+
export declare function formatProgressLine(snap: ProgressSnapshot, now?: number): string;
|
|
35
|
+
export declare function formatProgressTsv(snap: ProgressSnapshot, now?: number): string;
|
|
36
|
+
export declare function formatProgressJsonl(snap: ProgressSnapshot, now?: number): string;
|
|
37
|
+
export declare function createStderrProgress(startedAt?: number): {
|
|
38
|
+
emit: ProgressHandler;
|
|
39
|
+
stop: () => void;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/runtime/progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,EAAE,EAAE,MAAM,CAAA;CACV;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAA;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAA;AAK9D,eAAO,MAAM,mBAAmB,QAiBpB,CAAA;AAEZ,eAAO,MAAM,iBAAiB,QAWlB,CAAA;AAEZ,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,SAAa,GAAG,MAAM,CAoBnF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,SAAa,GAAG,MAAM,CAoBlF;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,SAAa,GAAG,MAAM,CAqBpF;AAED,wBAAgB,oBAAoB,CAAC,SAAS,SAAa,GAAG;IAC7D,IAAI,EAAE,eAAe,CAAA;IACrB,IAAI,EAAE,MAAM,IAAI,CAAA;CAChB,CAwCA"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live run status.
|
|
3
|
+
*
|
|
4
|
+
* Logs are logfmt (key=value, one event per line) — the usual shape for
|
|
5
|
+
* machines and people. Values are never truncated: a fixed-width table
|
|
6
|
+
* forced "…" on check names and URLs, and wrapped the header in a normal
|
|
7
|
+
* editor so the columns stopped lining up.
|
|
8
|
+
*
|
|
9
|
+
* stderr and progress.log are the same format. progress.jsonl is the same
|
|
10
|
+
* events as JSON. progress.tsv is the same columns, tab-separated.
|
|
11
|
+
*/
|
|
12
|
+
const HEARTBEAT_MS = 5_000;
|
|
13
|
+
const STALL_MS = 15_000;
|
|
14
|
+
export const PROGRESS_TSV_HEADER = [
|
|
15
|
+
"ts_ms",
|
|
16
|
+
"status",
|
|
17
|
+
"done",
|
|
18
|
+
"total",
|
|
19
|
+
"phase",
|
|
20
|
+
"entity",
|
|
21
|
+
"check",
|
|
22
|
+
"msg",
|
|
23
|
+
"req",
|
|
24
|
+
"find",
|
|
25
|
+
"method",
|
|
26
|
+
"path",
|
|
27
|
+
"http",
|
|
28
|
+
"last_ms",
|
|
29
|
+
"idle_ms",
|
|
30
|
+
"elapsed_ms",
|
|
31
|
+
].join("\t");
|
|
32
|
+
export const PROGRESS_GLOSSARY = [
|
|
33
|
+
"# logfmt — one event per line, full values, no truncation",
|
|
34
|
+
"# ts when this line was written (ISO-8601 UTC). ts_ms is the same instant as unix ms",
|
|
35
|
+
"# status=ok|stall stall means idle_ms >= 15000 (last call finished, nothing since)",
|
|
36
|
+
"# done/total entity index / how many entities",
|
|
37
|
+
"# phase load|auth|seed|test|teardown|done",
|
|
38
|
+
"# check check id (empty when not in a check)",
|
|
39
|
+
"# msg phase note (seeding, spec URL, teardown count)",
|
|
40
|
+
"# last_ms duration of the last HTTP call",
|
|
41
|
+
"# idle_ms ms since that call returned — if this climbs, the run is stuck",
|
|
42
|
+
"# elapsed_ms wall clock since oat started",
|
|
43
|
+
].join("\n");
|
|
44
|
+
export function formatProgressLine(snap, now = Date.now()) {
|
|
45
|
+
const f = fields(snap, now);
|
|
46
|
+
return logfmt({
|
|
47
|
+
ts: new Date(now).toISOString(),
|
|
48
|
+
status: f.status,
|
|
49
|
+
done: f.done,
|
|
50
|
+
total: f.total,
|
|
51
|
+
phase: f.phase,
|
|
52
|
+
entity: f.entity,
|
|
53
|
+
check: f.check,
|
|
54
|
+
msg: f.msg,
|
|
55
|
+
req: f.req,
|
|
56
|
+
find: f.find,
|
|
57
|
+
method: f.method,
|
|
58
|
+
path: f.path,
|
|
59
|
+
http: f.http,
|
|
60
|
+
last_ms: f.last_ms,
|
|
61
|
+
idle_ms: f.idle_ms,
|
|
62
|
+
elapsed_ms: f.elapsed_ms,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
export function formatProgressTsv(snap, now = Date.now()) {
|
|
66
|
+
const f = fields(snap, now);
|
|
67
|
+
return [
|
|
68
|
+
now,
|
|
69
|
+
f.status,
|
|
70
|
+
f.done,
|
|
71
|
+
f.total,
|
|
72
|
+
f.phase,
|
|
73
|
+
f.entity,
|
|
74
|
+
f.check,
|
|
75
|
+
f.msg,
|
|
76
|
+
f.req,
|
|
77
|
+
f.find,
|
|
78
|
+
f.method,
|
|
79
|
+
f.path,
|
|
80
|
+
f.http,
|
|
81
|
+
f.last_ms,
|
|
82
|
+
f.idle_ms,
|
|
83
|
+
f.elapsed_ms,
|
|
84
|
+
].join("\t");
|
|
85
|
+
}
|
|
86
|
+
export function formatProgressJsonl(snap, now = Date.now()) {
|
|
87
|
+
const f = fields(snap, now);
|
|
88
|
+
return JSON.stringify({
|
|
89
|
+
check: f.check === "-" ? null : f.check,
|
|
90
|
+
done: snap.entityIndex ?? null,
|
|
91
|
+
elapsed_ms: Number(f.elapsed_ms),
|
|
92
|
+
entity: snap.entity ?? null,
|
|
93
|
+
find: snap.findings,
|
|
94
|
+
http: snap.last?.status ?? null,
|
|
95
|
+
idle_ms: f.idle_ms === "-" ? null : Number(f.idle_ms),
|
|
96
|
+
last_ms: f.last_ms === "-" ? null : Number(f.last_ms),
|
|
97
|
+
method: f.method === "-" ? null : f.method,
|
|
98
|
+
msg: f.msg === "-" ? null : f.msg,
|
|
99
|
+
path: f.path === "-" ? null : f.path,
|
|
100
|
+
phase: snap.phase,
|
|
101
|
+
req: snap.requests,
|
|
102
|
+
status: f.status,
|
|
103
|
+
total: snap.entityTotal ?? null,
|
|
104
|
+
ts: new Date(now).toISOString(),
|
|
105
|
+
ts_ms: now,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
export function createStderrProgress(startedAt = Date.now()) {
|
|
109
|
+
let latest;
|
|
110
|
+
let lastKey = "";
|
|
111
|
+
let lastWrite = 0;
|
|
112
|
+
let headed = false;
|
|
113
|
+
const write = (snap) => {
|
|
114
|
+
if (!headed) {
|
|
115
|
+
headed = true;
|
|
116
|
+
process.stderr.write(`${PROGRESS_GLOSSARY}\n`);
|
|
117
|
+
}
|
|
118
|
+
process.stderr.write(`${formatProgressLine(snap)}\n`);
|
|
119
|
+
lastWrite = Date.now();
|
|
120
|
+
};
|
|
121
|
+
const timer = setInterval(() => {
|
|
122
|
+
if (latest === undefined)
|
|
123
|
+
return;
|
|
124
|
+
write({ ...latest, elapsedMs: Date.now() - startedAt });
|
|
125
|
+
}, HEARTBEAT_MS);
|
|
126
|
+
timer.unref();
|
|
127
|
+
return {
|
|
128
|
+
emit(snap) {
|
|
129
|
+
latest = snap;
|
|
130
|
+
const key = `${snap.phase}|${snap.entity ?? ""}|${snap.check ?? ""}|${snap.message ?? ""}`;
|
|
131
|
+
const keyChanged = key !== lastKey;
|
|
132
|
+
lastKey = key;
|
|
133
|
+
const stalled = snap.last !== undefined && Date.now() - snap.last.at >= STALL_MS;
|
|
134
|
+
const force = snap.phase === "done"
|
|
135
|
+
|| snap.phase === "load"
|
|
136
|
+
|| snap.phase === "auth"
|
|
137
|
+
|| (snap.phase === "seed" && snap.check === undefined);
|
|
138
|
+
const due = Date.now() - lastWrite >= 2_000;
|
|
139
|
+
if (force || keyChanged || stalled || due)
|
|
140
|
+
write(snap);
|
|
141
|
+
},
|
|
142
|
+
stop() {
|
|
143
|
+
clearInterval(timer);
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function fields(snap, now) {
|
|
148
|
+
const stalled = snap.last !== undefined && now - snap.last.at >= STALL_MS;
|
|
149
|
+
return {
|
|
150
|
+
check: snap.check ?? "-",
|
|
151
|
+
done: snap.entityIndex === undefined ? "-" : String(snap.entityIndex),
|
|
152
|
+
elapsed_ms: String(Math.max(0, Math.round(snap.elapsedMs))),
|
|
153
|
+
entity: snap.entity ?? "-",
|
|
154
|
+
find: String(snap.findings),
|
|
155
|
+
http: snap.last === undefined ? "-" : String(snap.last.status),
|
|
156
|
+
idle_ms: snap.last === undefined ? "-" : String(Math.max(0, now - snap.last.at)),
|
|
157
|
+
last_ms: snap.last === undefined ? "-" : String(snap.last.durationMs),
|
|
158
|
+
method: snap.last === undefined ? "-" : snap.last.method,
|
|
159
|
+
msg: snap.message ?? "-",
|
|
160
|
+
path: snap.last === undefined ? "-" : requestPath(snap.last.url),
|
|
161
|
+
phase: snap.phase,
|
|
162
|
+
req: String(snap.requests),
|
|
163
|
+
status: stalled ? "stall" : "ok",
|
|
164
|
+
total: snap.entityTotal === undefined ? "-" : String(snap.entityTotal),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function logfmt(pairs) {
|
|
168
|
+
return Object.entries(pairs)
|
|
169
|
+
.map(([key, value]) => {
|
|
170
|
+
if (value !== "" && !/[\s="\\]/.test(value))
|
|
171
|
+
return `${key}=${value}`;
|
|
172
|
+
return `${key}=${JSON.stringify(value)}`;
|
|
173
|
+
})
|
|
174
|
+
.join(" ");
|
|
175
|
+
}
|
|
176
|
+
/** Path + query, never truncated. Origin is already in the report backend field. */
|
|
177
|
+
function requestPath(url) {
|
|
178
|
+
try {
|
|
179
|
+
const parsed = new URL(url);
|
|
180
|
+
return `${parsed.pathname}${parsed.search}`;
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return url;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/runtime/progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run orchestrator: model → world → checks → findings.
|
|
3
|
+
*
|
|
4
|
+
* The world is seeded once and outlives every check. A seeding failure is recorded once and
|
|
5
|
+
* everything downstream is reported BLOCKED against that single cause, rather than re-failing
|
|
6
|
+
* per case — which is what made prior attempts produce dozens of failures from one broken fixture.
|
|
7
|
+
*/
|
|
8
|
+
import { type SpecModel } from "../spec/graph.ts";
|
|
9
|
+
import type { Hooks, Principal } from "../config/define-config.ts";
|
|
10
|
+
import { Client } from "./client.ts";
|
|
11
|
+
import type { ProgressHandler } from "./progress.ts";
|
|
12
|
+
import { type Finding, type Inconclusive } from "./finding.ts";
|
|
13
|
+
import { type TeardownReport } from "./teardown.ts";
|
|
14
|
+
export type PrincipalSpec = Principal;
|
|
15
|
+
export interface RunOptions {
|
|
16
|
+
spec: string;
|
|
17
|
+
baseUrl: string;
|
|
18
|
+
principals: PrincipalSpec[];
|
|
19
|
+
hooks?: Hooks;
|
|
20
|
+
roots?: Record<string, string>;
|
|
21
|
+
seed?: number;
|
|
22
|
+
cohortSize?: number;
|
|
23
|
+
globalHeaders?: Record<string, string>;
|
|
24
|
+
only?: string[];
|
|
25
|
+
/** Leaves created records in place. Useful when inspecting a failure by hand. */
|
|
26
|
+
keepFixtures?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Entities tested in parallel. Checks within one entity stay sequential — cascade suppression
|
|
29
|
+
* reads findings already reported for that entity, and ordering is what keeps one root cause
|
|
30
|
+
* from being reported as several.
|
|
31
|
+
*/
|
|
32
|
+
concurrency?: number;
|
|
33
|
+
/** Requests allowed in flight at once, across the whole run. */
|
|
34
|
+
maxInFlight?: number;
|
|
35
|
+
/** Live status. Called on phase/entity/check/request; the CLI prints a heartbeat from this. */
|
|
36
|
+
onProgress?: ProgressHandler;
|
|
37
|
+
}
|
|
38
|
+
export interface RunResult {
|
|
39
|
+
findings: Finding[];
|
|
40
|
+
model: SpecModel;
|
|
41
|
+
client: Client;
|
|
42
|
+
entitiesTested: string[];
|
|
43
|
+
checksRun: string[];
|
|
44
|
+
/** Checks that never ran, and what each needed. A quiet run is only meaningful alongside it. */
|
|
45
|
+
checksSkipped: Array<{
|
|
46
|
+
check: string;
|
|
47
|
+
entity: string;
|
|
48
|
+
needs: string;
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Checks that did not run because something they depend on was already reported broken.
|
|
52
|
+
*
|
|
53
|
+
* Recorded rather than dropped for the same reason skips are: suppression is correct — one
|
|
54
|
+
* root cause should produce one finding — but a suppressed check has *not* passed, and a
|
|
55
|
+
* report that shows only the root cause invites the reader to believe everything downstream
|
|
56
|
+
* was verified. It was not, and it must be re-run once the cause is fixed.
|
|
57
|
+
*/
|
|
58
|
+
checksSuppressed: Array<{
|
|
59
|
+
check: string;
|
|
60
|
+
entity: string;
|
|
61
|
+
because: string;
|
|
62
|
+
}>;
|
|
63
|
+
/** Checks that ran but could not reach a verdict — see `Inconclusive`. */
|
|
64
|
+
inconclusive: Inconclusive[];
|
|
65
|
+
created: number;
|
|
66
|
+
teardown: TeardownReport | null;
|
|
67
|
+
}
|
|
68
|
+
export declare function run(options: RunOptions): Promise<RunResult>;
|
|
69
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/runtime/run.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEpG,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAGlE,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAkC,MAAM,eAAe,CAAA;AACpF,OAAO,EAAE,KAAK,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAChF,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAK3D,MAAM,MAAM,aAAa,GAAG,SAAS,CAAA;AAErC,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,iFAAiF;IACjF,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED,MAAM,WAAW,SAAS;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,gGAAgG;IAChG,aAAa,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACtE;;;;;;;OAOG;IACH,gBAAgB,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3E,0EAA0E;IAC1E,YAAY,EAAE,YAAY,EAAE,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAA;CAC/B;AAkKD,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CA4ejE"}
|