@farmslot/recipe-cli 0.13.0 → 0.14.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/CHANGELOG.md +12 -0
- package/dist/harness/acceptance-ledger.d.ts +8 -13
- package/dist/harness/acceptance-ledger.d.ts.map +1 -1
- package/dist/harness/acceptance-ledger.js +39 -112
- package/dist/harness/acceptance-ledger.js.map +1 -1
- package/dist/harness/catalog.d.ts +3 -34
- package/dist/harness/catalog.d.ts.map +1 -1
- package/dist/harness/catalog.js +53 -0
- package/dist/harness/catalog.js.map +1 -1
- package/dist/harness/command-journal.d.ts +7 -1
- package/dist/harness/command-journal.d.ts.map +1 -1
- package/dist/harness/command-journal.js +27 -5
- package/dist/harness/command-journal.js.map +1 -1
- package/dist/harness/commands/call.d.ts.map +1 -1
- package/dist/harness/commands/call.js +5 -3
- package/dist/harness/commands/call.js.map +1 -1
- package/dist/harness/commands/doctor.d.ts +11 -5
- package/dist/harness/commands/doctor.d.ts.map +1 -1
- package/dist/harness/commands/doctor.js +58 -20
- package/dist/harness/commands/doctor.js.map +1 -1
- package/dist/harness/commands/launch.d.ts +7 -1
- package/dist/harness/commands/launch.d.ts.map +1 -1
- package/dist/harness/commands/launch.js +7 -7
- package/dist/harness/commands/launch.js.map +1 -1
- package/dist/harness/commands/logs.d.ts +25 -0
- package/dist/harness/commands/logs.d.ts.map +1 -0
- package/dist/harness/commands/logs.js +105 -0
- package/dist/harness/commands/logs.js.map +1 -0
- package/dist/harness/commands/reload.d.ts +2 -1
- package/dist/harness/commands/reload.d.ts.map +1 -1
- package/dist/harness/commands/reload.js +3 -3
- package/dist/harness/commands/reload.js.map +1 -1
- package/dist/harness/commands/run.d.ts +8 -8
- package/dist/harness/commands/run.d.ts.map +1 -1
- package/dist/harness/commands/run.js +23 -32
- package/dist/harness/commands/run.js.map +1 -1
- package/dist/harness/commands/status.d.ts.map +1 -1
- package/dist/harness/commands/status.js +15 -0
- package/dist/harness/commands/status.js.map +1 -1
- package/dist/harness/commands/stop.d.ts +2 -0
- package/dist/harness/commands/stop.d.ts.map +1 -1
- package/dist/harness/commands/stop.js +2 -2
- package/dist/harness/commands/stop.js.map +1 -1
- package/dist/harness/conformance.d.ts +5 -3
- package/dist/harness/conformance.d.ts.map +1 -1
- package/dist/harness/conformance.js +19 -12
- package/dist/harness/conformance.js.map +1 -1
- package/dist/harness/context-state.d.ts +2 -1
- package/dist/harness/context-state.d.ts.map +1 -1
- package/dist/harness/context-state.js.map +1 -1
- package/dist/harness/context.d.ts +8 -1
- package/dist/harness/context.d.ts.map +1 -1
- package/dist/harness/context.js +6 -1
- package/dist/harness/context.js.map +1 -1
- package/dist/harness/execution-provenance.js +1 -1
- package/dist/harness/execution-provenance.js.map +1 -1
- package/dist/harness/host.d.ts +2 -0
- package/dist/harness/host.d.ts.map +1 -1
- package/dist/harness/host.js.map +1 -1
- package/dist/harness/index.d.ts +6 -6
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +5 -5
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/project-host.d.ts +2 -1
- package/dist/harness/project-host.d.ts.map +1 -1
- package/dist/harness/project-host.js +8 -4
- package/dist/harness/project-host.js.map +1 -1
- package/dist/harness/recipe-library.d.ts +2 -2
- package/dist/harness/recipe-library.d.ts.map +1 -1
- package/dist/harness/recipe-library.js +5 -5
- package/dist/harness/recipe-library.js.map +1 -1
- package/dist/harness/recipe-validation.d.ts +2 -2
- package/dist/harness/recipe-validation.d.ts.map +1 -1
- package/dist/harness/recipe-validation.js +7 -7
- package/dist/harness/recipe-validation.js.map +1 -1
- package/dist/harness/run-diagnostics.d.ts +2 -49
- package/dist/harness/run-diagnostics.d.ts.map +1 -1
- package/dist/harness/run-diagnostics.js +1 -41
- package/dist/harness/run-diagnostics.js.map +1 -1
- package/dist/harness/run-engine.d.ts +6 -60
- package/dist/harness/run-engine.d.ts.map +1 -1
- package/dist/harness/run-engine.js +9 -233
- package/dist/harness/run-engine.js.map +1 -1
- package/dist/harness/run-options.d.ts.map +1 -1
- package/dist/harness/run-options.js +2 -1
- package/dist/harness/run-options.js.map +1 -1
- package/dist/harness/runtime-proof.d.ts +7 -19
- package/dist/harness/runtime-proof.d.ts.map +1 -1
- package/dist/harness/runtime-proof.js +54 -89
- package/dist/harness/runtime-proof.js.map +1 -1
- package/package.json +5 -5
- package/dist/harness/run-recording.d.ts +0 -48
- package/dist/harness/run-recording.d.ts.map +0 -1
- package/dist/harness/run-recording.js +0 -566
- package/dist/harness/run-recording.js.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Behavioral proof checks on a recipe: the plan before it runs, and the
|
|
2
2
|
// executed artifact package after, independently of any task host.
|
|
3
3
|
import assert from 'node:assert/strict';
|
|
4
|
-
import { normalizeRecipeRef, validateRecipeArtifactPackage, } from '@farmslot/protocol';
|
|
4
|
+
import { isRecord, normalizeRecipeRef, validateRecipeArtifactPackage, } from '@farmslot/protocol';
|
|
5
|
+
import { collectProofNodes, executedProofIndex, extractWorkflowGraph, potentiallyEligibleProof, } from '@farmslot/recipe-runner';
|
|
5
6
|
/** Validate executed behavioral proof, independently of any task host or control plane. */
|
|
6
|
-
export function validateRuntimeProof(bundle, smokeTarget) {
|
|
7
|
+
export function validateRuntimeProof(bundle, smokeTarget, teardownTarget, visualProof = {}) {
|
|
7
8
|
const checked = validateRecipeArtifactPackage(bundle);
|
|
8
9
|
assert.equal(checked.status, 'valid', JSON.stringify(checked.findings));
|
|
9
10
|
const { recipe, summary, trace, manifest, recipeResolution, resolvedRecipes } = bundle;
|
|
@@ -20,30 +21,8 @@ export function validateRuntimeProof(bundle, smokeTarget) {
|
|
|
20
21
|
const nodes = collectProofNodes(recipe, documents);
|
|
21
22
|
const executed = new Map(entries.map((entry, index) => [entry.nodeId ?? entry.id, { entry, index }]));
|
|
22
23
|
function proves(id) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
if (!current || current.entry.action !== node.action)
|
|
26
|
-
return false;
|
|
27
|
-
if (node.action === 'call')
|
|
28
|
-
return [...nodes.keys()].some((child) => child.startsWith(`${id}/`) && proves(child));
|
|
29
|
-
if (!assertions.has(node.action) ||
|
|
30
|
-
!current.entry.output ||
|
|
31
|
-
typeof current.entry.output !== 'object')
|
|
32
|
-
return false;
|
|
33
|
-
if (node.action === 'assert_output') {
|
|
34
|
-
const source = assertionSource(id, node);
|
|
35
|
-
const prior = executed.get(source);
|
|
36
|
-
const action = nodes.get(source)?.action;
|
|
37
|
-
return Boolean(prior &&
|
|
38
|
-
prior.index < current.index &&
|
|
39
|
-
action &&
|
|
40
|
-
action === prior.entry.action &&
|
|
41
|
-
isObservation(action));
|
|
42
|
-
}
|
|
43
|
-
if (node.action === 'ui.wait_for')
|
|
44
|
-
return entries.slice(0, current.index).some((entry) => inputs.has(entry.action));
|
|
45
|
-
return (typeof node.path === 'string' &&
|
|
46
|
-
manifest.artifacts.some((artifact) => artifact.path === node.path && artifact.category === 'proof'));
|
|
24
|
+
const index = executedProofIndex(id, nodes, entries, manifest.artifacts);
|
|
25
|
+
return index !== null && entries[index]?.ok === true;
|
|
47
26
|
}
|
|
48
27
|
assert(recipe.proofTargets?.length, 'Runtime recipe has no behavioral proof targets');
|
|
49
28
|
for (const target of recipe.proofTargets) {
|
|
@@ -52,60 +31,53 @@ export function validateRuntimeProof(bundle, smokeTarget) {
|
|
|
52
31
|
}
|
|
53
32
|
if (smokeTarget)
|
|
54
33
|
assert(recipe.proofTargets.some((target) => target.id === smokeTarget), 'Smoke target is absent from recipe');
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
'end',
|
|
59
|
-
'wait',
|
|
60
|
-
'manual',
|
|
61
|
-
'switch',
|
|
62
|
-
'call',
|
|
63
|
-
'index_artifacts',
|
|
64
|
-
'assert_exit_code',
|
|
65
|
-
'assert_file',
|
|
66
|
-
'branch',
|
|
67
|
-
'repeat',
|
|
68
|
-
'set',
|
|
69
|
-
'log',
|
|
70
|
-
]);
|
|
71
|
-
const inputs = new Set([
|
|
72
|
-
'ui.press',
|
|
73
|
-
'ui.key_press',
|
|
74
|
-
'ui.set_input',
|
|
75
|
-
'ui.swipe',
|
|
76
|
-
'ui.drag',
|
|
77
|
-
'ui.long_press',
|
|
78
|
-
]);
|
|
79
|
-
function isObservation(action) {
|
|
80
|
-
return !controls.has(action) && !assertions.has(action);
|
|
81
|
-
}
|
|
82
|
-
function assertionSource(id, node) {
|
|
83
|
-
const prefix = id.includes('/') ? id.slice(0, id.lastIndexOf('/') + 1) : '';
|
|
84
|
-
return prefix + String(node.source ?? node.node ?? '');
|
|
85
|
-
}
|
|
86
|
-
function collectProofNodes(recipe, documents) {
|
|
87
|
-
const nodes = new Map();
|
|
88
|
-
function collect(document, prefix = '', stack = new Set()) {
|
|
89
|
-
for (const [id, node] of Object.entries(document.workflow.nodes)) {
|
|
90
|
-
nodes.set(prefix + id, node);
|
|
91
|
-
if (node.action === 'call' && typeof node.ref === 'string') {
|
|
92
|
-
const ref = normalizeRecipeRef(node.ref);
|
|
93
|
-
assert(!stack.has(ref), 'Recursive recipe proof');
|
|
94
|
-
const nested = documents.get(ref);
|
|
95
|
-
assert(nested, `Missing resolved recipe ${ref}`);
|
|
96
|
-
collect(nested, `${prefix}${id}/`, new Set(stack).add(ref));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
34
|
+
if (teardownTarget) {
|
|
35
|
+
assert(recipe.proofTargets.some((target) => target.id === teardownTarget) &&
|
|
36
|
+
teardownProofNodes(recipe, nodes, teardownTarget).some(proves), `Teardown target ${teardownTarget} has no executed cleanup assertion`);
|
|
99
37
|
}
|
|
100
|
-
|
|
101
|
-
|
|
38
|
+
if (!visualProof.captureRequired && !visualProof.hudRequired)
|
|
39
|
+
return [];
|
|
40
|
+
const proofNodes = [...nodes].filter(([, node]) => node.proves?.includes(smokeTarget ?? ''));
|
|
41
|
+
const captures = manifest.artifacts.filter((artifact) => {
|
|
42
|
+
if (artifact.type !== 'screenshot' && artifact.type !== 'video')
|
|
43
|
+
return false;
|
|
44
|
+
const nodeId = artifact.nodeId;
|
|
45
|
+
if (!nodeId || !proofNodes.some(([id]) => nodeId === id || nodeId.startsWith(`${id}/`)))
|
|
46
|
+
return false;
|
|
47
|
+
const entry = executed.get(nodeId)?.entry;
|
|
48
|
+
if (!entry || entry.action !== nodes.get(nodeId)?.action)
|
|
49
|
+
return false;
|
|
50
|
+
if (!visualProof.hudRequired)
|
|
51
|
+
return true;
|
|
52
|
+
const hud = artifact.metadata?.hud;
|
|
53
|
+
if (!isRecord(hud) || typeof entry.intent !== 'string')
|
|
54
|
+
return false;
|
|
55
|
+
const expected = entry.intent.replace(/\s+/gu, ' ').trim();
|
|
56
|
+
const matches = (value) => {
|
|
57
|
+
if (!isRecord(value) || value.visible !== true || typeof value.intent !== 'string')
|
|
58
|
+
return false;
|
|
59
|
+
const observed = value.intent.replace(/\s+/gu, ' ').trim();
|
|
60
|
+
return Boolean(expected && observed === expected);
|
|
61
|
+
};
|
|
62
|
+
return matches(hud.before) && matches(hud.after);
|
|
63
|
+
});
|
|
64
|
+
assert(captures.length, visualProof.hudRequired
|
|
65
|
+
? 'Live smoke has no capture tied to its proof with the rendered intent HUD observed before and after capture.'
|
|
66
|
+
: 'Live smoke has no capture tied to its named proof.');
|
|
67
|
+
return captures.map((artifact) => artifact.path);
|
|
68
|
+
}
|
|
69
|
+
function teardownProofNodes(recipe, nodes, target) {
|
|
70
|
+
const graph = extractWorkflowGraph(recipe);
|
|
71
|
+
if (!graph.teardownEntry)
|
|
72
|
+
return [];
|
|
73
|
+
return [...nodes].flatMap(([id, node]) => node.proves?.includes(target) && !graph.mainNodeIds.has(id.split('/')[0]) ? [id] : []);
|
|
102
74
|
}
|
|
103
75
|
/**
|
|
104
76
|
* Check possible proof bindings after protocol/dependency validation, without executing a graph.
|
|
105
77
|
* A clean result is conditional: order, branches, successful observations and indexed artifacts
|
|
106
78
|
* still require validateRuntimeProof on the executed package.
|
|
107
79
|
*/
|
|
108
|
-
export function validateRuntimeProofPlan(recipe, documents = new Map()) {
|
|
80
|
+
export function validateRuntimeProofPlan(recipe, documents = new Map(), teardownTarget, smokeTarget) {
|
|
109
81
|
const finding = (code, path, message) => ({
|
|
110
82
|
severity: 'error',
|
|
111
83
|
code,
|
|
@@ -117,22 +89,8 @@ export function validateRuntimeProofPlan(recipe, documents = new Map()) {
|
|
|
117
89
|
finding('proof.targets_missing', 'proofTargets', 'Behavioral proof requires at least one proof target.'),
|
|
118
90
|
];
|
|
119
91
|
const nodes = collectProofNodes(recipe, documents);
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
const node = nodes.get(id);
|
|
123
|
-
if (node.action === 'call')
|
|
124
|
-
return [...nodes.keys()].some((child) => child.startsWith(`${id}/`) && eligible(child));
|
|
125
|
-
if (node.action === 'assert_output') {
|
|
126
|
-
const source = nodes.get(assertionSource(id, node));
|
|
127
|
-
return Boolean(source && isObservation(source.action));
|
|
128
|
-
}
|
|
129
|
-
// Inputs may live in a caller or a sibling call. Do not infer execution order here.
|
|
130
|
-
if (node.action === 'ui.wait_for')
|
|
131
|
-
return hasInput;
|
|
132
|
-
// The manifest is created at execution; a path alone cannot prove it will be indexed.
|
|
133
|
-
return node.action === 'assert_json' && typeof node.path === 'string';
|
|
134
|
-
}
|
|
135
|
-
return recipe.proofTargets.flatMap((target, index) => {
|
|
92
|
+
const eligible = (id) => potentiallyEligibleProof(id, nodes);
|
|
93
|
+
const findings = recipe.proofTargets.flatMap((target, index) => {
|
|
136
94
|
const linked = [...nodes].filter(([, node]) => node.proves?.includes(target.id));
|
|
137
95
|
return linked.some(([id]) => eligible(id))
|
|
138
96
|
? []
|
|
@@ -140,5 +98,12 @@ export function validateRuntimeProofPlan(recipe, documents = new Map()) {
|
|
|
140
98
|
finding('proof.no_runtime_assertion', `proofTargets[${index}]`, `Proof target ${target.id} has no potentially eligible runtime assertion. Bind proves to assert_output over an observation, ui.wait_for with an input action, assert_json over a proof artifact, or a call containing one. Runtime order, outcomes and artifact indexing remain unverified.`),
|
|
141
99
|
];
|
|
142
100
|
});
|
|
101
|
+
if (smokeTarget && !recipe.proofTargets.some((target) => target.id === smokeTarget)) {
|
|
102
|
+
findings.push(finding('proof.smoke_target_missing', 'proofTargets', `Smoke target ${smokeTarget} is absent from the recipe.`));
|
|
103
|
+
}
|
|
104
|
+
if (teardownTarget && !teardownProofNodes(recipe, nodes, teardownTarget).some(eligible)) {
|
|
105
|
+
findings.push(finding('proof.teardown_assertion_missing', 'workflow.teardown', `Teardown target ${teardownTarget} needs a runtime assertion in the authored teardown.`));
|
|
106
|
+
}
|
|
107
|
+
return findings;
|
|
143
108
|
}
|
|
144
109
|
//# sourceMappingURL=runtime-proof.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-proof.js","sourceRoot":"","sources":["../../src/harness/runtime-proof.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,mEAAmE;AACnE,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EACL,kBAAkB,
|
|
1
|
+
{"version":3,"file":"runtime-proof.js","sourceRoot":"","sources":["../../src/harness/runtime-proof.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farmslot/recipe-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"prepublishOnly": "node ../../scripts/quality/check-farmslot-package-readiness.mjs --publish --packages @farmslot/recipe-cli"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@farmslot/adapter-sdk": "0.
|
|
36
|
-
"@farmslot/agent-runtime": "0.
|
|
37
|
-
"@farmslot/protocol": "0.
|
|
38
|
-
"@farmslot/recipe-runner": "0.
|
|
35
|
+
"@farmslot/adapter-sdk": "0.9.0",
|
|
36
|
+
"@farmslot/agent-runtime": "0.18.0",
|
|
37
|
+
"@farmslot/protocol": "0.39.0",
|
|
38
|
+
"@farmslot/recipe-runner": "0.30.0",
|
|
39
39
|
"commander": "^12.0.0",
|
|
40
40
|
"es-module-lexer": "2.3.1",
|
|
41
41
|
"esbuild": "0.28.1",
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { type ChildProcessWithoutNullStreams } from 'node:child_process';
|
|
2
|
-
import { type CaptureHelperInterruptionEvent, readCaptureHelperTiming, type RecipeRunCaptureInterruption, type RecipeRunResult } from '@farmslot/recipe-runner';
|
|
3
|
-
export interface RecipeRecordingOptions {
|
|
4
|
-
record?: boolean;
|
|
5
|
-
cdpPort?: string;
|
|
6
|
-
}
|
|
7
|
-
export interface ActiveRecipeRecording {
|
|
8
|
-
child: ChildProcessWithoutNullStreams;
|
|
9
|
-
outputPath: string;
|
|
10
|
-
stagingDir: string;
|
|
11
|
-
stagedPath: string;
|
|
12
|
-
relativePath: string;
|
|
13
|
-
pid: number;
|
|
14
|
-
stdout: string;
|
|
15
|
-
stderr: string;
|
|
16
|
-
exited: boolean;
|
|
17
|
-
exitCode: number | null;
|
|
18
|
-
frameReady: boolean;
|
|
19
|
-
streamStopped?: boolean;
|
|
20
|
-
finalized: boolean;
|
|
21
|
-
finalizationError?: unknown;
|
|
22
|
-
startedAtUnixMs: number;
|
|
23
|
-
stoppedAtUnixMs?: number;
|
|
24
|
-
nativeTiming: boolean;
|
|
25
|
-
completedRecordingId?: string;
|
|
26
|
-
completedVideo?: boolean;
|
|
27
|
-
/** capture-helper's `stream_interrupted` event: its stream stopped and it kept the frames so far. */
|
|
28
|
-
interruption?: CaptureHelperInterruptionEvent;
|
|
29
|
-
nativeTimingEvidence?: Awaited<ReturnType<typeof readCaptureHelperTiming>>;
|
|
30
|
-
error?: Error;
|
|
31
|
-
activePidEnv: string;
|
|
32
|
-
previousActiveRecordingPid: string | undefined;
|
|
33
|
-
stderrBuffer: string;
|
|
34
|
-
pendingSnapshots: Map<string, PendingRecordingSnapshot>;
|
|
35
|
-
}
|
|
36
|
-
interface PendingRecordingSnapshot {
|
|
37
|
-
outputPath: string;
|
|
38
|
-
timer: NodeJS.Timeout;
|
|
39
|
-
resolve: (event: Record<string, unknown> | undefined) => void;
|
|
40
|
-
reject: (error: Error) => void;
|
|
41
|
-
}
|
|
42
|
-
export declare function startRecipeRecording(adapter: string, projectRoot: string, artifactsDir: string, options: RecipeRecordingOptions): Promise<ActiveRecipeRecording | undefined>;
|
|
43
|
-
/** Ask the recording of `pid` for an in-session snapshot; undefined when none runs. */
|
|
44
|
-
export declare function captureActiveRecipeRecordingSnapshot(pid: number, outputPath: string, timeoutMs?: number): Promise<Record<string, unknown> | undefined>;
|
|
45
|
-
/** Finalize and publish the run video; returns the interruption when only a partial video was kept. */
|
|
46
|
-
export declare function stopRecipeRecording(recording: ActiveRecipeRecording | undefined, result?: RecipeRunResult): Promise<RecipeRunCaptureInterruption | undefined>;
|
|
47
|
-
export {};
|
|
48
|
-
//# sourceMappingURL=run-recording.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-recording.d.ts","sourceRoot":"","sources":["../../src/harness/run-recording.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,8BAA8B,EAAoB,MAAM,oBAAoB,CAAC;AAI3F,OAAO,EACL,KAAK,8BAA8B,EAKnC,uBAAuB,EACvB,KAAK,4BAA4B,EACjC,KAAK,eAAe,EAIrB,MAAM,yBAAyB,CAAC;AAUjC,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,8BAA8B,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qGAAqG;IACrG,YAAY,CAAC,EAAE,8BAA8B,CAAC;IAC9C,oBAAoB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAC;IAC3E,KAAK,CAAC,EAAE,KAAK,CAAC;IAEd,YAAY,EAAE,MAAM,CAAC;IACrB,0BAA0B,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CACzD;AAED,UAAU,wBAAwB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC;IAEtB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,KAAK,IAAI,CAAC;IAC9D,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC;AAID,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAsH5C;AAED,uFAAuF;AACvF,wBAAsB,oCAAoC,CACxD,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,SAAS,SAAS,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CA4B9C;AAED,uGAAuG;AACvG,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,qBAAqB,GAAG,SAAS,EAC5C,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,4BAA4B,GAAG,SAAS,CAAC,CAuCnD"}
|