ghagga 3.2.0 → 3.4.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/README.md +1 -1
- package/dist/commands/audit.js +6 -2
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/index-cmd.d.ts +49 -0
- package/dist/commands/index-cmd.d.ts.map +1 -0
- package/dist/commands/index-cmd.js +367 -0
- package/dist/commands/index-cmd.js.map +1 -0
- package/dist/commands/index-cmd.test.d.ts +17 -0
- package/dist/commands/index-cmd.test.d.ts.map +1 -0
- package/dist/commands/index-cmd.test.js +535 -0
- package/dist/commands/index-cmd.test.js.map +1 -0
- package/dist/commands/indexer-registry.d.ts +93 -0
- package/dist/commands/indexer-registry.d.ts.map +1 -0
- package/dist/commands/indexer-registry.js +342 -0
- package/dist/commands/indexer-registry.js.map +1 -0
- package/dist/commands/indexer-registry.test.d.ts +10 -0
- package/dist/commands/indexer-registry.test.d.ts.map +1 -0
- package/dist/commands/indexer-registry.test.js +538 -0
- package/dist/commands/indexer-registry.test.js.map +1 -0
- package/dist/commands/review-blast-radius.test.d.ts +13 -0
- package/dist/commands/review-blast-radius.test.d.ts.map +1 -0
- package/dist/commands/review-blast-radius.test.js +179 -0
- package/dist/commands/review-blast-radius.test.js.map +1 -0
- package/dist/commands/review.d.ts +136 -1
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +357 -2
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/review.test.js +527 -1
- package/dist/commands/review.test.js.map +1 -1
- package/dist/commands/triage.d.ts +14 -0
- package/dist/commands/triage.d.ts.map +1 -0
- package/dist/commands/triage.js +248 -0
- package/dist/commands/triage.js.map +1 -0
- package/dist/commands/triage.test.d.ts +8 -0
- package/dist/commands/triage.test.d.ts.map +1 -0
- package/dist/commands/triage.test.js +272 -0
- package/dist/commands/triage.test.js.map +1 -0
- package/dist/index.js +38 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/cli-github-client-port.d.ts +2 -0
- package/dist/lib/cli-github-client-port.d.ts.map +1 -1
- package/dist/lib/cli-github-client-port.js +12 -0
- package/dist/lib/cli-github-client-port.js.map +1 -1
- package/dist/ui/__tests__/theme.test.js +3 -2
- package/dist/ui/__tests__/theme.test.js.map +1 -1
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +1 -0
- package/dist/ui/theme.js.map +1 -1
- package/package.json +11 -10
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the per-language SCIP indexer registry (D1) and marker-file
|
|
3
|
+
* language detection (spec "Language Detection").
|
|
4
|
+
*
|
|
5
|
+
* Mocked: `execFileSync` (toolchain checks/`run` under the hood) — no real
|
|
6
|
+
* toolchains are ever invoked. `detectPresentLanguages` only touches the
|
|
7
|
+
* filesystem (marker files), so it's tested against a real temp dir.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { tmpdir } from 'node:os';
|
|
11
|
+
import { dirname, join } from 'node:path';
|
|
12
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
13
|
+
// Mock only `execFileSync` — everything else (fs, path) stays real so
|
|
14
|
+
// `goEntry.run()` exercises its actual mkdir/rm/rename behavior against a
|
|
15
|
+
// real temp dir (that's the whole point of this suite: catching R1-001,
|
|
16
|
+
// which no mock-fs test caught).
|
|
17
|
+
const execFileSyncMock = vi.fn();
|
|
18
|
+
vi.mock('node:child_process', async (importOriginal) => {
|
|
19
|
+
const actual = await importOriginal();
|
|
20
|
+
return { ...actual, execFileSync: (...args) => execFileSyncMock(...args) };
|
|
21
|
+
});
|
|
22
|
+
import { DEFAULT_MARKER_DEPTH, detectMarkerDirectories, detectPresentLanguages, INDEXER_REGISTRY, scipOutputPath, } from './indexer-registry.js';
|
|
23
|
+
/** Find an entry in INDEXER_REGISTRY covering `language`, asserting it exists. */
|
|
24
|
+
function requireEntry(language) {
|
|
25
|
+
const entry = INDEXER_REGISTRY.find((e) => e.languages.includes(language));
|
|
26
|
+
if (!entry)
|
|
27
|
+
throw new Error(`no registry entry for ${language}`);
|
|
28
|
+
return entry;
|
|
29
|
+
}
|
|
30
|
+
let dir;
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
dir = mkdtempSync(join(tmpdir(), 'ghagga-indexer-registry-'));
|
|
33
|
+
});
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
rmSync(dir, { recursive: true, force: true });
|
|
36
|
+
});
|
|
37
|
+
describe('INDEXER_REGISTRY', () => {
|
|
38
|
+
it('contains exactly one entry for Go, refactored into IndexerEntry shape', () => {
|
|
39
|
+
const goEntries = INDEXER_REGISTRY.filter((entry) => entry.languages.includes('go'));
|
|
40
|
+
expect(goEntries).toHaveLength(1);
|
|
41
|
+
const go = goEntries[0];
|
|
42
|
+
expect(go).toBeDefined();
|
|
43
|
+
expect(go?.bin).toBe('scip-go');
|
|
44
|
+
expect(go?.markers).toContain('go.mod');
|
|
45
|
+
expect(typeof go?.toolchainCheck).toBe('function');
|
|
46
|
+
expect(typeof go?.run).toBe('function');
|
|
47
|
+
expect(typeof go?.installHint).toBe('string');
|
|
48
|
+
expect(go?.maturity).toBe('stable');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe('INDEXER_REGISTRY — Tier B mature languages', () => {
|
|
52
|
+
it('contains a TS/JS entry backed by scip-typescript', () => {
|
|
53
|
+
const ts = requireEntry('typescript');
|
|
54
|
+
expect(ts.bin).toBe('scip-typescript');
|
|
55
|
+
expect(ts.languages).toEqual(['typescript', 'javascript']);
|
|
56
|
+
expect(ts.markers).toEqual(expect.arrayContaining(['package.json', 'tsconfig.json']));
|
|
57
|
+
expect(ts.maturity).toBe('stable');
|
|
58
|
+
expect(typeof ts.installHint).toBe('string');
|
|
59
|
+
});
|
|
60
|
+
it('contains a Python entry backed by scip-python', () => {
|
|
61
|
+
const py = requireEntry('python');
|
|
62
|
+
expect(py.bin).toBe('scip-python');
|
|
63
|
+
expect(py.languages).toEqual(['python']);
|
|
64
|
+
expect(py.markers).toEqual(expect.arrayContaining(['pyproject.toml', 'requirements.txt', 'setup.py']));
|
|
65
|
+
expect(py.maturity).toBe('stable');
|
|
66
|
+
});
|
|
67
|
+
it('contains a Rust entry backed by rust-analyzer', () => {
|
|
68
|
+
const rust = requireEntry('rust');
|
|
69
|
+
expect(rust.bin).toBe('rust-analyzer');
|
|
70
|
+
expect(rust.languages).toEqual(['rust']);
|
|
71
|
+
expect(rust.markers).toEqual(expect.arrayContaining(['Cargo.toml']));
|
|
72
|
+
expect(rust.maturity).toBe('stable');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('INDEXER_REGISTRY — Tier C/D heavy + experimental languages', () => {
|
|
76
|
+
it('contains a Java+Kotlin entry backed by scip-java (shared indexer)', () => {
|
|
77
|
+
const java = requireEntry('java');
|
|
78
|
+
expect(java.bin).toBe('scip-java');
|
|
79
|
+
expect(java.languages).toEqual(['java', 'kotlin']);
|
|
80
|
+
expect(java.markers).toEqual(expect.arrayContaining(['pom.xml', 'build.gradle', 'build.gradle.kts']));
|
|
81
|
+
expect(java.maturity).toBe('heavy');
|
|
82
|
+
expect(typeof java.installHint).toBe('string');
|
|
83
|
+
// Same entry object covers both languages — not two separate entries.
|
|
84
|
+
const kotlin = requireEntry('kotlin');
|
|
85
|
+
expect(kotlin).toBe(java);
|
|
86
|
+
});
|
|
87
|
+
it('contains a C# entry backed by scip-dotnet', () => {
|
|
88
|
+
const csharp = requireEntry('csharp');
|
|
89
|
+
expect(csharp.bin).toBe('scip-dotnet');
|
|
90
|
+
expect(csharp.languages).toEqual(['csharp']);
|
|
91
|
+
expect(csharp.markers).toEqual(expect.arrayContaining(['*.csproj', '*.sln']));
|
|
92
|
+
expect(csharp.maturity).toBe('experimental');
|
|
93
|
+
});
|
|
94
|
+
it('contains a PHP entry backed by scip-php', () => {
|
|
95
|
+
const php = requireEntry('php');
|
|
96
|
+
expect(php.bin).toBe('scip-php');
|
|
97
|
+
expect(php.languages).toEqual(['php']);
|
|
98
|
+
expect(php.markers).toEqual(expect.arrayContaining(['composer.json']));
|
|
99
|
+
expect(php.maturity).toBe('experimental');
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe('detectPresentLanguages', () => {
|
|
103
|
+
it('detects Go via go.mod', () => {
|
|
104
|
+
writeFileSync(join(dir, 'go.mod'), 'module example.com/x\n');
|
|
105
|
+
const detected = detectPresentLanguages(dir);
|
|
106
|
+
const goEntries = detected.filter((entry) => entry.languages.includes('go'));
|
|
107
|
+
expect(goEntries).toHaveLength(1);
|
|
108
|
+
});
|
|
109
|
+
it('detects nothing in an empty directory', () => {
|
|
110
|
+
const detected = detectPresentLanguages(dir);
|
|
111
|
+
expect(detected).toEqual([]);
|
|
112
|
+
});
|
|
113
|
+
it('detects multiple languages present in a poly-language repo', () => {
|
|
114
|
+
writeFileSync(join(dir, 'go.mod'), 'module example.com/x\n');
|
|
115
|
+
mkdirSync(join(dir, 'app'));
|
|
116
|
+
writeFileSync(join(dir, 'app', 'package.json'), '{}');
|
|
117
|
+
const detected = detectPresentLanguages(dir);
|
|
118
|
+
// detectPresentLanguages checks marker files at repoPath root only (D-scope
|
|
119
|
+
// for Tier A) — package.json in a subdir is out of scope for this test,
|
|
120
|
+
// this only exercises root-level detection.
|
|
121
|
+
const goEntries = detected.filter((entry) => entry.languages.includes('go'));
|
|
122
|
+
expect(goEntries).toHaveLength(1);
|
|
123
|
+
});
|
|
124
|
+
it('does not duplicate an entry if multiple of its markers are present', () => {
|
|
125
|
+
writeFileSync(join(dir, 'go.mod'), 'module example.com/x\n');
|
|
126
|
+
const detected = detectPresentLanguages(dir);
|
|
127
|
+
expect(detected).toHaveLength(detected.length);
|
|
128
|
+
const goEntries = detected.filter((entry) => entry.languages.includes('go'));
|
|
129
|
+
expect(goEntries).toHaveLength(1);
|
|
130
|
+
});
|
|
131
|
+
it('detects TS/JS via package.json', () => {
|
|
132
|
+
writeFileSync(join(dir, 'package.json'), '{}');
|
|
133
|
+
const detected = detectPresentLanguages(dir);
|
|
134
|
+
expect(detected.some((e) => e.languages.includes('typescript'))).toBe(true);
|
|
135
|
+
});
|
|
136
|
+
it('does not duplicate the TS/JS entry when both package.json and tsconfig.json are present', () => {
|
|
137
|
+
writeFileSync(join(dir, 'package.json'), '{}');
|
|
138
|
+
writeFileSync(join(dir, 'tsconfig.json'), '{}');
|
|
139
|
+
const detected = detectPresentLanguages(dir).filter((e) => e.languages.includes('typescript'));
|
|
140
|
+
expect(detected).toHaveLength(1);
|
|
141
|
+
});
|
|
142
|
+
it('detects Python via pyproject.toml', () => {
|
|
143
|
+
writeFileSync(join(dir, 'pyproject.toml'), '[project]\nname = "x"\n');
|
|
144
|
+
const detected = detectPresentLanguages(dir);
|
|
145
|
+
expect(detected.some((e) => e.languages.includes('python'))).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
it('detects Python via requirements.txt', () => {
|
|
148
|
+
writeFileSync(join(dir, 'requirements.txt'), '');
|
|
149
|
+
const detected = detectPresentLanguages(dir);
|
|
150
|
+
expect(detected.some((e) => e.languages.includes('python'))).toBe(true);
|
|
151
|
+
});
|
|
152
|
+
it('detects Rust via Cargo.toml', () => {
|
|
153
|
+
writeFileSync(join(dir, 'Cargo.toml'), '[package]\nname = "x"\n');
|
|
154
|
+
const detected = detectPresentLanguages(dir);
|
|
155
|
+
expect(detected.some((e) => e.languages.includes('rust'))).toBe(true);
|
|
156
|
+
});
|
|
157
|
+
it('detects a poly-language repo with Go, TS, Python, and Rust markers all present', () => {
|
|
158
|
+
writeFileSync(join(dir, 'go.mod'), 'module example.com/x\n');
|
|
159
|
+
writeFileSync(join(dir, 'package.json'), '{}');
|
|
160
|
+
writeFileSync(join(dir, 'pyproject.toml'), '[project]\nname = "x"\n');
|
|
161
|
+
writeFileSync(join(dir, 'Cargo.toml'), '[package]\nname = "x"\n');
|
|
162
|
+
const detected = detectPresentLanguages(dir);
|
|
163
|
+
const languages = new Set(detected.flatMap((e) => e.languages));
|
|
164
|
+
expect(languages.has('go')).toBe(true);
|
|
165
|
+
expect(languages.has('typescript')).toBe(true);
|
|
166
|
+
expect(languages.has('python')).toBe(true);
|
|
167
|
+
expect(languages.has('rust')).toBe(true);
|
|
168
|
+
});
|
|
169
|
+
it('detects Java+Kotlin via pom.xml', () => {
|
|
170
|
+
writeFileSync(join(dir, 'pom.xml'), '<project></project>\n');
|
|
171
|
+
const detected = detectPresentLanguages(dir);
|
|
172
|
+
expect(detected.some((e) => e.languages.includes('java'))).toBe(true);
|
|
173
|
+
expect(detected.some((e) => e.languages.includes('kotlin'))).toBe(true);
|
|
174
|
+
});
|
|
175
|
+
it('detects Java+Kotlin via build.gradle.kts', () => {
|
|
176
|
+
writeFileSync(join(dir, 'build.gradle.kts'), '');
|
|
177
|
+
const detected = detectPresentLanguages(dir);
|
|
178
|
+
expect(detected.some((e) => e.languages.includes('java'))).toBe(true);
|
|
179
|
+
});
|
|
180
|
+
it('does not duplicate the Java entry when both pom.xml and build.gradle are present', () => {
|
|
181
|
+
writeFileSync(join(dir, 'pom.xml'), '<project></project>\n');
|
|
182
|
+
writeFileSync(join(dir, 'build.gradle'), '');
|
|
183
|
+
const detected = detectPresentLanguages(dir).filter((e) => e.languages.includes('java'));
|
|
184
|
+
expect(detected).toHaveLength(1);
|
|
185
|
+
});
|
|
186
|
+
it('detects C# via a glob marker on *.csproj (no fixed filename)', () => {
|
|
187
|
+
writeFileSync(join(dir, 'MyApp.csproj'), '<Project></Project>\n');
|
|
188
|
+
const detected = detectPresentLanguages(dir);
|
|
189
|
+
expect(detected.some((e) => e.languages.includes('csharp'))).toBe(true);
|
|
190
|
+
});
|
|
191
|
+
it('detects C# via a glob marker on *.sln', () => {
|
|
192
|
+
writeFileSync(join(dir, 'MyApp.sln'), '');
|
|
193
|
+
const detected = detectPresentLanguages(dir);
|
|
194
|
+
expect(detected.some((e) => e.languages.includes('csharp'))).toBe(true);
|
|
195
|
+
});
|
|
196
|
+
it('does not detect C# when no *.csproj/*.sln file is present', () => {
|
|
197
|
+
writeFileSync(join(dir, 'notes.txt'), 'csproject but not a marker\n');
|
|
198
|
+
const detected = detectPresentLanguages(dir);
|
|
199
|
+
expect(detected.some((e) => e.languages.includes('csharp'))).toBe(false);
|
|
200
|
+
});
|
|
201
|
+
it('detects PHP via composer.json', () => {
|
|
202
|
+
writeFileSync(join(dir, 'composer.json'), '{}');
|
|
203
|
+
const detected = detectPresentLanguages(dir);
|
|
204
|
+
expect(detected.some((e) => e.languages.includes('php'))).toBe(true);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
describe('detectMarkerDirectories', () => {
|
|
208
|
+
/** Build nested subdirectories `dir/segs[0]/segs[1]/...` and return the leaf path. */
|
|
209
|
+
function nestedDir(segs) {
|
|
210
|
+
let cur = dir;
|
|
211
|
+
for (const seg of segs) {
|
|
212
|
+
cur = join(cur, seg);
|
|
213
|
+
mkdirSync(cur, { recursive: true });
|
|
214
|
+
}
|
|
215
|
+
return cur;
|
|
216
|
+
}
|
|
217
|
+
it('finds a marker at repo root (depth 0) — no regression vs detectPresentLanguages', () => {
|
|
218
|
+
writeFileSync(join(dir, 'package.json'), '{}');
|
|
219
|
+
const pairs = detectMarkerDirectories(dir);
|
|
220
|
+
const tsPairs = pairs.filter((p) => p.entry.languages.includes('typescript'));
|
|
221
|
+
expect(tsPairs).toHaveLength(1);
|
|
222
|
+
expect(tsPairs[0]?.dir).toBe(dir);
|
|
223
|
+
});
|
|
224
|
+
it('finds a nested-only marker (no root-level marker present)', () => {
|
|
225
|
+
const backend = nestedDir(['apps', 'backend']);
|
|
226
|
+
writeFileSync(join(backend, 'go.mod'), 'module example.com/x\n');
|
|
227
|
+
const pairs = detectMarkerDirectories(dir);
|
|
228
|
+
const goPairs = pairs.filter((p) => p.entry.languages.includes('go'));
|
|
229
|
+
expect(goPairs).toHaveLength(1);
|
|
230
|
+
expect(goPairs[0]?.dir).toBe(backend);
|
|
231
|
+
});
|
|
232
|
+
it('respects the default depth bound: a marker at depth 4 is found, at depth 5 is not', () => {
|
|
233
|
+
expect(DEFAULT_MARKER_DEPTH).toBe(4);
|
|
234
|
+
const atDepth4 = nestedDir(['l1', 'l2', 'l3', 'l4']);
|
|
235
|
+
writeFileSync(join(atDepth4, 'go.mod'), 'module x\n');
|
|
236
|
+
const atDepth5 = nestedDir(['m1', 'm2', 'm3', 'm4', 'm5']);
|
|
237
|
+
writeFileSync(join(atDepth5, 'Cargo.toml'), '[package]\nname = "x"\n');
|
|
238
|
+
const pairs = detectMarkerDirectories(dir);
|
|
239
|
+
const goPairs = pairs.filter((p) => p.entry.languages.includes('go'));
|
|
240
|
+
const rustPairs = pairs.filter((p) => p.entry.languages.includes('rust'));
|
|
241
|
+
expect(goPairs).toHaveLength(1);
|
|
242
|
+
expect(goPairs[0]?.dir).toBe(atDepth4);
|
|
243
|
+
expect(rustPairs).toHaveLength(0);
|
|
244
|
+
});
|
|
245
|
+
it('an explicit maxDepth override is honored', () => {
|
|
246
|
+
const atDepth2 = nestedDir(['a', 'b']);
|
|
247
|
+
writeFileSync(join(atDepth2, 'go.mod'), 'module x\n');
|
|
248
|
+
expect(detectMarkerDirectories(dir, { maxDepth: 1 })).toHaveLength(0);
|
|
249
|
+
expect(detectMarkerDirectories(dir, { maxDepth: 2 })).toHaveLength(1);
|
|
250
|
+
});
|
|
251
|
+
it('skips EXCLUDED_DIRS additions (.tools) even well within the depth bound', () => {
|
|
252
|
+
const toolsSub = nestedDir(['.tools', 'codeql']);
|
|
253
|
+
writeFileSync(join(toolsSub, 'go.mod'), 'module x\n');
|
|
254
|
+
const pairs = detectMarkerDirectories(dir);
|
|
255
|
+
expect(pairs).toHaveLength(0);
|
|
256
|
+
});
|
|
257
|
+
it('skips .ghagga and .worktrees too', () => {
|
|
258
|
+
writeFileSync(join(nestedDir(['.ghagga']), 'package.json'), '{}');
|
|
259
|
+
writeFileSync(join(nestedDir(['.worktrees', 'wt1']), 'package.json'), '{}');
|
|
260
|
+
const pairs = detectMarkerDirectories(dir);
|
|
261
|
+
expect(pairs).toHaveLength(0);
|
|
262
|
+
});
|
|
263
|
+
it('same language present in two different subdirectories yields two distinct pairs', () => {
|
|
264
|
+
const mlService = nestedDir(['apps', 'ml-service']);
|
|
265
|
+
const aiAssistant = nestedDir(['services', 'ai-assistant']);
|
|
266
|
+
writeFileSync(join(mlService, 'pyproject.toml'), '[project]\nname = "a"\n');
|
|
267
|
+
writeFileSync(join(aiAssistant, 'pyproject.toml'), '[project]\nname = "b"\n');
|
|
268
|
+
const pairs = detectMarkerDirectories(dir);
|
|
269
|
+
const pyPairs = pairs.filter((p) => p.entry.languages.includes('python'));
|
|
270
|
+
expect(pyPairs).toHaveLength(2);
|
|
271
|
+
const dirs = pyPairs.map((p) => p.dir).sort();
|
|
272
|
+
expect(dirs).toEqual([aiAssistant, mlService].sort());
|
|
273
|
+
});
|
|
274
|
+
it('finds a glob marker (*.csproj) nested in a subdirectory', () => {
|
|
275
|
+
const backend = nestedDir(['src', 'Backend']);
|
|
276
|
+
writeFileSync(join(backend, 'Backend.csproj'), '<Project></Project>\n');
|
|
277
|
+
const pairs = detectMarkerDirectories(dir);
|
|
278
|
+
const csharpPairs = pairs.filter((p) => p.entry.languages.includes('csharp'));
|
|
279
|
+
expect(csharpPairs).toHaveLength(1);
|
|
280
|
+
expect(csharpPairs[0]?.dir).toBe(backend);
|
|
281
|
+
});
|
|
282
|
+
it('deduplicates: does not emit the same {entry, dir} pair twice even with multiple matching markers', () => {
|
|
283
|
+
writeFileSync(join(dir, 'package.json'), '{}');
|
|
284
|
+
writeFileSync(join(dir, 'tsconfig.json'), '{}');
|
|
285
|
+
const pairs = detectMarkerDirectories(dir);
|
|
286
|
+
const tsPairs = pairs.filter((p) => p.entry.languages.includes('typescript'));
|
|
287
|
+
expect(tsPairs).toHaveLength(1);
|
|
288
|
+
});
|
|
289
|
+
it('a poly-language repo with both a root marker and a nested marker yields both pairs', () => {
|
|
290
|
+
writeFileSync(join(dir, 'package.json'), '{}');
|
|
291
|
+
const backend = nestedDir(['apps', 'backend']);
|
|
292
|
+
writeFileSync(join(backend, 'go.mod'), 'module x\n');
|
|
293
|
+
const pairs = detectMarkerDirectories(dir);
|
|
294
|
+
expect(pairs.some((p) => p.entry.languages.includes('typescript') && p.dir === dir)).toBe(true);
|
|
295
|
+
expect(pairs.some((p) => p.entry.languages.includes('go') && p.dir === backend)).toBe(true);
|
|
296
|
+
});
|
|
297
|
+
it('returns [] for an empty/unreadable directory (no throw)', () => {
|
|
298
|
+
expect(detectMarkerDirectories(dir)).toEqual([]);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
describe('detectPresentLanguages as a depth-0 wrapper over detectMarkerDirectories', () => {
|
|
302
|
+
it('still ignores nested-only markers (root-scope only, unchanged Tier A behavior)', () => {
|
|
303
|
+
mkdirSync(join(dir, 'app'));
|
|
304
|
+
writeFileSync(join(dir, 'app', 'package.json'), '{}');
|
|
305
|
+
writeFileSync(join(dir, 'go.mod'), 'module example.com/x\n');
|
|
306
|
+
const detected = detectPresentLanguages(dir);
|
|
307
|
+
expect(detected.some((e) => e.languages.includes('go'))).toBe(true);
|
|
308
|
+
expect(detected.some((e) => e.languages.includes('typescript'))).toBe(false);
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
describe('goEntry.run (real fs, mocked execFileSync)', () => {
|
|
312
|
+
const goEntry = INDEXER_REGISTRY.find((entry) => entry.bin === 'scip-go');
|
|
313
|
+
afterEach(() => {
|
|
314
|
+
execFileSyncMock.mockReset();
|
|
315
|
+
});
|
|
316
|
+
it('creates the isolated .ghagga/scip/ output dir on a fresh repo (regression guard for R1-001: fails before the mkdirSync fix, passes after)', () => {
|
|
317
|
+
const outPath = scipOutputPath(dir, 'scip-go');
|
|
318
|
+
// Simulate scip-go writing `index.scip` at the repo root, as the real
|
|
319
|
+
// binary does — no native --output flag.
|
|
320
|
+
execFileSyncMock.mockImplementation(() => {
|
|
321
|
+
writeFileSync(join(dir, 'index.scip'), 'fake-scip-index');
|
|
322
|
+
return Buffer.from('');
|
|
323
|
+
});
|
|
324
|
+
expect(goEntry).toBeDefined();
|
|
325
|
+
// .ghagga/scip/ must NOT pre-exist — that's the whole point of the guard.
|
|
326
|
+
// The dispatcher passes `outPath` explicitly — this mock does NOT
|
|
327
|
+
// pre-create it (hardened regression guard, not a papered mock).
|
|
328
|
+
const result = goEntry?.run(dir, outPath);
|
|
329
|
+
expect(result).toBe(outPath);
|
|
330
|
+
expect(existsSync(outPath)).toBe(true);
|
|
331
|
+
});
|
|
332
|
+
it('removes a stale pre-existing root index.scip before running, so it cannot leak into the output', () => {
|
|
333
|
+
const outPath = scipOutputPath(dir, 'scip-go');
|
|
334
|
+
writeFileSync(join(dir, 'index.scip'), 'stale-from-a-prior-manual-run');
|
|
335
|
+
execFileSyncMock.mockImplementation(() => {
|
|
336
|
+
writeFileSync(join(dir, 'index.scip'), 'fresh-scip-index');
|
|
337
|
+
return Buffer.from('');
|
|
338
|
+
});
|
|
339
|
+
const result = goEntry?.run(dir, outPath);
|
|
340
|
+
expect(result).toBe(outPath);
|
|
341
|
+
expect(existsSync(outPath)).toBe(true);
|
|
342
|
+
});
|
|
343
|
+
it('writes to a dispatcher-disambiguated outPath distinct from the default scipOutputPath(dir, bin)', () => {
|
|
344
|
+
const disambiguatedPath = join(dir, '.ghagga', 'scip', 'scip-go__apps_backend.scip');
|
|
345
|
+
execFileSyncMock.mockImplementation(() => {
|
|
346
|
+
writeFileSync(join(dir, 'index.scip'), 'fake-scip-index');
|
|
347
|
+
return Buffer.from('');
|
|
348
|
+
});
|
|
349
|
+
const result = goEntry?.run(dir, disambiguatedPath);
|
|
350
|
+
expect(result).toBe(disambiguatedPath);
|
|
351
|
+
expect(existsSync(disambiguatedPath)).toBe(true);
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
describe('tsEntry.run (real fs, mocked execFileSync)', () => {
|
|
355
|
+
const tsEntry = requireEntry('typescript');
|
|
356
|
+
afterEach(() => {
|
|
357
|
+
execFileSyncMock.mockReset();
|
|
358
|
+
});
|
|
359
|
+
it('creates the isolated .ghagga/scip/ output dir and writes directly to it via --output', () => {
|
|
360
|
+
const expectedOutPath = scipOutputPath(dir, 'scip-typescript');
|
|
361
|
+
// The mock does NOT create the isolated dir — scip-typescript writes
|
|
362
|
+
// straight to --output but requires the parent to pre-exist (verified live:
|
|
363
|
+
// ENOENT otherwise). So this writeFileSync only succeeds if production's own
|
|
364
|
+
// mkdirSync(dirname(outPath)) ran first. Delete that production line and
|
|
365
|
+
// this test fails — the real R1-001 regression guard, not a papered mock.
|
|
366
|
+
execFileSyncMock.mockImplementation(() => {
|
|
367
|
+
writeFileSync(expectedOutPath, 'fake-scip-index');
|
|
368
|
+
return Buffer.from('');
|
|
369
|
+
});
|
|
370
|
+
// .ghagga/scip/ must NOT pre-exist going in — that's the point of the guard.
|
|
371
|
+
expect(existsSync(dirname(expectedOutPath))).toBe(false);
|
|
372
|
+
const result = tsEntry.run(dir, expectedOutPath);
|
|
373
|
+
expect(result).toBe(expectedOutPath);
|
|
374
|
+
expect(existsSync(expectedOutPath)).toBe(true);
|
|
375
|
+
expect(execFileSyncMock).toHaveBeenCalledWith('scip-typescript', expect.arrayContaining(['index', '--output', expectedOutPath]), expect.objectContaining({ cwd: dir }));
|
|
376
|
+
});
|
|
377
|
+
it('throws if scip-typescript does not produce an index at the passed outPath', () => {
|
|
378
|
+
const expectedOutPath = scipOutputPath(dir, 'scip-typescript');
|
|
379
|
+
execFileSyncMock.mockImplementation(() => Buffer.from(''));
|
|
380
|
+
expect(() => tsEntry.run(dir, expectedOutPath)).toThrow(/did not produce an index/);
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
describe('pythonEntry.run (real fs, mocked execFileSync)', () => {
|
|
384
|
+
const pythonEntry = requireEntry('python');
|
|
385
|
+
afterEach(() => {
|
|
386
|
+
execFileSyncMock.mockReset();
|
|
387
|
+
});
|
|
388
|
+
it('creates the isolated .ghagga/scip/ output dir and writes directly to it via --output', () => {
|
|
389
|
+
const expectedOutPath = scipOutputPath(dir, 'scip-python');
|
|
390
|
+
// Mock does NOT create the dir — production's mkdirSync must run first, or
|
|
391
|
+
// this writeFileSync throws ENOENT. Real regression guard for R1-001.
|
|
392
|
+
execFileSyncMock.mockImplementation(() => {
|
|
393
|
+
writeFileSync(expectedOutPath, 'fake-scip-index');
|
|
394
|
+
return Buffer.from('');
|
|
395
|
+
});
|
|
396
|
+
expect(existsSync(dirname(expectedOutPath))).toBe(false);
|
|
397
|
+
const result = pythonEntry.run(dir, expectedOutPath);
|
|
398
|
+
expect(result).toBe(expectedOutPath);
|
|
399
|
+
expect(existsSync(expectedOutPath)).toBe(true);
|
|
400
|
+
});
|
|
401
|
+
it('throws if scip-python does not produce an index at the passed outPath', () => {
|
|
402
|
+
const expectedOutPath = scipOutputPath(dir, 'scip-python');
|
|
403
|
+
execFileSyncMock.mockImplementation(() => Buffer.from(''));
|
|
404
|
+
expect(() => pythonEntry.run(dir, expectedOutPath)).toThrow(/did not produce an index/);
|
|
405
|
+
});
|
|
406
|
+
it('two runs of pythonEntry against distinct dispatcher-chosen outPaths do not clobber each other (D3 collision guard)', () => {
|
|
407
|
+
const mlServiceOut = join(dir, '.ghagga', 'scip', 'scip-python__apps_ml-service.scip');
|
|
408
|
+
const aiAssistantOut = join(dir, '.ghagga', 'scip', 'scip-python__services_ai-assistant.scip');
|
|
409
|
+
execFileSyncMock.mockImplementationOnce(() => {
|
|
410
|
+
writeFileSync(mlServiceOut, 'ml-service-index');
|
|
411
|
+
return Buffer.from('');
|
|
412
|
+
});
|
|
413
|
+
const firstResult = pythonEntry.run(dir, mlServiceOut);
|
|
414
|
+
execFileSyncMock.mockImplementationOnce(() => {
|
|
415
|
+
writeFileSync(aiAssistantOut, 'ai-assistant-index');
|
|
416
|
+
return Buffer.from('');
|
|
417
|
+
});
|
|
418
|
+
const secondResult = pythonEntry.run(dir, aiAssistantOut);
|
|
419
|
+
expect(firstResult).toBe(mlServiceOut);
|
|
420
|
+
expect(secondResult).toBe(aiAssistantOut);
|
|
421
|
+
expect(existsSync(mlServiceOut)).toBe(true);
|
|
422
|
+
expect(existsSync(aiAssistantOut)).toBe(true);
|
|
423
|
+
expect(readFileSync(mlServiceOut, 'utf-8')).toBe('ml-service-index');
|
|
424
|
+
expect(readFileSync(aiAssistantOut, 'utf-8')).toBe('ai-assistant-index');
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
describe('rustEntry.run (real fs, mocked execFileSync)', () => {
|
|
428
|
+
const rustEntry = requireEntry('rust');
|
|
429
|
+
afterEach(() => {
|
|
430
|
+
execFileSyncMock.mockReset();
|
|
431
|
+
});
|
|
432
|
+
it('creates the isolated .ghagga/scip/ output dir and writes directly to it via --output', () => {
|
|
433
|
+
const expectedOutPath = scipOutputPath(dir, 'rust-analyzer');
|
|
434
|
+
// Mock does NOT create the dir — production's mkdirSync must run first, or
|
|
435
|
+
// this writeFileSync throws ENOENT. Real regression guard for R1-001.
|
|
436
|
+
execFileSyncMock.mockImplementation(() => {
|
|
437
|
+
writeFileSync(expectedOutPath, 'fake-scip-index');
|
|
438
|
+
return Buffer.from('');
|
|
439
|
+
});
|
|
440
|
+
expect(existsSync(dirname(expectedOutPath))).toBe(false);
|
|
441
|
+
const result = rustEntry.run(dir, expectedOutPath);
|
|
442
|
+
expect(result).toBe(expectedOutPath);
|
|
443
|
+
expect(existsSync(expectedOutPath)).toBe(true);
|
|
444
|
+
expect(execFileSyncMock).toHaveBeenCalledWith('rust-analyzer', expect.arrayContaining(['scip', dir, '--output', expectedOutPath]), expect.objectContaining({ cwd: dir }));
|
|
445
|
+
});
|
|
446
|
+
it('throws if rust-analyzer does not produce an index at the passed outPath', () => {
|
|
447
|
+
const expectedOutPath = scipOutputPath(dir, 'rust-analyzer');
|
|
448
|
+
execFileSyncMock.mockImplementation(() => Buffer.from(''));
|
|
449
|
+
expect(() => rustEntry.run(dir, expectedOutPath)).toThrow(/did not produce an index/);
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
describe('javaEntry.run (real fs, mocked execFileSync)', () => {
|
|
453
|
+
const javaEntry = requireEntry('java');
|
|
454
|
+
afterEach(() => {
|
|
455
|
+
execFileSyncMock.mockReset();
|
|
456
|
+
});
|
|
457
|
+
it('creates the isolated .ghagga/scip/ output dir and writes directly to it via --output', () => {
|
|
458
|
+
const expectedOutPath = scipOutputPath(dir, 'scip-java');
|
|
459
|
+
// Mock does NOT create the dir — production's mkdirSync must run first, or
|
|
460
|
+
// this writeFileSync throws ENOENT. Real regression guard for R1-001.
|
|
461
|
+
execFileSyncMock.mockImplementation(() => {
|
|
462
|
+
writeFileSync(expectedOutPath, 'fake-scip-index');
|
|
463
|
+
return Buffer.from('');
|
|
464
|
+
});
|
|
465
|
+
expect(existsSync(dirname(expectedOutPath))).toBe(false);
|
|
466
|
+
const result = javaEntry.run(dir, expectedOutPath);
|
|
467
|
+
expect(result).toBe(expectedOutPath);
|
|
468
|
+
expect(existsSync(expectedOutPath)).toBe(true);
|
|
469
|
+
expect(execFileSyncMock).toHaveBeenCalledWith('scip-java', expect.arrayContaining(['index', '--output', expectedOutPath]), expect.objectContaining({ cwd: dir }));
|
|
470
|
+
});
|
|
471
|
+
it('throws if scip-java does not produce an index at the passed outPath', () => {
|
|
472
|
+
const expectedOutPath = scipOutputPath(dir, 'scip-java');
|
|
473
|
+
execFileSyncMock.mockImplementation(() => Buffer.from(''));
|
|
474
|
+
expect(() => javaEntry.run(dir, expectedOutPath)).toThrow(/did not produce an index/);
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
describe('csharpEntry.run (real fs, mocked execFileSync)', () => {
|
|
478
|
+
const csharpEntry = requireEntry('csharp');
|
|
479
|
+
afterEach(() => {
|
|
480
|
+
execFileSyncMock.mockReset();
|
|
481
|
+
});
|
|
482
|
+
it('creates the isolated .ghagga/scip/ output dir and writes directly to it via --output', () => {
|
|
483
|
+
const expectedOutPath = scipOutputPath(dir, 'scip-dotnet');
|
|
484
|
+
// Mock does NOT create the dir — production's mkdirSync must run first, or
|
|
485
|
+
// this writeFileSync throws ENOENT. Real regression guard for R1-001.
|
|
486
|
+
execFileSyncMock.mockImplementation(() => {
|
|
487
|
+
writeFileSync(expectedOutPath, 'fake-scip-index');
|
|
488
|
+
return Buffer.from('');
|
|
489
|
+
});
|
|
490
|
+
expect(existsSync(dirname(expectedOutPath))).toBe(false);
|
|
491
|
+
const result = csharpEntry.run(dir, expectedOutPath);
|
|
492
|
+
expect(result).toBe(expectedOutPath);
|
|
493
|
+
expect(existsSync(expectedOutPath)).toBe(true);
|
|
494
|
+
expect(execFileSyncMock).toHaveBeenCalledWith('scip-dotnet', expect.arrayContaining(['index', '--output', expectedOutPath, '--working-directory', dir]), expect.objectContaining({ cwd: dir }));
|
|
495
|
+
});
|
|
496
|
+
it('throws if scip-dotnet does not produce an index at the passed outPath', () => {
|
|
497
|
+
const expectedOutPath = scipOutputPath(dir, 'scip-dotnet');
|
|
498
|
+
execFileSyncMock.mockImplementation(() => Buffer.from(''));
|
|
499
|
+
expect(() => csharpEntry.run(dir, expectedOutPath)).toThrow(/did not produce an index/);
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
describe('phpEntry.run (real fs, mocked execFileSync)', () => {
|
|
503
|
+
const phpEntry = requireEntry('php');
|
|
504
|
+
afterEach(() => {
|
|
505
|
+
execFileSyncMock.mockReset();
|
|
506
|
+
});
|
|
507
|
+
it('creates the isolated .ghagga/scip/ output dir on a fresh repo (run-then-move, no native --output)', () => {
|
|
508
|
+
const outPath = scipOutputPath(dir, 'scip-php');
|
|
509
|
+
// Simulate scip-php writing `index.scip` at the repo root, as the real
|
|
510
|
+
// binary does — no --output flag (verified against upstream source).
|
|
511
|
+
execFileSyncMock.mockImplementation(() => {
|
|
512
|
+
writeFileSync(join(dir, 'index.scip'), 'fake-scip-index');
|
|
513
|
+
return Buffer.from('');
|
|
514
|
+
});
|
|
515
|
+
const result = phpEntry.run(dir, outPath);
|
|
516
|
+
expect(result).toBe(outPath);
|
|
517
|
+
expect(existsSync(outPath)).toBe(true);
|
|
518
|
+
// The root-level index.scip must have been moved, not left behind.
|
|
519
|
+
expect(existsSync(join(dir, 'index.scip'))).toBe(false);
|
|
520
|
+
});
|
|
521
|
+
it('removes a stale pre-existing root index.scip before running, so it cannot leak into the output', () => {
|
|
522
|
+
const outPath = scipOutputPath(dir, 'scip-php');
|
|
523
|
+
writeFileSync(join(dir, 'index.scip'), 'stale-from-a-prior-manual-run');
|
|
524
|
+
execFileSyncMock.mockImplementation(() => {
|
|
525
|
+
writeFileSync(join(dir, 'index.scip'), 'fresh-scip-index');
|
|
526
|
+
return Buffer.from('');
|
|
527
|
+
});
|
|
528
|
+
const result = phpEntry.run(dir, outPath);
|
|
529
|
+
expect(result).toBe(outPath);
|
|
530
|
+
expect(existsSync(outPath)).toBe(true);
|
|
531
|
+
});
|
|
532
|
+
it('throws if scip-php does not produce an index.scip at its cwd', () => {
|
|
533
|
+
const outPath = scipOutputPath(dir, 'scip-php');
|
|
534
|
+
execFileSyncMock.mockImplementation(() => Buffer.from(''));
|
|
535
|
+
expect(() => phpEntry.run(dir, outPath)).toThrow(/did not produce an index/);
|
|
536
|
+
});
|
|
537
|
+
});
|
|
538
|
+
//# sourceMappingURL=indexer-registry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer-registry.test.js","sourceRoot":"","sources":["../../src/commands/indexer-registry.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClG,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEzE,sEAAsE;AACtE,0EAA0E;AAC1E,wEAAwE;AACxE,iCAAiC;AACjC,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AACjC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IACrD,MAAM,MAAM,GAAG,MAAM,cAAc,EAAuC,CAAC;IAC3E,OAAO,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;AACxF,CAAC,CAAC,CAAC;AAEH,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,kFAAkF;AAClF,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAiB,CAAC,CAAC,CAAC;IACpF,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;IACjE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,IAAI,GAAW,CAAC;AAEhB,UAAU,CAAC,GAAG,EAAE;IACd,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,0BAA0B,CAAC,CAAC,CAAC;AAChE,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACzB,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,EAAE,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QACtC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACvC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;QACtF,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,EAAE,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CACxB,MAAM,CAAC,eAAe,CAAC,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,CAAC,CAAC,CAC3E,CAAC;QACF,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,4DAA4D,EAAE,GAAG,EAAE;IAC1E,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAC1B,MAAM,CAAC,eAAe,CAAC,CAAC,SAAS,EAAE,cAAc,EAAE,kBAAkB,CAAC,CAAC,CACxE,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/C,sEAAsE;QACtE,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACvE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAC7D,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5B,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QAEtD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,4EAA4E;QAC5E,wEAAwE;QACxE,4CAA4C;QAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yFAAyF,EAAE,GAAG,EAAE;QACjG,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/C,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;QAC/F,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,yBAAyB,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,yBAAyB,CAAC,CAAC;QAClE,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAC7D,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/C,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,yBAAyB,CAAC,CAAC;QACtE,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,yBAAyB,CAAC,CAAC;QAClE,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAChE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,uBAAuB,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kFAAkF,EAAE,GAAG,EAAE;QAC1F,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,uBAAuB,CAAC,CAAC;QAC7D,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,uBAAuB,CAAC,CAAC;QAClE,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,8BAA8B,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,sFAAsF;IACtF,SAAS,SAAS,CAAC,IAAc;QAC/B,IAAI,GAAG,GAAG,GAAG,CAAC;QACd,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QAC/C,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAEjE,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mFAAmF,EAAE,GAAG,EAAE;QAC3F,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAErC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACrD,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAC;QAEtD,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC3D,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,yBAAyB,CAAC,CAAC;QAEvE,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAE1E,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACvC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAC;QAEtD,MAAM,CAAC,uBAAuB,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,CAAC,uBAAuB,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjD,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAC;QAEtD,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QAClE,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QAE5E,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;QAC5D,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,EAAE,yBAAyB,CAAC,CAAC;QAC5E,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,yBAAyB,CAAC,CAAC;QAE9E,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;QAC9C,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,uBAAuB,CAAC,CAAC;QAExE,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kGAAkG,EAAE,GAAG,EAAE;QAC1G,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/C,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC;QAEhD,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE,GAAG,EAAE;QAC5F,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QAC/C,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAC;QAErD,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0EAA0E,EAAE,GAAG,EAAE;IACxF,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5B,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QACtD,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAE7D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC;IAE1E,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2IAA2I,EAAE,GAAG,EAAE;QACnJ,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC/C,sEAAsE;QACtE,yCAAyC;QACzC,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAC;YAC1D,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9B,0EAA0E;QAC1E,kEAAkE;QAClE,iEAAiE;QACjE,MAAM,MAAM,GAAG,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gGAAgG,EAAE,GAAG,EAAE;QACxG,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC/C,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,+BAA+B,CAAC,CAAC;QAExE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,kBAAkB,CAAC,CAAC;YAC3D,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iGAAiG,EAAE,GAAG,EAAE;QACzG,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,4BAA4B,CAAC,CAAC;QACrF,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAC;YAC1D,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAEpD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACvC,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sFAAsF,EAAE,GAAG,EAAE;QAC9F,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAC/D,qEAAqE;QACrE,4EAA4E;QAC5E,6EAA6E;QAC7E,yEAAyE;QACzE,0EAA0E;QAC1E,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,6EAA6E;QAC7E,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACrC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAC3C,iBAAiB,EACjB,MAAM,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC,EAC9D,MAAM,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CACtC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,GAAG,EAAE;QACnF,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAC/D,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sFAAsF,EAAE,GAAG,EAAE;QAC9F,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC3D,2EAA2E;QAC3E,sEAAsE;QACtE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAErD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACrC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC3D,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oHAAoH,EAAE,GAAG,EAAE;QAC5H,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,mCAAmC,CAAC,CAAC;QACvF,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,yCAAyC,CAAC,CAAC;QAE/F,gBAAgB,CAAC,sBAAsB,CAAC,GAAG,EAAE;YAC3C,aAAa,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;YAChD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAEvD,gBAAgB,CAAC,sBAAsB,CAAC,GAAG,EAAE;YAC3C,aAAa,CAAC,cAAc,EAAE,oBAAoB,CAAC,CAAC;YACpD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAE1D,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1C,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACrE,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAEvC,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sFAAsF,EAAE,GAAG,EAAE;QAC9F,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAC7D,2EAA2E;QAC3E,sEAAsE;QACtE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACrC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAC3C,eAAe,EACf,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC,EAClE,MAAM,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CACtC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAC7D,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAEvC,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sFAAsF,EAAE,GAAG,EAAE;QAC9F,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACzD,2EAA2E;QAC3E,sEAAsE;QACtE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACrC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAC3C,WAAW,EACX,MAAM,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC,EAC9D,MAAM,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CACtC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACzD,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sFAAsF,EAAE,GAAG,EAAE;QAC9F,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC3D,2EAA2E;QAC3E,sEAAsE;QACtE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAErD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACrC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAC3C,aAAa,EACb,MAAM,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,qBAAqB,EAAE,GAAG,CAAC,CAAC,EAC1F,MAAM,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CACtC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC3D,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;IAC3D,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAErC,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mGAAmG,EAAE,GAAG,EAAE;QAC3G,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAChD,uEAAuE;QACvE,qEAAqE;QACrE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAC;YAC1D,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,mEAAmE;QACnE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gGAAgG,EAAE,GAAG,EAAE;QACxG,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAChD,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,+BAA+B,CAAC,CAAC;QAExE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,kBAAkB,CAAC,CAAC;YAC3D,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAChD,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the blast-radius pure seams extracted from `reviewCommand`
|
|
3
|
+
* (design v2 D9): `resolveBlastRadiusEnabled`, `checkGraphStaleness`,
|
|
4
|
+
* `computeUncoveredLanguages`.
|
|
5
|
+
*
|
|
6
|
+
* `resolveBlastRadiusEnabled` touches the real filesystem (existsSync) — a
|
|
7
|
+
* REAL temp dir (mkdtempSync) is used, NOT a mocked `node:fs`, so the actual
|
|
8
|
+
* repoPath-relative resolution is exercised (CRITICAL-2 regression guard).
|
|
9
|
+
* This file deliberately does NOT `vi.mock('node:fs')` (unlike review.test.ts)
|
|
10
|
+
* to keep that guarantee honest.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=review-blast-radius.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-blast-radius.test.d.ts","sourceRoot":"","sources":["../../src/commands/review-blast-radius.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|