@datahogo/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +17 -0
- package/dist/engines/config.d.ts +3 -0
- package/dist/engines/config.d.ts.map +1 -0
- package/dist/engines/config.js +433 -0
- package/dist/engines/config.js.map +1 -0
- package/dist/engines/dast.d.ts +3 -0
- package/dist/engines/dast.d.ts.map +1 -0
- package/dist/engines/dast.js +167 -0
- package/dist/engines/dast.js.map +1 -0
- package/dist/engines/db-rules.d.ts +3 -0
- package/dist/engines/db-rules.d.ts.map +1 -0
- package/dist/engines/db-rules.js +166 -0
- package/dist/engines/db-rules.js.map +1 -0
- package/dist/engines/dependencies.d.ts +3 -0
- package/dist/engines/dependencies.d.ts.map +1 -0
- package/dist/engines/dependencies.js +167 -0
- package/dist/engines/dependencies.js.map +1 -0
- package/dist/engines/github-actions.d.ts +3 -0
- package/dist/engines/github-actions.d.ts.map +1 -0
- package/dist/engines/github-actions.js +215 -0
- package/dist/engines/github-actions.js.map +1 -0
- package/dist/engines/gitleaks.d.ts +3 -0
- package/dist/engines/gitleaks.d.ts.map +1 -0
- package/dist/engines/gitleaks.js +107 -0
- package/dist/engines/gitleaks.js.map +1 -0
- package/dist/engines/npm-audit.d.ts +3 -0
- package/dist/engines/npm-audit.d.ts.map +1 -0
- package/dist/engines/npm-audit.js +113 -0
- package/dist/engines/npm-audit.js.map +1 -0
- package/dist/engines/patterns.d.ts +3 -0
- package/dist/engines/patterns.d.ts.map +1 -0
- package/dist/engines/patterns.js +1330 -0
- package/dist/engines/patterns.js.map +1 -0
- package/dist/engines/secrets.d.ts +4 -0
- package/dist/engines/secrets.d.ts.map +1 -0
- package/dist/engines/secrets.js +260 -0
- package/dist/engines/secrets.js.map +1 -0
- package/dist/engines/semgrep.d.ts +3 -0
- package/dist/engines/semgrep.d.ts.map +1 -0
- package/dist/engines/semgrep.js +173 -0
- package/dist/engines/semgrep.js.map +1 -0
- package/dist/engines/types.d.ts +30 -0
- package/dist/engines/types.d.ts.map +1 -0
- package/dist/engines/types.js +3 -0
- package/dist/engines/types.js.map +1 -0
- package/dist/engines/url-scanner.d.ts +3 -0
- package/dist/engines/url-scanner.d.ts.map +1 -0
- package/dist/engines/url-scanner.js +469 -0
- package/dist/engines/url-scanner.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator.d.ts +32 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +237 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/rules/.gitkeep +0 -0
- package/dist/rules/ai-llm-security.yaml +199 -0
- package/dist/rules/api-security.yaml +489 -0
- package/dist/rules/auth-patterns.yaml +406 -0
- package/dist/rules/crypto-patterns.yaml +227 -0
- package/dist/rules/database-cloud-security.yaml +169 -0
- package/dist/rules/general-security.yaml +588 -0
- package/dist/rules/injection-patterns.yaml +318 -0
- package/dist/rules/nextjs-security.yaml +532 -0
- package/dist/rules/node-security.yaml +380 -0
- package/dist/rules/rules/.gitkeep +0 -0
- package/dist/rules/rules/ai-llm-security.yaml +199 -0
- package/dist/rules/rules/api-security.yaml +489 -0
- package/dist/rules/rules/auth-patterns.yaml +406 -0
- package/dist/rules/rules/crypto-patterns.yaml +227 -0
- package/dist/rules/rules/database-cloud-security.yaml +169 -0
- package/dist/rules/rules/general-security.yaml +588 -0
- package/dist/rules/rules/injection-patterns.yaml +318 -0
- package/dist/rules/rules/nextjs-security.yaml +532 -0
- package/dist/rules/rules/node-security.yaml +380 -0
- package/dist/rules/rules/supabase-security.yaml +387 -0
- package/dist/rules/supabase-security.yaml +387 -0
- package/dist/scanning/agents/csharp-agent.d.ts +12 -0
- package/dist/scanning/agents/csharp-agent.d.ts.map +1 -0
- package/dist/scanning/agents/csharp-agent.js +592 -0
- package/dist/scanning/agents/csharp-agent.js.map +1 -0
- package/dist/scanning/agents/go-agent.d.ts +14 -0
- package/dist/scanning/agents/go-agent.d.ts.map +1 -0
- package/dist/scanning/agents/go-agent.js +641 -0
- package/dist/scanning/agents/go-agent.js.map +1 -0
- package/dist/scanning/agents/java-agent.d.ts +8 -0
- package/dist/scanning/agents/java-agent.d.ts.map +1 -0
- package/dist/scanning/agents/java-agent.js +807 -0
- package/dist/scanning/agents/java-agent.js.map +1 -0
- package/dist/scanning/agents/javascript-agent.d.ts +8 -0
- package/dist/scanning/agents/javascript-agent.d.ts.map +1 -0
- package/dist/scanning/agents/javascript-agent.js +77 -0
- package/dist/scanning/agents/javascript-agent.js.map +1 -0
- package/dist/scanning/agents/mobile-agent.d.ts +8 -0
- package/dist/scanning/agents/mobile-agent.d.ts.map +1 -0
- package/dist/scanning/agents/mobile-agent.js +916 -0
- package/dist/scanning/agents/mobile-agent.js.map +1 -0
- package/dist/scanning/agents/php-agent.d.ts +8 -0
- package/dist/scanning/agents/php-agent.d.ts.map +1 -0
- package/dist/scanning/agents/php-agent.js +679 -0
- package/dist/scanning/agents/php-agent.js.map +1 -0
- package/dist/scanning/agents/python-agent.d.ts +8 -0
- package/dist/scanning/agents/python-agent.d.ts.map +1 -0
- package/dist/scanning/agents/python-agent.js +701 -0
- package/dist/scanning/agents/python-agent.js.map +1 -0
- package/dist/scanning/agents/supabase-agent.d.ts +8 -0
- package/dist/scanning/agents/supabase-agent.d.ts.map +1 -0
- package/dist/scanning/agents/supabase-agent.js +484 -0
- package/dist/scanning/agents/supabase-agent.js.map +1 -0
- package/dist/scanning/orchestrator.d.ts +29 -0
- package/dist/scanning/orchestrator.d.ts.map +1 -0
- package/dist/scanning/orchestrator.js +186 -0
- package/dist/scanning/orchestrator.js.map +1 -0
- package/dist/scanning/tech-detector.d.ts +12 -0
- package/dist/scanning/tech-detector.d.ts.map +1 -0
- package/dist/scanning/tech-detector.js +252 -0
- package/dist/scanning/tech-detector.js.map +1 -0
- package/dist/scanning/types.d.ts +87 -0
- package/dist/scanning/types.d.ts.map +1 -0
- package/dist/scanning/types.js +5 -0
- package/dist/scanning/types.js.map +1 -0
- package/dist/utils/child-process.d.ts +2 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +4 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/context-classifier.d.ts +11 -0
- package/dist/utils/context-classifier.d.ts.map +1 -0
- package/dist/utils/context-classifier.js +79 -0
- package/dist/utils/context-classifier.js.map +1 -0
- package/dist/utils/exec.d.ts +18 -0
- package/dist/utils/exec.d.ts.map +1 -0
- package/dist/utils/exec.js +51 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/file-filter.d.ts +4 -0
- package/dist/utils/file-filter.d.ts.map +1 -0
- package/dist/utils/file-filter.js +68 -0
- package/dist/utils/file-filter.js.map +1 -0
- package/dist/utils/fs.d.ts +2 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +5 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +12 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +27 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/post-processor.d.ts +10 -0
- package/dist/utils/post-processor.d.ts.map +1 -0
- package/dist/utils/post-processor.js +183 -0
- package/dist/utils/post-processor.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Gitleaks engine - runs the Gitleaks binary for comprehensive secret detection.
|
|
2
|
+
// Falls back gracefully if gitleaks is not installed (regex secrets engine covers basics).
|
|
3
|
+
import { execWithTimeout } from "../utils/exec.js";
|
|
4
|
+
import { readFile, rm } from "../utils/fs.js";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
// Map Gitleaks RuleIDs to our vulnerability catalog
|
|
8
|
+
const RULE_ID_MAP = {
|
|
9
|
+
"generic-api-key": { id: 53, severity: "critical", category: "vibecoding" },
|
|
10
|
+
"private-key": { id: 53, severity: "critical", category: "vibecoding" },
|
|
11
|
+
"aws-access-key-id": { id: 53, severity: "critical", category: "vibecoding" },
|
|
12
|
+
"aws-secret-access-key": { id: 53, severity: "critical", category: "vibecoding" },
|
|
13
|
+
"github-pat": { id: 53, severity: "critical", category: "vibecoding" },
|
|
14
|
+
"github-fine-grained-pat": { id: 53, severity: "critical", category: "vibecoding" },
|
|
15
|
+
"github-oauth": { id: 53, severity: "critical", category: "vibecoding" },
|
|
16
|
+
"github-app-token": { id: 53, severity: "critical", category: "vibecoding" },
|
|
17
|
+
"gcp-api-key": { id: 53, severity: "critical", category: "vibecoding" },
|
|
18
|
+
"stripe-access-token": { id: 53, severity: "critical", category: "vibecoding" },
|
|
19
|
+
"slack-bot-token": { id: 53, severity: "critical", category: "vibecoding" },
|
|
20
|
+
"slack-webhook-url": { id: 53, severity: "high", category: "vibecoding" },
|
|
21
|
+
"twilio-api-key": { id: 53, severity: "critical", category: "vibecoding" },
|
|
22
|
+
"sendgrid-api-key": { id: 53, severity: "critical", category: "vibecoding" },
|
|
23
|
+
"mailchimp-api-key": { id: 53, severity: "high", category: "vibecoding" },
|
|
24
|
+
"npm-access-token": { id: 53, severity: "critical", category: "supply-chain" },
|
|
25
|
+
"pypi-upload-token": { id: 53, severity: "critical", category: "supply-chain" },
|
|
26
|
+
"telegram-bot-api-token": { id: 53, severity: "high", category: "vibecoding" },
|
|
27
|
+
"discord-api-token": { id: 53, severity: "high", category: "vibecoding" },
|
|
28
|
+
"discord-client-secret": { id: 53, severity: "high", category: "vibecoding" },
|
|
29
|
+
"heroku-api-key": { id: 53, severity: "critical", category: "vibecoding" },
|
|
30
|
+
"linkedin-client-secret": { id: 53, severity: "high", category: "vibecoding" },
|
|
31
|
+
"vault-service-token": { id: 53, severity: "critical", category: "vibecoding" },
|
|
32
|
+
"jwt": { id: 53, severity: "high", category: "vibecoding" },
|
|
33
|
+
"password-in-url": { id: 55, severity: "critical", category: "vibecoding" },
|
|
34
|
+
"postgresql-connection-string": { id: 101, severity: "critical", category: "database" },
|
|
35
|
+
"mysql-connection-string": { id: 101, severity: "critical", category: "database" },
|
|
36
|
+
"mongodb-connection-string": { id: 101, severity: "critical", category: "database" },
|
|
37
|
+
};
|
|
38
|
+
const DEFAULT_MAPPING = { id: 53, severity: "critical", category: "vibecoding" };
|
|
39
|
+
export async function runGitleaks(repoDir) {
|
|
40
|
+
const reportPath = path.join(os.tmpdir(), `gitleaks-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
41
|
+
try {
|
|
42
|
+
// Gitleaks exits with code 1 when leaks are found — this is expected behavior
|
|
43
|
+
await execWithTimeout("gitleaks", [
|
|
44
|
+
"dir",
|
|
45
|
+
repoDir,
|
|
46
|
+
"-v",
|
|
47
|
+
"--report-format", "json",
|
|
48
|
+
"--report-path", reportPath,
|
|
49
|
+
"--no-git", // Scan current files, not git history (faster, history not available)
|
|
50
|
+
], { timeoutMs: 30_000 });
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// Only re-throw if it's a timeout or missing binary
|
|
54
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
55
|
+
if (message.includes("timed out") || message.includes("ENOENT")) {
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
// exit code 1 = leaks found, report file should exist
|
|
59
|
+
}
|
|
60
|
+
let reportContent;
|
|
61
|
+
try {
|
|
62
|
+
reportContent = await readFile(reportPath, "utf-8");
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// No report file = no leaks found (exit code 0, empty report)
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
await rm(reportPath, { force: true }).catch(() => { });
|
|
70
|
+
}
|
|
71
|
+
if (!reportContent.trim())
|
|
72
|
+
return [];
|
|
73
|
+
let results;
|
|
74
|
+
try {
|
|
75
|
+
results = JSON.parse(reportContent);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
if (!Array.isArray(results))
|
|
81
|
+
return [];
|
|
82
|
+
return results.map((leak) => mapLeakToFinding(leak, repoDir));
|
|
83
|
+
}
|
|
84
|
+
function mapLeakToFinding(leak, repoDir) {
|
|
85
|
+
const mapping = RULE_ID_MAP[leak.RuleID] ?? DEFAULT_MAPPING;
|
|
86
|
+
// Make file path relative to repo root
|
|
87
|
+
const filePath = leak.File.startsWith(repoDir)
|
|
88
|
+
? leak.File.slice(repoDir.length + 1)
|
|
89
|
+
: leak.File;
|
|
90
|
+
// Mask the actual secret value
|
|
91
|
+
const maskedSecret = leak.Secret.length > 6
|
|
92
|
+
? leak.Secret.substring(0, 6) + "...REDACTED"
|
|
93
|
+
: "***REDACTED***";
|
|
94
|
+
return {
|
|
95
|
+
vulnerability_id: mapping.id,
|
|
96
|
+
severity: mapping.severity,
|
|
97
|
+
category: mapping.category,
|
|
98
|
+
title: `${leak.Description}`,
|
|
99
|
+
description_technical: `Gitleaks detected ${leak.RuleID}: ${leak.Description}`,
|
|
100
|
+
file_path: filePath,
|
|
101
|
+
line_number: leak.StartLine,
|
|
102
|
+
code_snippet: leak.Match.replace(leak.Secret, maskedSecret),
|
|
103
|
+
owasp_ref: "A07:2021",
|
|
104
|
+
status: "open",
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=gitleaks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitleaks.js","sourceRoot":"","sources":["../../src/engines/gitleaks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-audit.d.ts","sourceRoot":"","sources":["../../src/engines/npm-audit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,YAAY,CAAC;AA0CxD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACzB,OAAO,CAAC,WAAW,EAAE,CAAC,CA2FxB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// npm audit engine - runs npm audit for real-time CVE dependency scanning.
|
|
2
|
+
// Only runs when package-lock.json exists in the repo (required by npm audit).
|
|
3
|
+
// The hardcoded dependencies engine still runs for typosquatting detection.
|
|
4
|
+
import { execWithTimeout } from "../utils/exec.js";
|
|
5
|
+
import { access } from "../utils/fs.js";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
const SEVERITY_MAP = {
|
|
8
|
+
critical: "critical",
|
|
9
|
+
high: "high",
|
|
10
|
+
moderate: "medium",
|
|
11
|
+
low: "low",
|
|
12
|
+
info: "info",
|
|
13
|
+
};
|
|
14
|
+
export async function runNpmAudit(repoDir, files) {
|
|
15
|
+
// npm audit requires package-lock.json
|
|
16
|
+
const lockfilePath = path.join(repoDir, "package-lock.json");
|
|
17
|
+
try {
|
|
18
|
+
await access(lockfilePath);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// No lockfile — can't run npm audit
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
let stdout;
|
|
25
|
+
try {
|
|
26
|
+
// npm audit exits with non-zero when vulnerabilities are found — expected behavior
|
|
27
|
+
const result = await execWithTimeout("npm", [
|
|
28
|
+
"audit",
|
|
29
|
+
"--json",
|
|
30
|
+
"--omit=dev",
|
|
31
|
+
], {
|
|
32
|
+
timeoutMs: 60_000,
|
|
33
|
+
cwd: repoDir,
|
|
34
|
+
});
|
|
35
|
+
stdout = result.stdout;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
39
|
+
if (message.includes("timed out") || message.includes("ENOENT")) {
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
// npm audit exits non-zero when vulns found — try to extract stdout from error
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
if (!stdout.trim())
|
|
46
|
+
return [];
|
|
47
|
+
let output;
|
|
48
|
+
try {
|
|
49
|
+
output = JSON.parse(stdout);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
if (!output.vulnerabilities)
|
|
55
|
+
return [];
|
|
56
|
+
const findings = [];
|
|
57
|
+
for (const [pkgName, vuln] of Object.entries(output.vulnerabilities)) {
|
|
58
|
+
// Get the actual advisory details from `via` (skip string-only entries)
|
|
59
|
+
const advisories = vuln.via.filter((v) => typeof v !== "string");
|
|
60
|
+
if (advisories.length === 0) {
|
|
61
|
+
// Transitive vulnerability — still report but with less detail
|
|
62
|
+
findings.push({
|
|
63
|
+
vulnerability_id: 3,
|
|
64
|
+
severity: SEVERITY_MAP[vuln.severity] ?? "medium",
|
|
65
|
+
category: "supply-chain",
|
|
66
|
+
title: `Vulnerable Dependency: ${pkgName}`,
|
|
67
|
+
description_technical: `${pkgName} (${vuln.range}) has known vulnerabilities. ${vuln.isDirect ? "Direct dependency." : "Transitive dependency."}`,
|
|
68
|
+
file_path: "package-lock.json",
|
|
69
|
+
code_snippet: `"${pkgName}": "${vuln.range}"`,
|
|
70
|
+
fix_description: formatFixAvailable(vuln.fixAvailable),
|
|
71
|
+
owasp_ref: "A06:2021",
|
|
72
|
+
status: "open",
|
|
73
|
+
});
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
for (const advisory of advisories) {
|
|
77
|
+
const cweStr = advisory.cwe?.join(", ") || "";
|
|
78
|
+
findings.push({
|
|
79
|
+
vulnerability_id: 3,
|
|
80
|
+
severity: SEVERITY_MAP[advisory.severity] ?? SEVERITY_MAP[vuln.severity] ?? "medium",
|
|
81
|
+
category: "supply-chain",
|
|
82
|
+
title: `${advisory.title}: ${pkgName}`,
|
|
83
|
+
description_technical: [
|
|
84
|
+
advisory.title,
|
|
85
|
+
`Package: ${pkgName} (${vuln.range})`,
|
|
86
|
+
vuln.isDirect ? "Direct dependency" : "Transitive dependency",
|
|
87
|
+
advisory.url ? `Advisory: ${advisory.url}` : "",
|
|
88
|
+
cweStr ? `CWE: ${cweStr}` : "",
|
|
89
|
+
advisory.cvss?.score ? `CVSS: ${advisory.cvss.score}` : "",
|
|
90
|
+
].filter(Boolean).join("\n"),
|
|
91
|
+
file_path: "package-lock.json",
|
|
92
|
+
code_snippet: `"${pkgName}": "${vuln.range}"`,
|
|
93
|
+
fix_description: formatFixAvailable(vuln.fixAvailable),
|
|
94
|
+
owasp_ref: "A06:2021",
|
|
95
|
+
status: "open",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return findings;
|
|
100
|
+
}
|
|
101
|
+
function formatFixAvailable(fix) {
|
|
102
|
+
if (fix === true)
|
|
103
|
+
return "A fix is available. Run `npm audit fix` to apply.";
|
|
104
|
+
if (fix === false)
|
|
105
|
+
return "No fix available yet. Consider finding an alternative package.";
|
|
106
|
+
if (typeof fix === "object") {
|
|
107
|
+
return fix.isSemVerMajor
|
|
108
|
+
? `Update ${fix.name} to ${fix.version} (breaking change). Run \`npm audit fix --force\`.`
|
|
109
|
+
: `Update ${fix.name} to ${fix.version}. Run \`npm audit fix\`.`;
|
|
110
|
+
}
|
|
111
|
+
return "";
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=npm-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-audit.js","sourceRoot":"","sources":["../../src/engines/npm-audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/engines/patterns.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAqB,MAAM,YAAY,CAAC;AAglCjE,wBAAgB,eAAe,CAC7B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACzB,WAAW,EAAE,CAsDf"}
|