depguard-cli 1.3.1 → 1.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 +116 -2
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js +14 -6
- package/dist/audit.js.map +1 -1
- package/dist/cli.js +75 -2
- package/dist/cli.js.map +1 -1
- package/dist/guard.d.ts +29 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/guard.js +233 -0
- package/dist/guard.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +54 -1
- package/dist/license.js.map +1 -1
- package/dist/mcp.js +65 -1
- package/dist/mcp.js.map +1 -1
- package/dist/scorer.d.ts.map +1 -1
- package/dist/scorer.js +55 -14
- package/dist/scorer.js.map +1 -1
- package/dist/semver.d.ts +3 -1
- package/dist/semver.d.ts.map +1 -1
- package/dist/semver.js +24 -5
- package/dist/semver.js.map +1 -1
- package/dist/sweep.d.ts +53 -0
- package/dist/sweep.d.ts.map +1 -0
- package/dist/sweep.js +639 -0
- package/dist/sweep.js.map +1 -0
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +31 -0
- package/dist/tokens.js.map +1 -1
- package/dist/types.d.ts +69 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/sweep.js
ADDED
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dead dependency detection.
|
|
3
|
+
*
|
|
4
|
+
* Scans a project's source files for import/require statements and
|
|
5
|
+
* cross-references with package.json to find unused dependencies.
|
|
6
|
+
*
|
|
7
|
+
* Purely filesystem-based — zero network calls.
|
|
8
|
+
* Zero dependencies — only Node.js built-ins.
|
|
9
|
+
*/
|
|
10
|
+
import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs';
|
|
11
|
+
import { join, extname, resolve } from 'node:path';
|
|
12
|
+
/** File extensions to scan for imports */
|
|
13
|
+
const SOURCE_EXTENSIONS = new Set([
|
|
14
|
+
'.js', '.ts', '.mjs', '.cjs', '.jsx', '.tsx',
|
|
15
|
+
'.vue', '.svelte', '.astro', '.mdx',
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Check if a package has install scripts (postinstall, preinstall, install).
|
|
19
|
+
* Packages with install scripts likely do something important at install time.
|
|
20
|
+
*/
|
|
21
|
+
function hasInstallScripts(projectPath, packageName) {
|
|
22
|
+
try {
|
|
23
|
+
const pkgPath = join(projectPath, 'node_modules', ...packageName.split('/'), 'package.json');
|
|
24
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
25
|
+
const scripts = pkg.scripts ?? {};
|
|
26
|
+
return !!(scripts.postinstall || scripts.preinstall || scripts.install);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Safety note included in every sweep result */
|
|
33
|
+
const SWEEP_NOTE = 'These are recommendations based on static analysis. Verify before removing — some packages may be used dynamically, in CI/CD pipelines, or by tools not detected by static scanning.';
|
|
34
|
+
/** Stylesheet extensions to scan for @use/@import of packages */
|
|
35
|
+
const STYLE_EXTENSIONS = new Set(['.css', '.scss', '.sass', '.less']);
|
|
36
|
+
/** Directories to always exclude from scanning */
|
|
37
|
+
const EXCLUDE_DIRS = new Set([
|
|
38
|
+
'node_modules', 'dist', 'build', '.git', '.next', '.nuxt', '.svelte-kit',
|
|
39
|
+
'coverage', 'out', '.output', '.cache', '.turbo', '__pycache__',
|
|
40
|
+
]);
|
|
41
|
+
/**
|
|
42
|
+
* Well-known config file patterns → the tool dependency they imply.
|
|
43
|
+
* Key is a filename prefix/pattern, value is the package(s) it implies.
|
|
44
|
+
*/
|
|
45
|
+
const CONFIG_FILE_DEPS = {
|
|
46
|
+
'.eslintrc': ['eslint'],
|
|
47
|
+
'eslint.config': ['eslint'],
|
|
48
|
+
'.prettierrc': ['prettier'],
|
|
49
|
+
'prettier.config': ['prettier'],
|
|
50
|
+
'jest.config': ['jest'],
|
|
51
|
+
'vitest.config': ['vitest'],
|
|
52
|
+
'babel.config': ['@babel/core'],
|
|
53
|
+
'.babelrc': ['@babel/core'],
|
|
54
|
+
'tsconfig': ['typescript'],
|
|
55
|
+
'tailwind.config': ['tailwindcss'],
|
|
56
|
+
'postcss.config': ['postcss'],
|
|
57
|
+
'webpack.config': ['webpack'],
|
|
58
|
+
'rollup.config': ['rollup'],
|
|
59
|
+
'vite.config': ['vite'],
|
|
60
|
+
'next.config': ['next'],
|
|
61
|
+
'nuxt.config': ['nuxt'],
|
|
62
|
+
'svelte.config': ['svelte'],
|
|
63
|
+
'.swcrc': ['@swc/core'],
|
|
64
|
+
'.mocharc': ['mocha'],
|
|
65
|
+
'cypress.config': ['cypress'],
|
|
66
|
+
'playwright.config': ['playwright', '@playwright/test'],
|
|
67
|
+
'.storybook': ['storybook'],
|
|
68
|
+
'turbo.json': ['turbo'],
|
|
69
|
+
'nx.json': ['nx'],
|
|
70
|
+
'lerna.json': ['lerna'],
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Normalize a module specifier to a package name.
|
|
74
|
+
* `@scope/pkg/sub/path` → `@scope/pkg`
|
|
75
|
+
* `pkg/sub/path` → `pkg`
|
|
76
|
+
* `pkg` → `pkg`
|
|
77
|
+
*/
|
|
78
|
+
export function normalizeToPackageName(specifier) {
|
|
79
|
+
if (specifier.startsWith('@')) {
|
|
80
|
+
// Scoped: @scope/pkg/...
|
|
81
|
+
const parts = specifier.split('/');
|
|
82
|
+
if (parts.length >= 2)
|
|
83
|
+
return `${parts[0]}/${parts[1]}`;
|
|
84
|
+
return specifier;
|
|
85
|
+
}
|
|
86
|
+
// Unscoped: pkg/...
|
|
87
|
+
return specifier.split('/')[0];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Extract package names from import/require/re-export statements in source code.
|
|
91
|
+
* Returns a Set of normalized package names (excludes relative imports).
|
|
92
|
+
*/
|
|
93
|
+
export function extractImports(source) {
|
|
94
|
+
const packages = new Set();
|
|
95
|
+
// ES static imports: import ... from 'pkg' / import 'pkg'
|
|
96
|
+
const esImport = /import\s+(?:[\s\S]*?\s+from\s+)?['"]([^'"./][^'"]*)['"]/g;
|
|
97
|
+
// Dynamic imports: import('pkg')
|
|
98
|
+
const dynImport = /import\s*\(\s*['"]([^'"./][^'"]*)['"]\s*\)/g;
|
|
99
|
+
// CommonJS: require('pkg')
|
|
100
|
+
const cjsRequire = /require\s*\(\s*['"]([^'"./][^'"]*)['"]\s*\)/g;
|
|
101
|
+
// Re-exports: export ... from 'pkg'
|
|
102
|
+
const reExport = /export\s+[\s\S]*?\s+from\s+['"]([^'"./][^'"]*)['"]/g;
|
|
103
|
+
// require.resolve('pkg') — used to locate packages without importing
|
|
104
|
+
const requireResolve = /require\.resolve\s*\(\s*['"]([^'"./][^'"]*)['"]\s*\)/g;
|
|
105
|
+
// jest.mock('pkg'), jest.requireActual('pkg'), jest.unmock('pkg')
|
|
106
|
+
const jestMock = /jest\.(?:mock|requireActual|unmock)\s*\(\s*['"]([^'"./][^'"]*)['"]/g;
|
|
107
|
+
// TypeScript module augmentation: declare module 'pkg'
|
|
108
|
+
const declareModule = /declare\s+module\s+['"]([^'"./][^'"]*)['"]/g;
|
|
109
|
+
for (const pattern of [esImport, dynImport, cjsRequire, reExport, requireResolve, jestMock, declareModule]) {
|
|
110
|
+
let match;
|
|
111
|
+
while ((match = pattern.exec(source)) !== null) {
|
|
112
|
+
const specifier = match[1];
|
|
113
|
+
// Skip node: built-in modules
|
|
114
|
+
if (specifier.startsWith('node:'))
|
|
115
|
+
continue;
|
|
116
|
+
packages.add(normalizeToPackageName(specifier));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return packages;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Recursively collect source files matching the given extensions.
|
|
123
|
+
* Excludes directories in the exclude set.
|
|
124
|
+
*/
|
|
125
|
+
export function collectSourceFiles(dir, extensions = SOURCE_EXTENSIONS, excludeDirs = EXCLUDE_DIRS) {
|
|
126
|
+
const files = [];
|
|
127
|
+
let entries;
|
|
128
|
+
try {
|
|
129
|
+
entries = readdirSync(dir);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return files;
|
|
133
|
+
}
|
|
134
|
+
for (const entry of entries) {
|
|
135
|
+
if (excludeDirs.has(entry))
|
|
136
|
+
continue;
|
|
137
|
+
const fullPath = join(dir, entry);
|
|
138
|
+
let stat;
|
|
139
|
+
try {
|
|
140
|
+
stat = statSync(fullPath);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (stat.isDirectory()) {
|
|
146
|
+
files.push(...collectSourceFiles(fullPath, extensions, excludeDirs));
|
|
147
|
+
}
|
|
148
|
+
else if (stat.isFile() && extensions.has(extname(entry))) {
|
|
149
|
+
files.push(fullPath);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return files;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Check config files in the project root for tool-dependency references.
|
|
156
|
+
* Returns a map of package name → usage reason.
|
|
157
|
+
*/
|
|
158
|
+
export function findConfigDependencies(projectPath) {
|
|
159
|
+
const configDeps = new Map();
|
|
160
|
+
let rootEntries;
|
|
161
|
+
try {
|
|
162
|
+
rootEntries = readdirSync(projectPath);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return configDeps;
|
|
166
|
+
}
|
|
167
|
+
for (const entry of rootEntries) {
|
|
168
|
+
for (const [pattern, deps] of Object.entries(CONFIG_FILE_DEPS)) {
|
|
169
|
+
if (entry.startsWith(pattern) || entry === pattern) {
|
|
170
|
+
for (const dep of deps) {
|
|
171
|
+
configDeps.set(dep, 'config-referenced');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Scan config file content for plugin references
|
|
176
|
+
if (entry.match(/eslint\.config|\.eslintrc/)) {
|
|
177
|
+
scanConfigForPlugins(join(projectPath, entry), configDeps, 'eslint-plugin-', 'eslint-config-', '@typescript-eslint/');
|
|
178
|
+
}
|
|
179
|
+
if (entry.match(/babel\.config|\.babelrc/)) {
|
|
180
|
+
scanConfigForPlugins(join(projectPath, entry), configDeps, '@babel/plugin-', '@babel/preset-', 'babel-plugin-', 'babel-preset-');
|
|
181
|
+
}
|
|
182
|
+
if (entry.match(/jest\.config/)) {
|
|
183
|
+
scanConfigForPlugins(join(projectPath, entry), configDeps, 'jest-', 'ts-jest', 'babel-jest', '@jest/');
|
|
184
|
+
}
|
|
185
|
+
if (entry.match(/tailwind\.config/)) {
|
|
186
|
+
scanConfigForPlugins(join(projectPath, entry), configDeps, '@tailwindcss/', 'tailwindcss-');
|
|
187
|
+
}
|
|
188
|
+
if (entry.match(/postcss\.config/)) {
|
|
189
|
+
scanConfigForPlugins(join(projectPath, entry), configDeps, 'postcss-', 'autoprefixer', 'cssnano');
|
|
190
|
+
}
|
|
191
|
+
if (entry.match(/webpack\.config/)) {
|
|
192
|
+
scanConfigForPlugins(join(projectPath, entry), configDeps, '-loader', '-plugin', 'webpack-');
|
|
193
|
+
}
|
|
194
|
+
if (entry.match(/vite\.config|rollup\.config/)) {
|
|
195
|
+
scanConfigForPlugins(join(projectPath, entry), configDeps, '@vitejs/', 'vite-plugin-', '@rollup/', 'rollup-plugin-');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return configDeps;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Scan a config file for plugin name references.
|
|
202
|
+
*/
|
|
203
|
+
function scanConfigForPlugins(filePath, configDeps, ...prefixes) {
|
|
204
|
+
try {
|
|
205
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
206
|
+
// Extract all string literals from the file
|
|
207
|
+
const strings = content.match(/['"]([^'"]+)['"]/g) ?? [];
|
|
208
|
+
for (const str of strings) {
|
|
209
|
+
const value = str.slice(1, -1); // Remove quotes
|
|
210
|
+
for (const prefix of prefixes) {
|
|
211
|
+
// Match: starts with prefix, ends with suffix, or equals prefix without trailing dash
|
|
212
|
+
if (value.startsWith(prefix) || value.endsWith(prefix) || value === prefix.replace(/-$/, '')) {
|
|
213
|
+
configDeps.set(value, 'config-referenced');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Also catch scoped packages referenced as strings in configs (e.g., "@scope/plugin")
|
|
217
|
+
if (value.startsWith('@') && value.includes('/')) {
|
|
218
|
+
configDeps.set(value, 'config-referenced');
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// Config file not readable, skip
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Check npm scripts in package.json for binary references.
|
|
228
|
+
* Returns a map of package name → usage reason.
|
|
229
|
+
*/
|
|
230
|
+
export function findScriptDependencies(scripts, projectPath) {
|
|
231
|
+
const scriptDeps = new Map();
|
|
232
|
+
// Build a map of binary name → package name from node_modules/.bin
|
|
233
|
+
const binMap = new Map();
|
|
234
|
+
const nmPath = join(projectPath, 'node_modules');
|
|
235
|
+
if (existsSync(nmPath)) {
|
|
236
|
+
try {
|
|
237
|
+
const topLevelDeps = readdirSync(nmPath);
|
|
238
|
+
for (const dep of topLevelDeps) {
|
|
239
|
+
if (dep.startsWith('.'))
|
|
240
|
+
continue;
|
|
241
|
+
if (dep.startsWith('@')) {
|
|
242
|
+
// Scoped packages
|
|
243
|
+
try {
|
|
244
|
+
const scopedDeps = readdirSync(join(nmPath, dep));
|
|
245
|
+
for (const scopedDep of scopedDeps) {
|
|
246
|
+
readBinFromPackage(join(nmPath, dep, scopedDep), `${dep}/${scopedDep}`, binMap);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch { /* skip */ }
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
readBinFromPackage(join(nmPath, dep), dep, binMap);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
catch { /* skip */ }
|
|
257
|
+
}
|
|
258
|
+
// Check each script value for binary references and --require/--loader flags
|
|
259
|
+
for (const scriptValue of Object.values(scripts)) {
|
|
260
|
+
const tokens = scriptValue.split(/[\s;&|]+/);
|
|
261
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
262
|
+
const token = tokens[i];
|
|
263
|
+
const cleanToken = token.replace(/^(?:npx|pnpx|yarn|bunx)\s+/, '');
|
|
264
|
+
// Check against binary map
|
|
265
|
+
const cleanMatch = binMap.get(cleanToken);
|
|
266
|
+
if (cleanMatch) {
|
|
267
|
+
scriptDeps.set(cleanMatch, 'npm-script');
|
|
268
|
+
}
|
|
269
|
+
// Also check if token matches a dependency name directly
|
|
270
|
+
const tokenMatch = binMap.get(token);
|
|
271
|
+
if (tokenMatch) {
|
|
272
|
+
scriptDeps.set(tokenMatch, 'npm-script');
|
|
273
|
+
}
|
|
274
|
+
// Detect --require <pkg> and --loader <pkg> patterns (node flags)
|
|
275
|
+
if ((token === '--require' || token === '-r' || token === '--loader' || token === '--import') && i + 1 < tokens.length) {
|
|
276
|
+
const nextToken = tokens[i + 1];
|
|
277
|
+
if (nextToken && !nextToken.startsWith('-') && !nextToken.startsWith('.') && !nextToken.startsWith('/')) {
|
|
278
|
+
scriptDeps.set(normalizeToPackageName(nextToken), 'npm-script');
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// Detect --require=pkg (equals form)
|
|
282
|
+
const requireMatch = token.match(/^(?:--require|-r|--loader|--import)=(.+)$/);
|
|
283
|
+
if (requireMatch && requireMatch[1] && !requireMatch[1].startsWith('.') && !requireMatch[1].startsWith('/')) {
|
|
284
|
+
scriptDeps.set(normalizeToPackageName(requireMatch[1]), 'npm-script');
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return scriptDeps;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Read the `bin` field from a package's package.json and add to the bin map.
|
|
292
|
+
*/
|
|
293
|
+
function readBinFromPackage(pkgDir, pkgName, binMap) {
|
|
294
|
+
try {
|
|
295
|
+
const pkgJson = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf-8'));
|
|
296
|
+
if (typeof pkgJson.bin === 'string') {
|
|
297
|
+
// Single binary, named after the package
|
|
298
|
+
const shortName = pkgName.includes('/') ? pkgName.split('/')[1] : pkgName;
|
|
299
|
+
binMap.set(shortName, pkgName);
|
|
300
|
+
}
|
|
301
|
+
else if (typeof pkgJson.bin === 'object' && pkgJson.bin !== null) {
|
|
302
|
+
for (const binName of Object.keys(pkgJson.bin)) {
|
|
303
|
+
binMap.set(binName, pkgName);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch { /* skip */ }
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Estimate the installed size of a package in KB.
|
|
311
|
+
* Does a shallow directory size estimation (not recursive into node_modules).
|
|
312
|
+
*/
|
|
313
|
+
export function estimatePackageSize(projectPath, packageName) {
|
|
314
|
+
const pkgDir = join(projectPath, 'node_modules', ...packageName.split('/'));
|
|
315
|
+
if (!existsSync(pkgDir))
|
|
316
|
+
return null;
|
|
317
|
+
try {
|
|
318
|
+
let totalBytes = 0;
|
|
319
|
+
const entries = readdirSync(pkgDir);
|
|
320
|
+
for (const entry of entries) {
|
|
321
|
+
if (entry === 'node_modules')
|
|
322
|
+
continue;
|
|
323
|
+
try {
|
|
324
|
+
const stat = statSync(join(pkgDir, entry));
|
|
325
|
+
if (stat.isFile()) {
|
|
326
|
+
totalBytes += stat.size;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
catch { /* skip */ }
|
|
330
|
+
}
|
|
331
|
+
return Math.round(totalBytes / 1024);
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Extract package names from stylesheet @use/@import statements.
|
|
339
|
+
* Handles SCSS @use 'pkg', @import 'pkg', and Less @import 'pkg'.
|
|
340
|
+
*/
|
|
341
|
+
export function extractStyleImports(source) {
|
|
342
|
+
const packages = new Set();
|
|
343
|
+
// SCSS @use 'package' / @import 'package' (non-relative only)
|
|
344
|
+
const atUse = /@use\s+['"]([^'"./~][^'"]*)['"]/g;
|
|
345
|
+
const atImport = /@import\s+['"]([^'"./~][^'"]*)['"]/g;
|
|
346
|
+
for (const pattern of [atUse, atImport]) {
|
|
347
|
+
let match;
|
|
348
|
+
while ((match = pattern.exec(source)) !== null) {
|
|
349
|
+
const specifier = match[1];
|
|
350
|
+
// Skip sass built-ins like 'sass:math'
|
|
351
|
+
if (specifier.startsWith('sass:'))
|
|
352
|
+
continue;
|
|
353
|
+
packages.add(normalizeToPackageName(specifier));
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return packages;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Find packages that are required as peer dependencies by other installed packages.
|
|
360
|
+
* If package A has peerDependencies: { B: "^1.0" }, and both A and B are in
|
|
361
|
+
* the project's deps, then B is considered "used" via peer-dep.
|
|
362
|
+
*/
|
|
363
|
+
function findPeerDependencyUsers(projectPath, depNames) {
|
|
364
|
+
const peerUsers = new Set();
|
|
365
|
+
const nmPath = join(projectPath, 'node_modules');
|
|
366
|
+
if (!existsSync(nmPath))
|
|
367
|
+
return peerUsers;
|
|
368
|
+
for (const depName of depNames) {
|
|
369
|
+
try {
|
|
370
|
+
const depPkgPath = join(nmPath, ...depName.split('/'), 'package.json');
|
|
371
|
+
const depPkg = JSON.parse(readFileSync(depPkgPath, 'utf-8'));
|
|
372
|
+
const peerDeps = depPkg.peerDependencies;
|
|
373
|
+
if (peerDeps) {
|
|
374
|
+
for (const peerName of Object.keys(peerDeps)) {
|
|
375
|
+
if (depNames.includes(peerName)) {
|
|
376
|
+
peerUsers.add(peerName);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
catch { /* package not installed or not readable */ }
|
|
382
|
+
}
|
|
383
|
+
return peerUsers;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* In monorepos, scan workspace package.json files for dependency references.
|
|
387
|
+
* This prevents marking a root dep as "unused" when a workspace uses it.
|
|
388
|
+
*/
|
|
389
|
+
function scanWorkspaceImports(projectPath, workspaces) {
|
|
390
|
+
const wsImports = new Set();
|
|
391
|
+
const patterns = Array.isArray(workspaces) ? workspaces : (workspaces.packages ?? []);
|
|
392
|
+
for (const pattern of patterns) {
|
|
393
|
+
// Resolve simple glob patterns (e.g., "packages/*")
|
|
394
|
+
const basePath = pattern.replace(/\*.*$/, '');
|
|
395
|
+
const wsRoot = join(projectPath, basePath);
|
|
396
|
+
if (!existsSync(wsRoot))
|
|
397
|
+
continue;
|
|
398
|
+
try {
|
|
399
|
+
const entries = readdirSync(wsRoot);
|
|
400
|
+
for (const entry of entries) {
|
|
401
|
+
const wsPkgPath = join(wsRoot, entry, 'package.json');
|
|
402
|
+
if (!existsSync(wsPkgPath))
|
|
403
|
+
continue;
|
|
404
|
+
try {
|
|
405
|
+
const wsPkg = JSON.parse(readFileSync(wsPkgPath, 'utf-8'));
|
|
406
|
+
const wsDeps = {
|
|
407
|
+
...(wsPkg.dependencies ?? {}),
|
|
408
|
+
...(wsPkg.devDependencies ?? {}),
|
|
409
|
+
...(wsPkg.peerDependencies ?? {}),
|
|
410
|
+
};
|
|
411
|
+
for (const dep of Object.keys(wsDeps)) {
|
|
412
|
+
wsImports.add(dep);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
catch { /* skip unreadable workspace package.json */ }
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
catch { /* skip unreadable directory */ }
|
|
419
|
+
}
|
|
420
|
+
return wsImports;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Detect unused dependencies in a project.
|
|
424
|
+
* Purely filesystem-based — no network calls.
|
|
425
|
+
*/
|
|
426
|
+
export async function sweep(projectPath, options = {}) {
|
|
427
|
+
const absPath = resolve(projectPath);
|
|
428
|
+
const warnings = [];
|
|
429
|
+
// Step 1: Read package.json
|
|
430
|
+
const pkgJsonPath = join(absPath, 'package.json');
|
|
431
|
+
if (!existsSync(pkgJsonPath)) {
|
|
432
|
+
return {
|
|
433
|
+
projectPath: absPath,
|
|
434
|
+
totalDependencies: 0,
|
|
435
|
+
unused: [],
|
|
436
|
+
maybeUnused: [],
|
|
437
|
+
used: 0,
|
|
438
|
+
estimatedSavingsKB: 0,
|
|
439
|
+
scannedFiles: 0,
|
|
440
|
+
warnings: ['No package.json found at project root'],
|
|
441
|
+
note: SWEEP_NOTE,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
let pkgJson;
|
|
445
|
+
try {
|
|
446
|
+
pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
447
|
+
}
|
|
448
|
+
catch {
|
|
449
|
+
return {
|
|
450
|
+
projectPath: absPath,
|
|
451
|
+
totalDependencies: 0,
|
|
452
|
+
unused: [],
|
|
453
|
+
maybeUnused: [],
|
|
454
|
+
used: 0,
|
|
455
|
+
estimatedSavingsKB: 0,
|
|
456
|
+
scannedFiles: 0,
|
|
457
|
+
warnings: ['Could not parse package.json'],
|
|
458
|
+
note: SWEEP_NOTE,
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
// Collect dependencies to check
|
|
462
|
+
const deps = (pkgJson.dependencies ?? {});
|
|
463
|
+
const devDeps = options.includeDevDependencies
|
|
464
|
+
? (pkgJson.devDependencies ?? {})
|
|
465
|
+
: {};
|
|
466
|
+
const allDeps = { ...deps, ...devDeps };
|
|
467
|
+
const depNames = Object.keys(allDeps);
|
|
468
|
+
if (depNames.length === 0) {
|
|
469
|
+
return {
|
|
470
|
+
projectPath: absPath,
|
|
471
|
+
totalDependencies: 0,
|
|
472
|
+
unused: [],
|
|
473
|
+
maybeUnused: [],
|
|
474
|
+
used: 0,
|
|
475
|
+
estimatedSavingsKB: 0,
|
|
476
|
+
scannedFiles: 0,
|
|
477
|
+
warnings: [],
|
|
478
|
+
note: SWEEP_NOTE,
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
// Warn about monorepos
|
|
482
|
+
if (pkgJson.workspaces) {
|
|
483
|
+
warnings.push('Monorepo detected (workspaces). Consider running sweep per workspace for accurate results.');
|
|
484
|
+
}
|
|
485
|
+
// Step 2: Scan source files for imports
|
|
486
|
+
const excludeDirs = new Set([...EXCLUDE_DIRS, ...(options.excludePatterns ?? [])]);
|
|
487
|
+
const sourceFiles = collectSourceFiles(absPath, SOURCE_EXTENSIONS, excludeDirs);
|
|
488
|
+
const importedPackages = new Set();
|
|
489
|
+
for (const file of sourceFiles) {
|
|
490
|
+
try {
|
|
491
|
+
const content = readFileSync(file, 'utf-8');
|
|
492
|
+
const imports = extractImports(content);
|
|
493
|
+
for (const pkg of imports) {
|
|
494
|
+
importedPackages.add(pkg);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
catch {
|
|
498
|
+
warnings.push(`Could not read: ${file}`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
// Step 2b: Scan stylesheet files for @use/@import of packages
|
|
502
|
+
const styleFiles = collectSourceFiles(absPath, STYLE_EXTENSIONS, excludeDirs);
|
|
503
|
+
for (const file of styleFiles) {
|
|
504
|
+
try {
|
|
505
|
+
const content = readFileSync(file, 'utf-8');
|
|
506
|
+
const styleImports = extractStyleImports(content);
|
|
507
|
+
for (const pkg of styleImports) {
|
|
508
|
+
importedPackages.add(pkg);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
catch {
|
|
512
|
+
warnings.push(`Could not read: ${file}`);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
// Step 3: Check config files
|
|
516
|
+
const configDeps = findConfigDependencies(absPath);
|
|
517
|
+
// Step 4: Check npm scripts
|
|
518
|
+
const scripts = (pkgJson.scripts ?? {});
|
|
519
|
+
const scriptDeps = findScriptDependencies(scripts, absPath);
|
|
520
|
+
// Step 5: Check peer dependencies — if package A needs B as peerDep, B is "used"
|
|
521
|
+
const peerDepUsers = findPeerDependencyUsers(absPath, depNames);
|
|
522
|
+
// Step 6: Scan workspace siblings if monorepo detected (npm/yarn workspaces or pnpm)
|
|
523
|
+
let workspaceImports = new Set();
|
|
524
|
+
if (pkgJson.workspaces) {
|
|
525
|
+
workspaceImports = scanWorkspaceImports(absPath, pkgJson.workspaces);
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
// Check for pnpm-workspace.yaml
|
|
529
|
+
const pnpmWsPath = join(absPath, 'pnpm-workspace.yaml');
|
|
530
|
+
if (existsSync(pnpmWsPath)) {
|
|
531
|
+
try {
|
|
532
|
+
const pnpmContent = readFileSync(pnpmWsPath, 'utf-8');
|
|
533
|
+
// Simple YAML parsing for packages list: " - 'packages/*'"
|
|
534
|
+
const pnpmPatterns = [];
|
|
535
|
+
const lines = pnpmContent.split('\n');
|
|
536
|
+
for (const line of lines) {
|
|
537
|
+
const match = line.match(/^\s*-\s+['"]?([^'"#\n]+)['"]?\s*$/);
|
|
538
|
+
if (match)
|
|
539
|
+
pnpmPatterns.push(match[1].trim());
|
|
540
|
+
}
|
|
541
|
+
if (pnpmPatterns.length > 0) {
|
|
542
|
+
workspaceImports = scanWorkspaceImports(absPath, pnpmPatterns);
|
|
543
|
+
warnings.push('Monorepo detected (pnpm workspaces). Consider running sweep per workspace for accurate results.');
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
catch { /* skip unreadable pnpm-workspace.yaml */ }
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
// Step 7: Classify each dependency
|
|
550
|
+
const unused = [];
|
|
551
|
+
const maybeUnused = [];
|
|
552
|
+
let usedCount = 0;
|
|
553
|
+
for (const name of depNames) {
|
|
554
|
+
const reasons = [];
|
|
555
|
+
const version = allDeps[name] ?? 'unknown';
|
|
556
|
+
// Check imports
|
|
557
|
+
if (importedPackages.has(name)) {
|
|
558
|
+
reasons.push('imported');
|
|
559
|
+
}
|
|
560
|
+
// Check config files
|
|
561
|
+
if (configDeps.has(name)) {
|
|
562
|
+
reasons.push('config-referenced');
|
|
563
|
+
}
|
|
564
|
+
// Check npm scripts
|
|
565
|
+
if (scriptDeps.has(name)) {
|
|
566
|
+
reasons.push('npm-script');
|
|
567
|
+
}
|
|
568
|
+
// Handle @types/* packages
|
|
569
|
+
if (name.startsWith('@types/')) {
|
|
570
|
+
const runtimeName = name.replace('@types/', '').replace('__', '/');
|
|
571
|
+
if (importedPackages.has(runtimeName) || depNames.includes(runtimeName)) {
|
|
572
|
+
reasons.push('types-only');
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
// Check peer dependencies — if another installed package needs this as peerDep
|
|
576
|
+
if (peerDepUsers.has(name)) {
|
|
577
|
+
reasons.push('peer-dep');
|
|
578
|
+
}
|
|
579
|
+
// Check workspace imports — if another workspace package imports this
|
|
580
|
+
if (workspaceImports.has(name)) {
|
|
581
|
+
reasons.push('imported');
|
|
582
|
+
}
|
|
583
|
+
// Check if this is a well-known config-only tool not caught by file patterns
|
|
584
|
+
// (e.g., typescript is referenced via tsconfig.json)
|
|
585
|
+
if (reasons.length === 0) {
|
|
586
|
+
for (const [, toolDeps] of Object.entries(CONFIG_FILE_DEPS)) {
|
|
587
|
+
if (toolDeps.includes(name) && configDeps.has(name)) {
|
|
588
|
+
reasons.push('config-referenced');
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
// Classify
|
|
593
|
+
if (reasons.length > 0) {
|
|
594
|
+
usedCount++;
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
const sizeKB = estimatePackageSize(absPath, name);
|
|
598
|
+
const depResult = {
|
|
599
|
+
name,
|
|
600
|
+
version,
|
|
601
|
+
status: 'unused',
|
|
602
|
+
reasons: [],
|
|
603
|
+
estimatedSizeKB: sizeKB,
|
|
604
|
+
};
|
|
605
|
+
// Conservative classification — when in doubt, use maybe-unused.
|
|
606
|
+
// We only say "unused" when we have high confidence.
|
|
607
|
+
const shouldBeCautious =
|
|
608
|
+
// devDependency — could be used by a config/tool we don't recognize
|
|
609
|
+
(devDeps[name] && !deps[name]) ||
|
|
610
|
+
// No node_modules — can't verify peer deps or bin scripts
|
|
611
|
+
!existsSync(join(absPath, 'node_modules')) ||
|
|
612
|
+
// Scoped packages used as plugins are hard to trace
|
|
613
|
+
name.startsWith('@') ||
|
|
614
|
+
// Packages with install scripts likely do something important
|
|
615
|
+
hasInstallScripts(absPath, name);
|
|
616
|
+
if (shouldBeCautious) {
|
|
617
|
+
depResult.status = 'maybe-unused';
|
|
618
|
+
maybeUnused.push(depResult);
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
unused.push(depResult);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
// Calculate estimated savings
|
|
626
|
+
const estimatedSavingsKB = unused.reduce((sum, dep) => sum + (dep.estimatedSizeKB ?? 0), 0);
|
|
627
|
+
return {
|
|
628
|
+
projectPath: absPath,
|
|
629
|
+
totalDependencies: depNames.length,
|
|
630
|
+
unused,
|
|
631
|
+
maybeUnused,
|
|
632
|
+
used: usedCount,
|
|
633
|
+
estimatedSavingsKB,
|
|
634
|
+
scannedFiles: sourceFiles.length + styleFiles.length,
|
|
635
|
+
warnings,
|
|
636
|
+
note: SWEEP_NOTE,
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
//# sourceMappingURL=sweep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sweep.js","sourceRoot":"","sources":["../src/sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGlD,0CAA0C;AAC1C,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC5C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM;CACpC,CAAC,CAAA;AAEF;;;GAGG;AACH,SAAS,iBAAiB,CAAC,WAAmB,EAAE,WAAmB;IACjE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAA;QAC5F,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;QACtD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAA;QACjC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,GAAG,sLAAsL,CAAA;AAEzM,iEAAiE;AACjE,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;AAErE,kDAAkD;AAClD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa;IACxE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa;CAChE,CAAC,CAAA;AAEF;;;GAGG;AACH,MAAM,gBAAgB,GAA6B;IACjD,WAAW,EAAE,CAAC,QAAQ,CAAC;IACvB,eAAe,EAAE,CAAC,QAAQ,CAAC;IAC3B,aAAa,EAAE,CAAC,UAAU,CAAC;IAC3B,iBAAiB,EAAE,CAAC,UAAU,CAAC;IAC/B,aAAa,EAAE,CAAC,MAAM,CAAC;IACvB,eAAe,EAAE,CAAC,QAAQ,CAAC;IAC3B,cAAc,EAAE,CAAC,aAAa,CAAC;IAC/B,UAAU,EAAE,CAAC,aAAa,CAAC;IAC3B,UAAU,EAAE,CAAC,YAAY,CAAC;IAC1B,iBAAiB,EAAE,CAAC,aAAa,CAAC;IAClC,gBAAgB,EAAE,CAAC,SAAS,CAAC;IAC7B,gBAAgB,EAAE,CAAC,SAAS,CAAC;IAC7B,eAAe,EAAE,CAAC,QAAQ,CAAC;IAC3B,aAAa,EAAE,CAAC,MAAM,CAAC;IACvB,aAAa,EAAE,CAAC,MAAM,CAAC;IACvB,aAAa,EAAE,CAAC,MAAM,CAAC;IACvB,eAAe,EAAE,CAAC,QAAQ,CAAC;IAC3B,QAAQ,EAAE,CAAC,WAAW,CAAC;IACvB,UAAU,EAAE,CAAC,OAAO,CAAC;IACrB,gBAAgB,EAAE,CAAC,SAAS,CAAC;IAC7B,mBAAmB,EAAE,CAAC,YAAY,EAAE,kBAAkB,CAAC;IACvD,YAAY,EAAE,CAAC,WAAW,CAAC;IAC3B,YAAY,EAAE,CAAC,OAAO,CAAC;IACvB,SAAS,EAAE,CAAC,IAAI,CAAC;IACjB,YAAY,EAAE,CAAC,OAAO,CAAC;CACxB,CAAA;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,yBAAyB;QACzB,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;QACvD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,oBAAoB;IACpB,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAA;IAElC,0DAA0D;IAC1D,MAAM,QAAQ,GAAG,0DAA0D,CAAA;IAC3E,iCAAiC;IACjC,MAAM,SAAS,GAAG,6CAA6C,CAAA;IAC/D,2BAA2B;IAC3B,MAAM,UAAU,GAAG,8CAA8C,CAAA;IACjE,oCAAoC;IACpC,MAAM,QAAQ,GAAG,qDAAqD,CAAA;IACtE,qEAAqE;IACrE,MAAM,cAAc,GAAG,uDAAuD,CAAA;IAC9E,kEAAkE;IAClE,MAAM,QAAQ,GAAG,qEAAqE,CAAA;IACtF,uDAAuD;IACvD,MAAM,aAAa,GAAG,6CAA6C,CAAA;IAEnE,KAAK,MAAM,OAAO,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,CAAC;QAC3G,IAAI,KAA6B,CAAA;QACjC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC/C,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;YAC1B,8BAA8B;YAC9B,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAQ;YAC3C,QAAQ,CAAC,GAAG,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,GAAW,EACX,aAA0B,iBAAiB,EAC3C,cAA2B,YAAY;IAEvC,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,IAAI,OAAiB,CAAA;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAQ;QAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACjC,IAAI,IAAI,CAAA;QACR,IAAI,CAAC;YACH,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,SAAQ;QACV,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAA;QACtE,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC3D,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,MAAM,UAAU,GAAG,IAAI,GAAG,EAA0B,CAAA;IAEpD,IAAI,WAAqB,CAAA;IACzB,IAAI,CAAC;QACH,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC,CAAA;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC/D,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;gBACnD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAA;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;QAED,iDAAiD;QACjD,IAAI,KAAK,CAAC,KAAK,CAAC,2BAA2B,CAAC,EAAE,CAAC;YAC7C,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,qBAAqB,CAAC,CAAA;QACvH,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAC;YAC3C,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,CAAC,CAAA;QAClI,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAChC,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAA;QACxG,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACpC,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,CAAC,CAAA;QAC7F,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACnC,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,CAAC,CAAA;QACnG,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACnC,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;QAC9F,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,CAAC,6BAA6B,CAAC,EAAE,CAAC;YAC/C,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAA;QACtH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC3B,QAAgB,EAChB,UAAuC,EACvC,GAAG,QAAkB;IAErB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC/C,4CAA4C;QAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAA;QACxD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,gBAAgB;YAC/C,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;gBAC9B,sFAAsF;gBACtF,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;oBAC7F,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAA;gBAC5C,CAAC;YACH,CAAC;YACD,sFAAsF;YACtF,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjD,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAA;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;IACnC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAA+B,EAC/B,WAAmB;IAEnB,MAAM,UAAU,GAAG,IAAI,GAAG,EAA0B,CAAA;IAEpD,mEAAmE;IACnE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;IAEhD,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;YACxC,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;gBAC/B,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,SAAQ;gBACjC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxB,kBAAkB;oBAClB,IAAI,CAAC;wBACH,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;wBACjD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;4BACnC,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,GAAG,GAAG,IAAI,SAAS,EAAE,EAAE,MAAM,CAAC,CAAA;wBACjF,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACN,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;gBACpD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,6EAA6E;IAC7E,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;YACvB,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAA;YAClE,2BAA2B;YAC3B,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;YACzC,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;YAC1C,CAAC;YACD,yDAAyD;YACzD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACpC,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;YAC1C,CAAC;YACD,kEAAkE;YAClE,IAAI,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBACvH,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;gBAC/B,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxG,UAAU,CAAC,GAAG,CAAC,sBAAsB,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC,CAAA;gBACjE,CAAC;YACH,CAAC;YACD,qCAAqC;YACrC,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;YAC7E,IAAI,YAAY,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5G,UAAU,CAAC,GAAG,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;YACvE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CACzB,MAAc,EACd,OAAe,EACf,MAA2B;IAE3B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAA;QAC/E,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpC,yCAAyC;YACzC,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;YACzE,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAChC,CAAC;aAAM,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;YACnE,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAmB,EAAE,WAAmB;IAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IAC3E,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAA;IAEpC,IAAI,CAAC;QACH,IAAI,UAAU,GAAG,CAAC,CAAA;QAClB,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;QACnC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,KAAK,cAAc;gBAAE,SAAQ;YACtC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;gBAC1C,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;oBAClB,UAAU,IAAI,IAAI,CAAC,IAAI,CAAA;gBACzB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAA;IAClC,8DAA8D;IAC9D,MAAM,KAAK,GAAG,kCAAkC,CAAA;IAChD,MAAM,QAAQ,GAAG,qCAAqC,CAAA;IAEtD,KAAK,MAAM,OAAO,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;QACxC,IAAI,KAA6B,CAAA;QACjC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC/C,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;YAC1B,uCAAuC;YACvC,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAQ;YAC3C,QAAQ,CAAC,GAAG,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;GAIG;AACH,SAAS,uBAAuB,CAAC,WAAmB,EAAE,QAAkB;IACtE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;IAChD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAA;IAEzC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAA;YACtE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;YAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAsD,CAAA;YAC9E,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC7C,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAChC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;oBACzB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,2CAA2C,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAC3B,WAAmB,EACnB,UAA6C;IAE7C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;IACnC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAA;IAErF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,oDAAoD;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;QAE1C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,SAAQ;QAEjC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;YACnC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,cAAc,CAAC,CAAA;gBACrD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;oBAAE,SAAQ;gBAEpC,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;oBAC1D,MAAM,MAAM,GAAG;wBACb,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC;wBAC7B,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC;wBAChC,GAAG,CAAC,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAAC;qBACR,CAAA;oBAE3B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;wBACtC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;oBACpB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAC,4CAA4C,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,+BAA+B,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,WAAmB,EACnB,UAAwB,EAAE;IAE1B,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IACpC,MAAM,QAAQ,GAAa,EAAE,CAAA;IAE7B,4BAA4B;IAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAA;IACjD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,WAAW,EAAE,OAAO;YACpB,iBAAiB,EAAE,CAAC;YACpB,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,EAAE;YACf,IAAI,EAAE,CAAC;YACP,kBAAkB,EAAE,CAAC;YACrB,YAAY,EAAE,CAAC;YACf,QAAQ,EAAE,CAAC,uCAAuC,CAAC;YACnD,IAAI,EAAE,UAAU;SACjB,CAAA;IACH,CAAC;IAED,IAAI,OAAgC,CAAA;IACpC,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAA;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,WAAW,EAAE,OAAO;YACpB,iBAAiB,EAAE,CAAC;YACpB,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,EAAE;YACf,IAAI,EAAE,CAAC;YACP,kBAAkB,EAAE,CAAC;YACrB,YAAY,EAAE,CAAC;YACf,QAAQ,EAAE,CAAC,8BAA8B,CAAC;YAC1C,IAAI,EAAE,UAAU;SACjB,CAAA;IACH,CAAC;IAED,gCAAgC;IAChC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAA2B,CAAA;IACnE,MAAM,OAAO,GAAG,OAAO,CAAC,sBAAsB;QAC5C,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAA2B;QAC3D,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,OAAO,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,CAAA;IACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAErC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,WAAW,EAAE,OAAO;YACpB,iBAAiB,EAAE,CAAC;YACpB,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,EAAE;YACf,IAAI,EAAE,CAAC;YACP,kBAAkB,EAAE,CAAC;YACrB,YAAY,EAAE,CAAC;YACf,QAAQ,EAAE,EAAE;YACZ,IAAI,EAAE,UAAU;SACjB,CAAA;IACH,CAAC;IAED,uBAAuB;IACvB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,QAAQ,CAAC,IAAI,CAAC,4FAA4F,CAAC,CAAA;IAC7G,CAAC;IAED,wCAAwC;IACxC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAClF,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,EAAE,WAAW,CAAC,CAAA;IAC/E,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAA;IAE1C,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAC3C,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;YACvC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAA;IAC7E,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAC3C,MAAM,YAAY,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAA;YACjD,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;gBAC/B,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAA;IAElD,4BAA4B;IAC5B,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAA2B,CAAA;IACjE,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAE3D,iFAAiF;IACjF,MAAM,YAAY,GAAG,uBAAuB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IAE/D,qFAAqF;IACrF,IAAI,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAA;IACxC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,gBAAgB,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,UAA+C,CAAC,CAAA;IAC3G,CAAC;SAAM,CAAC;QACN,gCAAgC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAA;QACvD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;gBACrD,4DAA4D;gBAC5D,MAAM,YAAY,GAAa,EAAE,CAAA;gBACjC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAA;oBAC7D,IAAI,KAAK;wBAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;gBAC/C,CAAC;gBACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC5B,gBAAgB,GAAG,oBAAoB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;oBAC9D,QAAQ,CAAC,IAAI,CAAC,iGAAiG,CAAC,CAAA;gBAClH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,yCAAyC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,MAAM,MAAM,GAAqB,EAAE,CAAA;IACnC,MAAM,WAAW,GAAqB,EAAE,CAAA;IACxC,IAAI,SAAS,GAAG,CAAC,CAAA;IAEjB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAqB,EAAE,CAAA;QACpC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,SAAS,CAAA;QAE1C,gBAAgB;QAChB,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC1B,CAAC;QAED,qBAAqB;QACrB,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QACnC,CAAC;QAED,oBAAoB;QACpB,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAC5B,CAAC;QAED,2BAA2B;QAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;YAClE,IAAI,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAC5B,CAAC;QACH,CAAC;QAED,+EAA+E;QAC/E,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC1B,CAAC;QAED,sEAAsE;QACtE,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC1B,CAAC;QAED,6EAA6E;QAC7E,qDAAqD;QACrD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC5D,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpD,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;gBACnC,CAAC;YACH,CAAC;QACH,CAAC;QAED,WAAW;QACX,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,SAAS,EAAE,CAAA;QACb,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YACjD,MAAM,SAAS,GAAmB;gBAChC,IAAI;gBACJ,OAAO;gBACP,MAAM,EAAE,QAAQ;gBAChB,OAAO,EAAE,EAAE;gBACX,eAAe,EAAE,MAAM;aACxB,CAAA;YAED,iEAAiE;YACjE,qDAAqD;YACrD,MAAM,gBAAgB;YACpB,oEAAoE;YACpE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9B,0DAA0D;gBAC1D,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;gBAC1C,oDAAoD;gBACpD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBACpB,8DAA8D;gBAC9D,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YAElC,IAAI,gBAAgB,EAAE,CAAC;gBACrB,SAAS,CAAC,MAAM,GAAG,cAAc,CAAA;gBACjC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC7B,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACxB,CAAC;QACH,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAE3F,OAAO;QACL,WAAW,EAAE,OAAO;QACpB,iBAAiB,EAAE,QAAQ,CAAC,MAAM;QAClC,MAAM;QACN,WAAW;QACX,IAAI,EAAE,SAAS;QACf,kBAAkB;QAClB,YAAY,EAAE,WAAW,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM;QACpD,QAAQ;QACR,IAAI,EAAE,UAAU;KACjB,CAAA;AACH,CAAC"}
|