musubix3 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/.github/plugin/marketplace.json +16 -0
- package/.github/skills/sdd-change/SKILL.md +78 -0
- package/.github/skills/sdd-design/SKILL.md +26 -0
- package/.github/skills/sdd-formal-codegraph/SKILL.md +53 -0
- package/.github/skills/sdd-implementation/SKILL.md +54 -0
- package/.github/skills/sdd-knowledge/SKILL.md +24 -0
- package/.github/skills/sdd-quality/SKILL.md +69 -0
- package/.github/skills/sdd-requirements/SKILL.md +42 -0
- package/.github/skills/sdd-traceability/SKILL.md +28 -0
- package/CHANGELOG.md +152 -0
- package/LICENSE +21 -0
- package/README-ja.md +573 -0
- package/README.md +639 -0
- package/assets/ADR-0001.md +15 -0
- package/assets/constitution.md +17 -0
- package/assets/design.md +13 -0
- package/assets/requirements.md +15 -0
- package/dist/packages/analysis/src/adapters.d.ts +12 -0
- package/dist/packages/analysis/src/adapters.js +167 -0
- package/dist/packages/analysis/src/adapters.js.map +1 -0
- package/dist/packages/analysis/src/attestation.d.ts +50 -0
- package/dist/packages/analysis/src/attestation.js +474 -0
- package/dist/packages/analysis/src/attestation.js.map +1 -0
- package/dist/packages/analysis/src/change.d.ts +53 -0
- package/dist/packages/analysis/src/change.js +337 -0
- package/dist/packages/analysis/src/change.js.map +1 -0
- package/dist/packages/analysis/src/config.d.ts +104 -0
- package/dist/packages/analysis/src/config.js +456 -0
- package/dist/packages/analysis/src/config.js.map +1 -0
- package/dist/packages/analysis/src/files.d.ts +13 -0
- package/dist/packages/analysis/src/files.js +103 -0
- package/dist/packages/analysis/src/files.js.map +1 -0
- package/dist/packages/analysis/src/formal.d.ts +82 -0
- package/dist/packages/analysis/src/formal.js +579 -0
- package/dist/packages/analysis/src/formal.js.map +1 -0
- package/dist/packages/analysis/src/gate.d.ts +56 -0
- package/dist/packages/analysis/src/gate.js +484 -0
- package/dist/packages/analysis/src/gate.js.map +1 -0
- package/dist/packages/analysis/src/graph.d.ts +52 -0
- package/dist/packages/analysis/src/graph.js +737 -0
- package/dist/packages/analysis/src/graph.js.map +1 -0
- package/dist/packages/analysis/src/index.d.ts +17 -0
- package/dist/packages/analysis/src/index.js +18 -0
- package/dist/packages/analysis/src/index.js.map +1 -0
- package/dist/packages/analysis/src/knowledge.d.ts +29 -0
- package/dist/packages/analysis/src/knowledge.js +95 -0
- package/dist/packages/analysis/src/knowledge.js.map +1 -0
- package/dist/packages/analysis/src/model-correspondence.d.ts +45 -0
- package/dist/packages/analysis/src/model-correspondence.js +310 -0
- package/dist/packages/analysis/src/model-correspondence.js.map +1 -0
- package/dist/packages/analysis/src/mutation.d.ts +54 -0
- package/dist/packages/analysis/src/mutation.js +299 -0
- package/dist/packages/analysis/src/mutation.js.map +1 -0
- package/dist/packages/analysis/src/order.d.ts +23 -0
- package/dist/packages/analysis/src/order.js +89 -0
- package/dist/packages/analysis/src/order.js.map +1 -0
- package/dist/packages/analysis/src/performance.d.ts +65 -0
- package/dist/packages/analysis/src/performance.js +319 -0
- package/dist/packages/analysis/src/performance.js.map +1 -0
- package/dist/packages/analysis/src/process.d.ts +14 -0
- package/dist/packages/analysis/src/process.js +79 -0
- package/dist/packages/analysis/src/process.js.map +1 -0
- package/dist/packages/analysis/src/tdd.d.ts +65 -0
- package/dist/packages/analysis/src/tdd.js +353 -0
- package/dist/packages/analysis/src/tdd.js.map +1 -0
- package/dist/packages/analysis/src/trace.d.ts +45 -0
- package/dist/packages/analysis/src/trace.js +242 -0
- package/dist/packages/analysis/src/trace.js.map +1 -0
- package/dist/packages/analysis/src/workflow.d.ts +59 -0
- package/dist/packages/analysis/src/workflow.js +405 -0
- package/dist/packages/analysis/src/workflow.js.map +1 -0
- package/dist/packages/cli/src/install.d.ts +15 -0
- package/dist/packages/cli/src/install.js +71 -0
- package/dist/packages/cli/src/install.js.map +1 -0
- package/dist/packages/cli/src/main.d.ts +3 -0
- package/dist/packages/cli/src/main.js +364 -0
- package/dist/packages/cli/src/main.js.map +1 -0
- package/dist/packages/domain/src/constitution.d.ts +3 -0
- package/dist/packages/domain/src/constitution.js +46 -0
- package/dist/packages/domain/src/constitution.js.map +1 -0
- package/dist/packages/domain/src/design.d.ts +8 -0
- package/dist/packages/domain/src/design.js +59 -0
- package/dist/packages/domain/src/design.js.map +1 -0
- package/dist/packages/domain/src/index.d.ts +5 -0
- package/dist/packages/domain/src/index.js +6 -0
- package/dist/packages/domain/src/index.js.map +1 -0
- package/dist/packages/domain/src/markdown.d.ts +16 -0
- package/dist/packages/domain/src/markdown.js +72 -0
- package/dist/packages/domain/src/markdown.js.map +1 -0
- package/dist/packages/domain/src/requirements.d.ts +3 -0
- package/dist/packages/domain/src/requirements.js +195 -0
- package/dist/packages/domain/src/requirements.js.map +1 -0
- package/dist/packages/domain/src/types.d.ts +100 -0
- package/dist/packages/domain/src/types.js +14 -0
- package/dist/packages/domain/src/types.js.map +1 -0
- package/package.json +59 -0
- package/plugin.json +9 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import { error } from '../../domain/src/index.js';
|
|
2
|
+
import { exists, readText, within } from './files.js';
|
|
3
|
+
export const checkNames = ['requirements', 'design', 'constitution', 'trace', 'graph', 'formal', 'model-correspondence', 'mutation', 'workflow', 'tdd', 'change-history', 'change-completeness', 'performance', 'attestation', 'test-identities', 'commands'];
|
|
4
|
+
export const defaultConfig = {
|
|
5
|
+
schemaVersion: 1,
|
|
6
|
+
language: 'auto',
|
|
7
|
+
commands: [],
|
|
8
|
+
requiredChecks: ['requirements', 'design', 'constitution', 'trace', 'graph', 'commands'],
|
|
9
|
+
thresholds: { design: 1, implementation: 1, tests: 1 },
|
|
10
|
+
architecture: { forbidCycles: true, rules: [] },
|
|
11
|
+
codeGraph: { mode: 'compatible' },
|
|
12
|
+
formal: { solver: 'none', minModeledFraction: 0, timeoutMs: 12_000 },
|
|
13
|
+
mutation: { mode: 'compatible' },
|
|
14
|
+
workflow: { mode: 'compatible', maxAgeSeconds: 3600, maxFutureSkewSeconds: 60 },
|
|
15
|
+
attestation: {
|
|
16
|
+
mode: 'local',
|
|
17
|
+
maxAgeSeconds: 3600,
|
|
18
|
+
maxFutureSkewSeconds: 60,
|
|
19
|
+
trustedPublicKeys: [],
|
|
20
|
+
githubOidc: { mode: 'off' },
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
export const defaultPolicyBaseline = {
|
|
24
|
+
schemaVersion: 1,
|
|
25
|
+
requiredChecks: [...defaultConfig.requiredChecks],
|
|
26
|
+
thresholds: { ...defaultConfig.thresholds },
|
|
27
|
+
architecture: { forbidCycles: defaultConfig.architecture.forbidCycles, rules: [...defaultConfig.architecture.rules] },
|
|
28
|
+
codeGraph: { ...defaultConfig.codeGraph },
|
|
29
|
+
formal: { solver: defaultConfig.formal.solver, minModeledFraction: defaultConfig.formal.minModeledFraction },
|
|
30
|
+
mutation: { ...defaultConfig.mutation },
|
|
31
|
+
workflow: { ...defaultConfig.workflow },
|
|
32
|
+
attestation: {
|
|
33
|
+
...defaultConfig.attestation,
|
|
34
|
+
trustedPublicKeys: [...defaultConfig.attestation.trustedPublicKeys],
|
|
35
|
+
githubOidc: { ...defaultConfig.attestation.githubOidc },
|
|
36
|
+
},
|
|
37
|
+
requiredCommands: [],
|
|
38
|
+
};
|
|
39
|
+
function object(value, location) {
|
|
40
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
41
|
+
throw new Error(`${location} must be an object.`);
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
function keys(value, allowed, location) {
|
|
45
|
+
for (const key of Object.keys(value)) {
|
|
46
|
+
if (!allowed.includes(key))
|
|
47
|
+
throw new Error(`Unknown config key ${location}.${key}.`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function strings(value, location, allowEmpty = false) {
|
|
51
|
+
if (!Array.isArray(value) || !value.every((s) => typeof s === 'string' && !s.includes('\0') && (allowEmpty || s.length > 0)))
|
|
52
|
+
throw new Error(`${location} must be an array of ${allowEmpty ? '' : 'nonempty '}strings without NUL bytes.`);
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
function optional(value, fallback) {
|
|
56
|
+
return value === undefined ? fallback : value;
|
|
57
|
+
}
|
|
58
|
+
export function parseConfig(input) {
|
|
59
|
+
const value = object(input, 'config');
|
|
60
|
+
keys(value, ['schemaVersion', 'language', 'commands', 'requiredChecks', 'thresholds', 'architecture', 'codeGraph', 'formal', 'mutation', 'workflow', 'attestation'], 'config');
|
|
61
|
+
if (value.schemaVersion !== 1)
|
|
62
|
+
throw new Error('Unsupported config schemaVersion; expected 1.');
|
|
63
|
+
const language = optional(value.language, 'auto');
|
|
64
|
+
if (!['auto', 'en', 'ja'].includes(String(language)))
|
|
65
|
+
throw new Error('language must be auto, en, or ja.');
|
|
66
|
+
const requiredChecks = strings(optional(value.requiredChecks, defaultConfig.requiredChecks), 'requiredChecks');
|
|
67
|
+
if (requiredChecks.some((s) => !checkNames.includes(s)))
|
|
68
|
+
throw new Error('Unknown required check.');
|
|
69
|
+
const thresholds = { ...defaultConfig.thresholds };
|
|
70
|
+
if (value.thresholds !== undefined) {
|
|
71
|
+
const raw = object(value.thresholds, 'thresholds');
|
|
72
|
+
keys(raw, Object.keys(thresholds), 'thresholds');
|
|
73
|
+
for (const key of Object.keys(thresholds)) {
|
|
74
|
+
const threshold = optional(raw[key], thresholds[key]);
|
|
75
|
+
if (typeof threshold !== 'number' || !Number.isFinite(threshold) || threshold < 0 || threshold > 1)
|
|
76
|
+
throw new Error(`thresholds.${key} must be in [0, 1].`);
|
|
77
|
+
thresholds[key] = threshold;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const rawCommands = optional(value.commands, []);
|
|
81
|
+
if (!Array.isArray(rawCommands))
|
|
82
|
+
throw new Error('commands must be an array.');
|
|
83
|
+
const commands = rawCommands.map((raw) => {
|
|
84
|
+
const c = object(raw, 'command');
|
|
85
|
+
keys(c, ['name', 'command', 'args', 'tddArgs', 'tddReport', 'testReport', 'mutationReport', 'adapter', 'required', 'timeoutMs'], 'command');
|
|
86
|
+
if (typeof c.name !== 'string' || !/^[a-zA-Z0-9_-]+$/.test(c.name))
|
|
87
|
+
throw new Error('Command name must be a simple nonempty identifier.');
|
|
88
|
+
if (typeof c.command !== 'string' || !c.command.trim() || c.command.includes('\0'))
|
|
89
|
+
throw new Error('Command executable must be nonempty.');
|
|
90
|
+
if (c.required !== undefined && typeof c.required !== 'boolean')
|
|
91
|
+
throw new Error('command.required must be boolean.');
|
|
92
|
+
if (c.adapter !== undefined && !['vitest', 'jest', 'pytest', 'go-test', 'cargo', 'junit'].includes(String(c.adapter))) {
|
|
93
|
+
throw new Error('command.adapter must be vitest, jest, pytest, go-test, cargo, or junit.');
|
|
94
|
+
}
|
|
95
|
+
const timeoutMs = optional(c.timeoutMs, 120_000);
|
|
96
|
+
if (typeof timeoutMs !== 'number' || !Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 3_600_000)
|
|
97
|
+
throw new Error('Command timeoutMs must be 1..3600000.');
|
|
98
|
+
const tddArgs = c.tddArgs === undefined ? undefined : strings(c.tddArgs, 'command.tddArgs', true);
|
|
99
|
+
if (tddArgs && !tddArgs.some((arg) => arg.includes('{testId}') || arg.includes('{testPath}'))) {
|
|
100
|
+
throw new Error('command.tddArgs must contain {testId} or {testPath}.');
|
|
101
|
+
}
|
|
102
|
+
let tddReport;
|
|
103
|
+
if (c.tddReport !== undefined) {
|
|
104
|
+
const report = object(c.tddReport, 'command.tddReport');
|
|
105
|
+
keys(report, ['format', 'path'], 'command.tddReport');
|
|
106
|
+
if (report.format !== 'musubix-json')
|
|
107
|
+
throw new Error('command.tddReport.format must be musubix-json.');
|
|
108
|
+
if (typeof report.path !== 'string' || !report.path || report.path.includes('\0') || !report.path.includes('{testId}')) {
|
|
109
|
+
throw new Error('command.tddReport.path must be a nonempty relative path containing {testId}.');
|
|
110
|
+
}
|
|
111
|
+
if (report.path.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(report.path))
|
|
112
|
+
throw new Error('command.tddReport.path must be relative.');
|
|
113
|
+
tddReport = { format: 'musubix-json', path: report.path };
|
|
114
|
+
}
|
|
115
|
+
if (!c.adapter && (tddArgs === undefined) !== (tddReport === undefined)) {
|
|
116
|
+
throw new Error('command.tddArgs and command.tddReport must be configured together.');
|
|
117
|
+
}
|
|
118
|
+
let testReport;
|
|
119
|
+
if (c.testReport !== undefined) {
|
|
120
|
+
const report = object(c.testReport, 'command.testReport');
|
|
121
|
+
keys(report, ['format', 'path'], 'command.testReport');
|
|
122
|
+
if (report.format !== 'musubix-json')
|
|
123
|
+
throw new Error('command.testReport.format must be musubix-json.');
|
|
124
|
+
if (typeof report.path !== 'string' || !report.path || report.path.includes('\0') || report.path.includes('{testId}')) {
|
|
125
|
+
throw new Error('command.testReport.path must be a nonempty aggregate report path without {testId}.');
|
|
126
|
+
}
|
|
127
|
+
if (report.path.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(report.path))
|
|
128
|
+
throw new Error('command.testReport.path must be relative.');
|
|
129
|
+
testReport = { format: 'musubix-json', path: report.path };
|
|
130
|
+
}
|
|
131
|
+
let mutationReport;
|
|
132
|
+
if (c.mutationReport !== undefined) {
|
|
133
|
+
const report = object(c.mutationReport, 'command.mutationReport');
|
|
134
|
+
keys(report, ['format', 'path'], 'command.mutationReport');
|
|
135
|
+
if (report.format !== 'musubix-mutation-json') {
|
|
136
|
+
throw new Error('command.mutationReport.format must be musubix-mutation-json.');
|
|
137
|
+
}
|
|
138
|
+
if (typeof report.path !== 'string' || !report.path || report.path.includes('\0')
|
|
139
|
+
|| report.path.includes('{testId}') || report.path.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(report.path)) {
|
|
140
|
+
throw new Error('command.mutationReport.path must be a nonempty relative aggregate report path.');
|
|
141
|
+
}
|
|
142
|
+
mutationReport = { format: 'musubix-mutation-json', path: report.path };
|
|
143
|
+
}
|
|
144
|
+
if (mutationReport && (testReport || c.adapter)) {
|
|
145
|
+
throw new Error('command.mutationReport cannot be combined with testReport or adapter.');
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
name: c.name,
|
|
149
|
+
command: c.command,
|
|
150
|
+
args: strings(optional(c.args, []), 'command.args', true),
|
|
151
|
+
...(tddArgs ? { tddArgs } : {}),
|
|
152
|
+
...(tddReport ? { tddReport } : {}),
|
|
153
|
+
...(testReport ? { testReport } : {}),
|
|
154
|
+
...(mutationReport ? { mutationReport } : {}),
|
|
155
|
+
...(c.adapter ? { adapter: c.adapter } : {}),
|
|
156
|
+
required: c.required !== false,
|
|
157
|
+
timeoutMs,
|
|
158
|
+
};
|
|
159
|
+
});
|
|
160
|
+
if (new Set(commands.map((c) => c.name)).size !== commands.length)
|
|
161
|
+
throw new Error('Command names must be unique.');
|
|
162
|
+
const architecture = object(optional(value.architecture, {}), 'architecture');
|
|
163
|
+
keys(architecture, ['forbidCycles', 'rules'], 'architecture');
|
|
164
|
+
if (architecture.forbidCycles !== undefined && typeof architecture.forbidCycles !== 'boolean')
|
|
165
|
+
throw new Error('architecture.forbidCycles must be boolean.');
|
|
166
|
+
const rawRules = optional(architecture.rules, []);
|
|
167
|
+
if (!Array.isArray(rawRules))
|
|
168
|
+
throw new Error('architecture.rules must be an array.');
|
|
169
|
+
const rules = rawRules.map((raw) => {
|
|
170
|
+
const r = object(raw, 'architecture rule');
|
|
171
|
+
keys(r, ['name', 'from', 'disallow'], 'architecture rule');
|
|
172
|
+
if (typeof r.name !== 'string' || !r.name || typeof r.from !== 'string' || !r.from)
|
|
173
|
+
throw new Error('Architecture rules need name and from glob.');
|
|
174
|
+
return { name: r.name, from: r.from, disallow: strings(r.disallow, 'rule.disallow') };
|
|
175
|
+
});
|
|
176
|
+
const rawCodeGraph = object(optional(value.codeGraph, {}), 'codeGraph');
|
|
177
|
+
keys(rawCodeGraph, ['mode'], 'codeGraph');
|
|
178
|
+
const codeGraphMode = optional(rawCodeGraph.mode, defaultConfig.codeGraph.mode);
|
|
179
|
+
if (!['compatible', 'strict'].includes(String(codeGraphMode))) {
|
|
180
|
+
throw new Error('codeGraph.mode must be compatible or strict.');
|
|
181
|
+
}
|
|
182
|
+
const rawFormal = object(optional(value.formal, {}), 'formal');
|
|
183
|
+
keys(rawFormal, ['solver', 'minModeledFraction', 'timeoutMs'], 'formal');
|
|
184
|
+
const solver = optional(rawFormal.solver, defaultConfig.formal.solver);
|
|
185
|
+
if (!['auto', 'none', 'z3', 'lean'].includes(String(solver)))
|
|
186
|
+
throw new Error('formal.solver must be auto, none, z3, or lean.');
|
|
187
|
+
const minModeledFraction = optional(rawFormal.minModeledFraction, defaultConfig.formal.minModeledFraction);
|
|
188
|
+
if (typeof minModeledFraction !== 'number' || !Number.isFinite(minModeledFraction) || minModeledFraction < 0 || minModeledFraction > 1) {
|
|
189
|
+
throw new Error('formal.minModeledFraction must be in [0, 1].');
|
|
190
|
+
}
|
|
191
|
+
const formalTimeoutMs = optional(rawFormal.timeoutMs, defaultConfig.formal.timeoutMs);
|
|
192
|
+
if (typeof formalTimeoutMs !== 'number' || !Number.isInteger(formalTimeoutMs) || formalTimeoutMs < 100 || formalTimeoutMs > 300_000) {
|
|
193
|
+
throw new Error('formal.timeoutMs must be 100..300000.');
|
|
194
|
+
}
|
|
195
|
+
const rawMutation = object(optional(value.mutation, {}), 'mutation');
|
|
196
|
+
keys(rawMutation, ['mode'], 'mutation');
|
|
197
|
+
const mutationMode = optional(rawMutation.mode, defaultConfig.mutation.mode);
|
|
198
|
+
if (!['compatible', 'strict'].includes(String(mutationMode))) {
|
|
199
|
+
throw new Error('mutation.mode must be compatible or strict.');
|
|
200
|
+
}
|
|
201
|
+
const rawWorkflow = object(optional(value.workflow, {}), 'workflow');
|
|
202
|
+
keys(rawWorkflow, ['mode', 'expectedSessionId', 'maxAgeSeconds', 'maxFutureSkewSeconds'], 'workflow');
|
|
203
|
+
const workflowMode = optional(rawWorkflow.mode, defaultConfig.workflow.mode);
|
|
204
|
+
if (!['compatible', 'strict'].includes(String(workflowMode))) {
|
|
205
|
+
throw new Error('workflow.mode must be compatible or strict.');
|
|
206
|
+
}
|
|
207
|
+
if (rawWorkflow.expectedSessionId !== undefined
|
|
208
|
+
&& (typeof rawWorkflow.expectedSessionId !== 'string'
|
|
209
|
+
|| !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(rawWorkflow.expectedSessionId))) {
|
|
210
|
+
throw new Error('workflow.expectedSessionId must be a UUID.');
|
|
211
|
+
}
|
|
212
|
+
if (rawWorkflow.expectedSessionId !== undefined && workflowMode !== 'strict') {
|
|
213
|
+
throw new Error('workflow.expectedSessionId requires workflow.mode strict.');
|
|
214
|
+
}
|
|
215
|
+
const workflowMaxAgeSeconds = optional(rawWorkflow.maxAgeSeconds, defaultConfig.workflow.maxAgeSeconds);
|
|
216
|
+
if (typeof workflowMaxAgeSeconds !== 'number' || !Number.isInteger(workflowMaxAgeSeconds)
|
|
217
|
+
|| workflowMaxAgeSeconds < 1 || workflowMaxAgeSeconds > 604_800) {
|
|
218
|
+
throw new Error('workflow.maxAgeSeconds must be 1..604800.');
|
|
219
|
+
}
|
|
220
|
+
const workflowMaxFutureSkewSeconds = optional(rawWorkflow.maxFutureSkewSeconds, defaultConfig.workflow.maxFutureSkewSeconds);
|
|
221
|
+
if (typeof workflowMaxFutureSkewSeconds !== 'number' || !Number.isInteger(workflowMaxFutureSkewSeconds)
|
|
222
|
+
|| workflowMaxFutureSkewSeconds < 0 || workflowMaxFutureSkewSeconds > 600) {
|
|
223
|
+
throw new Error('workflow.maxFutureSkewSeconds must be 0..600.');
|
|
224
|
+
}
|
|
225
|
+
const rawAttestation = object(optional(value.attestation, {}), 'attestation');
|
|
226
|
+
keys(rawAttestation, [
|
|
227
|
+
'mode', 'repository', 'maxAgeSeconds', 'maxFutureSkewSeconds', 'trustedPublicKeys', 'githubOidc',
|
|
228
|
+
], 'attestation');
|
|
229
|
+
const mode = optional(rawAttestation.mode, defaultConfig.attestation.mode);
|
|
230
|
+
if (!['off', 'local', 'ci-required'].includes(String(mode)))
|
|
231
|
+
throw new Error('attestation.mode must be off, local, or ci-required.');
|
|
232
|
+
if (rawAttestation.repository !== undefined && (typeof rawAttestation.repository !== 'string' || !rawAttestation.repository.trim())) {
|
|
233
|
+
throw new Error('attestation.repository must be a nonempty string.');
|
|
234
|
+
}
|
|
235
|
+
const maxAgeSeconds = optional(rawAttestation.maxAgeSeconds, defaultConfig.attestation.maxAgeSeconds);
|
|
236
|
+
if (typeof maxAgeSeconds !== 'number' || !Number.isInteger(maxAgeSeconds) || maxAgeSeconds < 1 || maxAgeSeconds > 604_800) {
|
|
237
|
+
throw new Error('attestation.maxAgeSeconds must be 1..604800.');
|
|
238
|
+
}
|
|
239
|
+
const maxFutureSkewSeconds = optional(rawAttestation.maxFutureSkewSeconds, defaultConfig.attestation.maxFutureSkewSeconds);
|
|
240
|
+
if (typeof maxFutureSkewSeconds !== 'number' || !Number.isInteger(maxFutureSkewSeconds)
|
|
241
|
+
|| maxFutureSkewSeconds < 0 || maxFutureSkewSeconds > 600) {
|
|
242
|
+
throw new Error('attestation.maxFutureSkewSeconds must be 0..600.');
|
|
243
|
+
}
|
|
244
|
+
const rawKeys = optional(rawAttestation.trustedPublicKeys, []);
|
|
245
|
+
if (!Array.isArray(rawKeys))
|
|
246
|
+
throw new Error('attestation.trustedPublicKeys must be an array.');
|
|
247
|
+
const trustedPublicKeys = rawKeys.map((raw) => {
|
|
248
|
+
const key = object(raw, 'attestation public key');
|
|
249
|
+
keys(key, ['id', 'publicKey'], 'attestation public key');
|
|
250
|
+
if (typeof key.id !== 'string' || !/^[A-Za-z0-9._-]+$/.test(key.id)
|
|
251
|
+
|| typeof key.publicKey !== 'string' || !key.publicKey.includes('BEGIN PUBLIC KEY')) {
|
|
252
|
+
throw new Error('Attestation keys need a simple id and PEM publicKey.');
|
|
253
|
+
}
|
|
254
|
+
return { id: key.id, publicKey: key.publicKey };
|
|
255
|
+
});
|
|
256
|
+
if (new Set(trustedPublicKeys.map((key) => key.id)).size !== trustedPublicKeys.length)
|
|
257
|
+
throw new Error('Attestation key IDs must be unique.');
|
|
258
|
+
const rawGithubOidc = object(optional(rawAttestation.githubOidc, {}), 'attestation.githubOidc');
|
|
259
|
+
keys(rawGithubOidc, ['mode', 'issuer', 'audience', 'repository', 'workflow', 'ref', 'keyBinding'], 'attestation.githubOidc');
|
|
260
|
+
const githubOidcMode = optional(rawGithubOidc.mode, defaultConfig.attestation.githubOidc?.mode ?? 'off');
|
|
261
|
+
if (!['off', 'strict'].includes(String(githubOidcMode))) {
|
|
262
|
+
throw new Error('attestation.githubOidc.mode must be off or strict.');
|
|
263
|
+
}
|
|
264
|
+
const githubIssuer = optional(rawGithubOidc.issuer, 'https://token.actions.githubusercontent.com');
|
|
265
|
+
if (githubIssuer !== 'https://token.actions.githubusercontent.com') {
|
|
266
|
+
throw new Error('attestation.githubOidc.issuer must be https://token.actions.githubusercontent.com.');
|
|
267
|
+
}
|
|
268
|
+
const githubAudience = rawGithubOidc.audience;
|
|
269
|
+
if (githubOidcMode === 'strict'
|
|
270
|
+
&& (typeof githubAudience !== 'string' || !githubAudience.trim()
|
|
271
|
+
|| githubAudience.includes('\0') || githubAudience.includes('#'))) {
|
|
272
|
+
throw new Error('attestation.githubOidc.audience must be nonempty and contain no # in strict mode.');
|
|
273
|
+
}
|
|
274
|
+
for (const key of ['repository', 'workflow', 'ref']) {
|
|
275
|
+
const claim = rawGithubOidc[key];
|
|
276
|
+
if (claim !== undefined && (typeof claim !== 'string' || !claim.trim() || claim.includes('\0'))) {
|
|
277
|
+
throw new Error(`attestation.githubOidc.${key} must be a nonempty string.`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const keyBinding = optional(rawGithubOidc.keyBinding, 'public-key');
|
|
281
|
+
if (!['public-key', 'key-id'].includes(String(keyBinding))) {
|
|
282
|
+
throw new Error('attestation.githubOidc.keyBinding must be public-key or key-id.');
|
|
283
|
+
}
|
|
284
|
+
if (githubOidcMode === 'strict' && mode !== 'ci-required') {
|
|
285
|
+
throw new Error('attestation.githubOidc.mode strict requires attestation.mode ci-required.');
|
|
286
|
+
}
|
|
287
|
+
if (typeof rawAttestation.repository === 'string' && typeof rawGithubOidc.repository === 'string'
|
|
288
|
+
&& rawAttestation.repository !== rawGithubOidc.repository) {
|
|
289
|
+
throw new Error('attestation.githubOidc.repository must match attestation.repository.');
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
schemaVersion: 1, language: language, commands, requiredChecks, thresholds,
|
|
293
|
+
architecture: { forbidCycles: architecture.forbidCycles !== false, rules },
|
|
294
|
+
codeGraph: { mode: codeGraphMode },
|
|
295
|
+
formal: { solver: solver, minModeledFraction, timeoutMs: formalTimeoutMs },
|
|
296
|
+
mutation: { mode: mutationMode },
|
|
297
|
+
workflow: {
|
|
298
|
+
mode: workflowMode,
|
|
299
|
+
...(typeof rawWorkflow.expectedSessionId === 'string' ? { expectedSessionId: rawWorkflow.expectedSessionId } : {}),
|
|
300
|
+
maxAgeSeconds: workflowMaxAgeSeconds,
|
|
301
|
+
maxFutureSkewSeconds: workflowMaxFutureSkewSeconds,
|
|
302
|
+
},
|
|
303
|
+
attestation: {
|
|
304
|
+
mode: mode,
|
|
305
|
+
...(typeof rawAttestation.repository === 'string' ? { repository: rawAttestation.repository } : {}),
|
|
306
|
+
maxAgeSeconds,
|
|
307
|
+
maxFutureSkewSeconds,
|
|
308
|
+
trustedPublicKeys,
|
|
309
|
+
githubOidc: githubOidcMode === 'strict'
|
|
310
|
+
? {
|
|
311
|
+
mode: 'strict',
|
|
312
|
+
issuer: 'https://token.actions.githubusercontent.com',
|
|
313
|
+
audience: githubAudience,
|
|
314
|
+
...(typeof rawGithubOidc.repository === 'string' ? { repository: rawGithubOidc.repository } : {}),
|
|
315
|
+
...(typeof rawGithubOidc.workflow === 'string' ? { workflow: rawGithubOidc.workflow } : {}),
|
|
316
|
+
...(typeof rawGithubOidc.ref === 'string' ? { ref: rawGithubOidc.ref } : {}),
|
|
317
|
+
keyBinding: keyBinding,
|
|
318
|
+
}
|
|
319
|
+
: { mode: 'off' },
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
export async function loadConfig(root) {
|
|
324
|
+
const path = '.musubix/config.json';
|
|
325
|
+
if (!await exists(within(root, path)))
|
|
326
|
+
throw new Error('Missing .musubix/config.json; run musubix3 init.');
|
|
327
|
+
return parseConfig(JSON.parse(await readText(root, path)));
|
|
328
|
+
}
|
|
329
|
+
export function parsePolicyBaseline(input) {
|
|
330
|
+
const value = object(input, 'policy baseline');
|
|
331
|
+
keys(value, [
|
|
332
|
+
'schemaVersion', 'requiredChecks', 'thresholds', 'architecture', 'codeGraph', 'formal',
|
|
333
|
+
'mutation', 'workflow', 'attestation', 'requiredCommands',
|
|
334
|
+
], 'policy baseline');
|
|
335
|
+
if (value.schemaVersion !== 1)
|
|
336
|
+
throw new Error('Unsupported policy baseline schemaVersion; expected 1.');
|
|
337
|
+
const parsed = parseConfig({
|
|
338
|
+
schemaVersion: 1,
|
|
339
|
+
requiredChecks: value.requiredChecks,
|
|
340
|
+
thresholds: value.thresholds,
|
|
341
|
+
architecture: value.architecture,
|
|
342
|
+
codeGraph: value.codeGraph,
|
|
343
|
+
formal: value.formal,
|
|
344
|
+
mutation: value.mutation,
|
|
345
|
+
workflow: value.workflow,
|
|
346
|
+
attestation: value.attestation,
|
|
347
|
+
commands: [],
|
|
348
|
+
});
|
|
349
|
+
return {
|
|
350
|
+
schemaVersion: 1,
|
|
351
|
+
requiredChecks: parsed.requiredChecks,
|
|
352
|
+
thresholds: parsed.thresholds,
|
|
353
|
+
architecture: parsed.architecture,
|
|
354
|
+
codeGraph: parsed.codeGraph,
|
|
355
|
+
formal: { solver: parsed.formal.solver, minModeledFraction: parsed.formal.minModeledFraction },
|
|
356
|
+
mutation: parsed.mutation,
|
|
357
|
+
workflow: parsed.workflow,
|
|
358
|
+
attestation: parsed.attestation,
|
|
359
|
+
requiredCommands: strings(optional(value.requiredCommands, []), 'requiredCommands'),
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
export async function loadPolicyBaseline(root) {
|
|
363
|
+
const path = '.musubix/policy-baseline.json';
|
|
364
|
+
return await exists(within(root, path))
|
|
365
|
+
? parsePolicyBaseline(JSON.parse(await readText(root, path)))
|
|
366
|
+
: null;
|
|
367
|
+
}
|
|
368
|
+
export function policyDiagnostics(config, baseline, changed = null) {
|
|
369
|
+
const diagnostics = [];
|
|
370
|
+
for (const check of baseline.requiredChecks) {
|
|
371
|
+
if (!config.requiredChecks.includes(check))
|
|
372
|
+
diagnostics.push(error('POLICY_REQUIRED_CHECK', `Required check ${check} was removed from the trusted baseline.`));
|
|
373
|
+
}
|
|
374
|
+
for (const key of Object.keys(baseline.thresholds)) {
|
|
375
|
+
if (config.thresholds[key] < baseline.thresholds[key])
|
|
376
|
+
diagnostics.push(error('POLICY_THRESHOLD', `thresholds.${key} is weaker than the trusted baseline.`));
|
|
377
|
+
}
|
|
378
|
+
if (baseline.architecture.forbidCycles && !config.architecture.forbidCycles)
|
|
379
|
+
diagnostics.push(error('POLICY_CYCLES', 'Cycle detection was disabled below the trusted baseline.'));
|
|
380
|
+
for (const rule of baseline.architecture.rules) {
|
|
381
|
+
if (!config.architecture.rules.some((candidate) => JSON.stringify(candidate) === JSON.stringify(rule))) {
|
|
382
|
+
diagnostics.push(error('POLICY_ARCHITECTURE', `Architecture rule ${rule.name} was removed or changed from the trusted baseline.`));
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (baseline.codeGraph.mode === 'strict' && config.codeGraph.mode !== 'strict') {
|
|
386
|
+
diagnostics.push(error('POLICY_CODE_GRAPH_MODE', 'codeGraph.mode cannot be weakened below strict as required by the trusted baseline.'));
|
|
387
|
+
}
|
|
388
|
+
if (config.formal.minModeledFraction < baseline.formal.minModeledFraction) {
|
|
389
|
+
diagnostics.push(error('POLICY_FORMAL_COVERAGE', 'formal.minModeledFraction is weaker than the trusted baseline.'));
|
|
390
|
+
}
|
|
391
|
+
if (baseline.formal.solver !== 'none' && config.formal.solver !== baseline.formal.solver) {
|
|
392
|
+
diagnostics.push(error('POLICY_FORMAL_SOLVER', `formal.solver must remain ${baseline.formal.solver} as required by the trusted baseline.`));
|
|
393
|
+
}
|
|
394
|
+
if (baseline.mutation.mode === 'strict' && config.mutation.mode !== 'strict') {
|
|
395
|
+
diagnostics.push(error('POLICY_MUTATION_MODE', 'mutation.mode cannot be weakened below strict as required by the trusted baseline.'));
|
|
396
|
+
}
|
|
397
|
+
if (baseline.workflow.mode === 'strict') {
|
|
398
|
+
if (config.workflow.mode !== 'strict') {
|
|
399
|
+
diagnostics.push(error('POLICY_WORKFLOW_MODE', 'workflow.mode cannot be weakened below strict as required by the trusted baseline.'));
|
|
400
|
+
}
|
|
401
|
+
if (baseline.workflow.expectedSessionId
|
|
402
|
+
&& config.workflow.expectedSessionId?.toLowerCase() !== baseline.workflow.expectedSessionId.toLowerCase()) {
|
|
403
|
+
diagnostics.push(error('POLICY_WORKFLOW_SESSION', 'workflow.expectedSessionId must remain bound to the trusted baseline session.'));
|
|
404
|
+
}
|
|
405
|
+
if ((config.workflow.maxAgeSeconds ?? 3600) > (baseline.workflow.maxAgeSeconds ?? 3600)) {
|
|
406
|
+
diagnostics.push(error('POLICY_WORKFLOW_MAX_AGE', 'workflow.maxAgeSeconds is weaker than the trusted baseline.'));
|
|
407
|
+
}
|
|
408
|
+
if ((config.workflow.maxFutureSkewSeconds ?? 60) > (baseline.workflow.maxFutureSkewSeconds ?? 60)) {
|
|
409
|
+
diagnostics.push(error('POLICY_WORKFLOW_FUTURE_SKEW', 'workflow.maxFutureSkewSeconds is weaker than the trusted baseline.'));
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (baseline.attestation.mode === 'ci-required') {
|
|
413
|
+
if (config.attestation.mode !== 'ci-required') {
|
|
414
|
+
diagnostics.push(error('POLICY_ATTESTATION_MODE', 'attestation.mode cannot be weakened below ci-required as required by the trusted baseline.'));
|
|
415
|
+
}
|
|
416
|
+
if (baseline.attestation.repository && config.attestation.repository !== baseline.attestation.repository) {
|
|
417
|
+
diagnostics.push(error('POLICY_ATTESTATION_REPOSITORY', 'attestation.repository must remain bound to the trusted baseline repository.'));
|
|
418
|
+
}
|
|
419
|
+
if ((config.attestation.maxAgeSeconds ?? 3600) > (baseline.attestation.maxAgeSeconds ?? 3600)) {
|
|
420
|
+
diagnostics.push(error('POLICY_ATTESTATION_MAX_AGE', 'attestation.maxAgeSeconds is weaker than the trusted baseline.'));
|
|
421
|
+
}
|
|
422
|
+
if ((config.attestation.maxFutureSkewSeconds ?? 60) > (baseline.attestation.maxFutureSkewSeconds ?? 60)) {
|
|
423
|
+
diagnostics.push(error('POLICY_ATTESTATION_FUTURE_SKEW', 'attestation.maxFutureSkewSeconds is weaker than the trusted baseline.'));
|
|
424
|
+
}
|
|
425
|
+
for (const key of baseline.attestation.trustedPublicKeys) {
|
|
426
|
+
if (!config.attestation.trustedPublicKeys.some((candidate) => candidate.id === key.id && candidate.publicKey === key.publicKey)) {
|
|
427
|
+
diagnostics.push(error('POLICY_ATTESTATION_KEY', `Trusted attestation key ${key.id} was removed or changed.`));
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (baseline.attestation.githubOidc?.mode === 'strict') {
|
|
432
|
+
const oidc = config.attestation.githubOidc;
|
|
433
|
+
if (oidc?.mode !== 'strict') {
|
|
434
|
+
diagnostics.push(error('POLICY_ATTESTATION_OIDC_MODE', 'attestation.githubOidc.mode cannot be weakened below strict.'));
|
|
435
|
+
}
|
|
436
|
+
if (oidc?.keyBinding !== baseline.attestation.githubOidc.keyBinding) {
|
|
437
|
+
diagnostics.push(error('POLICY_ATTESTATION_OIDC_BINDING', 'attestation.githubOidc.keyBinding must remain bound to the trusted baseline.'));
|
|
438
|
+
}
|
|
439
|
+
for (const key of ['issuer', 'audience', 'repository', 'workflow', 'ref']) {
|
|
440
|
+
const expected = baseline.attestation.githubOidc[key];
|
|
441
|
+
if (expected !== undefined && oidc?.[key] !== expected) {
|
|
442
|
+
diagnostics.push(error('POLICY_ATTESTATION_OIDC_IDENTITY', `attestation.githubOidc.${key} must match the trusted baseline.`));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
for (const name of baseline.requiredCommands) {
|
|
447
|
+
if (!config.commands.some((command) => command.name === name && command.required)) {
|
|
448
|
+
diagnostics.push(error('POLICY_COMMAND', `Required command ${name} was removed or made optional.`));
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (changed?.includes('.musubix/policy-baseline.json')) {
|
|
452
|
+
diagnostics.push(error('POLICY_APPROVAL_REQUIRED', 'The trusted policy baseline changed; independent approval is required before readiness can pass.'));
|
|
453
|
+
}
|
|
454
|
+
return diagnostics;
|
|
455
|
+
}
|
|
456
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../packages/analysis/src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAmB,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAiGtD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,CAAU,CAAC;AAEvQ,MAAM,CAAC,MAAM,aAAa,GAAW;IACnC,aAAa,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,EAAE;IACZ,cAAc,EAAE,CAAC,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;IACxF,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;IACtD,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IAC/C,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;IACjC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE;IACpE,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;IAChC,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE;IAC/E,WAAW,EAAE;QACX,IAAI,EAAE,OAAO;QACb,aAAa,EAAE,IAAI;QACnB,oBAAoB,EAAE,EAAE;QACxB,iBAAiB,EAAE,EAAE;QACrB,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;KAC5B;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAmB;IACnD,aAAa,EAAE,CAAC;IAChB,cAAc,EAAE,CAAC,GAAG,aAAa,CAAC,cAAc,CAAC;IACjD,UAAU,EAAE,EAAE,GAAG,aAAa,CAAC,UAAU,EAAE;IAC3C,YAAY,EAAE,EAAE,YAAY,EAAE,aAAa,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;IACrH,SAAS,EAAE,EAAE,GAAG,aAAa,CAAC,SAAS,EAAE;IACzC,MAAM,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,EAAE,aAAa,CAAC,MAAM,CAAC,kBAAkB,EAAE;IAC5G,QAAQ,EAAE,EAAE,GAAG,aAAa,CAAC,QAAQ,EAAE;IACvC,QAAQ,EAAE,EAAE,GAAG,aAAa,CAAC,QAAQ,EAAE;IACvC,WAAW,EAAE;QACX,GAAG,aAAa,CAAC,WAAW;QAC5B,iBAAiB,EAAE,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,iBAAiB,CAAC;QACnE,UAAU,EAAE,EAAE,GAAG,aAAa,CAAC,WAAW,CAAC,UAAW,EAAE;KACzD;IACD,gBAAgB,EAAE,EAAE;CACrB,CAAC;AAEF,SAAS,MAAM,CAAC,KAAc,EAAE,QAAgB;IAC9C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,qBAAqB,CAAC,CAAC;IACnH,OAAO,KAAgC,CAAC;AAC1C,CAAC;AAED,SAAS,IAAI,CAAC,KAA8B,EAAE,OAAiB,EAAE,QAAgB;IAC/E,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,IAAI,GAAG,GAAG,CAAC,CAAC;IACxF,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,KAAc,EAAE,QAAgB,EAAE,UAAU,GAAG,KAAK;IACnE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,wBAAwB,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,4BAA4B,CAAC,CAAC;IAC5O,OAAO,KAAiB,CAAC;AAC3B,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc,EAAE,QAAiB;IACjD,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK,EAAE,CAAC,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC/K,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAChG,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClD,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAC3G,MAAM,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,EAAE,aAAa,CAAC,cAAc,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC/G,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAA8B,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACjI,MAAM,UAAU,GAAG,EAAE,GAAG,aAAa,CAAC,UAAU,EAAE,CAAC;IACnD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QACnD,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;QACjD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAgC,EAAE,CAAC;YACzE,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YACtD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,qBAAqB,CAAC,CAAC;YAC5J,UAAU,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC/E,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,GAAY,EAAiB,EAAE;QAC/D,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,SAAS,CAAC,CAAC;QAC5I,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QAC1I,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC5I,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACtH,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YACtH,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;QAC7F,CAAC;QACD,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACtK,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAC;QAClG,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;YAC9F,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,SAAqC,CAAC;QAC1C,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,mBAAmB,CAAC,CAAC;YACtD,IAAI,MAAM,CAAC,MAAM,KAAK,cAAc;gBAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;YACxG,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBACvH,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAClG,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACpI,SAAS,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5D,CAAC;QACD,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,CAAC;YACxE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,UAAuC,CAAC;QAC5C,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;YAC1D,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,oBAAoB,CAAC,CAAC;YACvD,IAAI,MAAM,CAAC,MAAM,KAAK,cAAc;gBAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;YACzG,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBACtH,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;YACxG,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;YACrI,UAAU,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAC7D,CAAC;QACD,IAAI,cAA+C,CAAC;QACpD,IAAI,CAAC,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAC;YAClE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,wBAAwB,CAAC,CAAC;YAC3D,IAAI,MAAM,CAAC,MAAM,KAAK,uBAAuB,EAAE,CAAC;gBAC9C,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;YAClF,CAAC;YACD,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;mBAC5E,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5G,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;YACpG,CAAC;YACD,cAAc,GAAG,EAAE,MAAM,EAAE,uBAAuB,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1E,CAAC;QACD,IAAI,cAAc,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC3F,CAAC;QACD,OAAO;YACL,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC;YACzD,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAgD,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrF,QAAQ,EAAE,CAAC,CAAC,QAAQ,KAAK,KAAK;YAC9B,SAAS;SACV,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACpH,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC;IAC9E,IAAI,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC;IAC9D,IAAI,YAAY,CAAC,YAAY,KAAK,SAAS,IAAI,OAAO,YAAY,CAAC,YAAY,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC7J,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtF,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAY,EAAoB,EAAE;QAC5D,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;QAC3C,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,mBAAmB,CAAC,CAAC;QAC3D,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACnJ,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE,CAAC;IACxF,CAAC,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;IACxE,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IAC1C,MAAM,aAAa,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAChF,IAAI,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC/D,IAAI,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,oBAAoB,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;IACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvE,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAChI,MAAM,kBAAkB,GAAG,QAAQ,CAAC,SAAS,CAAC,kBAAkB,EAAE,aAAa,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC3G,IAAI,OAAO,kBAAkB,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,kBAAkB,GAAG,CAAC,IAAI,kBAAkB,GAAG,CAAC,EAAE,CAAC;QACvI,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACtF,IAAI,OAAO,eAAe,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,eAAe,GAAG,GAAG,IAAI,eAAe,GAAG,OAAO,EAAE,CAAC;QACpI,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IACrE,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7E,IAAI,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IACrE,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,eAAe,EAAE,sBAAsB,CAAC,EAAE,UAAU,CAAC,CAAC;IACtG,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7E,IAAI,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,WAAW,CAAC,iBAAiB,KAAK,SAAS;WAC1C,CAAC,OAAO,WAAW,CAAC,iBAAiB,KAAK,QAAQ;eAChD,CAAC,4EAA4E,CAAC,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC;QAC1H,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,WAAW,CAAC,iBAAiB,KAAK,SAAS,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC7E,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,qBAAqB,GAAG,QAAQ,CAAC,WAAW,CAAC,aAAa,EAAE,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACxG,IAAI,OAAO,qBAAqB,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC;WACpF,qBAAqB,GAAG,CAAC,IAAI,qBAAqB,GAAG,OAAO,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,4BAA4B,GAAG,QAAQ,CAC3C,WAAW,CAAC,oBAAoB,EAChC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAC5C,CAAC;IACF,IAAI,OAAO,4BAA4B,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,4BAA4B,CAAC;WAClG,4BAA4B,GAAG,CAAC,IAAI,4BAA4B,GAAG,GAAG,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;IAC9E,IAAI,CAAC,cAAc,EAAE;QACnB,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,YAAY;KACjG,EAAE,aAAa,CAAC,CAAC;IAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC3E,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACrI,IAAI,cAAc,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,OAAO,cAAc,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACpI,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,aAAa,GAAG,QAAQ,CAAC,cAAc,CAAC,aAAa,EAAE,aAAa,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IACtG,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,aAAa,GAAG,CAAC,IAAI,aAAa,GAAG,OAAO,EAAE,CAAC;QAC1H,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,oBAAoB,GAAG,QAAQ,CAAC,cAAc,CAAC,oBAAoB,EAAE,aAAa,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;IAC3H,IAAI,OAAO,oBAAoB,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC;WAClF,oBAAoB,GAAG,CAAC,IAAI,oBAAoB,GAAG,GAAG,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAChG,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAkD,EAAE;QAC5F,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;QAClD,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,wBAAwB,CAAC,CAAC;QACzD,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;eAC9D,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACtF,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IACH,IAAI,IAAI,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC9I,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAChG,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAC7H,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,IAAI,KAAK,CAAC,CAAC;IACzG,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,6CAA6C,CAAC,CAAC;IACnG,IAAI,YAAY,KAAK,6CAA6C,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;IACxG,CAAC;IACD,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC;IAC9C,IAAI,cAAc,KAAK,QAAQ;WAC1B,CAAC,OAAO,cAAc,KAAK,QAAQ,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE;eAC3D,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;IACvG,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE,KAAK,CAAU,EAAE,CAAC;QAC7D,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAChG,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,6BAA6B,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IACD,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACpE,IAAI,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,cAAc,KAAK,QAAQ,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;IAC/F,CAAC;IACD,IAAI,OAAO,cAAc,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,aAAa,CAAC,UAAU,KAAK,QAAQ;WAC5F,cAAc,CAAC,UAAU,KAAK,aAAa,CAAC,UAAU,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO;QACL,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,QAA8B,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU;QAChG,YAAY,EAAE,EAAE,YAAY,EAAE,YAAY,CAAC,YAAY,KAAK,KAAK,EAAE,KAAK,EAAE;QAC1E,SAAS,EAAE,EAAE,IAAI,EAAE,aAAwC,EAAE;QAC7D,MAAM,EAAE,EAAE,MAAM,EAAE,MAAgC,EAAE,kBAAkB,EAAE,SAAS,EAAE,eAAe,EAAE;QACpG,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAsC,EAAE;QAC1D,QAAQ,EAAE;YACR,IAAI,EAAE,YAAsC;YAC5C,GAAG,CAAC,OAAO,WAAW,CAAC,iBAAiB,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClH,aAAa,EAAE,qBAAqB;YACpC,oBAAoB,EAAE,4BAA4B;SACnD;QACD,WAAW,EAAE;YACX,IAAI,EAAE,IAAiC;YACvC,GAAG,CAAC,OAAO,cAAc,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnG,aAAa;YACb,oBAAoB;YACpB,iBAAiB;YACjB,UAAU,EAAE,cAAc,KAAK,QAAQ;gBACrC,CAAC,CAAC;oBACA,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,6CAA6C;oBACrD,QAAQ,EAAE,cAAwB;oBAClC,GAAG,CAAC,OAAO,aAAa,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjG,GAAG,CAAC,OAAO,aAAa,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC3F,GAAG,CAAC,OAAO,aAAa,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC5E,UAAU,EAAE,UAAqC;iBAClD;gBACD,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE;SACpB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,IAAI,GAAG,sBAAsB,CAAC;IACpC,IAAI,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAC3G,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAY,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,EAAE;QACV,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ;QACtF,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,kBAAkB;KAC1D,EAAE,iBAAiB,CAAC,CAAC;IACtB,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IACzG,MAAM,MAAM,GAAG,WAAW,CAAC;QACzB,aAAa,EAAE,CAAC;QAChB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,EAAE;KACb,CAAC,CAAC;IACH,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE;QAC9F,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,gBAAgB,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,CAAC,EAAE,kBAAkB,CAAC;KACpF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY;IACnD,MAAM,IAAI,GAAG,+BAA+B,CAAC;IAC7C,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAY,CAAC;QACxE,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,QAAwB,EAAE,UAA2B,IAAI;IACzG,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,uBAAuB,EAAE,kBAAkB,KAAK,yCAAyC,CAAC,CAAC,CAAC;IACjK,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAmC,EAAE,CAAC;QACrF,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,cAAc,GAAG,uCAAuC,CAAC,CAAC,CAAC;IAC/J,CAAC;IACD,IAAI,QAAQ,CAAC,YAAY,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,YAAY;QAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,0DAA0D,CAAC,CAAC,CAAC;IAClL,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACvG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,qBAAqB,IAAI,CAAC,IAAI,oDAAoD,CAAC,CAAC,CAAC;QACrI,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC/E,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,EAAE,qFAAqF,CAAC,CAAC,CAAC;IAC3I,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,kBAAkB,GAAG,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC1E,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,EAAE,gEAAgE,CAAC,CAAC,CAAC;IACtH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACzF,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAsB,EAAE,6BAA6B,QAAQ,CAAC,MAAM,CAAC,MAAM,uCAAuC,CAAC,CAAC,CAAC;IAC9I,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7E,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAsB,EAAE,oFAAoF,CAAC,CAAC,CAAC;IACxI,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACxC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAsB,EAAE,oFAAoF,CAAC,CAAC,CAAC;QACxI,CAAC;QACD,IAAI,QAAQ,CAAC,QAAQ,CAAC,iBAAiB;eAClC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,WAAW,EAAE,KAAK,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5G,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,yBAAyB,EAAE,+EAA+E,CAAC,CAAC,CAAC;QACtI,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,IAAI,IAAI,CAAC,EAAE,CAAC;YACxF,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,yBAAyB,EAAE,6DAA6D,CAAC,CAAC,CAAC;QACpH,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,IAAI,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,IAAI,EAAE,CAAC,EAAE,CAAC;YAClG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,6BAA6B,EAAE,oEAAoE,CAAC,CAAC,CAAC;QAC/H,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,WAAW,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QAChD,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC9C,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,yBAAyB,EAAE,4FAA4F,CAAC,CAAC,CAAC;QACnJ,CAAC;QACD,IAAI,QAAQ,CAAC,WAAW,CAAC,UAAU,IAAI,MAAM,CAAC,WAAW,CAAC,UAAU,KAAK,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;YACzG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,+BAA+B,EAAE,8EAA8E,CAAC,CAAC,CAAC;QAC3I,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,aAAa,IAAI,IAAI,CAAC,EAAE,CAAC;YAC9F,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,4BAA4B,EAAE,gEAAgE,CAAC,CAAC,CAAC;QAC1H,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,oBAAoB,IAAI,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,oBAAoB,IAAI,EAAE,CAAC,EAAE,CAAC;YACxG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,gCAAgC,EAAE,uEAAuE,CAAC,CAAC,CAAC;QACrI,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC,iBAAiB,EAAE,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAC3D,SAAS,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC,SAAS,KAAK,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACpE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,EAAE,2BAA2B,GAAG,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC;YACjH,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC;QAC3C,IAAI,IAAI,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,8BAA8B,EAAE,8DAA8D,CAAC,CAAC,CAAC;QAC1H,CAAC;QACD,IAAI,IAAI,EAAE,UAAU,KAAK,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;YACpE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,iCAAiC,EAAE,8EAA8E,CAAC,CAAC,CAAC;QAC7I,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,CAAU,EAAE,CAAC;YACnF,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACtD,IAAI,QAAQ,KAAK,SAAS,IAAI,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACvD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,kCAAkC,EAAE,0BAA0B,GAAG,mCAAmC,CAAC,CAAC,CAAC;YAChI,CAAC;QACH,CAAC;IACH,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClF,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,oBAAoB,IAAI,gCAAgC,CAAC,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;IACD,IAAI,OAAO,EAAE,QAAQ,CAAC,+BAA+B,CAAC,EAAE,CAAC;QACvD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,0BAA0B,EAAE,kGAAkG,CAAC,CAAC,CAAC;IAC1J,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function portable(path: string): string;
|
|
2
|
+
export declare function within(root: string, path: string): string;
|
|
3
|
+
export declare function exists(path: string): Promise<boolean>;
|
|
4
|
+
export declare function safePath(root: string, path: string): Promise<string>;
|
|
5
|
+
export declare function files(root: string): Promise<string[]>;
|
|
6
|
+
export declare function readText(root: string, path: string): Promise<string>;
|
|
7
|
+
export declare function writeText(root: string, path: string, text: string): Promise<void>;
|
|
8
|
+
export declare function writeJson(root: string, path: string, value: unknown): Promise<void>;
|
|
9
|
+
export declare function digest(content: string | Uint8Array): string;
|
|
10
|
+
export declare function isSource(path: string): boolean;
|
|
11
|
+
export declare function isTraceSource(path: string): boolean;
|
|
12
|
+
export declare function isArtifact(path: string): boolean;
|
|
13
|
+
export declare function snapshot(root: string, paths: string[]): Promise<Record<string, string>>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { lstat, mkdir, readdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, isAbsolute, relative, resolve, sep } from 'node:path';
|
|
4
|
+
const excluded = new Set(['.git', 'node_modules', 'dist', 'build', 'coverage', '.test-work', '.next', 'vendor']);
|
|
5
|
+
export function portable(path) {
|
|
6
|
+
return path.split(sep).join('/');
|
|
7
|
+
}
|
|
8
|
+
export function within(root, path) {
|
|
9
|
+
const absolute = resolve(root, path);
|
|
10
|
+
const rel = relative(resolve(root), absolute);
|
|
11
|
+
if (rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel))
|
|
12
|
+
throw new Error(`Path escapes project root: ${path}`);
|
|
13
|
+
return absolute;
|
|
14
|
+
}
|
|
15
|
+
export async function exists(path) {
|
|
16
|
+
try {
|
|
17
|
+
await lstat(path);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch (cause) {
|
|
21
|
+
if (cause.code === 'ENOENT')
|
|
22
|
+
return false;
|
|
23
|
+
throw cause;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export async function safePath(root, path) {
|
|
27
|
+
const absolute = within(root, path);
|
|
28
|
+
let cursor = resolve(root);
|
|
29
|
+
const segments = relative(cursor, absolute).split(sep).filter(Boolean);
|
|
30
|
+
for (const part of ['', ...segments]) {
|
|
31
|
+
if (part)
|
|
32
|
+
cursor = resolve(cursor, part);
|
|
33
|
+
try {
|
|
34
|
+
if ((await lstat(cursor)).isSymbolicLink())
|
|
35
|
+
throw new Error(`Refusing symbolic link: ${cursor}`);
|
|
36
|
+
}
|
|
37
|
+
catch (cause) {
|
|
38
|
+
if (cause.code !== 'ENOENT')
|
|
39
|
+
throw cause;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return absolute;
|
|
43
|
+
}
|
|
44
|
+
export async function files(root) {
|
|
45
|
+
const result = [];
|
|
46
|
+
async function walk(directory) {
|
|
47
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
48
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
49
|
+
if (entry.isSymbolicLink())
|
|
50
|
+
continue;
|
|
51
|
+
const absolute = resolve(directory, entry.name);
|
|
52
|
+
const path = portable(relative(root, absolute));
|
|
53
|
+
if (entry.isDirectory()) {
|
|
54
|
+
if (!excluded.has(entry.name) && path !== '.musubix/cache' && path !== '.musubix/evidence')
|
|
55
|
+
await walk(absolute);
|
|
56
|
+
}
|
|
57
|
+
else if (entry.isFile()) {
|
|
58
|
+
result.push(path);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
await walk(resolve(root));
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
export async function readText(root, path) {
|
|
66
|
+
return readFile(await safePath(root, path), 'utf8');
|
|
67
|
+
}
|
|
68
|
+
export async function writeText(root, path, text) {
|
|
69
|
+
const target = await safePath(root, path);
|
|
70
|
+
await mkdir(dirname(target), { recursive: true });
|
|
71
|
+
// Same-directory atomic replacement; no operating-system temporary directories.
|
|
72
|
+
const staging = `${target}.${process.pid}.${crypto.randomUUID()}.writing`;
|
|
73
|
+
try {
|
|
74
|
+
await writeFile(staging, text, { flag: 'wx' });
|
|
75
|
+
await rename(staging, target);
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
if (await exists(staging))
|
|
79
|
+
await unlink(staging);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export async function writeJson(root, path, value) {
|
|
83
|
+
await writeText(root, path, `${JSON.stringify(value, null, 2)}\n`);
|
|
84
|
+
}
|
|
85
|
+
export function digest(content) {
|
|
86
|
+
return createHash('sha256').update(content).digest('hex');
|
|
87
|
+
}
|
|
88
|
+
export function isSource(path) {
|
|
89
|
+
return /\.(?:[cm]?[jt]sx?)$/.test(path) && !/\.d\.[cm]?ts$/.test(path);
|
|
90
|
+
}
|
|
91
|
+
export function isTraceSource(path) {
|
|
92
|
+
return /\.(?:[cm]?[jt]sx?|rs|py|go|java|kt|kts|cs|c|cc|cpp|h|hh|hpp|rb|php|swift|[rR]|jl)$/.test(path)
|
|
93
|
+
&& !/\.d\.[cm]?ts$/.test(path);
|
|
94
|
+
}
|
|
95
|
+
export function isArtifact(path) {
|
|
96
|
+
return /^\.musubix\/features\/[^/]+\/(?:requirements|design)\.md$/.test(path) ||
|
|
97
|
+
/^\.musubix\/decisions\/ADR-\d+\.md$/.test(path);
|
|
98
|
+
}
|
|
99
|
+
export async function snapshot(root, paths) {
|
|
100
|
+
const entries = await Promise.all(paths.map(async (path) => [path, digest(await readFile(await safePath(root, path)))]));
|
|
101
|
+
return Object.fromEntries(entries);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../../../packages/analysis/src/files.ts"],"names":[],"mappings":"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"}
|