gateproof 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -350
- package/dist/act.d.ts +45 -0
- package/dist/act.d.ts.map +1 -1
- package/dist/act.js +22 -0
- package/dist/act.js.map +1 -1
- package/dist/action-executors.d.ts +17 -0
- package/dist/action-executors.d.ts.map +1 -1
- package/dist/action-executors.js +60 -0
- package/dist/action-executors.js.map +1 -1
- package/dist/assert.d.ts +20 -0
- package/dist/assert.d.ts.map +1 -1
- package/dist/assert.js +32 -0
- package/dist/assert.js.map +1 -1
- package/dist/authority.d.ts +34 -0
- package/dist/authority.d.ts.map +1 -0
- package/dist/authority.js +141 -0
- package/dist/authority.js.map +1 -0
- package/dist/cli/gateproof.js +76 -0
- package/dist/cli/gateproof.js.map +1 -1
- package/dist/filepath-backend.d.ts +64 -0
- package/dist/filepath-backend.d.ts.map +1 -0
- package/dist/filepath-backend.js +126 -0
- package/dist/filepath-backend.js.map +1 -0
- package/dist/filepath-protocol.d.ts +214 -0
- package/dist/filepath-protocol.d.ts.map +1 -0
- package/dist/filepath-protocol.js +239 -0
- package/dist/filepath-protocol.js.map +1 -0
- package/dist/filepath-runtime.d.ts +100 -0
- package/dist/filepath-runtime.d.ts.map +1 -0
- package/dist/filepath-runtime.js +190 -0
- package/dist/filepath-runtime.js.map +1 -0
- package/dist/http-backend.d.ts +9 -0
- package/dist/http-backend.d.ts.map +1 -1
- package/dist/http-backend.js +50 -8
- package/dist/http-backend.js.map +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/prd/index.d.ts +2 -0
- package/dist/prd/index.d.ts.map +1 -1
- package/dist/prd/index.js +4 -0
- package/dist/prd/index.js.map +1 -1
- package/dist/prd/loop.d.ts +160 -0
- package/dist/prd/loop.d.ts.map +1 -0
- package/dist/prd/loop.js +462 -0
- package/dist/prd/loop.js.map +1 -0
- package/dist/prd/runner.d.ts +2 -5
- package/dist/prd/runner.d.ts.map +1 -1
- package/dist/prd/runner.js +154 -122
- package/dist/prd/runner.js.map +1 -1
- package/dist/prd/scope-defaults.d.ts +75 -0
- package/dist/prd/scope-defaults.d.ts.map +1 -0
- package/dist/prd/scope-defaults.js +235 -0
- package/dist/prd/scope-defaults.js.map +1 -0
- package/dist/prd/types.d.ts +79 -0
- package/dist/prd/types.d.ts.map +1 -1
- package/dist/report.d.ts +70 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +183 -0
- package/dist/report.js.map +1 -1
- package/package.json +10 -2
package/dist/prd/runner.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { resolve } from "path";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
2
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { serializeError } from "../report";
|
|
4
4
|
import { validateScope, getDiffStats } from "./scope-check";
|
|
5
|
+
import { flattenStoryTree, mergeAuthority } from "../authority";
|
|
5
6
|
/**
|
|
6
7
|
* Validates that all story dependencies exist and there are no cycles.
|
|
7
8
|
*/
|
|
@@ -52,6 +53,35 @@ function orderStories(stories) {
|
|
|
52
53
|
}
|
|
53
54
|
return out;
|
|
54
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Groups topologically-sorted stories into parallel "levels".
|
|
58
|
+
* Stories within a level have all their dependencies satisfied by prior levels,
|
|
59
|
+
* so they can execute concurrently.
|
|
60
|
+
*/
|
|
61
|
+
function buildLevels(stories) {
|
|
62
|
+
const ordered = orderStories(stories);
|
|
63
|
+
const levels = [];
|
|
64
|
+
const resolved = new Set();
|
|
65
|
+
while (resolved.size < ordered.length) {
|
|
66
|
+
const level = [];
|
|
67
|
+
for (const story of ordered) {
|
|
68
|
+
if (resolved.has(story.id))
|
|
69
|
+
continue;
|
|
70
|
+
const deps = story.dependsOn ?? [];
|
|
71
|
+
if (deps.every((d) => resolved.has(d))) {
|
|
72
|
+
level.push(story);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (level.length === 0) {
|
|
76
|
+
throw new Error("Unable to resolve remaining story dependencies");
|
|
77
|
+
}
|
|
78
|
+
levels.push(level);
|
|
79
|
+
for (const s of level) {
|
|
80
|
+
resolved.add(s.id);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return levels;
|
|
84
|
+
}
|
|
55
85
|
/**
|
|
56
86
|
* Loads default forbidden paths from .gateproof/scope.defaults.json
|
|
57
87
|
*/
|
|
@@ -67,141 +97,146 @@ function loadDefaultForbidden(cwd) {
|
|
|
67
97
|
}
|
|
68
98
|
}
|
|
69
99
|
/**
|
|
70
|
-
* Runs a
|
|
71
|
-
* Stops on first failure.
|
|
72
|
-
*
|
|
73
|
-
* @param options.reportPath - If provided, writes a structured JSON report to this path
|
|
74
|
-
* @param options.checkScope - If true, validates scope constraints against git diff
|
|
75
|
-
* @param options.baseRef - Git ref to compare against for scope checking (default: "HEAD" for local, "origin/main" for CI)
|
|
100
|
+
* Runs a single story gate and returns a typed outcome.
|
|
76
101
|
*/
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const violations = validateScope(story, diffStats, defaultForbidden);
|
|
90
|
-
if (violations.length > 0) {
|
|
91
|
-
const violation = violations[0];
|
|
92
|
-
storyError = {
|
|
93
|
-
name: "ScopeViolation",
|
|
94
|
-
message: violation.message,
|
|
95
|
-
tag: violation.category,
|
|
96
|
-
};
|
|
97
|
-
storyResults.push({
|
|
98
|
-
id: story.id,
|
|
99
|
-
title: story.title,
|
|
100
|
-
gateFile: story.gateFile,
|
|
101
|
-
status: "failed",
|
|
102
|
-
durationMs: Date.now() - storyStartTime,
|
|
103
|
-
error: storyError,
|
|
104
|
-
});
|
|
105
|
-
return {
|
|
106
|
-
success: false,
|
|
107
|
-
failedStory: story,
|
|
108
|
-
error: new Error(violation.message),
|
|
109
|
-
report: {
|
|
110
|
-
version: "1",
|
|
111
|
-
success: false,
|
|
112
|
-
stories: storyResults,
|
|
113
|
-
failedStory: {
|
|
114
|
-
id: story.id,
|
|
115
|
-
title: story.title,
|
|
116
|
-
gateFile: story.gateFile,
|
|
117
|
-
},
|
|
118
|
-
totalDurationMs: Date.now() - startTime,
|
|
119
|
-
},
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
const gatePath = resolve(cwd, story.gateFile);
|
|
124
|
-
const mod = await import(`file://${gatePath}`);
|
|
125
|
-
const run = mod.run;
|
|
126
|
-
if (typeof run !== "function") {
|
|
127
|
-
throw new Error(`Gate file must export "run" function: ${story.gateFile}`);
|
|
128
|
-
}
|
|
129
|
-
console.log(`\n--- ${story.id}: ${story.title}`);
|
|
130
|
-
const result = (await run());
|
|
131
|
-
const durationMs = Date.now() - storyStartTime;
|
|
132
|
-
if (result.status !== "success") {
|
|
133
|
-
storyError = result.error ? serializeError(result.error) : {
|
|
134
|
-
name: "GateFailed",
|
|
135
|
-
message: `Gate failed with status: ${result.status}`,
|
|
102
|
+
async function runStory(story, cwd, options) {
|
|
103
|
+
const storyStartTime = Date.now();
|
|
104
|
+
try {
|
|
105
|
+
if (options.checkScope && story.scope) {
|
|
106
|
+
const diffStats = getDiffStats(options.baseRef);
|
|
107
|
+
const violations = validateScope(story, diffStats, options.defaultForbidden);
|
|
108
|
+
if (violations.length > 0) {
|
|
109
|
+
const violation = violations[0];
|
|
110
|
+
const storyError = {
|
|
111
|
+
name: "ScopeViolation",
|
|
112
|
+
message: violation.message,
|
|
113
|
+
tag: violation.category,
|
|
136
114
|
};
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
durationMs,
|
|
143
|
-
error: storyError,
|
|
144
|
-
});
|
|
145
|
-
const report = {
|
|
146
|
-
version: "1",
|
|
147
|
-
success: false,
|
|
148
|
-
stories: storyResults,
|
|
149
|
-
failedStory: {
|
|
150
|
-
id: story.id,
|
|
151
|
-
title: story.title,
|
|
152
|
-
gateFile: story.gateFile,
|
|
115
|
+
return {
|
|
116
|
+
ok: false,
|
|
117
|
+
result: {
|
|
118
|
+
id: story.id, title: story.title, gateFile: story.gateFile,
|
|
119
|
+
status: "failed", durationMs: Date.now() - storyStartTime, error: storyError,
|
|
153
120
|
},
|
|
154
|
-
|
|
121
|
+
story,
|
|
122
|
+
error: new Error(violation.message),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const gatePath = resolve(cwd, story.gateFile);
|
|
127
|
+
const mod = await import(`file://${gatePath}`);
|
|
128
|
+
const run = mod.run;
|
|
129
|
+
if (typeof run !== "function") {
|
|
130
|
+
throw new Error(`Gate file must export "run" function: ${story.gateFile}`);
|
|
131
|
+
}
|
|
132
|
+
console.log(`\n--- ${story.id}: ${story.title}`);
|
|
133
|
+
const result = (await run());
|
|
134
|
+
const durationMs = Date.now() - storyStartTime;
|
|
135
|
+
// Check for positive signal if required
|
|
136
|
+
if (result.status === "success" && story.requirePositiveSignal) {
|
|
137
|
+
const evidence = result.evidence;
|
|
138
|
+
const hasPositiveSignal = (evidence?.actionsSeen && evidence.actionsSeen.length > 0) ||
|
|
139
|
+
(evidence?.stagesSeen && evidence.stagesSeen.length > 0);
|
|
140
|
+
if (!hasPositiveSignal) {
|
|
141
|
+
const storyError = {
|
|
142
|
+
name: "NoPositiveSignal",
|
|
143
|
+
message: `Story "${story.id}" requires positive signal but no actions or stages were observed`,
|
|
155
144
|
};
|
|
156
|
-
if (options.reportPath) {
|
|
157
|
-
const { writeFileSync } = await import("node:fs");
|
|
158
|
-
writeFileSync(options.reportPath, JSON.stringify(report, null, 2));
|
|
159
|
-
}
|
|
160
145
|
return {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
146
|
+
ok: false,
|
|
147
|
+
result: {
|
|
148
|
+
id: story.id, title: story.title, gateFile: story.gateFile,
|
|
149
|
+
status: "failed", durationMs, error: storyError,
|
|
150
|
+
},
|
|
151
|
+
story,
|
|
152
|
+
error: new Error(`No positive signal observed for story "${story.id}"`),
|
|
165
153
|
};
|
|
166
154
|
}
|
|
167
|
-
storyResults.push({
|
|
168
|
-
id: story.id,
|
|
169
|
-
title: story.title,
|
|
170
|
-
gateFile: story.gateFile,
|
|
171
|
-
status: "success",
|
|
172
|
-
durationMs,
|
|
173
|
-
});
|
|
174
155
|
}
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
156
|
+
if (result.status !== "success") {
|
|
157
|
+
const storyError = result.error ? serializeError(result.error) : {
|
|
158
|
+
name: "GateFailed",
|
|
159
|
+
message: `Gate failed with status: ${result.status}`,
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
ok: false,
|
|
163
|
+
result: {
|
|
164
|
+
id: story.id, title: story.title, gateFile: story.gateFile,
|
|
165
|
+
status: result.status, durationMs, error: storyError,
|
|
166
|
+
},
|
|
167
|
+
story,
|
|
168
|
+
error: new Error(`Gate failed with status: ${result.status}`),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
ok: true,
|
|
173
|
+
result: {
|
|
174
|
+
id: story.id, title: story.title, gateFile: story.gateFile,
|
|
175
|
+
status: "success", durationMs,
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
const durationMs = Date.now() - storyStartTime;
|
|
181
|
+
return {
|
|
182
|
+
ok: false,
|
|
183
|
+
result: {
|
|
184
|
+
id: story.id, title: story.title, gateFile: story.gateFile,
|
|
185
|
+
status: "failed", durationMs, error: serializeError(error),
|
|
186
|
+
},
|
|
187
|
+
story,
|
|
188
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function writeReport(reportPath, report) {
|
|
193
|
+
if (reportPath) {
|
|
194
|
+
writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Runs a PRD by executing story gates in dependency order.
|
|
199
|
+
* Independent stories (no mutual dependencies) within a level run concurrently.
|
|
200
|
+
* Stops on first failure within a level.
|
|
201
|
+
*/
|
|
202
|
+
export async function runPrd(prd, cwd = process.cwd(), options = {}) {
|
|
203
|
+
// Flatten hierarchical stories (children[] → flat list with parentId)
|
|
204
|
+
// and merge authority policies from PRD defaults
|
|
205
|
+
const flatStories = flattenStoryTree(prd.stories).map((story) => ({
|
|
206
|
+
...story,
|
|
207
|
+
authority: mergeAuthority(story.authority, prd.defaultAuthority),
|
|
208
|
+
}));
|
|
209
|
+
const levels = buildLevels(flatStories);
|
|
210
|
+
const storyResults = [];
|
|
211
|
+
const startTime = Date.now();
|
|
212
|
+
const defaultForbidden = loadDefaultForbidden(cwd);
|
|
213
|
+
const baseRef = options.baseRef ?? (process.env.CI ? "origin/main" : "HEAD");
|
|
214
|
+
for (const level of levels) {
|
|
215
|
+
// Run all stories in this level concurrently
|
|
216
|
+
const outcomes = await Promise.all(level.map((story) => runStory(story, cwd, { checkScope: options.checkScope, baseRef, defaultForbidden })));
|
|
217
|
+
// Collect results from this level
|
|
218
|
+
for (const outcome of outcomes) {
|
|
219
|
+
storyResults.push(outcome.result);
|
|
220
|
+
}
|
|
221
|
+
// Check for any failures in this level
|
|
222
|
+
const firstFailure = outcomes.find((o) => !o.ok);
|
|
223
|
+
if (firstFailure && !firstFailure.ok) {
|
|
186
224
|
const report = {
|
|
187
225
|
version: "1",
|
|
188
226
|
success: false,
|
|
189
227
|
stories: storyResults,
|
|
190
228
|
failedStory: {
|
|
191
|
-
id: story.id,
|
|
192
|
-
title: story.title,
|
|
193
|
-
gateFile: story.gateFile,
|
|
229
|
+
id: firstFailure.story.id,
|
|
230
|
+
title: firstFailure.story.title,
|
|
231
|
+
gateFile: firstFailure.story.gateFile,
|
|
194
232
|
},
|
|
195
233
|
totalDurationMs: Date.now() - startTime,
|
|
196
234
|
};
|
|
197
|
-
|
|
198
|
-
const { writeFileSync } = await import("node:fs");
|
|
199
|
-
writeFileSync(options.reportPath, JSON.stringify(report, null, 2));
|
|
200
|
-
}
|
|
235
|
+
writeReport(options.reportPath, report);
|
|
201
236
|
return {
|
|
202
237
|
success: false,
|
|
203
|
-
failedStory: story,
|
|
204
|
-
error: error
|
|
238
|
+
failedStory: firstFailure.story,
|
|
239
|
+
error: firstFailure.error,
|
|
205
240
|
report,
|
|
206
241
|
};
|
|
207
242
|
}
|
|
@@ -212,10 +247,7 @@ export async function runPrd(prd, cwd = process.cwd(), options = {}) {
|
|
|
212
247
|
stories: storyResults,
|
|
213
248
|
totalDurationMs: Date.now() - startTime,
|
|
214
249
|
};
|
|
215
|
-
|
|
216
|
-
const { writeFileSync } = await import("node:fs");
|
|
217
|
-
writeFileSync(options.reportPath, JSON.stringify(report, null, 2));
|
|
218
|
-
}
|
|
250
|
+
writeReport(options.reportPath, report);
|
|
219
251
|
return { success: true, report };
|
|
220
252
|
}
|
|
221
253
|
//# sourceMappingURL=runner.js.map
|
package/dist/prd/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/prd/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/prd/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default scope guards for PRD stories.
|
|
3
|
+
*
|
|
4
|
+
* These provide sensible defaults for allowedPaths and forbiddenPaths
|
|
5
|
+
* to prevent agents from modifying sensitive areas by accident.
|
|
6
|
+
*
|
|
7
|
+
* All defaults are opt-in and can be overridden by explicit scope configuration.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Default forbidden paths that should never be modified by an agent.
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFAULT_FORBIDDEN_PATHS: string[];
|
|
13
|
+
/**
|
|
14
|
+
* Common source directory patterns to auto-detect.
|
|
15
|
+
*/
|
|
16
|
+
export declare const COMMON_SRC_PATTERNS: string[];
|
|
17
|
+
/**
|
|
18
|
+
* Configuration paths that should typically be allowed but carefully.
|
|
19
|
+
*/
|
|
20
|
+
export declare const CONFIG_PATHS: string[];
|
|
21
|
+
export interface InferredScopeDefaults {
|
|
22
|
+
/** Detected source directories that likely contain code to modify */
|
|
23
|
+
allowedPaths: string[];
|
|
24
|
+
/** Paths that should never be modified */
|
|
25
|
+
forbiddenPaths: string[];
|
|
26
|
+
/** Whether a monorepo structure was detected */
|
|
27
|
+
isMonorepo: boolean;
|
|
28
|
+
/** Root directories of detected workspaces (if monorepo) */
|
|
29
|
+
workspaces: string[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Infers sensible scope defaults based on project structure.
|
|
33
|
+
*
|
|
34
|
+
* This function analyzes the project to determine:
|
|
35
|
+
* - Which directories contain source code (allowedPaths)
|
|
36
|
+
* - Which directories should never be modified (forbiddenPaths)
|
|
37
|
+
* - Whether this is a monorepo
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const defaults = inferScopeDefaults(process.cwd());
|
|
42
|
+
* console.log(defaults.allowedPaths);
|
|
43
|
+
* // ["src/", "app/", "components/"]
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function inferScopeDefaults(cwd?: string): InferredScopeDefaults;
|
|
47
|
+
/**
|
|
48
|
+
* Loads custom scope defaults from .gateproof/scope.defaults.json
|
|
49
|
+
*/
|
|
50
|
+
export declare function loadCustomScopeDefaults(cwd?: string): Partial<InferredScopeDefaults> | null;
|
|
51
|
+
/**
|
|
52
|
+
* Merges inferred defaults with custom overrides.
|
|
53
|
+
*/
|
|
54
|
+
export declare function getScopeDefaults(cwd?: string): InferredScopeDefaults;
|
|
55
|
+
/**
|
|
56
|
+
* Applies default scope to a story if no explicit scope is provided.
|
|
57
|
+
* Returns a new story object with scope defaults applied.
|
|
58
|
+
*
|
|
59
|
+
* Note: This is opt-in - stories without scope are not modified unless
|
|
60
|
+
* applyDefaults is called.
|
|
61
|
+
*/
|
|
62
|
+
export declare function applyDefaultScope<TId extends string>(story: {
|
|
63
|
+
id: TId;
|
|
64
|
+
scope?: {
|
|
65
|
+
allowedPaths?: string[];
|
|
66
|
+
forbiddenPaths?: string[];
|
|
67
|
+
};
|
|
68
|
+
}, defaults: InferredScopeDefaults): {
|
|
69
|
+
id: TId;
|
|
70
|
+
scope: {
|
|
71
|
+
allowedPaths: string[];
|
|
72
|
+
forbiddenPaths: string[];
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=scope-defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-defaults.d.ts","sourceRoot":"","sources":["../../src/prd/scope-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;GAEG;AACH,eAAO,MAAM,uBAAuB,UAenC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,UAW/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,UAWxB,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,0CAA0C;IAC1C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gDAAgD;IAChD,UAAU,EAAE,OAAO,CAAC;IACpB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAuFD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAsB,GAAG,qBAAqB,CAmCrF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAU1G;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAsB,GAAG,qBAAqB,CAYnF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,SAAS,MAAM,EAClD,KAAK,EAAE;IAAE,EAAE,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;CAAE,EAClF,QAAQ,EAAE,qBAAqB,GAC9B;IAAE,EAAE,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;CAAE,CAW1E"}
|