ppef 1.0.1 → 1.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/bin/ppef.mjs +20 -0
- package/dist/__tests__/framework-pipeline.integration.test.js +13 -11
- package/dist/__tests__/framework-pipeline.integration.test.js.map +1 -1
- package/dist/__tests__/index-exports.unit.test.d.ts +8 -0
- package/dist/__tests__/index-exports.unit.test.d.ts.map +1 -0
- package/dist/__tests__/index-exports.unit.test.js +127 -0
- package/dist/__tests__/index-exports.unit.test.js.map +1 -0
- package/dist/__tests__/registry-executor.integration.test.js +12 -9
- package/dist/__tests__/registry-executor.integration.test.js.map +1 -1
- package/dist/aggregation/__tests__/aggregators.unit.test.d.ts +7 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.d.ts.map +1 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.js +350 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.js.map +1 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.d.ts +7 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.d.ts.map +1 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.js +213 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.js.map +1 -0
- package/dist/aggregation/aggregators.d.ts +9 -0
- package/dist/aggregation/aggregators.d.ts.map +1 -1
- package/dist/aggregation/aggregators.js +1 -1
- package/dist/aggregation/aggregators.js.map +1 -1
- package/dist/aggregation/index.d.ts +1 -1
- package/dist/aggregation/index.d.ts.map +1 -1
- package/dist/aggregation/index.js +1 -1
- package/dist/aggregation/index.js.map +1 -1
- package/dist/claims/__tests__/evaluator.unit.test.d.ts +12 -0
- package/dist/claims/__tests__/evaluator.unit.test.d.ts.map +1 -0
- package/dist/claims/__tests__/evaluator.unit.test.js +801 -0
- package/dist/claims/__tests__/evaluator.unit.test.js.map +1 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.js +396 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.js.map +1 -0
- package/dist/cli/__tests__/commands.unit.test.d.ts +10 -0
- package/dist/cli/__tests__/commands.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/commands.unit.test.js +217 -0
- package/dist/cli/__tests__/commands.unit.test.js.map +1 -0
- package/dist/cli/__tests__/index.unit.test.d.ts +10 -0
- package/dist/cli/__tests__/index.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/index.unit.test.js +65 -0
- package/dist/cli/__tests__/index.unit.test.js.map +1 -0
- package/dist/cli/__tests__/logger.unit.test.d.ts +11 -0
- package/dist/cli/__tests__/logger.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/logger.unit.test.js +180 -0
- package/dist/cli/__tests__/logger.unit.test.js.map +1 -0
- package/dist/cli/__tests__/module-loader.unit.test.d.ts +11 -0
- package/dist/cli/__tests__/module-loader.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/module-loader.unit.test.js +262 -0
- package/dist/cli/__tests__/module-loader.unit.test.js.map +1 -0
- package/dist/cli/__tests__/output-writer.unit.test.d.ts +10 -0
- package/dist/cli/__tests__/output-writer.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/output-writer.unit.test.js +216 -0
- package/dist/cli/__tests__/output-writer.unit.test.js.map +1 -0
- package/dist/cli/__tests__/plan.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/plan.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/plan.command.unit.test.js +289 -0
- package/dist/cli/__tests__/plan.command.unit.test.js.map +1 -0
- package/dist/cli/__tests__/run.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/run.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/run.command.unit.test.js +422 -0
- package/dist/cli/__tests__/run.command.unit.test.js.map +1 -0
- package/dist/cli/__tests__/validate.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/validate.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/validate.command.unit.test.js +226 -0
- package/dist/cli/__tests__/validate.command.unit.test.js.map +1 -0
- package/dist/cli/command-deps.d.ts +125 -0
- package/dist/cli/command-deps.d.ts.map +1 -0
- package/dist/cli/command-deps.js +7 -0
- package/dist/cli/command-deps.js.map +1 -0
- package/dist/cli/commands/aggregate.d.ts +35 -0
- package/dist/cli/commands/aggregate.d.ts.map +1 -0
- package/dist/cli/commands/aggregate.js +121 -0
- package/dist/cli/commands/aggregate.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +36 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +109 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/run.d.ts +33 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +185 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +27 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +88 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/config-loader.d.ts +30 -0
- package/dist/cli/config-loader.d.ts.map +1 -0
- package/dist/cli/config-loader.js +181 -0
- package/dist/cli/config-loader.js.map +1 -0
- package/dist/cli/index.d.ts +26 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +58 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/logger.d.ts +75 -0
- package/dist/cli/logger.d.ts.map +1 -0
- package/dist/cli/logger.js +131 -0
- package/dist/cli/logger.js.map +1 -0
- package/dist/cli/module-loader.d.ts +46 -0
- package/dist/cli/module-loader.d.ts.map +1 -0
- package/dist/cli/module-loader.js +116 -0
- package/dist/cli/module-loader.js.map +1 -0
- package/dist/cli/output-writer.d.ts +51 -0
- package/dist/cli/output-writer.d.ts.map +1 -0
- package/dist/cli/output-writer.js +65 -0
- package/dist/cli/output-writer.js.map +1 -0
- package/dist/cli/types.d.ts +174 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +7 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/collector/__tests__/result-collector.unit.test.d.ts +7 -0
- package/dist/collector/__tests__/result-collector.unit.test.d.ts.map +1 -0
- package/dist/collector/__tests__/result-collector.unit.test.js +1021 -0
- package/dist/collector/__tests__/result-collector.unit.test.js.map +1 -0
- package/dist/collector/__tests__/schema.unit.test.d.ts +7 -0
- package/dist/collector/__tests__/schema.unit.test.d.ts.map +1 -0
- package/dist/collector/__tests__/schema.unit.test.js +360 -0
- package/dist/collector/__tests__/schema.unit.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.js +83 -1
- package/dist/executor/__tests__/checkpoint-manager.unit.test.js.map +1 -1
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts +3 -6
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts.map +1 -1
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js +428 -159
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js.map +1 -1
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js +105 -1
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js.map +1 -1
- package/dist/executor/__tests__/executor.unit.test.js +69 -1
- package/dist/executor/__tests__/executor.unit.test.js.map +1 -1
- package/dist/executor/__tests__/memory-monitor.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.js +285 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.js.map +1 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.d.ts +2 -1
- package/dist/executor/__tests__/parallel-executor.unit.test.d.ts.map +1 -1
- package/dist/executor/__tests__/parallel-executor.unit.test.js +426 -156
- package/dist/executor/__tests__/parallel-executor.unit.test.js.map +1 -1
- package/dist/executor/__tests__/run-id.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/run-id.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/run-id.unit.test.js +156 -0
- package/dist/executor/__tests__/run-id.unit.test.js.map +1 -0
- package/dist/executor/__tests__/worker-entry.integration.test.d.ts +24 -0
- package/dist/executor/__tests__/worker-entry.integration.test.d.ts.map +1 -0
- package/dist/executor/__tests__/worker-entry.integration.test.js +82 -0
- package/dist/executor/__tests__/worker-entry.integration.test.js.map +1 -0
- package/dist/executor/__tests__/worker-entry.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/worker-entry.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/worker-entry.unit.test.js +364 -0
- package/dist/executor/__tests__/worker-entry.unit.test.js.map +1 -0
- package/dist/executor/parallel-executor.d.ts +186 -0
- package/dist/executor/parallel-executor.d.ts.map +1 -1
- package/dist/executor/parallel-executor.js +218 -83
- package/dist/executor/parallel-executor.js.map +1 -1
- package/dist/executor/run-id.d.ts.map +1 -1
- package/dist/executor/run-id.js +8 -1
- package/dist/executor/run-id.js.map +1 -1
- package/dist/executor/worker-entry.d.ts +2 -0
- package/dist/executor/worker-entry.d.ts.map +1 -1
- package/dist/executor/worker-entry.js +29 -54
- package/dist/executor/worker-entry.js.map +1 -1
- package/dist/executor/worker-executor.d.ts +156 -0
- package/dist/executor/worker-executor.d.ts.map +1 -0
- package/dist/executor/worker-executor.js +88 -0
- package/dist/executor/worker-executor.js.map +1 -0
- package/dist/robustness/__tests__/analyzer.unit.test.d.ts +11 -0
- package/dist/robustness/__tests__/analyzer.unit.test.d.ts.map +1 -0
- package/dist/robustness/__tests__/analyzer.unit.test.js +455 -0
- package/dist/robustness/__tests__/analyzer.unit.test.js.map +1 -0
- package/dist/robustness/__tests__/perturbations.unit.test.d.ts +11 -0
- package/dist/robustness/__tests__/perturbations.unit.test.d.ts.map +1 -0
- package/dist/robustness/__tests__/perturbations.unit.test.js +284 -0
- package/dist/robustness/__tests__/perturbations.unit.test.js.map +1 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts +7 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts.map +1 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.js +185 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.js.map +1 -0
- package/package.json +8 -1
|
@@ -8,36 +8,77 @@
|
|
|
8
8
|
* results/execute/checkpoint-worker-00.json
|
|
9
9
|
* results/execute/checkpoint-worker-01.json
|
|
10
10
|
* ...
|
|
11
|
+
*
|
|
12
|
+
* Dependency Injection:
|
|
13
|
+
* - Logger interface enables testing of log output
|
|
14
|
+
* - ProcessSpawner interface enables mocking spawn() calls
|
|
15
|
+
* - SystemInfo interface enables testing CPU count and node path logic
|
|
11
16
|
*/
|
|
12
17
|
import { spawn } from "node:child_process";
|
|
13
18
|
import { randomBytes } from "node:crypto";
|
|
14
19
|
import { cpus } from "node:os";
|
|
15
20
|
import { dirname, resolve } from "node:path";
|
|
16
21
|
/**
|
|
17
|
-
*
|
|
18
|
-
* The CLI entry point is dist/cli.js, so we go up one level from there.
|
|
22
|
+
* Production logger using console.
|
|
19
23
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const entryPoint = process.argv[1];
|
|
24
|
-
// Resolve to absolute path first (handles relative paths like "dist/cli.js")
|
|
25
|
-
const absoluteEntry = resolve(entryPoint);
|
|
26
|
-
const entryDir = dirname(absoluteEntry);
|
|
27
|
-
// If entry point is in dist/, go up one level to get package root
|
|
28
|
-
if (entryDir.endsWith("/dist") || entryDir.endsWith(String.raw `\dist`)) {
|
|
29
|
-
return entryDir.slice(0, -5); // Remove "/dist"
|
|
24
|
+
export class ConsoleLogger {
|
|
25
|
+
log(message) {
|
|
26
|
+
console.log(message);
|
|
30
27
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
28
|
+
debug(message) {
|
|
29
|
+
console.log(message);
|
|
30
|
+
}
|
|
31
|
+
info(message) {
|
|
32
|
+
console.log(message);
|
|
33
|
+
}
|
|
34
|
+
warn(message) {
|
|
35
|
+
console.warn(message);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Production process spawner using node:child_process.
|
|
40
|
+
*/
|
|
41
|
+
export class ProcessSpawner {
|
|
42
|
+
spawn(command, args, options) {
|
|
43
|
+
return spawn(command, args, options);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Production system info using node:os and process.
|
|
48
|
+
*/
|
|
49
|
+
export class SystemInfo {
|
|
50
|
+
cpuCount = cpus().length;
|
|
51
|
+
nodePath = process.execPath;
|
|
52
|
+
env = process.env;
|
|
53
|
+
packageRoot;
|
|
54
|
+
constructor() {
|
|
55
|
+
this.packageRoot = this.getPackageRoot();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the package root directory by resolving from the entry point script.
|
|
59
|
+
* The CLI entry point is dist/cli.js, so we go up one level from there.
|
|
60
|
+
*/
|
|
61
|
+
getPackageRoot() {
|
|
62
|
+
// Get the directory containing the entry point script
|
|
63
|
+
// process.argv[1] is the path to the executed script (e.g., /path/to/graphbox/dist/cli.js)
|
|
64
|
+
const entryPoint = process.argv[1];
|
|
65
|
+
// Resolve to absolute path first (handles relative paths like "dist/cli.js")
|
|
66
|
+
const absoluteEntry = resolve(entryPoint);
|
|
67
|
+
const entryDir = dirname(absoluteEntry);
|
|
68
|
+
// If entry point is in dist/, go up one level to get package root
|
|
69
|
+
if (entryDir.endsWith("/dist") || entryDir.endsWith(String.raw `\dist`)) {
|
|
70
|
+
return entryDir.slice(0, -5); // Remove "/dist"
|
|
71
|
+
}
|
|
72
|
+
// Fallback: use current directory
|
|
73
|
+
return process.cwd();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
35
76
|
/**
|
|
36
77
|
* Generate random worker names using tech-themed adjectives.
|
|
37
78
|
* Returns unique names for each worker.
|
|
38
79
|
* @param count
|
|
39
80
|
*/
|
|
40
|
-
const generateWorkerNames = (count) => {
|
|
81
|
+
export const generateWorkerNames = (count) => {
|
|
41
82
|
const adjectives = [
|
|
42
83
|
"swift",
|
|
43
84
|
"nimble",
|
|
@@ -111,84 +152,178 @@ const generateWorkerNames = (count) => {
|
|
|
111
152
|
* @returns Path to the worker's checkpoint file
|
|
112
153
|
*/
|
|
113
154
|
export const shardPath = (checkpointDir, workerIndex) => resolve(checkpointDir, `checkpoint-worker-${String(workerIndex).padStart(2, "0")}.json`);
|
|
155
|
+
/**
|
|
156
|
+
* Parallel executor class with dependency injection.
|
|
157
|
+
*
|
|
158
|
+
* Spawns multiple Node.js processes, each executing a subset of runs.
|
|
159
|
+
* Each worker writes to its own sharded checkpoint file to avoid race conditions.
|
|
160
|
+
*/
|
|
161
|
+
export class ParallelExecutor {
|
|
162
|
+
logger;
|
|
163
|
+
spawner;
|
|
164
|
+
systemInfo;
|
|
165
|
+
constructor(logger, spawner, systemInfo) {
|
|
166
|
+
this.logger = logger ?? new ConsoleLogger();
|
|
167
|
+
this.spawner = spawner ?? new ProcessSpawner();
|
|
168
|
+
this.systemInfo = systemInfo ?? new SystemInfo();
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Split runs into batches for parallel processing.
|
|
172
|
+
* @param runs - Runs to distribute
|
|
173
|
+
* @param numberWorkers - Number of worker processes
|
|
174
|
+
* @returns Array of run batches
|
|
175
|
+
*/
|
|
176
|
+
_createBatches(runs, numberWorkers) {
|
|
177
|
+
const batchSize = Math.ceil(runs.length / numberWorkers);
|
|
178
|
+
const batches = [];
|
|
179
|
+
for (let i = 0; i < runs.length; i += batchSize) {
|
|
180
|
+
const batch = runs.slice(i, i + batchSize);
|
|
181
|
+
const batchIndex = Math.floor(i / batchSize);
|
|
182
|
+
const runIds = new Set(batch.map((r) => r.runId));
|
|
183
|
+
batches.push({
|
|
184
|
+
index: batchIndex,
|
|
185
|
+
runIds: [...runIds],
|
|
186
|
+
filter: JSON.stringify([...runIds]),
|
|
187
|
+
firstRunId: batch[0]?.runId ?? "none",
|
|
188
|
+
lastRunId: batch.at(-1)?.runId ?? "none",
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return batches;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create worker configurations for all batches.
|
|
195
|
+
* @param batches - Run batches
|
|
196
|
+
* @param workerNames - Names for each worker
|
|
197
|
+
* @param cliPath - Path to CLI entry point
|
|
198
|
+
* @param checkpointDir - Base checkpoint directory
|
|
199
|
+
* @param timeoutMs - Per-run timeout in milliseconds
|
|
200
|
+
* @returns Array of worker configurations
|
|
201
|
+
*/
|
|
202
|
+
_createWorkerConfigs(batches, workerNames, cliPath, checkpointDir, timeoutMs) {
|
|
203
|
+
return batches.map((batch) => {
|
|
204
|
+
const workerName = workerNames[batch.index];
|
|
205
|
+
const workerCheckpointPath = shardPath(checkpointDir, batch.index);
|
|
206
|
+
const arguments_ = [
|
|
207
|
+
cliPath,
|
|
208
|
+
"evaluate",
|
|
209
|
+
"--phase=execute",
|
|
210
|
+
"--checkpoint-mode=file",
|
|
211
|
+
`--run-filter=${batch.filter}`,
|
|
212
|
+
];
|
|
213
|
+
// Add timeout if specified
|
|
214
|
+
if (timeoutMs > 0) {
|
|
215
|
+
arguments_.push(`--timeout=${timeoutMs}`);
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
index: batch.index,
|
|
219
|
+
name: workerName,
|
|
220
|
+
checkpointPath: workerCheckpointPath,
|
|
221
|
+
arguments: arguments_,
|
|
222
|
+
env: {
|
|
223
|
+
...this.systemInfo.env,
|
|
224
|
+
NODE_OPTIONS: "--max-old-space-size=4096",
|
|
225
|
+
GRAPHBOX_WORKER_NAME: workerName,
|
|
226
|
+
GRAPHBOX_WORKER_INDEX: batch.index.toString(),
|
|
227
|
+
GRAPHBOX_TOTAL_WORKERS: batches.length.toString(),
|
|
228
|
+
GRAPHBOX_CHECKPOINT_DIR: checkpointDir,
|
|
229
|
+
GRAPHBOX_CHECKPOINT_PATH: workerCheckpointPath,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Spawn worker processes for all configurations.
|
|
236
|
+
* @param workerConfigs - Worker configurations
|
|
237
|
+
* @param nodePath - Path to node executable
|
|
238
|
+
* @param packageRoot - Package root directory
|
|
239
|
+
* @returns Array of child processes
|
|
240
|
+
*/
|
|
241
|
+
_spawnWorkers(workerConfigs, nodePath, packageRoot) {
|
|
242
|
+
return workerConfigs.map((config) => {
|
|
243
|
+
this.logger.debug(`Spawning worker ${config.index}: ${config.name} with ${config.arguments.length} args`);
|
|
244
|
+
return this.spawner.spawn(nodePath, config.arguments, {
|
|
245
|
+
stdio: "inherit",
|
|
246
|
+
cwd: packageRoot,
|
|
247
|
+
env: config.env,
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Wait for all workers to complete.
|
|
253
|
+
* @param workers - Child processes
|
|
254
|
+
* @returns Promise that resolves when all workers exit
|
|
255
|
+
*/
|
|
256
|
+
async _waitForWorkers(workers) {
|
|
257
|
+
return Promise.all(workers.map((w) => new Promise((resolve) => {
|
|
258
|
+
w.on("exit", (code) => {
|
|
259
|
+
resolve(code);
|
|
260
|
+
});
|
|
261
|
+
})));
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Execute runs using multiple parallel processes.
|
|
265
|
+
*
|
|
266
|
+
* Each worker writes to its own sharded checkpoint file to avoid race conditions.
|
|
267
|
+
* After all workers complete, the main process should merge the shards.
|
|
268
|
+
*
|
|
269
|
+
* @param runs - Planned runs to execute
|
|
270
|
+
* @param suts - SUT definitions (not used directly, passed to workers)
|
|
271
|
+
* @param cases - Case definitions (not used directly, passed to workers)
|
|
272
|
+
* @param config - Executor configuration
|
|
273
|
+
* @param options - Parallel executor options
|
|
274
|
+
* @returns Execution results (empty - CLI will load from shards)
|
|
275
|
+
*/
|
|
276
|
+
async execute(runs, _suts, _cases, config, options = {}) {
|
|
277
|
+
const numberWorkers = options.workers ?? this.systemInfo.cpuCount;
|
|
278
|
+
const nodePath = options.nodePath ?? this.systemInfo.nodePath;
|
|
279
|
+
const checkpointDir = options.checkpointDir ?? resolve(this.systemInfo.packageRoot, "results/execute");
|
|
280
|
+
const timeoutMs = options.timeoutMs ?? config.timeoutMs;
|
|
281
|
+
this.logger.info(`ParallelExecutor: Spawning ${numberWorkers} processes for ${runs.length} runs`);
|
|
282
|
+
this.logger.info(`Checkpoint directory: ${checkpointDir}`);
|
|
283
|
+
if (timeoutMs > 0) {
|
|
284
|
+
this.logger.info(`Per-run timeout: ${timeoutMs}ms (${Math.round(timeoutMs / 1000)}s)`);
|
|
285
|
+
}
|
|
286
|
+
// Generate unique names for each worker
|
|
287
|
+
const workerNames = generateWorkerNames(numberWorkers);
|
|
288
|
+
this.logger.info(`Workers: ${workerNames.map((name, index) => `${index + 1}. ${name}`).join(", ")}`);
|
|
289
|
+
// Split runs into batches
|
|
290
|
+
const batches = this._createBatches(runs, numberWorkers);
|
|
291
|
+
// Log batch information
|
|
292
|
+
for (const batch of batches) {
|
|
293
|
+
this.logger.debug(`Batch ${batch.index} has ${batch.runIds.length} runs, filter length: ${batch.filter.length}`);
|
|
294
|
+
this.logger.debug(` First run: ${batch.firstRunId}, Last run: ${batch.lastRunId}`);
|
|
295
|
+
}
|
|
296
|
+
// Create worker configurations
|
|
297
|
+
const cliPath = resolve(this.systemInfo.packageRoot, "dist/cli.js");
|
|
298
|
+
const workerConfigs = this._createWorkerConfigs(batches, workerNames, cliPath, checkpointDir, timeoutMs);
|
|
299
|
+
// Spawn worker processes
|
|
300
|
+
const workers = this._spawnWorkers(workerConfigs, nodePath, this.systemInfo.packageRoot);
|
|
301
|
+
// Wait for all workers to complete
|
|
302
|
+
const exitCodes = await this._waitForWorkers(workers);
|
|
303
|
+
this.logger.debug(`All workers exited with codes: ${exitCodes.join(", ")}`);
|
|
304
|
+
// Load and return aggregated results
|
|
305
|
+
// For now, return empty - the CLI will handle results and merge shards
|
|
306
|
+
return { results: [], errors: [] };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
114
309
|
/**
|
|
115
310
|
* Execute runs using multiple parallel processes.
|
|
116
311
|
*
|
|
117
312
|
* Each worker writes to its own sharded checkpoint file to avoid race conditions.
|
|
118
313
|
* After all workers complete, the main process should merge the shards.
|
|
119
314
|
*
|
|
315
|
+
* This is a convenience function that creates a ParallelExecutor with default dependencies.
|
|
316
|
+
* For testing or custom behavior, use the ParallelExecutor class directly.
|
|
317
|
+
*
|
|
120
318
|
* @param runs - Planned runs to execute
|
|
121
319
|
* @param suts - SUT definitions (not used directly, passed to workers)
|
|
122
320
|
* @param cases - Case definitions (not used directly, passed to workers)
|
|
123
321
|
* @param config - Executor configuration
|
|
124
322
|
* @param options - Parallel executor options
|
|
323
|
+
* @returns Execution results (empty - CLI will load from shards)
|
|
125
324
|
*/
|
|
126
325
|
export const executeParallel = async (runs, suts, cases, config, options = {}) => {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
const checkpointDir = options.checkpointDir ?? resolve(PACKAGE_ROOT, "results/execute");
|
|
130
|
-
const timeoutMs = options.timeoutMs ?? config.timeoutMs;
|
|
131
|
-
console.log(`ParallelExecutor: Spawning ${numberWorkers} processes for ${runs.length} runs`);
|
|
132
|
-
console.log(`Checkpoint directory: ${checkpointDir}`);
|
|
133
|
-
if (timeoutMs > 0) {
|
|
134
|
-
console.log(`Per-run timeout: ${timeoutMs}ms (${Math.round(timeoutMs / 1000)}s)`);
|
|
135
|
-
}
|
|
136
|
-
// Generate unique names for each worker
|
|
137
|
-
const workerNames = generateWorkerNames(numberWorkers);
|
|
138
|
-
console.log(`Workers: ${workerNames.map((name, index) => `${index + 1}. ${name}`).join(", ")}`);
|
|
139
|
-
// Split runs into batches
|
|
140
|
-
const batchSize = Math.ceil(runs.length / numberWorkers);
|
|
141
|
-
const batches = [];
|
|
142
|
-
for (let index = 0; index < runs.length; index += batchSize) {
|
|
143
|
-
batches.push(runs.slice(index, index + batchSize));
|
|
144
|
-
}
|
|
145
|
-
// Create a run filter function for each batch
|
|
146
|
-
const runFilters = batches.map((batch, _index) => {
|
|
147
|
-
const runIds = new Set(batch.map((r) => r.runId));
|
|
148
|
-
const filter = JSON.stringify([...runIds]);
|
|
149
|
-
const firstRunId = batch[0]?.runId ?? "none";
|
|
150
|
-
const lastRunId = batch.at(-1)?.runId ?? "none";
|
|
151
|
-
console.log(`DEBUG: Batch ${_index} has ${batch.length} runs, filter length: ${filter.length}`);
|
|
152
|
-
console.log(`DEBUG: First run: ${firstRunId}, Last run: ${lastRunId}`);
|
|
153
|
-
return filter;
|
|
154
|
-
});
|
|
155
|
-
// Spawn worker processes
|
|
156
|
-
const workers = runFilters.map((runFilter, index) => {
|
|
157
|
-
const workerName = workerNames[index];
|
|
158
|
-
const workerCheckpointPath = shardPath(checkpointDir, index);
|
|
159
|
-
const arguments_ = [
|
|
160
|
-
resolve(PACKAGE_ROOT, "dist/cli.js"),
|
|
161
|
-
"evaluate",
|
|
162
|
-
"--phase=execute",
|
|
163
|
-
"--checkpoint-mode=file",
|
|
164
|
-
`--run-filter=${runFilter}`, // JSON array - needs to be quoted in shell but spawn() handles this
|
|
165
|
-
];
|
|
166
|
-
// Add timeout if specified
|
|
167
|
-
if (timeoutMs > 0) {
|
|
168
|
-
arguments_.push(`--timeout=${timeoutMs}`);
|
|
169
|
-
}
|
|
170
|
-
return spawn(nodePath, arguments_, {
|
|
171
|
-
stdio: "inherit",
|
|
172
|
-
cwd: PACKAGE_ROOT, // Ensure workers use the package root as working directory
|
|
173
|
-
env: {
|
|
174
|
-
...process.env,
|
|
175
|
-
NODE_OPTIONS: "--max-old-space-size=4096",
|
|
176
|
-
GRAPHBOX_WORKER_NAME: workerName,
|
|
177
|
-
GRAPHBOX_WORKER_INDEX: index.toString(),
|
|
178
|
-
GRAPHBOX_TOTAL_WORKERS: numberWorkers.toString(),
|
|
179
|
-
GRAPHBOX_CHECKPOINT_DIR: checkpointDir,
|
|
180
|
-
GRAPHBOX_CHECKPOINT_PATH: workerCheckpointPath,
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
// Wait for all workers to complete
|
|
185
|
-
await Promise.all(workers.map((w) => new Promise((resolve) => {
|
|
186
|
-
w.on("exit", (code) => {
|
|
187
|
-
resolve(code);
|
|
188
|
-
});
|
|
189
|
-
})));
|
|
190
|
-
// Load and return aggregated results
|
|
191
|
-
// For now, return empty - the CLI will handle results and merge shards
|
|
192
|
-
return { results: [], errors: [] };
|
|
326
|
+
const executor = new ParallelExecutor();
|
|
327
|
+
return executor.execute(runs, suts, cases, config, options);
|
|
193
328
|
};
|
|
194
329
|
//# sourceMappingURL=parallel-executor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parallel-executor.js","sourceRoot":"","sources":["../../src/executor/parallel-executor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"parallel-executor.js","sourceRoot":"","sources":["../../src/executor/parallel-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-id.d.ts","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IAEd,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IAEf,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,WAAW,KAAG,MAInD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,
|
|
1
|
+
{"version":3,"file":"run-id.d.ts","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IAEd,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IAEf,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,WAAW,KAAG,MAInD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAUpE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,QAAQ,WAAW,KAAG,OACnC,CAAC;AAEjC;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAM1E,CAAC"}
|
package/dist/executor/run-id.js
CHANGED
|
@@ -38,7 +38,14 @@ export const generateRunId = (inputs) => {
|
|
|
38
38
|
* @returns 8-character hex string
|
|
39
39
|
*/
|
|
40
40
|
export const generateConfigHash = (config) => {
|
|
41
|
-
|
|
41
|
+
// Sort keys for consistent ordering, then stringify without replacer
|
|
42
|
+
// (using replacer array would filter nested properties)
|
|
43
|
+
const sortedKeys = Object.keys(config).sort();
|
|
44
|
+
const sortedObj = {};
|
|
45
|
+
for (const key of sortedKeys) {
|
|
46
|
+
sortedObj[key] = config[key];
|
|
47
|
+
}
|
|
48
|
+
const canonical = JSON.stringify(sortedObj);
|
|
42
49
|
return createHash("sha256").update(canonical).digest("hex").slice(0, 8);
|
|
43
50
|
};
|
|
44
51
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-id.js","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAsBzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAmB,EAAU,EAAE;IAC5D,mCAAmC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAA+B,EAAU,EAAE;IAC7E,MAAM,
|
|
1
|
+
{"version":3,"file":"run-id.js","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAsBzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAmB,EAAU,EAAE;IAC5D,mCAAmC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAA+B,EAAU,EAAE;IAC7E,qEAAqE;IACrE,wDAAwD;IACxD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAa,EAAE,MAAmB,EAAW,EAAE,CAC5E,KAAK,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC;AAEjC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAsC,EAAE;IAC/E,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO;QACN,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QACnC,MAAM,EAAE,KAAK,CAAC,MAAM;KACpB,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-entry.d.ts","sourceRoot":"","sources":["../../src/executor/worker-entry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"worker-entry.d.ts","sourceRoot":"","sources":["../../src/executor/worker-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -3,65 +3,40 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This file is loaded as a worker thread and receives messages
|
|
5
5
|
* with batches of runs to execute.
|
|
6
|
+
*
|
|
7
|
+
* It uses dependency injection to allow testing of the core logic.
|
|
6
8
|
*/
|
|
7
9
|
import { dirname, resolve } from "node:path";
|
|
8
10
|
import { fileURLToPath } from "node:url";
|
|
9
11
|
import { parentPort } from "node:worker_threads";
|
|
12
|
+
import { WorkerExecutor, } from "./worker-executor.js";
|
|
10
13
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
14
|
const __dirname = dirname(__filename);
|
|
12
15
|
const projectRoot = resolve(__dirname, "../../../");
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
timeoutMs: message.config.timeoutMs,
|
|
40
|
-
collectProvenance: message.config.collectProvenance,
|
|
41
|
-
});
|
|
42
|
-
// Execute the runs
|
|
43
|
-
const results = await executor.execute(suts, cases, () => ({}));
|
|
44
|
-
return {
|
|
45
|
-
results: results.results,
|
|
46
|
-
errors: results.errors,
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
// Listen for messages from parent thread
|
|
50
|
-
parentPort?.on("message", (data) => {
|
|
51
|
-
// Validate message structure
|
|
52
|
-
const message = data;
|
|
53
|
-
// Execute asynchronously without returning the promise
|
|
54
|
-
void (async () => {
|
|
55
|
-
try {
|
|
56
|
-
const result = await executeBatch(message);
|
|
57
|
-
parentPort?.postMessage({ type: "done", ...result });
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
parentPort?.postMessage({
|
|
61
|
-
type: "error",
|
|
62
|
-
error: error instanceof Error ? error.message : String(error),
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
})();
|
|
66
|
-
});
|
|
16
|
+
/**
|
|
17
|
+
* Real module loader implementation for production use.
|
|
18
|
+
*/
|
|
19
|
+
class RealModuleLoader {
|
|
20
|
+
async loadExecutor() {
|
|
21
|
+
return (await import(`${projectRoot}/dist/experiments/framework/executor/executor.js`));
|
|
22
|
+
}
|
|
23
|
+
async loadEvaluate() {
|
|
24
|
+
return (await import(`${projectRoot}/dist/cli-commands/evaluate.js`));
|
|
25
|
+
}
|
|
26
|
+
async loadRegistry() {
|
|
27
|
+
return (await import(`${projectRoot}/dist/experiments/framework/registry/index.js`));
|
|
28
|
+
}
|
|
29
|
+
async loadSuts() {
|
|
30
|
+
return (await import(`${projectRoot}/dist/experiments/framework/suts/index.js`));
|
|
31
|
+
}
|
|
32
|
+
async loadDatasets() {
|
|
33
|
+
return (await import(`${projectRoot}/dist/experiments/evaluation/fixtures/benchmark-datasets.js`));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Create executor with real dependencies and start listening
|
|
37
|
+
if (parentPort) {
|
|
38
|
+
const moduleLoader = new RealModuleLoader();
|
|
39
|
+
const executor = new WorkerExecutor(parentPort, moduleLoader, projectRoot);
|
|
40
|
+
executor.start();
|
|
41
|
+
}
|
|
67
42
|
//# sourceMappingURL=worker-entry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/executor/worker-entry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/executor/worker-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAON,cAAc,GACd,MAAM,sBAAsB,CAAC;AAE9B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,gBAAgB;IACd,KAAK,CAAC,YAAY;QACxB,OAAO,CAAC,MAAM,MAAM,CACnB,GAAG,WAAW,kDAAkD,CAChE,CAA+B,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,YAAY;QACxB,OAAO,CAAC,MAAM,MAAM,CACnB,GAAG,WAAW,gCAAgC,CAC9C,CAA+B,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,YAAY;QACxB,OAAO,CAAC,MAAM,MAAM,CACnB,GAAG,WAAW,+CAA+C,CAC7D,CAA+B,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,QAAQ;QACpB,OAAO,CAAC,MAAM,MAAM,CACnB,GAAG,WAAW,2CAA2C,CACzD,CAA2B,CAAC;IAC9B,CAAC;IAEM,KAAK,CAAC,YAAY;QACxB,OAAO,CAAC,MAAM,MAAM,CACnB,GAAG,WAAW,6DAA6D,CAC3E,CAA+B,CAAC;IAClC,CAAC;CACD;AAED,6DAA6D;AAC7D,IAAI,UAAU,EAAE,CAAC;IAChB,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAC3E,QAAQ,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC"}
|