@quantracode/vibecheck 0.0.1 → 0.0.2
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 +6 -6
- package/dist/index.d.ts +0 -2
- package/dist/index.js +7902 -8
- package/package.json +13 -7
- package/dist/__tests__/cli.test.d.ts +0 -2
- package/dist/__tests__/cli.test.d.ts.map +0 -1
- package/dist/__tests__/cli.test.js +0 -243
- package/dist/__tests__/fixtures/safe-app/app/api/users/route.js +0 -36
- package/dist/__tests__/fixtures/vulnerable-app/app/api/users/route.js +0 -28
- package/dist/__tests__/fixtures/vulnerable-app/lib/config.d.ts +0 -4
- package/dist/__tests__/fixtures/vulnerable-app/lib/config.d.ts.map +0 -1
- package/dist/__tests__/fixtures/vulnerable-app/lib/config.js +0 -6
- package/dist/__tests__/scanners/env-config.test.d.ts +0 -2
- package/dist/__tests__/scanners/env-config.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/env-config.test.js +0 -142
- package/dist/__tests__/scanners/nextjs-middleware.test.d.ts +0 -2
- package/dist/__tests__/scanners/nextjs-middleware.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/nextjs-middleware.test.js +0 -193
- package/dist/__tests__/scanners/scanner-packs.test.d.ts +0 -2
- package/dist/__tests__/scanners/scanner-packs.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/scanner-packs.test.js +0 -126
- package/dist/__tests__/scanners/unused-security-imports.test.d.ts +0 -2
- package/dist/__tests__/scanners/unused-security-imports.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/unused-security-imports.test.js +0 -145
- package/dist/commands/demo-artifact.d.ts +0 -7
- package/dist/commands/demo-artifact.d.ts.map +0 -1
- package/dist/commands/demo-artifact.js +0 -322
- package/dist/commands/evaluate.d.ts +0 -30
- package/dist/commands/evaluate.d.ts.map +0 -1
- package/dist/commands/evaluate.js +0 -258
- package/dist/commands/explain.d.ts +0 -12
- package/dist/commands/explain.d.ts.map +0 -1
- package/dist/commands/explain.js +0 -214
- package/dist/commands/index.d.ts +0 -7
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js +0 -6
- package/dist/commands/intent.d.ts +0 -21
- package/dist/commands/intent.d.ts.map +0 -1
- package/dist/commands/intent.js +0 -192
- package/dist/commands/scan.d.ts +0 -44
- package/dist/commands/scan.d.ts.map +0 -1
- package/dist/commands/scan.js +0 -497
- package/dist/commands/waivers.d.ts +0 -30
- package/dist/commands/waivers.d.ts.map +0 -1
- package/dist/commands/waivers.js +0 -249
- package/dist/index.d.ts.map +0 -1
- package/dist/phase3/index.d.ts +0 -11
- package/dist/phase3/index.d.ts.map +0 -1
- package/dist/phase3/index.js +0 -12
- package/dist/phase3/intent-miner.d.ts +0 -32
- package/dist/phase3/intent-miner.d.ts.map +0 -1
- package/dist/phase3/intent-miner.js +0 -323
- package/dist/phase3/proof-trace-builder.d.ts +0 -42
- package/dist/phase3/proof-trace-builder.d.ts.map +0 -1
- package/dist/phase3/proof-trace-builder.js +0 -441
- package/dist/phase3/scanners/auth-by-ui-server-gap.d.ts +0 -15
- package/dist/phase3/scanners/auth-by-ui-server-gap.d.ts.map +0 -1
- package/dist/phase3/scanners/auth-by-ui-server-gap.js +0 -237
- package/dist/phase3/scanners/comment-claim-unproven.d.ts +0 -14
- package/dist/phase3/scanners/comment-claim-unproven.d.ts.map +0 -1
- package/dist/phase3/scanners/comment-claim-unproven.js +0 -161
- package/dist/phase3/scanners/index.d.ts +0 -31
- package/dist/phase3/scanners/index.d.ts.map +0 -1
- package/dist/phase3/scanners/index.js +0 -40
- package/dist/phase3/scanners/middleware-assumed-not-matching.d.ts +0 -14
- package/dist/phase3/scanners/middleware-assumed-not-matching.d.ts.map +0 -1
- package/dist/phase3/scanners/middleware-assumed-not-matching.js +0 -172
- package/dist/phase3/scanners/validation-claimed-missing.d.ts +0 -15
- package/dist/phase3/scanners/validation-claimed-missing.d.ts.map +0 -1
- package/dist/phase3/scanners/validation-claimed-missing.js +0 -204
- package/dist/scanners/abuse/compute-abuse.d.ts +0 -20
- package/dist/scanners/abuse/compute-abuse.d.ts.map +0 -1
- package/dist/scanners/abuse/compute-abuse.js +0 -509
- package/dist/scanners/abuse/index.d.ts +0 -12
- package/dist/scanners/abuse/index.d.ts.map +0 -1
- package/dist/scanners/abuse/index.js +0 -15
- package/dist/scanners/auth/index.d.ts +0 -5
- package/dist/scanners/auth/index.d.ts.map +0 -1
- package/dist/scanners/auth/index.js +0 -10
- package/dist/scanners/auth/middleware-gap.d.ts +0 -22
- package/dist/scanners/auth/middleware-gap.d.ts.map +0 -1
- package/dist/scanners/auth/middleware-gap.js +0 -203
- package/dist/scanners/auth/unprotected-api-route.d.ts +0 -12
- package/dist/scanners/auth/unprotected-api-route.d.ts.map +0 -1
- package/dist/scanners/auth/unprotected-api-route.js +0 -126
- package/dist/scanners/config/index.d.ts +0 -5
- package/dist/scanners/config/index.d.ts.map +0 -1
- package/dist/scanners/config/index.js +0 -10
- package/dist/scanners/config/insecure-defaults.d.ts +0 -12
- package/dist/scanners/config/insecure-defaults.d.ts.map +0 -1
- package/dist/scanners/config/insecure-defaults.js +0 -77
- package/dist/scanners/config/undocumented-env.d.ts +0 -24
- package/dist/scanners/config/undocumented-env.d.ts.map +0 -1
- package/dist/scanners/config/undocumented-env.js +0 -159
- package/dist/scanners/crypto/index.d.ts +0 -6
- package/dist/scanners/crypto/index.d.ts.map +0 -1
- package/dist/scanners/crypto/index.js +0 -11
- package/dist/scanners/crypto/jwt-decode-unverified.d.ts +0 -14
- package/dist/scanners/crypto/jwt-decode-unverified.d.ts.map +0 -1
- package/dist/scanners/crypto/jwt-decode-unverified.js +0 -87
- package/dist/scanners/crypto/math-random-tokens.d.ts +0 -13
- package/dist/scanners/crypto/math-random-tokens.d.ts.map +0 -1
- package/dist/scanners/crypto/math-random-tokens.js +0 -80
- package/dist/scanners/crypto/weak-hashing.d.ts +0 -11
- package/dist/scanners/crypto/weak-hashing.d.ts.map +0 -1
- package/dist/scanners/crypto/weak-hashing.js +0 -95
- package/dist/scanners/env-config.d.ts +0 -24
- package/dist/scanners/env-config.d.ts.map +0 -1
- package/dist/scanners/env-config.js +0 -164
- package/dist/scanners/hallucinations/index.d.ts +0 -4
- package/dist/scanners/hallucinations/index.d.ts.map +0 -1
- package/dist/scanners/hallucinations/index.js +0 -8
- package/dist/scanners/hallucinations/unused-security-imports.d.ts +0 -36
- package/dist/scanners/hallucinations/unused-security-imports.d.ts.map +0 -1
- package/dist/scanners/hallucinations/unused-security-imports.js +0 -309
- package/dist/scanners/helpers/ast-helpers.d.ts +0 -6
- package/dist/scanners/helpers/ast-helpers.d.ts.map +0 -1
- package/dist/scanners/helpers/ast-helpers.js +0 -945
- package/dist/scanners/helpers/context-builder.d.ts +0 -17
- package/dist/scanners/helpers/context-builder.d.ts.map +0 -1
- package/dist/scanners/helpers/context-builder.js +0 -148
- package/dist/scanners/helpers/index.d.ts +0 -3
- package/dist/scanners/helpers/index.d.ts.map +0 -1
- package/dist/scanners/helpers/index.js +0 -2
- package/dist/scanners/index.d.ts +0 -30
- package/dist/scanners/index.d.ts.map +0 -1
- package/dist/scanners/index.js +0 -102
- package/dist/scanners/middleware/index.d.ts +0 -4
- package/dist/scanners/middleware/index.d.ts.map +0 -1
- package/dist/scanners/middleware/index.js +0 -7
- package/dist/scanners/middleware/missing-rate-limit.d.ts +0 -13
- package/dist/scanners/middleware/missing-rate-limit.d.ts.map +0 -1
- package/dist/scanners/middleware/missing-rate-limit.js +0 -140
- package/dist/scanners/network/cors-misconfiguration.d.ts +0 -14
- package/dist/scanners/network/cors-misconfiguration.d.ts.map +0 -1
- package/dist/scanners/network/cors-misconfiguration.js +0 -89
- package/dist/scanners/network/index.d.ts +0 -7
- package/dist/scanners/network/index.d.ts.map +0 -1
- package/dist/scanners/network/index.js +0 -18
- package/dist/scanners/network/missing-timeout.d.ts +0 -15
- package/dist/scanners/network/missing-timeout.d.ts.map +0 -1
- package/dist/scanners/network/missing-timeout.js +0 -93
- package/dist/scanners/network/open-redirect.d.ts +0 -15
- package/dist/scanners/network/open-redirect.d.ts.map +0 -1
- package/dist/scanners/network/open-redirect.js +0 -88
- package/dist/scanners/network/ssrf-prone-fetch.d.ts +0 -12
- package/dist/scanners/network/ssrf-prone-fetch.d.ts.map +0 -1
- package/dist/scanners/network/ssrf-prone-fetch.js +0 -90
- package/dist/scanners/nextjs-middleware.d.ts +0 -26
- package/dist/scanners/nextjs-middleware.d.ts.map +0 -1
- package/dist/scanners/nextjs-middleware.js +0 -246
- package/dist/scanners/privacy/debug-flags.d.ts +0 -13
- package/dist/scanners/privacy/debug-flags.d.ts.map +0 -1
- package/dist/scanners/privacy/debug-flags.js +0 -124
- package/dist/scanners/privacy/index.d.ts +0 -6
- package/dist/scanners/privacy/index.d.ts.map +0 -1
- package/dist/scanners/privacy/index.js +0 -11
- package/dist/scanners/privacy/over-broad-response.d.ts +0 -15
- package/dist/scanners/privacy/over-broad-response.d.ts.map +0 -1
- package/dist/scanners/privacy/over-broad-response.js +0 -109
- package/dist/scanners/privacy/sensitive-logging.d.ts +0 -11
- package/dist/scanners/privacy/sensitive-logging.d.ts.map +0 -1
- package/dist/scanners/privacy/sensitive-logging.js +0 -78
- package/dist/scanners/types.d.ts +0 -456
- package/dist/scanners/types.d.ts.map +0 -1
- package/dist/scanners/types.js +0 -16
- package/dist/scanners/unused-security-imports.d.ts +0 -34
- package/dist/scanners/unused-security-imports.d.ts.map +0 -1
- package/dist/scanners/unused-security-imports.js +0 -206
- package/dist/scanners/uploads/index.d.ts +0 -5
- package/dist/scanners/uploads/index.d.ts.map +0 -1
- package/dist/scanners/uploads/index.js +0 -9
- package/dist/scanners/uploads/missing-constraints.d.ts +0 -15
- package/dist/scanners/uploads/missing-constraints.d.ts.map +0 -1
- package/dist/scanners/uploads/missing-constraints.js +0 -109
- package/dist/scanners/uploads/public-path.d.ts +0 -11
- package/dist/scanners/uploads/public-path.d.ts.map +0 -1
- package/dist/scanners/uploads/public-path.js +0 -87
- package/dist/scanners/validation/client-side-only.d.ts +0 -14
- package/dist/scanners/validation/client-side-only.d.ts.map +0 -1
- package/dist/scanners/validation/client-side-only.js +0 -140
- package/dist/scanners/validation/ignored-validation.d.ts +0 -12
- package/dist/scanners/validation/ignored-validation.d.ts.map +0 -1
- package/dist/scanners/validation/ignored-validation.js +0 -119
- package/dist/scanners/validation/index.d.ts +0 -5
- package/dist/scanners/validation/index.d.ts.map +0 -1
- package/dist/scanners/validation/index.js +0 -9
- package/dist/utils/exclude-patterns.d.ts +0 -35
- package/dist/utils/exclude-patterns.d.ts.map +0 -1
- package/dist/utils/exclude-patterns.js +0 -78
- package/dist/utils/file-utils.d.ts +0 -37
- package/dist/utils/file-utils.d.ts.map +0 -1
- package/dist/utils/file-utils.js +0 -77
- package/dist/utils/fingerprint.d.ts +0 -25
- package/dist/utils/fingerprint.d.ts.map +0 -1
- package/dist/utils/fingerprint.js +0 -28
- package/dist/utils/git-info.d.ts +0 -14
- package/dist/utils/git-info.d.ts.map +0 -1
- package/dist/utils/git-info.js +0 -55
- package/dist/utils/index.d.ts +0 -4
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -3
- package/dist/utils/progress.d.ts +0 -42
- package/dist/utils/progress.d.ts.map +0 -1
- package/dist/utils/progress.js +0 -165
- package/dist/utils/sarif-formatter.d.ts +0 -92
- package/dist/utils/sarif-formatter.d.ts.map +0 -1
- package/dist/utils/sarif-formatter.js +0 -172
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { resolvePath } from "../../utils/file-utils.js";
|
|
2
|
-
import { generateFingerprint, generateFindingId } from "../../utils/fingerprint.js";
|
|
3
|
-
const RULE_ID = "VC-VAL-001";
|
|
4
|
-
/**
|
|
5
|
-
* VC-VAL-001: Validation defined but output ignored
|
|
6
|
-
*
|
|
7
|
-
* Detects when zod/yup/joi validation is performed but:
|
|
8
|
-
* - The validated result is not assigned to a variable
|
|
9
|
-
* - The validated result is assigned but never referenced
|
|
10
|
-
* - Raw request body is used after validation
|
|
11
|
-
*/
|
|
12
|
-
export async function scanIgnoredValidation(context) {
|
|
13
|
-
const { repoRoot, fileIndex, helpers } = context;
|
|
14
|
-
const findings = [];
|
|
15
|
-
// Scan API route files for validation issues
|
|
16
|
-
for (const relPath of fileIndex.apiRouteFiles) {
|
|
17
|
-
const absPath = resolvePath(repoRoot, relPath);
|
|
18
|
-
const sourceFile = helpers.parseFile(absPath);
|
|
19
|
-
if (!sourceFile)
|
|
20
|
-
continue;
|
|
21
|
-
const handlers = helpers.findRouteHandlers(sourceFile);
|
|
22
|
-
for (const handler of handlers) {
|
|
23
|
-
const validationUsages = helpers.findValidationUsage(handler.functionNode);
|
|
24
|
-
for (const usage of validationUsages) {
|
|
25
|
-
// Case 1: Validation called but result not assigned
|
|
26
|
-
if (!usage.resultAssigned) {
|
|
27
|
-
const evidence = [
|
|
28
|
-
{
|
|
29
|
-
file: relPath,
|
|
30
|
-
startLine: usage.line,
|
|
31
|
-
endLine: usage.line,
|
|
32
|
-
snippet: helpers.getNodeText(usage.node).slice(0, 150),
|
|
33
|
-
label: `${usage.library}.${usage.method}() called but result not assigned`,
|
|
34
|
-
},
|
|
35
|
-
];
|
|
36
|
-
const fingerprint = generateFingerprint({
|
|
37
|
-
ruleId: RULE_ID,
|
|
38
|
-
file: relPath,
|
|
39
|
-
symbol: `${usage.library}.${usage.method}`,
|
|
40
|
-
startLine: usage.line,
|
|
41
|
-
});
|
|
42
|
-
findings.push({
|
|
43
|
-
id: generateFindingId({
|
|
44
|
-
ruleId: RULE_ID,
|
|
45
|
-
file: relPath,
|
|
46
|
-
symbol: `${usage.library}.${usage.method}`,
|
|
47
|
-
startLine: usage.line,
|
|
48
|
-
}),
|
|
49
|
-
ruleId: RULE_ID,
|
|
50
|
-
title: `Validation result ignored: ${usage.library}.${usage.method}()`,
|
|
51
|
-
description: `The ${usage.library} validation method ${usage.method}() is called but its result is not assigned to a variable. This means validation errors are silently ignored and unvalidated data may be used.`,
|
|
52
|
-
severity: "high",
|
|
53
|
-
confidence: 0.92,
|
|
54
|
-
category: "validation",
|
|
55
|
-
evidence,
|
|
56
|
-
remediation: {
|
|
57
|
-
recommendedFix: `Assign the validation result to a variable and use the validated data instead of the raw input.`,
|
|
58
|
-
patch: usage.library === "zod"
|
|
59
|
-
? `// Instead of:
|
|
60
|
-
schema.parse(data);
|
|
61
|
-
|
|
62
|
-
// Do:
|
|
63
|
-
const validatedData = schema.parse(data);
|
|
64
|
-
// Use validatedData for all subsequent operations`
|
|
65
|
-
: `// Assign and use the validated result
|
|
66
|
-
const validatedData = await schema.validate(data);`,
|
|
67
|
-
},
|
|
68
|
-
links: {
|
|
69
|
-
cwe: "https://cwe.mitre.org/data/definitions/20.html",
|
|
70
|
-
},
|
|
71
|
-
fingerprint,
|
|
72
|
-
});
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
// Case 2: Result assigned but raw body used after
|
|
76
|
-
if (usage.resultAssigned && usage.rawBodyUsedAfter && !usage.resultUsed) {
|
|
77
|
-
const evidence = [
|
|
78
|
-
{
|
|
79
|
-
file: relPath,
|
|
80
|
-
startLine: usage.line,
|
|
81
|
-
endLine: usage.line,
|
|
82
|
-
snippet: helpers.getNodeText(usage.node).slice(0, 150),
|
|
83
|
-
label: `Validated data assigned but raw body used instead`,
|
|
84
|
-
},
|
|
85
|
-
];
|
|
86
|
-
const fingerprint = generateFingerprint({
|
|
87
|
-
ruleId: RULE_ID,
|
|
88
|
-
file: relPath,
|
|
89
|
-
symbol: `${usage.library}.${usage.method}-unused`,
|
|
90
|
-
startLine: usage.line,
|
|
91
|
-
});
|
|
92
|
-
findings.push({
|
|
93
|
-
id: generateFindingId({
|
|
94
|
-
ruleId: RULE_ID,
|
|
95
|
-
file: relPath,
|
|
96
|
-
symbol: `${usage.library}.${usage.method}-unused`,
|
|
97
|
-
startLine: usage.line,
|
|
98
|
-
}),
|
|
99
|
-
ruleId: RULE_ID,
|
|
100
|
-
title: `Validated data unused, raw body accessed instead`,
|
|
101
|
-
description: `The ${usage.library} validation is performed and the result is assigned, but the code continues to use the raw request body instead of the validated data. This defeats the purpose of validation.`,
|
|
102
|
-
severity: "high",
|
|
103
|
-
confidence: 0.85,
|
|
104
|
-
category: "validation",
|
|
105
|
-
evidence,
|
|
106
|
-
remediation: {
|
|
107
|
-
recommendedFix: `Use the validated data variable instead of accessing the raw request body after validation.`,
|
|
108
|
-
},
|
|
109
|
-
links: {
|
|
110
|
-
cwe: "https://cwe.mitre.org/data/definitions/20.html",
|
|
111
|
-
},
|
|
112
|
-
fingerprint,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return findings;
|
|
119
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { ScannerPack } from "../types.js";
|
|
2
|
-
export declare const validationPack: ScannerPack;
|
|
3
|
-
export { scanIgnoredValidation } from "./ignored-validation.js";
|
|
4
|
-
export { scanClientSideOnlyValidation } from "./client-side-only.js";
|
|
5
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/validation/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,eAAO,MAAM,cAAc,EAAE,WAI5B,CAAC;AAEF,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { scanIgnoredValidation } from "./ignored-validation.js";
|
|
2
|
-
import { scanClientSideOnlyValidation } from "./client-side-only.js";
|
|
3
|
-
export const validationPack = {
|
|
4
|
-
id: "validation",
|
|
5
|
-
name: "Input Validation",
|
|
6
|
-
scanners: [scanIgnoredValidation, scanClientSideOnlyValidation],
|
|
7
|
-
};
|
|
8
|
-
export { scanIgnoredValidation } from "./ignored-validation.js";
|
|
9
|
-
export { scanClientSideOnlyValidation } from "./client-side-only.js";
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default exclude patterns for file scanning
|
|
3
|
-
*
|
|
4
|
-
* These patterns are applied by default to exclude common
|
|
5
|
-
* non-source directories and test files.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Core excludes that are always applied (build artifacts, dependencies, etc.)
|
|
9
|
-
*/
|
|
10
|
-
export declare const CORE_EXCLUDES: string[];
|
|
11
|
-
/**
|
|
12
|
-
* Test-related excludes (can be disabled with --include-tests)
|
|
13
|
-
*/
|
|
14
|
-
export declare const TEST_EXCLUDES: string[];
|
|
15
|
-
/**
|
|
16
|
-
* Get default exclude patterns based on options
|
|
17
|
-
*/
|
|
18
|
-
export declare function getDefaultExcludes(options?: {
|
|
19
|
-
includeTests?: boolean;
|
|
20
|
-
}): string[];
|
|
21
|
-
/**
|
|
22
|
-
* Merge custom excludes with defaults
|
|
23
|
-
*/
|
|
24
|
-
export declare function mergeExcludes(customExcludes: string[], options?: {
|
|
25
|
-
includeTests?: boolean;
|
|
26
|
-
}): string[];
|
|
27
|
-
/**
|
|
28
|
-
* Normalize glob pattern for cross-platform compatibility
|
|
29
|
-
*/
|
|
30
|
-
export declare function normalizeGlobPattern(pattern: string): string;
|
|
31
|
-
/**
|
|
32
|
-
* Normalize a list of patterns
|
|
33
|
-
*/
|
|
34
|
-
export declare function normalizePatterns(patterns: string[]): string[];
|
|
35
|
-
//# sourceMappingURL=exclude-patterns.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"exclude-patterns.d.ts","sourceRoot":"","sources":["../../src/utils/exclude-patterns.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,EAYjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,EAqBjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,EAAE,CAQrF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,cAAc,EAAE,MAAM,EAAE,EACxB,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,MAAM,EAAE,CAIV;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAE9D"}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default exclude patterns for file scanning
|
|
3
|
-
*
|
|
4
|
-
* These patterns are applied by default to exclude common
|
|
5
|
-
* non-source directories and test files.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Core excludes that are always applied (build artifacts, dependencies, etc.)
|
|
9
|
-
*/
|
|
10
|
-
export const CORE_EXCLUDES = [
|
|
11
|
-
"**/node_modules/**",
|
|
12
|
-
"**/dist/**",
|
|
13
|
-
"**/.git/**",
|
|
14
|
-
"**/build/**",
|
|
15
|
-
"**/.next/**",
|
|
16
|
-
"**/coverage/**",
|
|
17
|
-
"**/.turbo/**",
|
|
18
|
-
"**/.cache/**",
|
|
19
|
-
"**/out/**",
|
|
20
|
-
"**/.vercel/**",
|
|
21
|
-
"**/.netlify/**",
|
|
22
|
-
];
|
|
23
|
-
/**
|
|
24
|
-
* Test-related excludes (can be disabled with --include-tests)
|
|
25
|
-
*/
|
|
26
|
-
export const TEST_EXCLUDES = [
|
|
27
|
-
"**/__tests__/**",
|
|
28
|
-
"**/*.test.ts",
|
|
29
|
-
"**/*.test.tsx",
|
|
30
|
-
"**/*.test.js",
|
|
31
|
-
"**/*.test.jsx",
|
|
32
|
-
"**/*.spec.ts",
|
|
33
|
-
"**/*.spec.tsx",
|
|
34
|
-
"**/*.spec.js",
|
|
35
|
-
"**/*.spec.jsx",
|
|
36
|
-
"**/test/**",
|
|
37
|
-
"**/tests/**",
|
|
38
|
-
"**/fixtures/**",
|
|
39
|
-
"**/__mocks__/**",
|
|
40
|
-
"**/__fixtures__/**",
|
|
41
|
-
"**/cypress/**",
|
|
42
|
-
"**/e2e/**",
|
|
43
|
-
"**/*.stories.ts",
|
|
44
|
-
"**/*.stories.tsx",
|
|
45
|
-
"**/*.stories.js",
|
|
46
|
-
"**/*.stories.jsx",
|
|
47
|
-
];
|
|
48
|
-
/**
|
|
49
|
-
* Get default exclude patterns based on options
|
|
50
|
-
*/
|
|
51
|
-
export function getDefaultExcludes(options = {}) {
|
|
52
|
-
const excludes = [...CORE_EXCLUDES];
|
|
53
|
-
if (!options.includeTests) {
|
|
54
|
-
excludes.push(...TEST_EXCLUDES);
|
|
55
|
-
}
|
|
56
|
-
return excludes;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Merge custom excludes with defaults
|
|
60
|
-
*/
|
|
61
|
-
export function mergeExcludes(customExcludes, options = {}) {
|
|
62
|
-
const defaults = getDefaultExcludes(options);
|
|
63
|
-
const merged = new Set([...defaults, ...customExcludes]);
|
|
64
|
-
return Array.from(merged);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Normalize glob pattern for cross-platform compatibility
|
|
68
|
-
*/
|
|
69
|
-
export function normalizeGlobPattern(pattern) {
|
|
70
|
-
// Ensure forward slashes for glob patterns
|
|
71
|
-
return pattern.replace(/\\/g, "/");
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Normalize a list of patterns
|
|
75
|
-
*/
|
|
76
|
-
export function normalizePatterns(patterns) {
|
|
77
|
-
return patterns.map(normalizeGlobPattern);
|
|
78
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Read file contents as string, returns null if file doesn't exist
|
|
3
|
-
*/
|
|
4
|
-
export declare function readFileSync(filePath: string): string | null;
|
|
5
|
-
/**
|
|
6
|
-
* Check if a file exists
|
|
7
|
-
*/
|
|
8
|
-
export declare function fileExists(filePath: string): boolean;
|
|
9
|
-
/**
|
|
10
|
-
* Ensure a directory exists, creating it if necessary
|
|
11
|
-
*/
|
|
12
|
-
export declare function ensureDir(dirPath: string): void;
|
|
13
|
-
/**
|
|
14
|
-
* Write content to file, creating directories as needed
|
|
15
|
-
*/
|
|
16
|
-
export declare function writeFileSync(filePath: string, content: string): void;
|
|
17
|
-
/**
|
|
18
|
-
* Find files matching glob patterns
|
|
19
|
-
*/
|
|
20
|
-
export declare function findFiles(patterns: string | string[], options: {
|
|
21
|
-
cwd: string;
|
|
22
|
-
ignore?: string[];
|
|
23
|
-
absolute?: boolean;
|
|
24
|
-
}): Promise<string[]>;
|
|
25
|
-
/**
|
|
26
|
-
* Get relative path from base directory
|
|
27
|
-
*/
|
|
28
|
-
export declare function relativePath(filePath: string, basePath: string): string;
|
|
29
|
-
/**
|
|
30
|
-
* Resolve to absolute path
|
|
31
|
-
*/
|
|
32
|
-
export declare function resolvePath(...paths: string[]): string;
|
|
33
|
-
/**
|
|
34
|
-
* Read and parse JSON file
|
|
35
|
-
*/
|
|
36
|
-
export declare function readJsonSync<T>(filePath: string): T | null;
|
|
37
|
-
//# sourceMappingURL=file-utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/utils/file-utils.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAGrE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAC3B,OAAO,EAAE;IACP,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GACA,OAAO,CAAC,MAAM,EAAE,CAAC,CAOnB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAQ1D"}
|
package/dist/utils/file-utils.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import fg from "fast-glob";
|
|
4
|
-
/**
|
|
5
|
-
* Read file contents as string, returns null if file doesn't exist
|
|
6
|
-
*/
|
|
7
|
-
export function readFileSync(filePath) {
|
|
8
|
-
try {
|
|
9
|
-
return fs.readFileSync(filePath, "utf-8");
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Check if a file exists
|
|
17
|
-
*/
|
|
18
|
-
export function fileExists(filePath) {
|
|
19
|
-
try {
|
|
20
|
-
return fs.existsSync(filePath);
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Ensure a directory exists, creating it if necessary
|
|
28
|
-
*/
|
|
29
|
-
export function ensureDir(dirPath) {
|
|
30
|
-
if (!fs.existsSync(dirPath)) {
|
|
31
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Write content to file, creating directories as needed
|
|
36
|
-
*/
|
|
37
|
-
export function writeFileSync(filePath, content) {
|
|
38
|
-
ensureDir(path.dirname(filePath));
|
|
39
|
-
fs.writeFileSync(filePath, content, "utf-8");
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Find files matching glob patterns
|
|
43
|
-
*/
|
|
44
|
-
export async function findFiles(patterns, options) {
|
|
45
|
-
return fg(patterns, {
|
|
46
|
-
cwd: options.cwd,
|
|
47
|
-
ignore: options.ignore ?? ["**/node_modules/**", "**/dist/**", "**/.git/**"],
|
|
48
|
-
absolute: options.absolute ?? false,
|
|
49
|
-
dot: false,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Get relative path from base directory
|
|
54
|
-
*/
|
|
55
|
-
export function relativePath(filePath, basePath) {
|
|
56
|
-
return path.relative(basePath, filePath).replace(/\\/g, "/");
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Resolve to absolute path
|
|
60
|
-
*/
|
|
61
|
-
export function resolvePath(...paths) {
|
|
62
|
-
return path.resolve(...paths);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Read and parse JSON file
|
|
66
|
-
*/
|
|
67
|
-
export function readJsonSync(filePath) {
|
|
68
|
-
const content = readFileSync(filePath);
|
|
69
|
-
if (!content)
|
|
70
|
-
return null;
|
|
71
|
-
try {
|
|
72
|
-
return JSON.parse(content);
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate a deterministic fingerprint for a finding based on its key attributes.
|
|
3
|
-
* This allows deduplication across scans.
|
|
4
|
-
*/
|
|
5
|
-
export declare function generateFingerprint(parts: {
|
|
6
|
-
ruleId: string;
|
|
7
|
-
file: string;
|
|
8
|
-
symbol?: string;
|
|
9
|
-
route?: string;
|
|
10
|
-
startLine?: number;
|
|
11
|
-
}): string;
|
|
12
|
-
/**
|
|
13
|
-
* Generate a stable finding ID based on fingerprint components
|
|
14
|
-
*/
|
|
15
|
-
export declare function generateFindingId(parts: {
|
|
16
|
-
ruleId: string;
|
|
17
|
-
file: string;
|
|
18
|
-
symbol?: string;
|
|
19
|
-
startLine?: number;
|
|
20
|
-
}): string;
|
|
21
|
-
/**
|
|
22
|
-
* Hash a directory path for repo identification
|
|
23
|
-
*/
|
|
24
|
-
export declare function hashPath(dirPath: string): string;
|
|
25
|
-
//# sourceMappingURL=fingerprint.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/utils/fingerprint.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAUT;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAGT;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhD"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
/**
|
|
3
|
-
* Generate a deterministic fingerprint for a finding based on its key attributes.
|
|
4
|
-
* This allows deduplication across scans.
|
|
5
|
-
*/
|
|
6
|
-
export function generateFingerprint(parts) {
|
|
7
|
-
const data = [
|
|
8
|
-
parts.ruleId,
|
|
9
|
-
parts.file,
|
|
10
|
-
parts.symbol ?? "",
|
|
11
|
-
parts.route ?? "",
|
|
12
|
-
parts.startLine?.toString() ?? "",
|
|
13
|
-
].join("::");
|
|
14
|
-
return crypto.createHash("sha256").update(data).digest("hex").slice(0, 16);
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Generate a stable finding ID based on fingerprint components
|
|
18
|
-
*/
|
|
19
|
-
export function generateFindingId(parts) {
|
|
20
|
-
const fp = generateFingerprint(parts);
|
|
21
|
-
return `${parts.ruleId.toLowerCase()}-${fp.slice(0, 8)}`;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Hash a directory path for repo identification
|
|
25
|
-
*/
|
|
26
|
-
export function hashPath(dirPath) {
|
|
27
|
-
return crypto.createHash("sha256").update(dirPath).digest("hex").slice(0, 16);
|
|
28
|
-
}
|
package/dist/utils/git-info.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { GitInfo } from "@vibecheck/schema";
|
|
2
|
-
/**
|
|
3
|
-
* Check if directory is a git repository
|
|
4
|
-
*/
|
|
5
|
-
export declare function isGitRepo(cwd: string): boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Get git information for a repository
|
|
8
|
-
*/
|
|
9
|
-
export declare function getGitInfo(cwd: string): GitInfo | undefined;
|
|
10
|
-
/**
|
|
11
|
-
* Get repository name from git remote or directory name
|
|
12
|
-
*/
|
|
13
|
-
export declare function getRepoName(cwd: string): string;
|
|
14
|
-
//# sourceMappingURL=git-info.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git-info.d.ts","sourceRoot":"","sources":["../../src/utils/git-info.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAcjD;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAgB3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAe/C"}
|
package/dist/utils/git-info.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { execSync } from "node:child_process";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileExists } from "./file-utils.js";
|
|
4
|
-
/**
|
|
5
|
-
* Execute a git command and return output, or null on error
|
|
6
|
-
*/
|
|
7
|
-
function execGit(cmd, cwd) {
|
|
8
|
-
try {
|
|
9
|
-
return execSync(cmd, { cwd, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Check if directory is a git repository
|
|
17
|
-
*/
|
|
18
|
-
export function isGitRepo(cwd) {
|
|
19
|
-
return fileExists(path.join(cwd, ".git"));
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Get git information for a repository
|
|
23
|
-
*/
|
|
24
|
-
export function getGitInfo(cwd) {
|
|
25
|
-
if (!isGitRepo(cwd)) {
|
|
26
|
-
return undefined;
|
|
27
|
-
}
|
|
28
|
-
const branch = execGit("git rev-parse --abbrev-ref HEAD", cwd);
|
|
29
|
-
const commit = execGit("git rev-parse HEAD", cwd);
|
|
30
|
-
const remoteUrl = execGit("git config --get remote.origin.url", cwd);
|
|
31
|
-
const status = execGit("git status --porcelain", cwd);
|
|
32
|
-
return {
|
|
33
|
-
branch: branch ?? undefined,
|
|
34
|
-
commit: commit ?? undefined,
|
|
35
|
-
remoteUrl: remoteUrl ?? undefined,
|
|
36
|
-
isDirty: status !== null && status.length > 0,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Get repository name from git remote or directory name
|
|
41
|
-
*/
|
|
42
|
-
export function getRepoName(cwd) {
|
|
43
|
-
const remoteUrl = execGit("git config --get remote.origin.url", cwd);
|
|
44
|
-
if (remoteUrl) {
|
|
45
|
-
// Extract repo name from URL like:
|
|
46
|
-
// https://github.com/user/repo.git -> repo
|
|
47
|
-
// git@github.com:user/repo.git -> repo
|
|
48
|
-
const match = remoteUrl.match(/\/([^/]+?)(?:\.git)?$/);
|
|
49
|
-
if (match) {
|
|
50
|
-
return match[1];
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
// Fall back to directory name
|
|
54
|
-
return path.basename(cwd);
|
|
55
|
-
}
|
package/dist/utils/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC"}
|
package/dist/utils/index.js
DELETED
package/dist/utils/progress.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Terminal progress display - clean, minimal design
|
|
3
|
-
*/
|
|
4
|
-
interface PackInfo {
|
|
5
|
-
id: string;
|
|
6
|
-
name: string;
|
|
7
|
-
scannerCount: number;
|
|
8
|
-
}
|
|
9
|
-
export declare class ScanProgress {
|
|
10
|
-
private packs;
|
|
11
|
-
private results;
|
|
12
|
-
private startTime;
|
|
13
|
-
private currentPack;
|
|
14
|
-
private totalFiles;
|
|
15
|
-
private currentFile;
|
|
16
|
-
private filesProcessed;
|
|
17
|
-
constructor(packs: PackInfo[], totalFiles?: number);
|
|
18
|
-
start(): void;
|
|
19
|
-
startPack(packIndex: number): void;
|
|
20
|
-
startScanner(packIndex: number, _scannerIndex: number): void;
|
|
21
|
-
/** Called when a file is processed */
|
|
22
|
-
onFileProgress(file: string, processed: number, _total: number): void;
|
|
23
|
-
completeScanner(packIndex: number, findingsFound: number): void;
|
|
24
|
-
private renderPackProgress;
|
|
25
|
-
completePack(packIndex: number): void;
|
|
26
|
-
stop(): void;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Simple spinner for single operations
|
|
30
|
-
*/
|
|
31
|
-
export declare class Spinner {
|
|
32
|
-
private message;
|
|
33
|
-
private startTime;
|
|
34
|
-
constructor(message: string);
|
|
35
|
-
start(): void;
|
|
36
|
-
update(message: string): void;
|
|
37
|
-
succeed(message?: string): void;
|
|
38
|
-
fail(message?: string): void;
|
|
39
|
-
stop(): void;
|
|
40
|
-
}
|
|
41
|
-
export {};
|
|
42
|
-
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/utils/progress.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAuBD,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,cAAc,CAAa;gBAEvB,KAAK,EAAE,QAAQ,EAAE,EAAE,UAAU,GAAE,MAAU;IAKrD,KAAK,IAAI,IAAI;IAcb,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAMlC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI;IAI5D,sCAAsC;IACtC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAMrE,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI;IAS/D,OAAO,CAAC,kBAAkB;IA8B1B,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IA2BrC,IAAI,IAAI,IAAI;CA0Bb;AAED;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAa;gBAElB,OAAO,EAAE,MAAM;IAI3B,KAAK,IAAI,IAAI;IAKb,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAM/B,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAK5B,IAAI,IAAI,IAAI;CAGb"}
|