aws-security-mcp 0.7.0 → 0.7.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/dashboard/dist/assets/index-BXloWmhE.css +2 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/bin/aws-security-mcp.js +478 -12
- package/dist/bin/aws-security-mcp.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +479 -12
- package/dist/src/index.js.map +1 -1
- package/package.json +2 -2
- package/dashboard/dist/assets/index-UN8P_PO6.css +0 -2
- /package/dashboard/dist/assets/{index-AKJ_-GfD.js → index-DsWFAp9v.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/dashboard.ts","../../src/commands/deploy-dashboard.ts","../../src/index.ts","../../src/version.ts","../../src/utils/aws-client.ts","../../src/utils/assume-role.ts","../../src/utils/org-accounts.ts","../../src/scanners/runner.ts","../../src/scanners/service-detection.ts","../../src/utils/risk-scoring.ts","../../src/scanners/secret-exposure.ts","../../src/scanners/ssl-certificate.ts","../../src/scanners/dns-dangling.ts","../../src/scanners/network-reachability.ts","../../src/scanners/iam-privilege-escalation.ts","../../src/scanners/public-access-verify.ts","../../src/scanners/tag-compliance.ts","../../src/scanners/idle-resources.ts","../../src/scanners/disaster-recovery.ts","../../src/scanners/security-hub-findings.ts","../../src/utils/sh-source.ts","../../src/scanners/guardduty-findings.ts","../../src/scanners/inspector-findings.ts","../../src/scanners/trusted-advisor-findings.ts","../../src/scanners/config-rules-findings.ts","../../src/scanners/access-analyzer-findings.ts","../../src/scanners/patch-compliance-findings.ts","../../src/scanners/imdsv2-enforcement.ts","../../src/scanners/waf-coverage.ts","../../src/i18n/zh.ts","../../src/i18n/en.ts","../../src/i18n/index.ts","../../src/tools/report-tool.ts","../../src/data/mlps3-full-checklist.json","../../src/data/mlps3-check-mapping.ts","../../src/tools/mlps-report.ts","../../src/tools/html-report.ts","../../src/tools/save-results.ts","../../src/tools/scan-groups.ts","../../src/resources/index.ts","../../bin/aws-security-mcp.ts"],"sourcesContent":["import { createServer } from \"node:http\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, extname, resolve } from \"node:path\";\nimport { existsSync, copyFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { exec } from \"node:child_process\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = join(__filename, \"..\");\n\nconst MIME_TYPES: Record<string, string> = {\n \".html\": \"text/html\",\n \".js\": \"text/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n};\n\nexport function startDashboard(port = 3000): void {\n // dashboard/dist is two levels up from dist/src/commands/\n const dashboardDir = join(__dirname, \"../../dashboard/dist\");\n\n if (!existsSync(dashboardDir)) {\n console.error(\n `Dashboard not built. Run \"npm run build:dashboard\" first.\\n` +\n `Expected: ${dashboardDir}`,\n );\n process.exit(1);\n }\n\n // Copy real data.json if available\n const dataSource = join(\n process.env.HOME || process.env.USERPROFILE || \"~\",\n \".aws-security/dashboard/data.json\",\n );\n const dataDest = join(dashboardDir, \"data.json\");\n if (existsSync(dataSource)) {\n copyFileSync(dataSource, dataDest);\n console.log(`Loaded scan data from ${dataSource}`);\n } else {\n console.log(\n \"No scan data found at ~/.aws-security/dashboard/data.json — using bundled sample data\",\n );\n }\n\n const resolvedBase = resolve(dashboardDir);\n\n const server = createServer(async (req, res) => {\n const url = req.url?.split(\"?\")[0] ?? \"/\";\n let filePath = resolve(\n join(dashboardDir, url === \"/\" ? \"index.html\" : url),\n );\n\n // Ensure the resolved path is within dashboardDir\n if (!filePath.startsWith(resolvedBase + \"/\") && filePath !== resolvedBase) {\n res.writeHead(403);\n res.end(\"Forbidden\");\n return;\n }\n\n // SPA fallback: if file doesn't exist and isn't a static asset, serve index.html\n if (!existsSync(filePath)) {\n filePath = join(dashboardDir, \"index.html\");\n }\n\n try {\n const content = await readFile(filePath);\n const ext = extname(filePath);\n res.writeHead(200, {\n \"Content-Type\": MIME_TYPES[ext] || \"application/octet-stream\",\n });\n res.end(content);\n } catch {\n res.writeHead(404);\n res.end(\"Not found\");\n }\n });\n\n server.listen(port, () => {\n const url = `http://localhost:${port}`;\n console.log(`\\nAWS Security Dashboard: ${url}\\n`);\n console.log(\"Press Ctrl+C to stop.\\n\");\n\n // Try to open browser\n const cmd =\n process.platform === \"darwin\"\n ? \"open\"\n : process.platform === \"win32\"\n ? \"start\"\n : \"xdg-open\";\n exec(`${cmd} ${url}`, () => {\n // ignore errors — browser open is best-effort\n });\n });\n\n server.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n console.error(`Port ${port} is already in use. Try --port <other>`);\n process.exit(1);\n }\n throw err;\n });\n}\n","import { readdirSync, readFileSync, existsSync, copyFileSync } from \"node:fs\";\nimport { join, extname, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n S3Client,\n PutObjectCommand,\n PutBucketWebsiteCommand,\n PutBucketPolicyCommand,\n} from \"@aws-sdk/client-s3\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = join(__filename, \"..\");\n\nconst CONTENT_TYPES: Record<string, string> = {\n \".html\": \"text/html\",\n \".js\": \"text/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n};\n\nfunction collectFiles(dir: string): string[] {\n const files: string[] = [];\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...collectFiles(full));\n } else {\n files.push(full);\n }\n }\n return files;\n}\n\nexport async function deployDashboard(\n bucket: string,\n region: string,\n): Promise<void> {\n const dashboardDir = join(__dirname, \"../../dashboard/dist\");\n\n if (!existsSync(dashboardDir)) {\n console.error(\n `Dashboard not built. Run \"npm run build:dashboard\" first.\\n` +\n `Expected: ${dashboardDir}`,\n );\n process.exit(1);\n }\n\n // Copy real data.json if available\n const dataSource = join(\n process.env.HOME || process.env.USERPROFILE || \"~\",\n \".aws-security/dashboard/data.json\",\n );\n const dataDest = join(dashboardDir, \"data.json\");\n if (existsSync(dataSource)) {\n copyFileSync(dataSource, dataDest);\n console.log(`Loaded scan data from ${dataSource}`);\n } else {\n console.log(\n \"No scan data at ~/.aws-security/dashboard/data.json — deploying with bundled sample data\",\n );\n }\n\n const s3 = new S3Client({ region });\n\n // Configure static website hosting\n console.log(`Configuring s3://${bucket} for static website hosting...`);\n await s3.send(\n new PutBucketWebsiteCommand({\n Bucket: bucket,\n WebsiteConfiguration: {\n IndexDocument: { Suffix: \"index.html\" },\n ErrorDocument: { Key: \"index.html\" }, // SPA fallback\n },\n }),\n );\n\n // Set bucket policy for public read access\n const partition = region.startsWith(\"cn-\") ? \"aws-cn\" : \"aws\";\n console.log(`Setting public read bucket policy on s3://${bucket}...`);\n await s3.send(\n new PutBucketPolicyCommand({\n Bucket: bucket,\n Policy: JSON.stringify({\n Version: \"2012-10-17\",\n Statement: [\n {\n Sid: \"PublicReadGetObject\",\n Effect: \"Allow\",\n Principal: \"*\",\n Action: \"s3:GetObject\",\n Resource: `arn:${partition}:s3:::${bucket}/*`,\n },\n ],\n }),\n }),\n );\n\n // Upload all files\n const files = collectFiles(dashboardDir);\n console.log(`Uploading ${files.length} files to s3://${bucket}...`);\n\n for (const filePath of files) {\n const key = relative(dashboardDir, filePath);\n const ext = extname(filePath);\n const contentType = CONTENT_TYPES[ext] || \"application/octet-stream\";\n const body = readFileSync(filePath);\n\n await s3.send(\n new PutObjectCommand({\n Bucket: bucket,\n Key: key,\n Body: body,\n ContentType: contentType,\n }),\n );\n console.log(` ${key}`);\n }\n\n const domain = region.startsWith(\"cn-\") ? \"amazonaws.com.cn\" : \"amazonaws.com\";\n const websiteUrl = `http://${bucket}.s3-website.${region}.${domain}`;\n console.log(`\\nDashboard deployed successfully!`);\n console.log(`Website URL: ${websiteUrl}`);\n console.log(\n \"\\nNote: Ensure S3 Block Public Access is disabled on this bucket for the website to be accessible.\\n\",\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\n\nimport { VERSION } from \"./version.js\";\nimport type { Scanner } from \"./scanners/base.js\";\nimport { runAllScanners, runMultiAccountScanners } from \"./scanners/runner.js\";\nimport { ServiceDetectionScanner } from \"./scanners/service-detection.js\";\nimport type { ServiceDetectionResult } from \"./scanners/service-detection.js\";\nimport { SecretExposureScanner } from \"./scanners/secret-exposure.js\";\nimport { SslCertificateScanner } from \"./scanners/ssl-certificate.js\";\nimport { DnsDanglingScanner } from \"./scanners/dns-dangling.js\";\nimport { NetworkReachabilityScanner } from \"./scanners/network-reachability.js\";\nimport { IamPrivilegeEscalationScanner } from \"./scanners/iam-privilege-escalation.js\";\nimport { PublicAccessVerifyScanner } from \"./scanners/public-access-verify.js\";\nimport { TagComplianceScanner } from \"./scanners/tag-compliance.js\";\nimport { IdleResourcesScanner } from \"./scanners/idle-resources.js\";\nimport { DisasterRecoveryScanner } from \"./scanners/disaster-recovery.js\";\nimport { SecurityHubFindingsScanner } from \"./scanners/security-hub-findings.js\";\nimport { GuardDutyFindingsScanner } from \"./scanners/guardduty-findings.js\";\nimport { InspectorFindingsScanner } from \"./scanners/inspector-findings.js\";\nimport { TrustedAdvisorFindingsScanner } from \"./scanners/trusted-advisor-findings.js\";\nimport { ConfigRulesFindingsScanner } from \"./scanners/config-rules-findings.js\";\nimport { AccessAnalyzerFindingsScanner } from \"./scanners/access-analyzer-findings.js\";\nimport { PatchComplianceFindingsScanner } from \"./scanners/patch-compliance-findings.js\";\nimport { Imdsv2EnforcementScanner } from \"./scanners/imdsv2-enforcement.js\";\nimport { WafCoverageScanner } from \"./scanners/waf-coverage.js\";\nimport { generateMarkdownReport } from \"./tools/report-tool.js\";\nimport { generateMlps3Report } from \"./tools/mlps-report.js\";\nimport { generateHtmlReport, generateMlps3HtmlReport } from \"./tools/html-report.js\";\nimport { saveResults } from \"./tools/save-results.js\";\nimport { SCAN_GROUPS, applyFindingsFilter } from \"./tools/scan-groups.js\";\nimport {\n SECURITY_RULES_CONTENT,\n RISK_SCORING_CONTENT,\n} from \"./resources/index.js\";\nimport { getPartition, getAccountId } from \"./utils/aws-client.js\";\nimport { listOrgAccounts } from \"./utils/org-accounts.js\";\nimport type { FullScanResult, ScanResult, ScanContext } from \"./types.js\";\nimport { getI18n, type Lang } from \"./i18n/index.js\";\nimport { readFileSync } from \"fs\";\nimport { join, dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nexport { type Lang } from \"./i18n/index.js\";\nexport { type Scanner } from \"./scanners/base.js\";\nexport { runAllScanners, runMultiAccountScanners } from \"./scanners/runner.js\";\nexport { assumeRole, buildRoleArn, getCurrentAccountId } from \"./utils/assume-role.js\";\nexport { listOrgAccounts, type OrgAccount } from \"./utils/org-accounts.js\";\nexport { generateMarkdownReport } from \"./tools/report-tool.js\";\nexport { generateHtmlReport, generateMlps3HtmlReport } from \"./tools/html-report.js\";\nexport { saveResults, calculateScore } from \"./tools/save-results.js\";\nexport type {\n Finding,\n ScanResult,\n ScanContext,\n FullScanResult,\n DashboardData,\n DashboardHistoryEntry,\n Severity,\n Priority,\n} from \"./types.js\";\n\nconst MODULE_DESCRIPTIONS: Record<string, string> = {\n service_detection:\n \"Detects which AWS security services (Security Hub, GuardDuty, Inspector, Config) are enabled and assesses security maturity.\",\n secret_exposure:\n \"Checks Lambda env vars and EC2 userData for exposed secrets (AWS keys, private keys, passwords).\",\n ssl_certificate:\n \"Checks ACM certificates for expiry, failed status, and upcoming renewals.\",\n dns_dangling:\n \"Checks Route53 CNAME records for dangling DNS (subdomain takeover risk).\",\n network_reachability:\n \"Analyzes true network reachability by combining Security Group + NACL rules for public EC2 instances.\",\n iam_privilege_escalation:\n \"Detects IAM privilege escalation paths — users/roles that can escalate to admin via policy manipulation, role creation, or service abuse.\",\n public_access_verify:\n \"Verifies actual public accessibility of resources marked as public (S3 HTTP check, RDS DNS resolution).\",\n tag_compliance:\n \"Checks EC2, RDS, and S3 resources for required tags (Environment, Project, Owner).\",\n idle_resources:\n \"Finds unused/idle AWS resources (unattached EBS volumes, unused EIPs, stopped instances, unused security groups) that waste money and increase attack surface.\",\n disaster_recovery:\n \"Assesses disaster recovery readiness — RDS Multi-AZ & backups, EBS snapshot coverage, S3 versioning & cross-region replication.\",\n security_hub_findings:\n \"Aggregates active findings from AWS Security Hub — replaces individual config scanners with centralized compliance checks.\",\n guardduty_findings:\n \"Checks if GuardDuty is enabled. Findings are aggregated via Security Hub.\",\n inspector_findings:\n \"Checks if Inspector is enabled. Findings are aggregated via Security Hub.\",\n trusted_advisor_findings:\n \"Aggregates security checks from AWS Trusted Advisor — requires Business or Enterprise Support plan.\",\n config_rules_findings:\n \"Checks if AWS Config Rules are configured. Findings are aggregated via Security Hub.\",\n access_analyzer_findings:\n \"Checks if IAM Access Analyzer is configured. Findings are aggregated via Security Hub.\",\n patch_compliance_findings:\n \"Checks SSM Patch Manager compliance — managed instances with missing or failed security and system patches.\",\n imdsv2_enforcement:\n \"Checks if EC2 instances enforce IMDSv2 (HttpTokens: required) — IMDSv1 allows credential theft via SSRF.\",\n waf_coverage:\n \"Checks if internet-facing ALBs have WAF Web ACL associated for protection against common web exploits.\",\n};\n\nfunction getHwDefenseChecklist(lang?: Lang): string {\n return getI18n(lang ?? \"zh\").hwChecklist;\n}\n\n// SERVICE_RECOMMENDATIONS are now in the i18n module (t.serviceRecommendations)\n\nconst SERVICE_NOT_ENABLED_PATTERNS = [\n \"not enabled\",\n \"not found\",\n \"No IAM Access Analyzer\",\n \"No SSM-managed instances\",\n \"requires AWS Business or Enterprise Support\",\n \"not available\",\n \"is not enabled\",\n];\n\nfunction buildServiceReminder(modules: ScanResult[], lang?: Lang): string {\n const t = getI18n(lang ?? \"zh\");\n const disabledServices: Array<{ icon: string; service: string; impact: string; action: string }> = [];\n\n for (const mod of modules) {\n const rec = t.serviceRecommendations[mod.module];\n if (!rec) continue;\n if (!mod.warnings?.length) continue;\n\n const hasNotEnabled = mod.warnings.some((w) =>\n SERVICE_NOT_ENABLED_PATTERNS.some((p) => w.includes(p)),\n );\n if (hasNotEnabled) {\n disabledServices.push(rec);\n }\n }\n\n if (disabledServices.length === 0) return \"\";\n\n const lines = [\n \"\",\n t.serviceReminderTitle,\n \"\",\n ];\n\n for (const svc of disabledServices) {\n lines.push(`${svc.icon} ${svc.service} ${t.notEnabled}`);\n lines.push(` ${t.serviceImpact}: ${svc.impact}`);\n lines.push(` ${t.serviceAction}: ${svc.action}`);\n lines.push(\"\");\n }\n\n lines.push(t.serviceReminderFooter);\n\n return lines.join(\"\\n\");\n}\n\nfunction summarizeResult(result: FullScanResult, lang?: Lang): string {\n const { summary } = result;\n const lines = [\n `Scan complete for account ${result.accountId} in ${result.region}.`,\n `Total findings: ${summary.totalFindings} (${summary.critical} Critical, ${summary.high} High, ${summary.medium} Medium, ${summary.low} Low)`,\n `Modules: ${summary.modulesSuccess} succeeded, ${summary.modulesError} errored`,\n ];\n\n const reminder = buildServiceReminder(result.modules, lang);\n if (reminder) {\n lines.push(reminder);\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction summarizeScanResult(result: ScanResult): string {\n const lines = [\n `Module: ${result.module} — ${result.status}`,\n `Resources scanned: ${result.resourcesScanned}, Findings: ${result.findingsCount}`,\n ];\n if (result.warnings?.length) {\n lines.push(`Warnings: ${result.warnings.length}`);\n }\n return lines.join(\"\\n\");\n}\n\nasync function buildScanContext(region: string): Promise<ScanContext> {\n let accountId: string;\n try {\n accountId = await getAccountId(region);\n } catch {\n accountId = \"unknown\";\n }\n return { region, partition: getPartition(region), accountId };\n}\n\nexport function createServer(defaultRegion: string): McpServer {\n const server = new McpServer(\n { name: \"aws-security-mcp\", version: VERSION },\n { capabilities: { resources: {}, tools: {}, prompts: {} } },\n );\n\n const allScanners: Scanner[] = [\n new ServiceDetectionScanner(),\n new SecretExposureScanner(),\n new SslCertificateScanner(),\n new DnsDanglingScanner(),\n new NetworkReachabilityScanner(),\n new IamPrivilegeEscalationScanner(),\n new PublicAccessVerifyScanner(),\n new TagComplianceScanner(),\n new IdleResourcesScanner(),\n new DisasterRecoveryScanner(),\n new SecurityHubFindingsScanner(),\n new GuardDutyFindingsScanner(),\n new InspectorFindingsScanner(),\n new TrustedAdvisorFindingsScanner(),\n new ConfigRulesFindingsScanner(),\n new AccessAnalyzerFindingsScanner(),\n new PatchComplianceFindingsScanner(),\n new Imdsv2EnforcementScanner(),\n new WafCoverageScanner(),\n ];\n\n const scannerMap = new Map<string, Scanner>();\n for (const s of allScanners) {\n scannerMap.set(s.moduleName, s);\n }\n\n // --- Tools ---\n\n // 1. scan_all\n server.tool(\n \"scan_all\",\n \"Run all security scanners in parallel (including service detection). Read-only. Does not modify any AWS resources. Supports multi-account org scanning.\",\n {\n region: z.string().optional().describe(\"AWS region to scan (default: server region)\"),\n org_mode: z.boolean().optional().describe(\"Enable multi-account scanning via AWS Organizations\"),\n role_name: z.string().optional().describe(\"IAM role name to assume in child accounts (default: AWSSecurityMCPAudit)\"),\n account_ids: z.array(z.string()).optional().describe(\"Specific account IDs to scan (default: all org accounts)\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ region, org_mode, role_name, account_ids, lang }) => {\n try {\n const r = region ?? defaultRegion;\n let result: FullScanResult;\n\n if (org_mode) {\n result = await runMultiAccountScanners(allScanners, r, {\n orgMode: true,\n roleName: role_name ?? \"AWSSecurityMCPAudit\",\n accountIds: account_ids,\n });\n } else {\n result = await runAllScanners(allScanners, r);\n }\n\n return {\n content: [\n { type: \"text\", text: summarizeResult(result, lang ?? \"zh\") },\n { type: \"text\", text: JSON.stringify(result, null, 2) },\n ],\n };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // Individual scanner tools\n const individualScanners: Array<{ toolName: string; moduleName: string; label: string }> = [\n { toolName: \"detect_services\", moduleName: \"service_detection\", label: \"Security Service Detection\" },\n { toolName: \"scan_secret_exposure\", moduleName: \"secret_exposure\", label: \"Secret Exposure\" },\n { toolName: \"scan_ssl_certificate\", moduleName: \"ssl_certificate\", label: \"SSL Certificate\" },\n { toolName: \"scan_dns_dangling\", moduleName: \"dns_dangling\", label: \"Dangling DNS\" },\n { toolName: \"scan_network_reachability\", moduleName: \"network_reachability\", label: \"Network Reachability\" },\n { toolName: \"scan_iam_privilege_escalation\", moduleName: \"iam_privilege_escalation\", label: \"IAM Privilege Escalation\" },\n { toolName: \"scan_public_access_verify\", moduleName: \"public_access_verify\", label: \"Public Access Verify\" },\n { toolName: \"scan_tag_compliance\", moduleName: \"tag_compliance\", label: \"Tag Compliance\" },\n { toolName: \"scan_idle_resources\", moduleName: \"idle_resources\", label: \"Idle Resources\" },\n { toolName: \"scan_disaster_recovery\", moduleName: \"disaster_recovery\", label: \"Disaster Recovery\" },\n { toolName: \"scan_security_hub_findings\", moduleName: \"security_hub_findings\", label: \"Security Hub Findings\" },\n { toolName: \"scan_guardduty_findings\", moduleName: \"guardduty_findings\", label: \"GuardDuty Findings\" },\n { toolName: \"scan_inspector_findings\", moduleName: \"inspector_findings\", label: \"Inspector Findings\" },\n { toolName: \"scan_trusted_advisor_findings\", moduleName: \"trusted_advisor_findings\", label: \"Trusted Advisor Findings\" },\n { toolName: \"scan_config_rules_findings\", moduleName: \"config_rules_findings\", label: \"Config Rules Findings\" },\n { toolName: \"scan_access_analyzer_findings\", moduleName: \"access_analyzer_findings\", label: \"Access Analyzer Findings\" },\n { toolName: \"scan_patch_compliance_findings\", moduleName: \"patch_compliance_findings\", label: \"Patch Compliance Findings\" },\n { toolName: \"scan_imdsv2_enforcement\", moduleName: \"imdsv2_enforcement\", label: \"IMDSv2 Enforcement\" },\n { toolName: \"scan_waf_coverage\", moduleName: \"waf_coverage\", label: \"WAF Coverage\" },\n ];\n\n for (const { toolName, moduleName, label } of individualScanners) {\n server.tool(\n toolName,\n `Run ${label} security scanner only. Read-only. Does not modify any AWS resources.`,\n { region: z.string().optional().describe(\"AWS region to scan (default: server region)\") },\n async ({ region }) => {\n try {\n const r = region ?? defaultRegion;\n const ctx = await buildScanContext(r);\n const scanner = scannerMap.get(moduleName)!;\n const result: ScanResult = await scanner.scan(ctx);\n return {\n content: [\n { type: \"text\", text: summarizeScanResult(result) },\n { type: \"text\", text: JSON.stringify(result, null, 2) },\n ],\n };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n }\n\n // scan_group\n server.tool(\n \"scan_group\",\n \"Run a predefined group of security scanners for a specific scenario (e.g., MLPS compliance, network defense). Read-only. Supports multi-account org scanning.\",\n {\n group: z.string().describe(\"Scan group ID: mlps3_precheck, hw_defense, exposure, data_encryption, least_privilege, log_integrity, disaster_recovery, idle_resources, tag_compliance, new_account_baseline, aggregation\"),\n region: z.string().optional().describe(\"AWS region to scan (default: server region)\"),\n org_mode: z.boolean().optional().describe(\"Enable multi-account scanning via AWS Organizations\"),\n role_name: z.string().optional().describe(\"IAM role name to assume in child accounts (default: AWSSecurityMCPAudit)\"),\n account_ids: z.array(z.string()).optional().describe(\"Specific account IDs to scan (default: all org accounts)\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ group, region, org_mode, role_name, account_ids, lang }) => {\n try {\n const groupDef = SCAN_GROUPS[group];\n if (!groupDef) {\n const available = Object.keys(SCAN_GROUPS).join(\", \");\n return {\n content: [{ type: \"text\", text: `Error: Unknown scan group \"${group}\". Available groups: ${available}` }],\n isError: true,\n };\n }\n\n const r = region ?? defaultRegion;\n\n // Resolve scanners: \"ALL\" means all registered scanners\n let selectedScanners: Scanner[];\n const missingModules: string[] = [];\n\n if (groupDef.modules.includes(\"ALL\")) {\n selectedScanners = allScanners;\n } else {\n selectedScanners = [];\n for (const mod of groupDef.modules) {\n const scanner = scannerMap.get(mod);\n if (scanner) {\n selectedScanners.push(scanner);\n } else {\n missingModules.push(mod);\n }\n }\n }\n\n if (selectedScanners.length === 0) {\n return {\n content: [{ type: \"text\", text: `Error: No available scanners for group \"${group}\". Requested modules: ${groupDef.modules.join(\", \")}` }],\n isError: true,\n };\n }\n\n let result: FullScanResult;\n\n if (org_mode) {\n result = await runMultiAccountScanners(selectedScanners, r, {\n orgMode: true,\n roleName: role_name ?? \"AWSSecurityMCPAudit\",\n accountIds: account_ids,\n });\n } else {\n result = await runAllScanners(selectedScanners, r);\n }\n\n // Apply post-filter if the group defines one\n if (groupDef.findingsFilter) {\n for (const mod of result.modules) {\n const originalCount = mod.findings.length;\n mod.findings = applyFindingsFilter(mod.module, mod.findings, groupDef.findingsFilter);\n mod.findingsCount = mod.findings.length;\n if (mod.findings.length < originalCount) {\n const filtered = originalCount - mod.findings.length;\n if (!mod.warnings) mod.warnings = [];\n mod.warnings.push(`Post-filter removed ${filtered} finding(s) not matching group criteria.`);\n }\n }\n // Recalculate summary after filtering\n let critical = 0, high = 0, medium = 0, low = 0;\n for (const m of result.modules) {\n for (const f of m.findings) {\n switch (f.severity) {\n case \"CRITICAL\": critical++; break;\n case \"HIGH\": high++; break;\n case \"MEDIUM\": medium++; break;\n case \"LOW\": low++; break;\n }\n }\n }\n result.summary.totalFindings = critical + high + medium + low;\n result.summary.critical = critical;\n result.summary.high = high;\n result.summary.medium = medium;\n result.summary.low = low;\n }\n\n const lines: string[] = [\n `Scan group: ${groupDef.name} (${group})`,\n groupDef.description,\n \"\",\n summarizeResult(result, lang ?? \"zh\"),\n ];\n\n if (missingModules.length > 0) {\n lines.push(\"\");\n lines.push(`Warning: ${missingModules.length} requested module(s) not available: ${missingModules.join(\", \")}`);\n }\n\n const content: Array<{ type: \"text\"; text: string }> = [\n { type: \"text\", text: lines.join(\"\\n\") },\n { type: \"text\", text: JSON.stringify(result, null, 2) },\n ];\n\n if (group === \"hw_defense\") {\n // Append checklist to summary\n const summaryContent = content[0];\n if (summaryContent && summaryContent.type === \"text\") {\n summaryContent.text += \"\\n\\n\" + getHwDefenseChecklist(lang ?? \"zh\");\n }\n }\n\n return { content };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // list_groups\n server.tool(\n \"list_groups\",\n \"List available scan groups with descriptions. Read-only.\",\n async () => {\n try {\n const groups = Object.entries(SCAN_GROUPS).map(([id, def]) => ({\n id,\n name: def.name,\n description: def.description,\n modules: def.modules,\n reportType: def.reportType,\n }));\n return { content: [{ type: \"text\", text: JSON.stringify(groups, null, 2) }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // 9. generate_report\n server.tool(\n \"generate_report\",\n \"Generate a Markdown security report from scan results. Read-only. Does not modify any AWS resources.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_all\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results, lang }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const report = generateMarkdownReport(parsed, lang ?? \"zh\");\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // generate_mlps3_report\n server.tool(\n \"generate_mlps3_report\",\n \"Generate a GB/T 22239-2019 等保三级 compliance pre-check report from scan results. Best used with scan_group mlps3_precheck results. Read-only.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_group mlps3_precheck or scan_all\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results, lang }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const report = generateMlps3Report(parsed, lang ?? \"zh\");\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // generate_html_report\n server.tool(\n \"generate_html_report\",\n \"Generate a professional HTML security report. Save the output as an .html file.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_all\"),\n history: z.string().optional().describe(\"JSON string of DashboardHistoryEntry[] from dashboard data.json for 30-day trend charts\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results, history, lang }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const historyData = history ? JSON.parse(history) : undefined;\n const report = generateHtmlReport(parsed, historyData, lang ?? \"zh\");\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // generate_mlps3_html_report\n server.tool(\n \"generate_mlps3_html_report\",\n \"Generate a professional HTML MLPS Level 3 compliance report (等保三级). Save as .html file.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_group mlps3_precheck or scan_all\"),\n history: z.string().optional().describe(\"JSON string of DashboardHistoryEntry[] from dashboard data.json for 30-day trend charts\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results, history, lang }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const historyData = history ? JSON.parse(history) : undefined;\n const report = generateMlps3HtmlReport(parsed, historyData, lang ?? \"zh\");\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // 10. generate_maturity_report\n server.tool(\n \"generate_maturity_report\",\n \"Generate a security maturity assessment report from scan_all results. Requires service_detection module output. Read-only.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_all\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const sdModule = parsed.modules.find((m) => m.module === \"service_detection\");\n if (!sdModule) {\n return {\n content: [{ type: \"text\", text: \"Error: scan results do not include service_detection module. Run scan_all first.\" }],\n isError: true,\n };\n }\n\n // Extract the serviceDetection data attached by the scanner\n const detection = (sdModule as ScanResult & { serviceDetection?: ServiceDetectionResult }).serviceDetection;\n\n if (!detection) {\n return {\n content: [{ type: \"text\", text: \"Error: service detection data is missing (possible JSON round-trip loss). Run scan_all to get fresh results with complete service detection data.\" }],\n isError: true,\n };\n }\n\n const serviceImpacts: Record<string, string> = {\n \"CloudTrail\": \"API activity logging\",\n \"Security Hub\": \"+300 security checks\",\n \"GuardDuty\": \"Threat detection\",\n \"Inspector\": \"Vulnerability scanning\",\n \"AWS Config\": \"Configuration tracking\",\n };\n const serviceFreeTrials: Record<string, boolean> = {\n \"Security Hub\": true,\n \"GuardDuty\": true,\n \"Inspector\": true,\n };\n\n const services = detection.services;\n const coveragePercent = detection.coveragePercent;\n const maturityLevel = detection.maturityLevel;\n\n const enabledCount = services.filter((s) => s.enabled === true).length;\n const knownCount = services.filter((s) => s.enabled !== null).length;\n const totalServices = services.length;\n\n // Build the report\n const lines: string[] = [];\n lines.push(\"# AWS Security Maturity Assessment\");\n lines.push(\"\");\n lines.push(`## Account: ${parsed.accountId} | Region: ${parsed.region}`);\n lines.push(\"\");\n lines.push(`## Security Service Coverage: ${coveragePercent}%`);\n lines.push(`## Maturity Level: ${maturityLevel.charAt(0).toUpperCase() + maturityLevel.slice(1)}`);\n lines.push(\"\");\n lines.push(\"### Service Status\");\n lines.push(\"\");\n lines.push(\"| Service | Status | Impact |\");\n lines.push(\"|---------|--------|--------|\");\n for (const svc of services) {\n const status = svc.enabled === true ? \"\\u2705 Enabled\" : svc.enabled === false ? \"\\u274c Not Enabled\" : \"\\u26a0\\ufe0f Unknown\";\n const impact = serviceImpacts[svc.name] ?? \"\";\n lines.push(`| ${svc.name} | ${status} | ${impact} |`);\n }\n\n const unknowns = services.filter((s) => s.enabled === null);\n if (unknowns.length > 0) {\n lines.push(\"\");\n lines.push(`> \\u26a0\\ufe0f ${unknowns.length} service(s) could not be checked (access denied or detection error). Re-run with appropriate permissions for accurate coverage.`);\n }\n\n // Recommendations\n const disabled = services.filter((s) => s.enabled === false);\n if (disabled.length > 0) {\n lines.push(\"\");\n lines.push(\"### Recommendations (Priority Order)\");\n lines.push(\"\");\n // Priority order: Security Hub, GuardDuty, Inspector, Config, CloudTrail\n const priorityOrder = [\"Security Hub\", \"GuardDuty\", \"Inspector\", \"AWS Config\", \"CloudTrail\"];\n const sorted = disabled.sort(\n (a, b) => priorityOrder.indexOf(a.name) - priorityOrder.indexOf(b.name),\n );\n let idx = 1;\n for (const svc of sorted) {\n const trial = serviceFreeTrials[svc.name] ? \" \\u2014 free trial available\" : \"\";\n lines.push(`${idx}. Enable ${svc.name}${trial}`);\n idx++;\n }\n }\n\n // Maturity roadmap\n lines.push(\"\");\n lines.push(\"### Maturity Roadmap\");\n lines.push(\"\");\n if (unknowns.length > 0) {\n lines.push(`- **Current**: ${maturityLevel.charAt(0).toUpperCase() + maturityLevel.slice(1)} (${enabledCount}/${knownCount} known services, ${unknowns.length} unknown)`);\n } else {\n lines.push(`- **Current**: ${maturityLevel.charAt(0).toUpperCase() + maturityLevel.slice(1)} (${enabledCount}/${totalServices} services)`);\n }\n\n if (maturityLevel !== \"comprehensive\") {\n const nextMilestones: Record<string, { level: string; target: number; suggestions: string[] }> = {\n basic: { level: \"Intermediate\", target: 2, suggestions: [\"Security Hub\", \"GuardDuty\"] },\n intermediate: { level: \"Advanced\", target: 4, suggestions: [\"Inspector\", \"AWS Config\"] },\n advanced: { level: \"Comprehensive\", target: 5, suggestions: [\"CloudTrail\"] },\n };\n const next = nextMilestones[maturityLevel];\n if (next) {\n const remaining = next.suggestions.filter((s) =>\n services.some((svc) => svc.name === s && !svc.enabled),\n );\n if (remaining.length > 0) {\n lines.push(`- **Next milestone**: ${next.level} (${next.target}/${knownCount}) \\u2014 enable ${remaining.join(\" + \")}`);\n }\n }\n lines.push(`- **Target**: Comprehensive (${knownCount}/${knownCount})`);\n }\n\n lines.push(\"\");\n\n const report = lines.join(\"\\n\");\n\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n },\n );\n\n // 11. save_results\n server.tool(\n \"save_results\",\n \"Saves scan results to local disk or S3 for dashboard display. Does not modify any AWS resources.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_all\"),\n output_dir: z.string().optional().describe(\"Output directory (default: ~/.aws-security)\"),\n },\n async ({ scan_results, output_dir }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const dataPath = saveResults(parsed, output_dir);\n return {\n content: [\n { type: \"text\", text: `Dashboard data saved to ${dataPath}` },\n ],\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n },\n );\n\n // 11. list_modules\n server.tool(\n \"list_modules\",\n \"List available security scan modules with descriptions. Read-only. Does not modify any AWS resources.\",\n async () => {\n try {\n const modules = allScanners.map((s) => ({\n name: s.moduleName,\n description: MODULE_DESCRIPTIONS[s.moduleName] ?? s.moduleName,\n }));\n return { content: [{ type: \"text\", text: JSON.stringify(modules, null, 2) }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // list_org_accounts\n server.tool(\n \"list_org_accounts\",\n \"List all accounts in the AWS Organization. Useful for discovering accounts before multi-account scanning. Read-only.\",\n { region: z.string().optional().describe(\"AWS region (default: server region)\") },\n async ({ region }) => {\n try {\n const r = region ?? defaultRegion;\n const accounts = await listOrgAccounts(r);\n return {\n content: [\n { type: \"text\", text: `Found ${accounts.length} active account(s) in the organization.` },\n { type: \"text\", text: JSON.stringify(accounts, null, 2) },\n ],\n };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // get_setup_template\n server.tool(\n \"get_setup_template\",\n \"Returns the CloudFormation StackSet template for deploying the cross-account security audit IAM role. Read-only.\",\n {\n format: z.enum([\"yaml\", \"json\"]).optional().describe(\"Template format: yaml or json (default: yaml)\"),\n },\n async ({ format }) => {\n try {\n const ext = format === \"json\" ? \"json\" : \"yaml\";\n const templateFileName = `stackset-audit-role.${ext}`;\n // Try multiple locations for the template\n let templateContent: string;\n try {\n // When running from source\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const templatePath = join(currentDir, \"..\", \"templates\", templateFileName);\n templateContent = readFileSync(templatePath, \"utf-8\");\n } catch {\n try {\n // When running from dist\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const templatePath = join(currentDir, \"..\", \"..\", \"templates\", templateFileName);\n templateContent = readFileSync(templatePath, \"utf-8\");\n } catch {\n return {\n content: [{ type: \"text\", text: `Error: Template file ${templateFileName} not found. Ensure the templates/ directory is included in the package.` }],\n isError: true,\n };\n }\n }\n return {\n content: [\n { type: \"text\", text: `CloudFormation StackSet template (${ext.toUpperCase()}) for cross-account audit role:\\n\\nDeploy this as a StackSet from your Management Account to all member accounts.` },\n { type: \"text\", text: templateContent },\n ],\n };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // --- Resources ---\n\n server.resource(\n \"security-rules\",\n \"security://rules\",\n { description: \"Describes all 19 scan modules and their check rules\", mimeType: \"text/markdown\" },\n async () => ({\n contents: [{ uri: \"security://rules\", text: SECURITY_RULES_CONTENT, mimeType: \"text/markdown\" }],\n }),\n );\n\n server.resource(\n \"risk-scoring\",\n \"security://risk-scoring\",\n { description: \"Describes the risk scoring model and severity/priority mapping\", mimeType: \"text/markdown\" },\n async () => ({\n contents: [{ uri: \"security://risk-scoring\", text: RISK_SCORING_CONTENT, mimeType: \"text/markdown\" }],\n }),\n );\n\n // --- Prompts ---\n\n server.prompt(\n \"security-scan\",\n \"Run a full AWS security scan workflow: scan all modules, generate a report, and summarize findings.\",\n async () => ({\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: \"Run scan_all to perform a full AWS security scan. Then take the JSON result and pass it to generate_report to create a Markdown report. Finally, summarize the top findings and recommend immediate actions based on priority.\",\n },\n },\n ],\n }),\n );\n\n server.prompt(\n \"analyze-finding\",\n \"Deep analysis of a specific security finding.\",\n { finding: z.string().describe(\"JSON string of a single Finding object to analyze\") },\n async ({ finding }) => ({\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Analyze this AWS security finding in depth. Explain the risk, potential attack vectors, blast radius, and provide detailed step-by-step remediation guidance.\\n\\nFinding:\\n${finding}`,\n },\n },\n ],\n }),\n );\n\n server.prompt(\n \"hw_defense_checklist\",\n \"护网行动完整检查清单 — 包含自动化扫描项和人工检查项\",\n async () => ({\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `请基于以下护网行动检查清单,帮助我制定护网准备计划:\\n\\n${getHwDefenseChecklist(\"zh\")}\\n\\n自动化扫描部分请使用 scan_group hw_defense 执行。以上人工检查项请逐项确认并提供具体建议。`,\n },\n },\n ],\n }),\n );\n\n return server;\n}\n\nexport async function startServer(defaultRegion: string): Promise<void> {\n const server = createServer(defaultRegion);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","export const VERSION = \"0.7.0\";\n","import { STSClient, GetCallerIdentityCommand } from \"@aws-sdk/client-sts\";\n\nlet cachedAccountId: string | undefined;\n\nexport function getPartition(region: string): string {\n if (region.startsWith(\"cn-\")) return \"aws-cn\";\n if (region.startsWith(\"us-gov-\")) return \"aws-us-gov\";\n return \"aws\";\n}\n\nexport function getIamRegion(region: string): string {\n // IAM is global in standard AWS (us-east-1) but regional in China\n if (region.startsWith(\"cn-\")) return region;\n return \"us-east-1\";\n}\n\nexport async function getAccountId(region?: string): Promise<string> {\n if (cachedAccountId) return cachedAccountId;\n\n const stsRegion = region ?? \"us-east-1\";\n const sts = new STSClient({ region: stsRegion });\n const response = await sts.send(new GetCallerIdentityCommand({}));\n cachedAccountId = response.Account ?? \"unknown\";\n return cachedAccountId;\n}\n\nexport function createClient<T>(\n ClientClass: new (config: any) => T,\n region?: string,\n credentials?: { accessKeyId: string; secretAccessKey: string; sessionToken: string },\n): T {\n const config: any = { region: region ?? \"us-east-1\" };\n if (credentials) config.credentials = credentials;\n return new ClientClass(config);\n}\n","import { STSClient, AssumeRoleCommand, GetCallerIdentityCommand } from \"@aws-sdk/client-sts\";\n\nexport async function getCurrentAccountId(region: string): Promise<string> {\n const sts = new STSClient({ region });\n const result = await sts.send(new GetCallerIdentityCommand({}));\n return result.Account!;\n}\n\nexport const DEFAULT_EXTERNAL_ID = \"aws-security-mcp-audit\";\n\nexport async function assumeRole(roleArn: string, region: string, options?: {\n sessionName?: string;\n externalId?: string;\n}): Promise<{\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken: string;\n}> {\n const sessionName = options?.sessionName ?? \"aws-security-mcp\";\n const externalId = options?.externalId ?? DEFAULT_EXTERNAL_ID;\n const sts = new STSClient({ region });\n const result = await sts.send(new AssumeRoleCommand({\n RoleArn: roleArn,\n RoleSessionName: sessionName,\n ExternalId: externalId,\n DurationSeconds: 3600,\n }));\n return {\n accessKeyId: result.Credentials!.AccessKeyId!,\n secretAccessKey: result.Credentials!.SecretAccessKey!,\n sessionToken: result.Credentials!.SessionToken!,\n };\n}\n\nexport function buildRoleArn(accountId: string, roleName: string, partition = \"aws\"): string {\n return `arn:${partition}:iam::${accountId}:role/${roleName}`;\n}\n","import { OrganizationsClient, ListAccountsCommand } from \"@aws-sdk/client-organizations\";\n\nexport interface OrgAccount {\n id: string;\n name: string;\n email: string;\n status: string;\n}\n\nexport async function listOrgAccounts(region: string): Promise<OrgAccount[]> {\n // Organizations API must use specific endpoints\n // Global: us-east-1, China: cn-northwest-1\n const orgRegion = region.startsWith(\"cn-\") ? \"cn-northwest-1\" : \"us-east-1\";\n const client = new OrganizationsClient({ region: orgRegion });\n const accounts: OrgAccount[] = [];\n let nextToken: string | undefined;\n\n do {\n const result = await client.send(new ListAccountsCommand({ NextToken: nextToken }));\n for (const acct of result.Accounts || []) {\n if (acct.Status === \"ACTIVE\") {\n accounts.push({\n id: acct.Id!,\n name: acct.Name || \"\",\n email: acct.Email || \"\",\n status: acct.Status!,\n });\n }\n }\n nextToken = result.NextToken;\n } while (nextToken);\n\n return accounts;\n}\n","import { FullScanResult, ScanResult, ScanContext, AwsCredentials } from \"../types.js\";\nimport { Scanner } from \"./base.js\";\nimport { getAccountId, getPartition } from \"../utils/aws-client.js\";\nimport { assumeRole, buildRoleArn } from \"../utils/assume-role.js\";\nimport { listOrgAccounts, type OrgAccount } from \"../utils/org-accounts.js\";\n\n/** Aggregation scanners that already pull cross-account data — run once from admin account */\nconst AGGREGATION_MODULES = new Set([\n \"security_hub_findings\",\n \"guardduty_findings\",\n \"inspector_findings\",\n \"config_rules_findings\",\n \"access_analyzer_findings\",\n]);\n\nfunction buildSummary(modules: ScanResult[]) {\n let critical = 0;\n let high = 0;\n let medium = 0;\n let low = 0;\n let modulesSuccess = 0;\n let modulesError = 0;\n\n for (const m of modules) {\n if (m.status === \"success\") {\n modulesSuccess++;\n } else {\n modulesError++;\n }\n for (const f of m.findings) {\n switch (f.severity) {\n case \"CRITICAL\": critical++; break;\n case \"HIGH\": high++; break;\n case \"MEDIUM\": medium++; break;\n case \"LOW\": low++; break;\n }\n }\n }\n\n return {\n totalFindings: critical + high + medium + low,\n critical,\n high,\n medium,\n low,\n modulesSuccess,\n modulesError,\n };\n}\n\nasync function runScannersWithContext(\n scanners: Scanner[],\n ctx: ScanContext,\n): Promise<ScanResult[]> {\n const settled = await Promise.allSettled(scanners.map((s) => s.scan(ctx)));\n\n return settled.map((result, i) => {\n if (result.status === \"fulfilled\") {\n // Stamp accountId on all findings\n for (const f of result.value.findings) {\n if (!f.accountId) f.accountId = ctx.accountId;\n if (!f.accountAlias && ctx.accountAlias) f.accountAlias = ctx.accountAlias;\n }\n return result.value;\n }\n return {\n module: scanners[i].moduleName,\n status: \"error\" as const,\n error: result.reason instanceof Error ? result.reason.message : String(result.reason),\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: 0,\n findings: [],\n };\n });\n}\n\nexport async function runAllScanners(\n scanners: Scanner[],\n region: string,\n): Promise<FullScanResult> {\n const scanStart = new Date().toISOString();\n\n // Best-effort accountId retrieval — don't let STS failure break the whole scan\n let accountId: string;\n try {\n accountId = await getAccountId(region);\n } catch {\n accountId = \"unknown\";\n }\n\n const partition = getPartition(region);\n const ctx: ScanContext = { region, partition, accountId };\n\n const modules = await runScannersWithContext(scanners, ctx);\n\n const scanEnd = new Date().toISOString();\n\n return {\n scanStart,\n scanEnd,\n region,\n accountId,\n modules,\n summary: buildSummary(modules),\n };\n}\n\nexport interface MultiAccountOptions {\n orgMode: boolean;\n roleName: string;\n accountIds?: string[];\n}\n\nexport async function runMultiAccountScanners(\n scanners: Scanner[],\n region: string,\n opts: MultiAccountOptions,\n): Promise<FullScanResult> {\n const scanStart = new Date().toISOString();\n const partition = getPartition(region);\n\n // Get current (admin) account ID\n let adminAccountId: string;\n try {\n adminAccountId = await getAccountId(region);\n } catch {\n adminAccountId = \"unknown\";\n }\n\n // Discover org accounts\n let accounts: OrgAccount[];\n try {\n accounts = await listOrgAccounts(region);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n // Graceful fallback: scan current account only, with clear warning\n const result = await runAllScanners(scanners, region);\n if (result.modules.length > 0) {\n if (!result.modules[0].warnings) result.modules[0].warnings = [];\n result.modules[0].warnings.unshift(`org_mode enabled but Organizations listing failed: ${errMsg}. Scanning current account only.`);\n }\n return result;\n }\n\n // Filter to specific accounts if requested\n if (opts.accountIds?.length) {\n const idSet = new Set(opts.accountIds);\n accounts = accounts.filter((a) => idSet.has(a.id));\n }\n\n // Separate aggregation vs per-account scanners\n const aggregationScanners = scanners.filter((s) => AGGREGATION_MODULES.has(s.moduleName));\n const perAccountScanners = scanners.filter((s) => !AGGREGATION_MODULES.has(s.moduleName));\n\n const allModules: ScanResult[] = [];\n\n // 1. Run aggregation scanners ONCE from admin account (they already aggregate cross-account)\n if (aggregationScanners.length > 0) {\n const adminCtx: ScanContext = { region, partition, accountId: adminAccountId };\n const aggResults = await runScannersWithContext(aggregationScanners, adminCtx);\n allModules.push(...aggResults);\n }\n\n // 2. Run per-account scanners for each account\n for (const account of accounts) {\n let credentials: AwsCredentials | undefined;\n let accountAlias = account.name;\n\n // Skip assume-role for the admin account itself\n if (account.id !== adminAccountId) {\n try {\n const roleArn = buildRoleArn(account.id, opts.roleName, partition);\n credentials = await assumeRole(roleArn, region);\n } catch (err) {\n // Record a failed module for this account\n allModules.push({\n module: `assume_role_${account.id}`,\n status: \"error\",\n error: `Failed to assume role in account ${account.id} (${account.name}): ${err instanceof Error ? err.message : String(err)}`,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: 0,\n findings: [],\n });\n continue;\n }\n }\n\n const ctx: ScanContext = {\n region,\n partition,\n accountId: account.id,\n accountAlias,\n credentials,\n };\n\n const accountResults = await runScannersWithContext(perAccountScanners, ctx);\n allModules.push(...accountResults);\n }\n\n const scanEnd = new Date().toISOString();\n\n // Post-filter: if account_ids was specified, filter aggregation findings too\n if (opts.accountIds?.length) {\n const idSet = new Set(opts.accountIds);\n for (const mod of allModules) {\n if (AGGREGATION_MODULES.has(mod.module)) {\n mod.findings = mod.findings.filter((f) => !f.accountId || idSet.has(f.accountId));\n mod.findingsCount = mod.findings.length;\n }\n }\n }\n\n return {\n scanStart,\n scanEnd,\n region,\n accountId: adminAccountId,\n modules: allModules,\n summary: buildSummary(allModules),\n };\n}\n","import {\n SecurityHubClient,\n DescribeHubCommand,\n} from \"@aws-sdk/client-securityhub\";\nimport {\n GuardDutyClient,\n ListDetectorsCommand,\n} from \"@aws-sdk/client-guardduty\";\nimport {\n Inspector2Client,\n BatchGetAccountStatusCommand,\n} from \"@aws-sdk/client-inspector2\";\nimport {\n ConfigServiceClient,\n DescribeConfigurationRecordersCommand,\n} from \"@aws-sdk/client-config-service\";\nimport {\n CloudTrailClient,\n DescribeTrailsCommand,\n} from \"@aws-sdk/client-cloudtrail\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nexport interface ServiceStatus {\n name: string;\n enabled: boolean | null; // null = unknown (access denied or detection error)\n details?: string;\n recommendation?: string;\n freeTrialAvailable?: boolean;\n}\n\nexport interface ServiceDetectionResult {\n services: ServiceStatus[];\n coveragePercent: number;\n maturityLevel: \"basic\" | \"intermediate\" | \"advanced\" | \"comprehensive\";\n}\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction isAccessDenied(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const name = (err as Error & { name?: string }).name ?? \"\";\n const code = (err as Error & { Code?: string }).Code ?? \"\";\n return (\n name === \"AccessDeniedException\" ||\n name === \"UnauthorizedAccess\" ||\n name === \"AccessDenied\" ||\n code === \"AccessDeniedException\" ||\n code === \"AccessDenied\" ||\n name === \"ForbiddenException\" ||\n // AWS SDK v3 uses __type or $metadata for some errors\n (err.message?.includes(\"is not authorized to perform\") ?? false) ||\n (err.message?.includes(\"Access Denied\") ?? false)\n );\n}\n\nfunction isNotEnabled(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n return (\n err.name === \"InvalidAccessException\" || // Security Hub specific\n err.name === \"DisabledException\" ||\n err.message.includes(\"not enabled\") ||\n err.message.includes(\"not subscribed\")\n );\n}\n\nfunction computeMaturityLevel(\n enabledCount: number,\n): \"basic\" | \"intermediate\" | \"advanced\" | \"comprehensive\" {\n if (enabledCount >= 5) return \"comprehensive\";\n if (enabledCount >= 4) return \"advanced\";\n if (enabledCount >= 2) return \"intermediate\";\n return \"basic\";\n}\n\nexport class ServiceDetectionScanner implements Scanner {\n readonly moduleName = \"service_detection\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n const services: ServiceStatus[] = [];\n\n // --- CloudTrail ---\n try {\n const ct = createClient(CloudTrailClient, region, ctx.credentials);\n const resp = await ct.send(new DescribeTrailsCommand({}));\n const trails = resp.trailList ?? [];\n if (trails.length > 0) {\n services.push({\n name: \"CloudTrail\",\n enabled: true,\n details: `${trails.length} trail(s) configured`,\n });\n } else {\n services.push({\n name: \"CloudTrail\",\n enabled: false,\n recommendation: \"Create a multi-region trail for API logging\",\n });\n // CloudTrail is checked by service detection only for coverage assessment.\n }\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"CloudTrail: insufficient permissions to check status\");\n services.push({ name: \"CloudTrail\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"CloudTrail\",\n enabled: false,\n recommendation: \"Create a multi-region trail for API logging\",\n });\n // CloudTrail is checked by service detection only for coverage assessment\n } else {\n warnings.push(`CloudTrail detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"CloudTrail\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // --- Security Hub ---\n try {\n const sh = createClient(SecurityHubClient, region, ctx.credentials);\n await sh.send(new DescribeHubCommand({}));\n services.push({\n name: \"Security Hub\",\n enabled: true,\n details: \"Enabled with automated security checks\",\n });\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"Security Hub: insufficient permissions to check status\");\n services.push({ name: \"Security Hub\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"Security Hub\",\n enabled: false,\n recommendation: \"Enable Security Hub for 300+ automated security checks\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: \"AWS Security Hub is not enabled\",\n resourceType: \"AWS::SecurityHub::Hub\",\n resourceId: \"securityhub\",\n resourceArn: `arn:${partition}:securityhub:${region}:${accountId}:hub/default`,\n region,\n description:\n \"AWS Security Hub is not enabled in this region. Security Hub provides a comprehensive view of security alerts and compliance status.\",\n impact:\n \"Enables 300+ automated security checks across AWS services. Without it, security findings are fragmented across individual services.\",\n remediationSteps: [\n \"Open the AWS Security Hub console.\",\n \"Click 'Go to Security Hub' and enable it.\",\n \"Enable the AWS Foundational Security Best Practices standard.\",\n \"Security Hub offers a 30-day free trial.\",\n ],\n }),\n );\n } else {\n warnings.push(`Security Hub detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"Security Hub\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // --- GuardDuty ---\n try {\n const gd = createClient(GuardDutyClient, region, ctx.credentials);\n const resp = await gd.send(new ListDetectorsCommand({}));\n const detectors = resp.DetectorIds ?? [];\n if (detectors.length > 0) {\n services.push({\n name: \"GuardDuty\",\n enabled: true,\n details: `${detectors.length} detector(s) active`,\n });\n } else {\n services.push({\n name: \"GuardDuty\",\n enabled: false,\n recommendation: \"Enable GuardDuty for continuous threat detection\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: \"Amazon GuardDuty is not enabled\",\n resourceType: \"AWS::GuardDuty::Detector\",\n resourceId: \"guardduty\",\n resourceArn: `arn:${partition}:guardduty:${region}:${accountId}:detector/none`,\n region,\n description:\n \"Amazon GuardDuty is not enabled in this region. GuardDuty provides intelligent threat detection by analyzing CloudTrail, VPC Flow Logs, and DNS logs.\",\n impact:\n \"Provides continuous threat detection for account compromise, instance compromise, and malicious reconnaissance. Without it, many attack patterns go undetected.\",\n remediationSteps: [\n \"Open the Amazon GuardDuty console.\",\n \"Click 'Get Started' and enable GuardDuty.\",\n \"GuardDuty offers a 30-day free trial.\",\n \"Consider enabling S3 protection and EKS protection add-ons.\",\n ],\n }),\n );\n }\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"GuardDuty: insufficient permissions to check status\");\n services.push({ name: \"GuardDuty\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"GuardDuty\",\n enabled: false,\n recommendation: \"Enable GuardDuty for continuous threat detection\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: \"Amazon GuardDuty is not enabled\",\n resourceType: \"AWS::GuardDuty::Detector\",\n resourceId: \"guardduty\",\n resourceArn: `arn:${partition}:guardduty:${region}:${accountId}:detector/none`,\n region,\n description:\n \"Amazon GuardDuty is not enabled in this region. GuardDuty provides intelligent threat detection by analyzing CloudTrail, VPC Flow Logs, and DNS logs.\",\n impact:\n \"Provides continuous threat detection for account compromise, instance compromise, and malicious reconnaissance. Without it, many attack patterns go undetected.\",\n remediationSteps: [\n \"Open the Amazon GuardDuty console.\",\n \"Click 'Get Started' and enable GuardDuty.\",\n \"GuardDuty offers a 30-day free trial.\",\n \"Consider enabling S3 protection and EKS protection add-ons.\",\n ],\n }),\n );\n } else {\n warnings.push(`GuardDuty detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"GuardDuty\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // --- Inspector ---\n try {\n const insp = createClient(Inspector2Client, region, ctx.credentials);\n const resp = await insp.send(new BatchGetAccountStatusCommand({ accountIds: [accountId] }));\n const accounts = resp.accounts ?? [];\n const active = accounts.some((a) => {\n const s = a.state?.status;\n if (s === \"ENABLED\" || s === \"ENABLING\") return true;\n // Also check individual resource type scanning states (ec2, ecr, lambda, lambdaCode, codeRepository)\n const rs = a.resourceState as Record<string, { status?: string } | undefined> | undefined;\n if (!rs) return false;\n return [\"ec2\", \"ecr\", \"lambda\", \"lambdaCode\", \"codeRepository\"].some(\n (k) => rs[k]?.status === \"ENABLED\",\n );\n });\n if (active) {\n services.push({\n name: \"Inspector\",\n enabled: true,\n details: \"Vulnerability scanning active\",\n });\n } else {\n services.push({\n name: \"Inspector\",\n enabled: false,\n recommendation: \"Enable Inspector to scan for software vulnerabilities\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: \"Amazon Inspector is not enabled\",\n resourceType: \"AWS::Inspector2::AccountStatus\",\n resourceId: \"inspector\",\n resourceArn: `arn:${partition}:inspector2:${region}:${accountId}:account`,\n region,\n description:\n \"Amazon Inspector is not enabled in this region. Inspector automatically discovers and scans EC2 instances, containers, and Lambda functions for software vulnerabilities.\",\n impact:\n \"Scans for software vulnerabilities in EC2 instances, container images, and Lambda functions. Without it, known CVEs may go undetected.\",\n remediationSteps: [\n \"Open the Amazon Inspector console.\",\n \"Click 'Get Started' and enable Inspector.\",\n \"Inspector offers a 15-day free trial.\",\n \"Enable scanning for EC2, ECR, and Lambda as appropriate.\",\n ],\n }),\n );\n }\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"Inspector: insufficient permissions to check status\");\n services.push({ name: \"Inspector\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"Inspector\",\n enabled: false,\n recommendation: \"Enable Inspector to scan for software vulnerabilities\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: \"Amazon Inspector is not enabled\",\n resourceType: \"AWS::Inspector2::AccountStatus\",\n resourceId: \"inspector\",\n resourceArn: `arn:${partition}:inspector2:${region}:${accountId}:account`,\n region,\n description:\n \"Amazon Inspector is not enabled in this region. Inspector automatically discovers and scans EC2 instances, containers, and Lambda functions for software vulnerabilities.\",\n impact:\n \"Scans for software vulnerabilities in EC2 instances, container images, and Lambda functions. Without it, known CVEs may go undetected.\",\n remediationSteps: [\n \"Open the Amazon Inspector console.\",\n \"Click 'Get Started' and enable Inspector.\",\n \"Inspector offers a 15-day free trial.\",\n \"Enable scanning for EC2, ECR, and Lambda as appropriate.\",\n ],\n }),\n );\n } else {\n warnings.push(`Inspector detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"Inspector\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // --- AWS Config ---\n try {\n const cfg = createClient(ConfigServiceClient, region, ctx.credentials);\n const resp = await cfg.send(new DescribeConfigurationRecordersCommand({}));\n const recorders = resp.ConfigurationRecorders ?? [];\n if (recorders.length > 0) {\n services.push({\n name: \"AWS Config\",\n enabled: true,\n details: `${recorders.length} recorder(s) configured`,\n });\n } else {\n services.push({\n name: \"AWS Config\",\n enabled: false,\n recommendation: \"Enable AWS Config to track configuration changes\",\n });\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: \"AWS Config is not enabled\",\n resourceType: \"AWS::Config::ConfigurationRecorder\",\n resourceId: \"config\",\n resourceArn: `arn:${partition}:config:${region}:${accountId}:configuration-recorder/none`,\n region,\n description:\n \"AWS Config is not enabled in this region. Config continuously records resource configurations and enables compliance auditing.\",\n impact:\n \"Tracks configuration changes and enables compliance rules. Without it, configuration drift and non-compliant resources go undetected.\",\n remediationSteps: [\n \"Open the AWS Config console.\",\n \"Click 'Get Started' and configure a recorder.\",\n \"Select the resource types to record.\",\n \"Configure an S3 bucket for configuration snapshots.\",\n ],\n }),\n );\n }\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"AWS Config: insufficient permissions to check status\");\n services.push({ name: \"AWS Config\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"AWS Config\",\n enabled: false,\n recommendation: \"Enable AWS Config to track configuration changes\",\n });\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: \"AWS Config is not enabled\",\n resourceType: \"AWS::Config::ConfigurationRecorder\",\n resourceId: \"config\",\n resourceArn: `arn:${partition}:config:${region}:${accountId}:configuration-recorder/none`,\n region,\n description:\n \"AWS Config is not enabled in this region. Config continuously records resource configurations and enables compliance auditing.\",\n impact:\n \"Tracks configuration changes and enables compliance rules. Without it, configuration drift and non-compliant resources go undetected.\",\n remediationSteps: [\n \"Open the AWS Config console.\",\n \"Click 'Get Started' and configure a recorder.\",\n \"Select the resource types to record.\",\n \"Configure an S3 bucket for configuration snapshots.\",\n ],\n }),\n );\n } else {\n warnings.push(`AWS Config detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"AWS Config\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // Compute coverage and maturity (exclude unknown services from coverage denominator)\n const knownServices = services.filter((s) => s.enabled !== null);\n const enabledCount = services.filter((s) => s.enabled === true).length;\n const coveragePercent = knownServices.length > 0 ? Math.round((enabledCount / knownServices.length) * 100) : 0;\n const maturityLevel = computeMaturityLevel(enabledCount);\n\n const detectionResult: ServiceDetectionResult = {\n services,\n coveragePercent,\n maturityLevel,\n };\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: services.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n // Attach the structured detection result as a custom property via the findings metadata\n ...({ serviceDetection: detectionResult } as Record<string, unknown>),\n } as ScanResult & { serviceDetection: ServiceDetectionResult };\n }\n}\n","import { Severity, Priority } from \"../types.js\";\n\nexport function severityFromScore(score: number): Severity {\n if (score >= 9.0) return \"CRITICAL\";\n if (score >= 7.0) return \"HIGH\";\n if (score >= 4.0) return \"MEDIUM\";\n return \"LOW\";\n}\n\nexport function priorityFromSeverity(severity: Severity): Priority {\n switch (severity) {\n case \"CRITICAL\": return \"P0\";\n case \"HIGH\": return \"P1\";\n case \"MEDIUM\": return \"P2\";\n case \"LOW\": return \"P3\";\n }\n}\n","import {\n LambdaClient,\n ListFunctionsCommand,\n type FunctionConfiguration,\n} from \"@aws-sdk/client-lambda\";\nimport {\n EC2Client,\n DescribeInstancesCommand,\n DescribeInstanceAttributeCommand,\n type Instance,\n} from \"@aws-sdk/client-ec2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nconst SECRET_PATTERNS: Array<{ name: string; pattern: RegExp; matchType: \"value\" | \"name\" }> = [\n { name: \"AWS Access Key\", pattern: /AKIA[0-9A-Z]{16}/, matchType: \"value\" },\n { name: \"Private Key\", pattern: /-----BEGIN.*PRIVATE KEY-----/, matchType: \"value\" },\n { name: \"Password in env var\", pattern: /^(PASSWORD|PASSWD|DB_PASSWORD|SECRET|API_KEY|APIKEY|TOKEN|AUTH_TOKEN)$/i, matchType: \"name\" },\n];\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class SecretExposureScanner implements Scanner {\n readonly moduleName = \"secret_exposure\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n // --- Lambda functions ---\n try {\n const lambda = createClient(LambdaClient, region, ctx.credentials);\n const functions: FunctionConfiguration[] = [];\n let marker: string | undefined;\n do {\n const resp = await lambda.send(\n new ListFunctionsCommand({ Marker: marker }),\n );\n if (resp.Functions) functions.push(...resp.Functions);\n marker = resp.NextMarker;\n } while (marker);\n\n resourcesScanned += functions.length;\n\n for (const fn of functions) {\n const fnName = fn.FunctionName ?? \"unknown\";\n const fnArn =\n fn.FunctionArn ??\n `arn:${partition}:lambda:${region}:${accountId}:function:${fnName}`;\n const envVars = fn.Environment?.Variables ?? {};\n\n for (const [varName, varValue] of Object.entries(envVars)) {\n for (const sp of SECRET_PATTERNS) {\n if (sp.matchType === \"name\") {\n if (sp.pattern.test(varName)) {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `Lambda ${fnName} has suspicious env var \"${varName}\"`,\n resourceType: \"AWS::Lambda::Function\",\n resourceId: fnName,\n resourceArn: fnArn,\n region,\n description: `Lambda function \"${fnName}\" has an environment variable named \"${varName}\" which may contain a secret.`,\n impact:\n \"Secrets in Lambda environment variables are visible to anyone with lambda:GetFunctionConfiguration permission and may leak through logs.\",\n remediationSteps: [\n \"Move the secret to AWS Secrets Manager or SSM Parameter Store (SecureString).\",\n \"Update the Lambda function to fetch the secret at runtime.\",\n \"Rotate the exposed credential immediately.\",\n ],\n }),\n );\n }\n } else {\n // match value\n if (sp.pattern.test(varValue)) {\n const riskScore = sp.name === \"AWS Access Key\" ? 9.5 : 9.0;\n findings.push(\n makeFinding({\n riskScore,\n title: `Lambda ${fnName} env var contains ${sp.name}`,\n resourceType: \"AWS::Lambda::Function\",\n resourceId: fnName,\n resourceArn: fnArn,\n region,\n description: `Lambda function \"${fnName}\" has an environment variable containing a ${sp.name} pattern.`,\n impact:\n \"Hard-coded credentials in Lambda environment variables can be extracted by any principal with read access to the function configuration.\",\n remediationSteps: [\n \"Remove the hard-coded credential from environment variables.\",\n \"Use AWS Secrets Manager or SSM Parameter Store (SecureString) instead.\",\n \"Rotate the exposed credential immediately.\",\n \"Review CloudTrail logs for unauthorized use of the credential.\",\n ],\n }),\n );\n }\n }\n }\n }\n }\n } catch (e: unknown) {\n warnings.push(`Lambda scan error: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n // --- EC2 userData ---\n try {\n const ec2 = createClient(EC2Client, region, ctx.credentials);\n const instances: Instance[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await ec2.send(\n new DescribeInstancesCommand({ NextToken: nextToken }),\n );\n for (const res of resp.Reservations ?? []) {\n if (res.Instances) instances.push(...res.Instances);\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n resourcesScanned += instances.length;\n\n for (const inst of instances) {\n const instId = inst.InstanceId ?? \"unknown\";\n const instArn = `arn:${partition}:ec2:${region}:${accountId}:instance/${instId}`;\n\n let userData: string | undefined;\n try {\n const attrResp = await ec2.send(\n new DescribeInstanceAttributeCommand({\n InstanceId: instId,\n Attribute: \"userData\",\n }),\n );\n const raw = attrResp.UserData?.Value;\n if (raw) {\n userData = Buffer.from(raw, \"base64\").toString(\"utf-8\");\n }\n } catch (e: unknown) {\n warnings.push(`Could not read userData for ${instId}: ${e instanceof Error ? e.message : String(e)}`);\n continue;\n }\n\n if (!userData) continue;\n\n for (const sp of SECRET_PATTERNS) {\n if (sp.matchType === \"name\") continue; // name-matching doesn't apply to userData\n if (sp.pattern.test(userData)) {\n const riskScore = sp.name === \"AWS Access Key\" ? 9.5 : 8.0;\n findings.push(\n makeFinding({\n riskScore,\n title: `EC2 ${instId} userData contains ${sp.name}`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: instArn,\n region,\n description: `EC2 instance \"${instId}\" has user data containing a ${sp.name} pattern.`,\n impact:\n \"Instance user data is accessible to anyone with ec2:DescribeInstanceAttribute permission and from the instance metadata service.\",\n remediationSteps: [\n \"Remove the secret from instance user data.\",\n \"Use IAM instance profiles for AWS API access instead of embedding keys.\",\n \"Use Secrets Manager or SSM Parameter Store for other secrets.\",\n \"Rotate the exposed credential immediately.\",\n ],\n }),\n );\n }\n }\n }\n } catch (e: unknown) {\n warnings.push(`EC2 userData scan error: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n ACMClient,\n ListCertificatesCommand,\n DescribeCertificateCommand,\n type CertificateSummary,\n} from \"@aws-sdk/client-acm\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class SslCertificateScanner implements Scanner {\n readonly moduleName = \"ssl_certificate\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const client = createClient(ACMClient, region, ctx.credentials);\n\n // List all certificates\n const certs: CertificateSummary[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await client.send(\n new ListCertificatesCommand({ NextToken: nextToken }),\n );\n if (resp.CertificateSummaryList) {\n certs.push(...resp.CertificateSummaryList);\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n for (const cert of certs) {\n const certArn = cert.CertificateArn ?? \"unknown\";\n const domainName = cert.DomainName ?? \"unknown\";\n\n let detail;\n try {\n const descResp = await client.send(\n new DescribeCertificateCommand({ CertificateArn: certArn }),\n );\n detail = descResp.Certificate;\n } catch (e: unknown) {\n warnings.push(`Could not describe certificate ${certArn}: ${e instanceof Error ? e.message : String(e)}`);\n continue;\n }\n\n if (!detail) continue;\n\n const status = detail.Status ?? \"UNKNOWN\";\n const inUseBy = detail.InUseBy ?? [];\n const inUseStr = inUseBy.length > 0 ? ` In use by ${inUseBy.length} resource(s).` : \" Not currently in use.\";\n\n // Check for FAILED status\n if (status === \"FAILED\") {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `Certificate for ${domainName} is in FAILED status`,\n resourceType: \"AWS::ACM::Certificate\",\n resourceId: domainName,\n resourceArn: certArn,\n region,\n description: `ACM certificate for \"${domainName}\" has status FAILED.${inUseStr}`,\n impact:\n \"The certificate failed validation and cannot be used for TLS termination. Services relying on it may lose HTTPS protection.\",\n remediationSteps: [\n \"Check the failure reason in the ACM console.\",\n \"Request a new certificate with correct domain validation.\",\n \"If using DNS validation, ensure the CNAME records are correctly configured.\",\n ],\n }),\n );\n continue;\n }\n\n // Check expiry (only for ISSUED certificates)\n if (status === \"ISSUED\" && detail.NotAfter) {\n const now = new Date();\n const expiryDate = new Date(detail.NotAfter);\n const daysUntilExpiry = Math.floor(\n (expiryDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24),\n );\n\n if (daysUntilExpiry < 0) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `Certificate for ${domainName} has expired`,\n resourceType: \"AWS::ACM::Certificate\",\n resourceId: domainName,\n resourceArn: certArn,\n region,\n description: `ACM certificate for \"${domainName}\" expired ${Math.abs(daysUntilExpiry)} days ago.${inUseStr}`,\n impact:\n \"Expired certificates cause TLS errors for end users. Browsers will display security warnings and block access.\",\n remediationSteps: [\n \"Renew or replace the certificate immediately.\",\n \"If using ACM-managed renewal, check why automatic renewal failed.\",\n \"Verify domain validation records are still in place.\",\n ],\n }),\n );\n } else if (daysUntilExpiry < 30) {\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: `Certificate for ${domainName} expires in ${daysUntilExpiry} days`,\n resourceType: \"AWS::ACM::Certificate\",\n resourceId: domainName,\n resourceArn: certArn,\n region,\n description: `ACM certificate for \"${domainName}\" expires in ${daysUntilExpiry} days (${expiryDate.toISOString().split(\"T\")[0]}).${inUseStr}`,\n impact:\n \"Certificate will expire soon. If not renewed, services will experience TLS errors.\",\n remediationSteps: [\n \"Verify ACM automatic renewal is working (check renewal status).\",\n \"If imported certificate, prepare and import the renewed certificate.\",\n \"Set up CloudWatch alarms for certificate expiry.\",\n ],\n }),\n );\n } else if (daysUntilExpiry < 90) {\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `Certificate for ${domainName} expires in ${daysUntilExpiry} days`,\n resourceType: \"AWS::ACM::Certificate\",\n resourceId: domainName,\n resourceArn: certArn,\n region,\n description: `ACM certificate for \"${domainName}\" expires in ${daysUntilExpiry} days (${expiryDate.toISOString().split(\"T\")[0]}).${inUseStr}`,\n impact:\n \"Certificate is approaching expiry. Plan renewal to avoid service disruption.\",\n remediationSteps: [\n \"Verify ACM automatic renewal is configured and working.\",\n \"If imported certificate, begin the renewal process.\",\n \"Consider setting up monitoring for certificate expiry dates.\",\n ],\n }),\n );\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: certs.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n Route53Client,\n ListHostedZonesCommand,\n ListResourceRecordSetsCommand,\n type HostedZone,\n type ResourceRecordSet,\n} from \"@aws-sdk/client-route-53\";\nimport {\n S3Client,\n HeadBucketCommand,\n} from \"@aws-sdk/client-s3\";\nimport { promises as dns } from \"dns\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction extractS3BucketName(target: string): string | null {\n // Matches: bucket.s3.amazonaws.com, bucket.s3-website-us-east-1.amazonaws.com,\n // bucket.s3.cn-north-1.amazonaws.com.cn, etc.\n const s3Pattern = /^([^.]+)\\.s3[.-]/;\n const m = target.match(s3Pattern);\n return m ? m[1] : null;\n}\n\nfunction classifyTarget(target: string): \"s3\" | \"elb\" | \"cloudfront\" | null {\n if (/\\.s3[.-](.*\\.)?amazonaws\\.com(\\.cn)?\\.?$/.test(target)) return \"s3\";\n if (/\\.elb\\.amazonaws\\.com(\\.cn)?\\.?$/.test(target)) return \"elb\";\n if (/\\.cloudfront\\.net\\.?$/.test(target)) return \"cloudfront\";\n return null;\n}\n\nasync function dnsResolves(hostname: string): Promise<boolean> {\n try {\n // Remove trailing dot for DNS lookup\n const h = hostname.endsWith(\".\") ? hostname.slice(0, -1) : hostname;\n await dns.resolve(h);\n return true;\n } catch {\n return false;\n }\n}\n\nexport class DnsDanglingScanner implements Scanner {\n readonly moduleName = \"dns_dangling\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n const route53 = createClient(Route53Client, region, ctx.credentials);\n\n // List hosted zones\n const zones: HostedZone[] = [];\n let marker: string | undefined;\n do {\n const resp = await route53.send(\n new ListHostedZonesCommand({ Marker: marker }),\n );\n if (resp.HostedZones) zones.push(...resp.HostedZones);\n marker = resp.IsTruncated ? resp.NextMarker : undefined;\n } while (marker);\n\n for (const zone of zones) {\n const zoneId = zone.Id ?? \"unknown\";\n const zoneName = zone.Name ?? \"unknown\";\n const shortZoneId = zoneId.replace(\"/hostedzone/\", \"\");\n\n // List record sets\n const records: ResourceRecordSet[] = [];\n let nextName: string | undefined;\n let nextType: string | undefined;\n do {\n const resp = await route53.send(\n new ListResourceRecordSetsCommand({\n HostedZoneId: shortZoneId,\n StartRecordName: nextName,\n StartRecordType: nextType as ResourceRecordSet[\"Type\"],\n }),\n );\n if (resp.ResourceRecordSets) records.push(...resp.ResourceRecordSets);\n if (resp.IsTruncated) {\n nextName = resp.NextRecordName;\n nextType = resp.NextRecordType;\n } else {\n nextName = undefined;\n nextType = undefined;\n }\n } while (nextName);\n\n // Filter CNAME records\n const cnameRecords = records.filter(\n (r) => r.Type === \"CNAME\" && r.ResourceRecords && r.ResourceRecords.length > 0,\n );\n\n resourcesScanned += cnameRecords.length;\n\n for (const record of cnameRecords) {\n const recordName = record.Name ?? \"unknown\";\n const target = record.ResourceRecords![0].Value ?? \"\";\n const recordArn = `arn:${partition}:route53:::hostedzone/${shortZoneId}`;\n const targetType = classifyTarget(target);\n\n if (targetType === \"s3\") {\n // Check if S3 bucket exists\n const bucketName = extractS3BucketName(target);\n if (bucketName) {\n let bucketExists = false;\n try {\n const s3 = createClient(S3Client, region, ctx.credentials);\n await s3.send(new HeadBucketCommand({ Bucket: bucketName }));\n bucketExists = true;\n } catch (e: unknown) {\n const errName = (e as { name?: string }).name ?? \"\";\n // 404 / NoSuchBucket = doesn't exist; 403 = exists but no access\n if (errName === \"Forbidden\" || errName === \"AccessDenied\" || errName === \"403\") {\n bucketExists = true;\n }\n }\n\n if (!bucketExists) {\n findings.push(\n makeFinding({\n riskScore: 9.5,\n title: `CNAME ${recordName} points to non-existent S3 bucket \"${bucketName}\"`,\n resourceType: \"AWS::Route53::RecordSet\",\n resourceId: recordName,\n resourceArn: recordArn,\n region,\n description: `DNS record \"${recordName}\" in zone \"${zoneName}\" has a CNAME to S3 bucket \"${bucketName}\" which does not exist. An attacker can claim this bucket for subdomain takeover.`,\n impact:\n \"Critical subdomain takeover vulnerability. An attacker can create the S3 bucket and serve arbitrary content on your domain, enabling phishing, cookie theft, and reputation damage.\",\n remediationSteps: [\n \"Immediately create the S3 bucket to prevent takeover.\",\n \"Remove the dangling DNS record if the bucket is no longer needed.\",\n \"Audit all CNAME records pointing to S3 buckets.\",\n ],\n }),\n );\n }\n }\n } else if (targetType === \"elb\") {\n const resolves = await dnsResolves(target);\n if (!resolves) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `CNAME ${recordName} points to non-resolving ELB`,\n resourceType: \"AWS::Route53::RecordSet\",\n resourceId: recordName,\n resourceArn: recordArn,\n region,\n description: `DNS record \"${recordName}\" in zone \"${zoneName}\" has a CNAME to ELB \"${target}\" which does not resolve. The load balancer may have been deleted.`,\n impact:\n \"Potential subdomain takeover if the ELB DNS name can be re-registered. Dangling DNS records indicate resource lifecycle gaps.\",\n remediationSteps: [\n \"Remove the dangling DNS record.\",\n \"If the ELB was deleted, clean up all associated DNS records.\",\n \"Implement automated DNS record cleanup when decommissioning resources.\",\n ],\n }),\n );\n }\n } else if (targetType === \"cloudfront\") {\n const resolves = await dnsResolves(target);\n if (!resolves) {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `CNAME ${recordName} points to non-resolving CloudFront distribution`,\n resourceType: \"AWS::Route53::RecordSet\",\n resourceId: recordName,\n resourceArn: recordArn,\n region,\n description: `DNS record \"${recordName}\" in zone \"${zoneName}\" has a CNAME to CloudFront \"${target}\" which does not resolve. The distribution may have been deleted.`,\n impact:\n \"Potential subdomain takeover via CloudFront. An attacker may create a distribution with this alternate domain name.\",\n remediationSteps: [\n \"Remove the dangling DNS record.\",\n \"If the CloudFront distribution was deleted, clean up associated DNS records.\",\n \"Use CloudFront Origin Access Identity to limit exposure.\",\n ],\n }),\n );\n }\n } else if (targetType === null) {\n // Generic CNAME — just check if it resolves\n const resolves = await dnsResolves(target);\n if (!resolves) {\n findings.push(\n makeFinding({\n riskScore: 5.0,\n title: `CNAME ${recordName} target does not resolve`,\n resourceType: \"AWS::Route53::RecordSet\",\n resourceId: recordName,\n resourceArn: recordArn,\n region,\n description: `DNS record \"${recordName}\" in zone \"${zoneName}\" has a CNAME to \"${target}\" which does not resolve.`,\n impact:\n \"Orphaned DNS record pointing to a non-existent target. May indicate incomplete resource cleanup.\",\n remediationSteps: [\n \"Verify the target resource still exists.\",\n \"Remove the DNS record if it is no longer needed.\",\n \"Implement DNS record lifecycle management.\",\n ],\n }),\n );\n }\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n EC2Client,\n DescribeInstancesCommand,\n DescribeSecurityGroupsCommand,\n DescribeNetworkAclsCommand,\n DescribeAddressesCommand,\n type Instance,\n type SecurityGroup,\n type NetworkAcl,\n type IpPermission,\n type NetworkAclEntry,\n} from \"@aws-sdk/client-ec2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nconst HIGH_RISK_PORTS: Record<number, string> = {\n 22: \"SSH\",\n 3389: \"RDP\",\n 3306: \"MySQL\",\n 5432: \"PostgreSQL\",\n 1433: \"MSSQL\",\n 27017: \"MongoDB\",\n 6379: \"Redis\",\n 9200: \"Elasticsearch\",\n 11211: \"Memcached\",\n};\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction sgAllowsPort(sgs: SecurityGroup[], port: number): boolean {\n for (const sg of sgs) {\n for (const perm of sg.IpPermissions ?? []) {\n if (permissionAllowsWorldPort(perm, port)) return true;\n }\n }\n return false;\n}\n\nfunction sgAllowsAllPorts(sgs: SecurityGroup[]): boolean {\n for (const sg of sgs) {\n for (const perm of sg.IpPermissions ?? []) {\n if (isAllPorts(perm) && hasWorldCidr(perm)) return true;\n }\n }\n return false;\n}\n\nfunction permissionAllowsWorldPort(perm: IpPermission, port: number): boolean {\n if (!hasWorldCidr(perm)) return false;\n const from = perm.FromPort ?? -1;\n const to = perm.ToPort ?? -1;\n if (from === -1 && to === -1) return true; // all traffic\n return port >= from && port <= to;\n}\n\nfunction hasWorldCidr(perm: IpPermission): boolean {\n const hasIpv4 = (perm.IpRanges ?? []).some((r) => r.CidrIp === \"0.0.0.0/0\");\n const hasIpv6 = (perm.Ipv6Ranges ?? []).some((r) => r.CidrIpv6 === \"::/0\");\n return hasIpv4 || hasIpv6;\n}\n\nfunction isAllPorts(perm: IpPermission): boolean {\n const from = perm.FromPort ?? -1;\n const to = perm.ToPort ?? -1;\n return (from === -1 && to === -1) || (from === 0 && to === 65535);\n}\n\nfunction naclAllowsPort(nacl: NetworkAcl, port: number): boolean {\n // NACL rules are evaluated in order (lowest rule number first)\n // We check inbound rules only (Egress === false)\n const inboundRules = (nacl.Entries ?? [])\n .filter((e) => e.Egress === false)\n .sort((a, b) => (a.RuleNumber ?? 0) - (b.RuleNumber ?? 0));\n\n for (const rule of inboundRules) {\n if (naclRuleMatchesPort(rule, port) && naclRuleMatchesWorldCidr(rule)) {\n // RuleAction \"allow\" or \"deny\"\n return rule.RuleAction === \"allow\";\n }\n }\n // Default: deny\n return false;\n}\n\nfunction naclRuleMatchesPort(rule: NetworkAclEntry, port: number): boolean {\n // Protocol -1 means all traffic\n if (rule.Protocol === \"-1\") return true;\n // Protocol 6 = TCP, 17 = UDP\n if (rule.Protocol !== \"6\" && rule.Protocol !== \"17\") return false;\n const from = rule.PortRange?.From ?? 0;\n const to = rule.PortRange?.To ?? 65535;\n return port >= from && port <= to;\n}\n\nfunction naclRuleMatchesWorldCidr(rule: NetworkAclEntry): boolean {\n return rule.CidrBlock === \"0.0.0.0/0\" || rule.Ipv6CidrBlock === \"::/0\";\n}\n\nexport class NetworkReachabilityScanner implements Scanner {\n readonly moduleName = \"network_reachability\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const client = createClient(EC2Client, region, ctx.credentials);\n\n // Get EIPs for lookup\n const eipMap = new Map<string, string>(); // instanceId -> EIP\n try {\n const eipResp = await client.send(new DescribeAddressesCommand({}));\n for (const addr of eipResp.Addresses ?? []) {\n if (addr.InstanceId && addr.PublicIp) {\n eipMap.set(addr.InstanceId, addr.PublicIp);\n }\n }\n } catch (e: unknown) {\n warnings.push(`Could not list Elastic IPs: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n // Get instances\n const instances: Instance[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await client.send(\n new DescribeInstancesCommand({ NextToken: nextToken }),\n );\n for (const res of resp.Reservations ?? []) {\n if (res.Instances) instances.push(...res.Instances);\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n // Filter to instances with public IPs or EIPs\n const publicInstances = instances.filter((inst) => {\n const instId = inst.InstanceId ?? \"\";\n return inst.PublicIpAddress || eipMap.has(instId);\n });\n\n // Collect all SG IDs and subnet IDs\n const sgIds = new Set<string>();\n const subnetIds = new Set<string>();\n for (const inst of publicInstances) {\n for (const sg of inst.SecurityGroups ?? []) {\n if (sg.GroupId) sgIds.add(sg.GroupId);\n }\n if (inst.SubnetId) subnetIds.add(inst.SubnetId);\n }\n\n // Fetch all referenced SGs\n const sgMap = new Map<string, SecurityGroup>();\n if (sgIds.size > 0) {\n const sgResp = await client.send(\n new DescribeSecurityGroupsCommand({\n GroupIds: [...sgIds],\n }),\n );\n for (const sg of sgResp.SecurityGroups ?? []) {\n if (sg.GroupId) sgMap.set(sg.GroupId, sg);\n }\n }\n\n // Fetch NACLs for referenced subnets\n const subnetNaclMap = new Map<string, NetworkAcl>(); // subnetId -> NACL\n if (subnetIds.size > 0) {\n let naclToken: string | undefined;\n const allNacls: NetworkAcl[] = [];\n do {\n const naclResp = await client.send(\n new DescribeNetworkAclsCommand({\n Filters: [{ Name: \"association.subnet-id\", Values: [...subnetIds] }],\n NextToken: naclToken,\n }),\n );\n if (naclResp.NetworkAcls) allNacls.push(...naclResp.NetworkAcls);\n naclToken = naclResp.NextToken;\n } while (naclToken);\n\n for (const nacl of allNacls) {\n for (const assoc of nacl.Associations ?? []) {\n if (assoc.SubnetId) {\n subnetNaclMap.set(assoc.SubnetId, nacl);\n }\n }\n }\n }\n\n // Analyze each public instance\n for (const inst of publicInstances) {\n const instId = inst.InstanceId ?? \"unknown\";\n const instArn = `arn:${partition}:ec2:${region}:${accountId}:instance/${instId}`;\n const publicIp = inst.PublicIpAddress ?? eipMap.get(instId) ?? \"unknown\";\n const subnetId = inst.SubnetId ?? \"\";\n\n // Get this instance's SGs\n const instSgs: SecurityGroup[] = [];\n for (const sg of inst.SecurityGroups ?? []) {\n if (sg.GroupId) {\n const fullSg = sgMap.get(sg.GroupId);\n if (fullSg) instSgs.push(fullSg);\n }\n }\n\n const nacl = subnetNaclMap.get(subnetId);\n\n // Check each high-risk port\n for (const [portStr, portName] of Object.entries(HIGH_RISK_PORTS)) {\n const port = Number(portStr);\n const sgAllows = sgAllowsPort(instSgs, port);\n const naclAllows = nacl ? naclAllowsPort(nacl, port) : true; // if no NACL info, assume allow\n\n if (sgAllows && naclAllows) {\n findings.push(\n makeFinding({\n riskScore: 9.5,\n title: `EC2 ${instId} (${publicIp}): ${portName} (${port}) reachable from internet`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: instArn,\n region,\n description: `EC2 instance \"${instId}\" has public IP ${publicIp} and both its security group(s) and subnet NACL allow inbound ${portName} (port ${port}) from the internet.`,\n impact:\n `${portName} is directly reachable from the internet, enabling brute-force, exploitation, or unauthorized access.`,\n remediationSteps: [\n `Restrict security group inbound rules for port ${port} to specific IPs.`,\n \"Use Systems Manager Session Manager or a bastion host instead of direct access.\",\n \"Add NACL deny rules for high-risk ports as an additional layer.\",\n \"Enable VPC Flow Logs to monitor connection attempts.\",\n ],\n }),\n );\n } else if (sgAllows && !naclAllows) {\n findings.push(\n makeFinding({\n riskScore: 2.0,\n title: `EC2 ${instId}: ${portName} (${port}) allowed by SG but blocked by NACL`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: instArn,\n region,\n description: `EC2 instance \"${instId}\" (${publicIp}) has security group rules allowing ${portName} (port ${port}) from the internet, but the subnet NACL blocks it.`,\n impact:\n \"Currently protected by NACL, but the SG is overly permissive. NACL changes could expose the port.\",\n remediationSteps: [\n `Tighten the security group rules for port ${port} to match the intended access.`,\n \"Do not rely solely on NACLs for access control.\",\n ],\n }),\n );\n }\n }\n\n // Check for all-ports open via SG + NACL\n if (sgAllowsAllPorts(instSgs)) {\n // Check if NACL is also wide open (allows common ports)\n const naclOpen = nacl ? naclAllowsPort(nacl, 80) : true; // proxy check with port 80\n if (naclOpen) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `EC2 ${instId} (${publicIp}): all ports reachable from internet`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: instArn,\n region,\n description: `EC2 instance \"${instId}\" has public IP ${publicIp} and its security group allows all ports from the internet with no NACL restriction.`,\n impact:\n \"All services on this instance are exposed to the internet, creating a large attack surface.\",\n remediationSteps: [\n \"Replace the all-ports SG rule with specific port rules.\",\n \"Implement NACL rules to restrict inbound traffic as defense in depth.\",\n \"Audit all services running on the instance.\",\n ],\n }),\n );\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: publicInstances.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n IAMClient,\n ListUsersCommand,\n ListAttachedUserPoliciesCommand,\n GetPolicyCommand,\n GetPolicyVersionCommand,\n ListUserPoliciesCommand,\n GetUserPolicyCommand,\n type User,\n} from \"@aws-sdk/client-iam\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient, getIamRegion } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\ninterface PolicyStatement {\n Effect?: string;\n Action?: string | string[];\n Resource?: string | string[];\n}\n\nfunction extractActions(doc: unknown): string[] {\n const actions: string[] = [];\n if (!doc || typeof doc !== \"object\") return actions;\n const policy = doc as { Statement?: PolicyStatement | PolicyStatement[] };\n const stmts = Array.isArray(policy.Statement)\n ? policy.Statement\n : policy.Statement\n ? [policy.Statement]\n : [];\n\n for (const stmt of stmts) {\n if (stmt.Effect !== \"Allow\") continue;\n const acts = Array.isArray(stmt.Action)\n ? stmt.Action\n : stmt.Action\n ? [stmt.Action]\n : [];\n actions.push(...acts);\n }\n return actions.map((a) => a.toLowerCase());\n}\n\nfunction hasAction(actions: string[], pattern: string): boolean {\n const pat = pattern.toLowerCase();\n return actions.some((a) => {\n if (a === \"*\") return true;\n if (a === pat) return true;\n // Wildcard match: \"iam:*\" matches \"iam:createrole\"\n if (a.endsWith(\"*\")) {\n const prefix = a.slice(0, -1);\n if (pat.startsWith(prefix)) return true;\n }\n return false;\n });\n}\n\nexport class IamPrivilegeEscalationScanner implements Scanner {\n readonly moduleName = \"iam_privilege_escalation\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n const iamRegion = getIamRegion(region);\n\n warnings.push(\n \"Note: This scanner currently checks IAM users only. Role and group policy analysis will be added in a future version.\",\n );\n\n try {\n const client = createClient(IAMClient, iamRegion, ctx.credentials);\n\n // List all IAM users\n const users: User[] = [];\n let marker: string | undefined;\n do {\n const resp = await client.send(\n new ListUsersCommand({ Marker: marker }),\n );\n if (resp.Users) users.push(...resp.Users);\n marker = resp.IsTruncated ? resp.Marker : undefined;\n } while (marker);\n\n for (const user of users) {\n const userName = user.UserName ?? \"unknown\";\n const userArn =\n user.Arn ??\n `arn:${partition}:iam::${accountId}:user/${userName}`;\n\n // Collect all allowed actions from both managed and inline policies\n const allActions: string[] = [];\n\n // 1. Check attached (managed) policies\n try {\n const attachedResp = await client.send(\n new ListAttachedUserPoliciesCommand({ UserName: userName }),\n );\n for (const policy of attachedResp.AttachedPolicies ?? []) {\n const policyArn = policy.PolicyArn;\n if (!policyArn) continue;\n try {\n const policyResp = await client.send(\n new GetPolicyCommand({ PolicyArn: policyArn }),\n );\n const versionId =\n policyResp.Policy?.DefaultVersionId ?? \"v1\";\n const versionResp = await client.send(\n new GetPolicyVersionCommand({\n PolicyArn: policyArn,\n VersionId: versionId,\n }),\n );\n const doc = versionResp.PolicyVersion?.Document;\n if (doc) {\n const parsed = JSON.parse(decodeURIComponent(doc));\n allActions.push(...extractActions(parsed));\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(\n `Could not read policy ${policyArn} for user ${userName}: ${msg}`,\n );\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(\n `Could not list attached policies for user ${userName}: ${msg}`,\n );\n }\n\n // 2. Check inline policies\n try {\n const inlineResp = await client.send(\n new ListUserPoliciesCommand({ UserName: userName }),\n );\n for (const policyName of inlineResp.PolicyNames ?? []) {\n try {\n const inlinePolicyResp = await client.send(\n new GetUserPolicyCommand({\n UserName: userName,\n PolicyName: policyName,\n }),\n );\n const doc = inlinePolicyResp.PolicyDocument;\n if (doc) {\n const parsed = JSON.parse(decodeURIComponent(doc));\n allActions.push(...extractActions(parsed));\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(\n `Could not read inline policy ${policyName} for user ${userName}: ${msg}`,\n );\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(\n `Could not list inline policies for user ${userName}: ${msg}`,\n );\n }\n\n if (allActions.length === 0) continue;\n\n // Check for wildcard iam:* or full wildcard *\n if (\n hasAction(allActions, \"iam:*\") ||\n allActions.includes(\"*\")\n ) {\n findings.push(\n makeFinding({\n riskScore: 9.0,\n title: `IAM user ${userName} has iam:* wildcard permissions`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has wildcard IAM permissions (iam:* or *), granting full control over identity and access management.`,\n impact:\n \"The user can create, modify, or delete any IAM resource including creating admin users, modifying policies, and escalating privileges without restriction.\",\n remediationSteps: [\n `Remove wildcard IAM permissions from user \"${userName}\".`,\n \"Replace with specific, least-privilege IAM permissions.\",\n \"Use IAM Access Analyzer to identify actually used permissions.\",\n ],\n }),\n );\n // Skip further checks — wildcard already covers everything\n continue;\n }\n\n // Self-grant admin: iam:PutUserPolicy or iam:AttachUserPolicy\n if (\n hasAction(allActions, \"iam:putuserpolicy\") ||\n hasAction(allActions, \"iam:attachuserpolicy\")\n ) {\n findings.push(\n makeFinding({\n riskScore: 9.5,\n title: `IAM user ${userName} can self-grant admin via policy attachment`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has iam:PutUserPolicy or iam:AttachUserPolicy, allowing them to attach AdministratorAccess or any policy to themselves.`,\n impact:\n \"The user can escalate to full administrator access by attaching an admin policy to their own account.\",\n remediationSteps: [\n `Remove iam:PutUserPolicy and iam:AttachUserPolicy from user \"${userName}\".`,\n \"Use permission boundaries to restrict policy attachment scope.\",\n \"Require MFA for sensitive IAM operations via condition keys.\",\n ],\n }),\n );\n }\n\n // Create admin roles: iam:CreateRole + iam:AttachRolePolicy\n if (\n hasAction(allActions, \"iam:createrole\") &&\n hasAction(allActions, \"iam:attachrolepolicy\")\n ) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `IAM user ${userName} can create admin roles`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has both iam:CreateRole and iam:AttachRolePolicy, allowing creation of new roles with admin policies.`,\n impact:\n \"The user can create a new IAM role with AdministratorAccess and assume it to gain full account access.\",\n remediationSteps: [\n `Restrict iam:CreateRole and iam:AttachRolePolicy with resource conditions for user \"${userName}\".`,\n \"Use permission boundaries on all created roles.\",\n \"Monitor IAM role creation via CloudTrail alerts.\",\n ],\n }),\n );\n }\n\n // PassRole + Lambda escalation: iam:PassRole + lambda:CreateFunction\n if (\n hasAction(allActions, \"iam:passrole\") &&\n hasAction(allActions, \"lambda:createfunction\")\n ) {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `IAM user ${userName} can escalate via Lambda role passing`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has iam:PassRole and lambda:CreateFunction, allowing them to create a Lambda function with an admin role.`,\n impact:\n \"The user can pass a high-privilege role to a Lambda function and invoke it to execute actions beyond their own permissions.\",\n remediationSteps: [\n `Restrict iam:PassRole to specific role ARNs for user \"${userName}\".`,\n \"Use condition keys to limit which roles can be passed to Lambda.\",\n \"Implement SCP guardrails for privilege escalation paths.\",\n ],\n }),\n );\n }\n\n // Create access keys for other users: iam:CreateAccessKey\n if (hasAction(allActions, \"iam:createaccesskey\")) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `IAM user ${userName} can create access keys for other users`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has iam:CreateAccessKey, which allows creating access keys for any IAM user unless restricted by resource conditions.`,\n impact:\n \"The user can impersonate other IAM users (including admins) by generating access keys on their behalf.\",\n remediationSteps: [\n `Restrict iam:CreateAccessKey to the user's own ARN using a resource condition.`,\n \"Implement SCP to prevent cross-user key creation.\",\n \"Monitor CreateAccessKey events in CloudTrail.\",\n ],\n }),\n );\n }\n\n // STS AssumeRole on admin roles\n if (hasAction(allActions, \"sts:assumerole\")) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `IAM user ${userName} can assume roles (potential admin escalation)`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has sts:AssumeRole, which may allow assuming high-privilege or admin roles if not restricted by resource ARN.`,\n impact:\n \"The user can escalate privileges by assuming roles with higher permissions than their own.\",\n remediationSteps: [\n `Restrict sts:AssumeRole to specific role ARNs for user \"${userName}\".`,\n \"Require MFA for assuming sensitive roles via role trust policy conditions.\",\n \"Audit which roles this user can assume and their permission levels.\",\n ],\n }),\n );\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: users.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n S3Client,\n ListBucketsCommand,\n GetPublicAccessBlockCommand,\n GetBucketAclCommand,\n GetBucketPolicyStatusCommand,\n GetBucketLocationCommand,\n} from \"@aws-sdk/client-s3\";\nimport {\n RDSClient,\n DescribeDBInstancesCommand,\n type DBInstance,\n} from \"@aws-sdk/client-rds\";\nimport dns from \"node:dns\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction s3Endpoint(bucket: string, region: string): string {\n const suffix = region.startsWith(\"cn-\")\n ? \"amazonaws.com.cn\"\n : \"amazonaws.com\";\n return `https://${bucket}.s3.${region}.${suffix}/`;\n}\n\nasync function getBucketRegion(\n client: S3Client,\n bucketName: string,\n defaultRegion: string,\n warnings: string[],\n): Promise<string> {\n try {\n const resp = await client.send(\n new GetBucketLocationCommand({ Bucket: bucketName }),\n );\n const loc = String(resp.LocationConstraint ?? \"\") || \"us-east-1\";\n return loc;\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Failed to detect region for bucket ${bucketName}, using ${defaultRegion}: ${msg}`);\n return defaultRegion;\n }\n}\n\nasync function isBucketMarkedPublic(\n client: S3Client,\n bucketName: string,\n warnings: string[],\n): Promise<boolean | \"skip\"> {\n // Check if Block Public Access is off AND (public ACL or public policy)\n let bpaBlocks = false;\n try {\n const bpa = await client.send(\n new GetPublicAccessBlockCommand({ Bucket: bucketName }),\n );\n const cfg = bpa.PublicAccessBlockConfiguration;\n bpaBlocks = !!(\n cfg?.BlockPublicAcls &&\n cfg?.IgnorePublicAcls &&\n cfg?.BlockPublicPolicy &&\n cfg?.RestrictPublicBuckets\n );\n } catch (e: unknown) {\n if (\n e instanceof Error &&\n e.name === \"NoSuchPublicAccessBlockConfiguration\"\n ) {\n bpaBlocks = false;\n } else {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Could not check public access for bucket ${bucketName}: ${msg}`);\n return \"skip\";\n }\n }\n\n if (bpaBlocks) return false;\n\n // Check ACL for public grants\n try {\n const acl = await client.send(\n new GetBucketAclCommand({ Bucket: bucketName }),\n );\n for (const grant of acl.Grants ?? []) {\n const uri = grant.Grantee?.URI ?? \"\";\n if (uri.includes(\"AllUsers\") || uri.includes(\"AuthenticatedUsers\")) {\n return true;\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Could not check ACL for bucket ${bucketName}: ${msg}`);\n }\n\n // Check bucket policy status\n try {\n const policyStatus = await client.send(\n new GetBucketPolicyStatusCommand({ Bucket: bucketName }),\n );\n if (policyStatus.PolicyStatus?.IsPublic) return true;\n } catch (e: unknown) {\n // NoSuchBucketPolicy is expected for buckets without policies\n if (e instanceof Error && !e.name.includes(\"NoSuchBucketPolicy\")) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Could not check policy status for bucket ${bucketName}: ${msg}`);\n }\n }\n\n return false;\n}\n\nfunction isPrivateIp(ip: string): boolean {\n if (ip.startsWith(\"10.\")) return true;\n if (ip.startsWith(\"192.168.\")) return true;\n if (ip.startsWith(\"172.\")) {\n const second = parseInt(ip.split(\".\")[1], 10);\n return second >= 16 && second <= 31;\n }\n if (ip.startsWith(\"127.\")) return true;\n return false;\n}\n\nexport class PublicAccessVerifyScanner implements Scanner {\n readonly moduleName = \"public_access_verify\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n // --- S3 public access verification ---\n try {\n const s3Client = createClient(S3Client, region, ctx.credentials);\n const listResp = await s3Client.send(new ListBucketsCommand({}));\n const buckets = listResp.Buckets ?? [];\n\n for (const bucket of buckets) {\n const name = bucket.Name ?? \"unknown\";\n const arn = `arn:${partition}:s3:::${name}`;\n\n const bucketRegion = await getBucketRegion(s3Client, name, region, warnings);\n const bucketClient =\n bucketRegion === region\n ? s3Client\n : createClient(S3Client, bucketRegion, ctx.credentials);\n\n const markedPublic = await isBucketMarkedPublic(bucketClient, name, warnings);\n if (markedPublic === \"skip\" || !markedPublic) continue;\n\n resourcesScanned++;\n const url = s3Endpoint(name, bucketRegion);\n\n try {\n const resp = await fetch(url, {\n method: \"HEAD\",\n signal: AbortSignal.timeout(5000),\n });\n\n if (resp.ok || resp.status === 200) {\n findings.push(\n makeFinding({\n riskScore: 9.5,\n title: `S3 bucket ${name} is publicly readable (verified)`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region: bucketRegion,\n description: `HTTP HEAD to ${url} returned status ${resp.status}. The bucket is confirmed publicly accessible from the internet.`,\n impact:\n \"Anyone on the internet can read objects from this bucket, potentially exposing sensitive data.\",\n remediationSteps: [\n \"Enable Block Public Access on the bucket immediately.\",\n \"Review and remove public ACL grants and public bucket policies.\",\n \"Audit bucket contents for sensitive data exposure.\",\n ],\n }),\n );\n } else if (resp.status === 403) {\n findings.push(\n makeFinding({\n riskScore: 2.0,\n title: `S3 bucket ${name} is marked public but returns 403 (blocked)`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region: bucketRegion,\n description: `Bucket \"${name}\" has public ACL/policy configuration but HTTP access returns 403 Forbidden, likely blocked by other controls.`,\n impact:\n \"Currently not accessible, but the public configuration is a risk if blocking controls are removed.\",\n remediationSteps: [\n \"Clean up the public ACL or policy to match the intended access model.\",\n \"Enable Block Public Access to formalize the restriction.\",\n ],\n }),\n );\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`HTTP check for bucket ${name} failed: ${msg}`);\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`S3 public access verification failed: ${msg}`);\n }\n\n // --- RDS public DNS verification ---\n try {\n const rdsClient = createClient(RDSClient, region, ctx.credentials);\n const instances: DBInstance[] = [];\n let marker: string | undefined;\n do {\n const resp = await rdsClient.send(\n new DescribeDBInstancesCommand({ Marker: marker }),\n );\n if (resp.DBInstances) instances.push(...resp.DBInstances);\n marker = resp.Marker;\n } while (marker);\n\n for (const db of instances) {\n if (!db.PubliclyAccessible) continue;\n\n const dbId = db.DBInstanceIdentifier ?? \"unknown\";\n const dbArn =\n db.DBInstanceArn ??\n `arn:${partition}:rds:${region}:${accountId}:db/${dbId}`;\n const endpoint = db.Endpoint?.Address;\n if (!endpoint) continue;\n\n resourcesScanned++;\n\n try {\n const addresses = await dns.promises.resolve4(endpoint);\n const hasPublicIp = addresses.some((ip) => !isPrivateIp(ip));\n\n if (hasPublicIp) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `RDS instance ${dbId} endpoint resolves to public IP (verified)`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS endpoint ${endpoint} resolves to public IP(s): ${addresses.join(\", \")}. The database is network-reachable from the internet.`,\n impact:\n \"The database can be reached from the public internet, making it vulnerable to brute-force, credential stuffing, and exploitation of database vulnerabilities.\",\n remediationSteps: [\n \"Set PubliclyAccessible to false on the RDS instance.\",\n \"Move the instance to a private subnet.\",\n \"Use VPN or bastion host for database access.\",\n \"Restrict security group inbound rules to known IPs.\",\n ],\n }),\n );\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`DNS resolution for RDS ${dbId} (${endpoint}) failed: ${msg}`);\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`RDS public access verification failed: ${msg}`);\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n EC2Client,\n DescribeInstancesCommand,\n type Instance,\n} from \"@aws-sdk/client-ec2\";\nimport {\n RDSClient,\n DescribeDBInstancesCommand,\n type DBInstance,\n} from \"@aws-sdk/client-rds\";\nimport {\n S3Client,\n ListBucketsCommand,\n GetBucketTaggingCommand,\n} from \"@aws-sdk/client-s3\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nconst DEFAULT_REQUIRED_TAGS = [\"Environment\", \"Project\", \"Owner\"];\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction getMissingTags(\n tags: Array<{ Key?: string; Value?: string }>,\n requiredTags: string[],\n): string[] {\n const tagKeys = new Set(tags.map((t) => t.Key ?? \"\"));\n return requiredTags.filter((rt) => !tagKeys.has(rt));\n}\n\nexport class TagComplianceScanner implements Scanner {\n readonly moduleName = \"tag_compliance\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n const requiredTags = DEFAULT_REQUIRED_TAGS;\n\n try {\n // --- EC2 instances ---\n try {\n const ec2Client = createClient(EC2Client, region, ctx.credentials);\n const instances: Instance[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await ec2Client.send(\n new DescribeInstancesCommand({ NextToken: nextToken }),\n );\n for (const res of resp.Reservations ?? []) {\n if (res.Instances) instances.push(...res.Instances);\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n resourcesScanned += instances.length;\n\n for (const instance of instances) {\n const id = instance.InstanceId ?? \"unknown\";\n const arn = `arn:${partition}:ec2:${region}:${accountId}:instance/${id}`;\n const tags = instance.Tags ?? [];\n const missing = getMissingTags(tags, requiredTags);\n\n if (missing.length > 0) {\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `EC2 instance ${id} missing required tags: ${missing.join(\", \")}`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: id,\n resourceArn: arn,\n region,\n description: `EC2 instance \"${id}\" is missing the following required tags: ${missing.join(\", \")}.`,\n impact:\n \"Resources without proper tags cannot be tracked for cost allocation, ownership, or compliance purposes.\",\n remediationSteps: [\n `Add the missing tags (${missing.join(\", \")}) to instance ${id}.`,\n \"Implement AWS Config rules or Tag Policies to enforce tagging.\",\n \"Use AWS Tag Editor for bulk tagging operations.\",\n ],\n }),\n );\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`EC2 tag compliance check failed: ${msg}`);\n }\n\n // --- RDS instances ---\n try {\n const rdsClient = createClient(RDSClient, region, ctx.credentials);\n const dbInstances: DBInstance[] = [];\n let marker: string | undefined;\n do {\n const resp = await rdsClient.send(\n new DescribeDBInstancesCommand({ Marker: marker }),\n );\n if (resp.DBInstances) dbInstances.push(...resp.DBInstances);\n marker = resp.Marker;\n } while (marker);\n\n resourcesScanned += dbInstances.length;\n\n for (const db of dbInstances) {\n const dbId = db.DBInstanceIdentifier ?? \"unknown\";\n const dbArn =\n db.DBInstanceArn ??\n `arn:${partition}:rds:${region}:${accountId}:db/${dbId}`;\n const tags = (db.TagList ?? []).map((t) => ({\n Key: t.Key,\n Value: t.Value,\n }));\n const missing = getMissingTags(tags, requiredTags);\n\n if (missing.length > 0) {\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `RDS instance ${dbId} missing required tags: ${missing.join(\", \")}`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS instance \"${dbId}\" is missing the following required tags: ${missing.join(\", \")}.`,\n impact:\n \"Resources without proper tags cannot be tracked for cost allocation, ownership, or compliance purposes.\",\n remediationSteps: [\n `Add the missing tags (${missing.join(\", \")}) to RDS instance ${dbId}.`,\n \"Implement AWS Config rules or Tag Policies to enforce tagging.\",\n \"Use AWS Tag Editor for bulk tagging operations.\",\n ],\n }),\n );\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`RDS tag compliance check failed: ${msg}`);\n }\n\n // --- S3 buckets ---\n try {\n const s3Client = createClient(S3Client, region, ctx.credentials);\n const listResp = await s3Client.send(new ListBucketsCommand({}));\n const buckets = listResp.Buckets ?? [];\n resourcesScanned += buckets.length;\n\n for (const bucket of buckets) {\n const name = bucket.Name ?? \"unknown\";\n const arn = `arn:${partition}:s3:::${name}`;\n\n try {\n const taggingResp = await s3Client.send(\n new GetBucketTaggingCommand({ Bucket: name }),\n );\n const tags = (taggingResp.TagSet ?? []).map((t) => ({\n Key: t.Key,\n Value: t.Value,\n }));\n const missing = getMissingTags(tags, requiredTags);\n\n if (missing.length > 0) {\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `S3 bucket ${name} missing required tags: ${missing.join(\", \")}`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region: \"global\",\n description: `S3 bucket \"${name}\" is missing the following required tags: ${missing.join(\", \")}.`,\n impact:\n \"Resources without proper tags cannot be tracked for cost allocation, ownership, or compliance purposes.\",\n remediationSteps: [\n `Add the missing tags (${missing.join(\", \")}) to bucket ${name}.`,\n \"Implement AWS Config rules or Tag Policies to enforce tagging.\",\n \"Use AWS Tag Editor for bulk tagging operations.\",\n ],\n }),\n );\n }\n } catch (e: unknown) {\n if (\n e instanceof Error &&\n e.name === \"NoSuchTagSet\"\n ) {\n // No tags at all — all required tags are missing\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `S3 bucket ${name} missing required tags: ${requiredTags.join(\", \")}`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region: \"global\",\n description: `S3 bucket \"${name}\" has no tags configured. Missing all required tags: ${requiredTags.join(\", \")}.`,\n impact:\n \"Resources without proper tags cannot be tracked for cost allocation, ownership, or compliance purposes.\",\n remediationSteps: [\n `Add the required tags (${requiredTags.join(\", \")}) to bucket ${name}.`,\n \"Implement AWS Config rules or Tag Policies to enforce tagging.\",\n \"Use AWS Tag Editor for bulk tagging operations.\",\n ],\n }),\n );\n } else {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`S3 tag check for ${name} failed: ${msg}`);\n }\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`S3 tag compliance check failed: ${msg}`);\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n EC2Client,\n DescribeVolumesCommand,\n DescribeAddressesCommand,\n DescribeInstancesCommand,\n DescribeNetworkInterfacesCommand,\n DescribeSecurityGroupsCommand,\n type Volume,\n type Address,\n type Instance,\n type SecurityGroup,\n} from \"@aws-sdk/client-ec2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class IdleResourcesScanner implements Scanner {\n readonly moduleName = \"idle_resources\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const client = createClient(EC2Client, region, ctx.credentials);\n let resourcesScanned = 0;\n\n // 1. Unattached EBS volumes (State = \"available\")\n const volumes: Volume[] = [];\n let volToken: string | undefined;\n do {\n const resp = await client.send(\n new DescribeVolumesCommand({ NextToken: volToken }),\n );\n if (resp.Volumes) volumes.push(...resp.Volumes);\n volToken = resp.NextToken;\n } while (volToken);\n\n resourcesScanned += volumes.length;\n\n for (const vol of volumes) {\n if (vol.State === \"available\") {\n const volId = vol.VolumeId ?? \"unknown\";\n findings.push(\n makeFinding({\n riskScore: 3.0,\n title: `EBS volume ${volId} is unattached`,\n resourceType: \"AWS::EC2::Volume\",\n resourceId: volId,\n resourceArn: `arn:${partition}:ec2:${region}:${accountId}:volume/${volId}`,\n region,\n description: `EBS volume \"${volId}\" (${vol.Size ?? \"?\"}GB, ${vol.VolumeType ?? \"unknown\"}) is in \"available\" state with no attachments.`,\n impact:\n \"Unattached volumes incur storage costs and may contain sensitive data that is no longer actively managed.\",\n remediationSteps: [\n \"Determine if the volume is still needed.\",\n \"If not needed, create a snapshot for archival and delete the volume.\",\n \"If needed, attach it to the appropriate instance.\",\n ],\n }),\n );\n }\n }\n\n // 2. Unused Elastic IPs (not associated with any instance)\n let addresses: Address[] = [];\n try {\n const addrResp = await client.send(new DescribeAddressesCommand({}));\n addresses = addrResp.Addresses ?? [];\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Elastic IP check failed: ${msg}`);\n }\n\n resourcesScanned += addresses.length;\n\n for (const addr of addresses) {\n if (!addr.AssociationId) {\n const allocId = addr.AllocationId ?? \"unknown\";\n const publicIp = addr.PublicIp ?? \"unknown\";\n findings.push(\n makeFinding({\n riskScore: 2.0,\n title: `Elastic IP ${publicIp} is not associated`,\n resourceType: \"AWS::EC2::EIP\",\n resourceId: allocId,\n resourceArn: `arn:${partition}:ec2:${region}:${accountId}:elastic-ip/${allocId}`,\n region,\n description: `Elastic IP ${publicIp} (${allocId}) is allocated but not associated with any instance or network interface.`,\n impact:\n \"Unused Elastic IPs cost ~$3.60/month each and represent unnecessary spend.\",\n remediationSteps: [\n \"Associate the EIP with an instance or network interface if needed.\",\n \"Release the EIP if it is no longer required.\",\n ],\n }),\n );\n }\n }\n\n // 3. Stopped EC2 instances (>30 days)\n const instances: Instance[] = [];\n let instToken: string | undefined;\n do {\n const instResp = await client.send(\n new DescribeInstancesCommand({ NextToken: instToken }),\n );\n for (const res of instResp.Reservations ?? []) {\n if (res.Instances) instances.push(...res.Instances);\n }\n instToken = instResp.NextToken;\n } while (instToken);\n\n resourcesScanned += instances.length;\n const now = Date.now();\n\n for (const inst of instances) {\n if (inst.State?.Name === \"stopped\") {\n const instId = inst.InstanceId ?? \"unknown\";\n const reason = inst.StateTransitionReason ?? \"\";\n const stoppedTime = reason ? parseStopTime(reason) : null;\n\n if (!stoppedTime) {\n warnings.push(\n `Could not determine stop date for instance ${instId}. StateTransitionReason: ${reason}`,\n );\n continue;\n }\n\n const stoppedDays = Math.round(\n (now - stoppedTime) / (24 * 60 * 60 * 1000),\n );\n\n if (stoppedDays > 30) {\n findings.push(\n makeFinding({\n riskScore: 3.0,\n title: `EC2 instance ${instId} has been stopped for ${stoppedDays} days`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: `arn:${partition}:ec2:${region}:${accountId}:instance/${instId}`,\n region,\n description: `EC2 instance \"${instId}\" (${inst.InstanceType ?? \"unknown\"}) is in stopped state for ${stoppedDays} days. Attached EBS volumes continue to incur charges.`,\n impact:\n \"Stopped instances still incur EBS storage costs and may contain stale configurations or unpatched AMIs.\",\n remediationSteps: [\n \"Determine if the instance is still needed.\",\n \"If not needed, create an AMI for archival and terminate the instance.\",\n \"If needed temporarily, consider using a launch template for on-demand recreation.\",\n ],\n }),\n );\n }\n }\n }\n\n // 4. Unused Security Groups (not attached to any ENI)\n const securityGroups: SecurityGroup[] = [];\n let sgToken: string | undefined;\n do {\n const sgResp = await client.send(\n new DescribeSecurityGroupsCommand({ NextToken: sgToken }),\n );\n if (sgResp.SecurityGroups) securityGroups.push(...sgResp.SecurityGroups);\n sgToken = sgResp.NextToken;\n } while (sgToken);\n\n // Find all SGs referenced by ENIs\n const usedSgIds = new Set<string>();\n let eniToken: string | undefined;\n do {\n const eniResp = await client.send(\n new DescribeNetworkInterfacesCommand({ NextToken: eniToken }),\n );\n for (const eni of eniResp.NetworkInterfaces ?? []) {\n for (const group of eni.Groups ?? []) {\n if (group.GroupId) usedSgIds.add(group.GroupId);\n }\n }\n eniToken = eniResp.NextToken;\n } while (eniToken);\n\n resourcesScanned += securityGroups.length;\n\n for (const sg of securityGroups) {\n const sgId = sg.GroupId ?? \"unknown\";\n // Skip default security groups — they cannot be deleted\n if (sg.GroupName === \"default\") continue;\n\n if (!usedSgIds.has(sgId)) {\n findings.push(\n makeFinding({\n riskScore: 2.0,\n title: `Security group ${sgId} is not attached to any resource`,\n resourceType: \"AWS::EC2::SecurityGroup\",\n resourceId: sgId,\n resourceArn: `arn:${partition}:ec2:${region}:${sg.OwnerId ?? accountId}:security-group/${sgId}`,\n region,\n description: `Security group \"${sg.GroupName}\" (${sgId}) is not associated with any network interface.`,\n impact:\n \"Unused security groups add clutter and may cause confusion during security reviews.\",\n remediationSteps: [\n \"Verify the security group is not referenced by other resources (e.g., launch templates).\",\n \"Delete the security group if it is no longer needed.\",\n ],\n }),\n );\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n\n/**\n * Parse the stop time from EC2 StateTransitionReason.\n * Format: \"User initiated (2024-01-15 08:30:00 GMT)\"\n */\nfunction parseStopTime(reason: string): number | null {\n const match = reason.match(/\\((\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\w+)\\)/);\n if (!match) return null;\n const parsed = Date.parse(match[1]);\n return isNaN(parsed) ? null : parsed;\n}\n","import {\n RDSClient,\n DescribeDBInstancesCommand,\n type DBInstance,\n} from \"@aws-sdk/client-rds\";\nimport {\n EC2Client,\n DescribeVolumesCommand,\n DescribeSnapshotsCommand,\n type Volume,\n type Snapshot,\n} from \"@aws-sdk/client-ec2\";\nimport {\n S3Client,\n ListBucketsCommand,\n GetBucketVersioningCommand,\n GetBucketReplicationCommand,\n} from \"@aws-sdk/client-s3\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nconst SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class DisasterRecoveryScanner implements Scanner {\n readonly moduleName = \"disaster_recovery\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n let resourcesScanned = 0;\n\n // --- RDS checks ---\n const rdsClient = createClient(RDSClient, region, ctx.credentials);\n const instances: DBInstance[] = [];\n let marker: string | undefined;\n do {\n const resp = await rdsClient.send(\n new DescribeDBInstancesCommand({ Marker: marker }),\n );\n if (resp.DBInstances) instances.push(...resp.DBInstances);\n marker = resp.Marker;\n } while (marker);\n\n resourcesScanned += instances.length;\n\n for (const db of instances) {\n const dbId = db.DBInstanceIdentifier ?? \"unknown\";\n const dbArn =\n db.DBInstanceArn ??\n `arn:${partition}:rds:${region}:${accountId}:db/${dbId}`;\n const engine = db.Engine ?? \"unknown\";\n\n // MultiAZ check\n if (!db.MultiAZ) {\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: `RDS instance ${dbId} is not Multi-AZ`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS instance \"${dbId}\" (${engine}) does not have Multi-AZ deployment enabled.`,\n impact:\n \"Single-AZ deployments have no automatic failover. An AZ outage will cause downtime and potential data loss.\",\n remediationSteps: [\n \"Enable Multi-AZ deployment for the RDS instance.\",\n \"This provides automatic failover to a standby in a different AZ.\",\n ],\n }),\n );\n }\n\n // Backup retention check\n const retention = db.BackupRetentionPeriod ?? 0;\n if (retention === 0) {\n findings.push(\n makeFinding({\n riskScore: 5.5,\n title: `RDS instance ${dbId} has automated backups disabled`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS instance \"${dbId}\" (${engine}) has backup retention period set to 0 (disabled).`,\n impact:\n \"No automated backups or point-in-time recovery. Data loss from failures or corruption is unrecoverable.\",\n remediationSteps: [\n \"Set the backup retention period to at least 7 days.\",\n \"Consider cross-region backup replication for critical databases.\",\n ],\n }),\n );\n } else if (retention < 7) {\n findings.push(\n makeFinding({\n riskScore: 5.5,\n title: `RDS instance ${dbId} backup retention is only ${retention} day(s)`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS instance \"${dbId}\" (${engine}) has backup retention period of ${retention} day(s), below the recommended 7 days.`,\n impact:\n \"Short retention windows limit point-in-time recovery options and may not meet compliance requirements.\",\n remediationSteps: [\n \"Increase the backup retention period to at least 7 days.\",\n \"For production databases, consider 14-35 days retention.\",\n ],\n }),\n );\n }\n }\n\n // --- EBS snapshot checks ---\n const ec2Client = createClient(EC2Client, region, ctx.credentials);\n\n const volumes: Volume[] = [];\n let volToken: string | undefined;\n do {\n const resp = await ec2Client.send(\n new DescribeVolumesCommand({ NextToken: volToken }),\n );\n if (resp.Volumes) volumes.push(...resp.Volumes);\n volToken = resp.NextToken;\n } while (volToken);\n\n // Get all snapshots owned by this account\n const snapshots: Snapshot[] = [];\n let snapToken: string | undefined;\n do {\n const resp = await ec2Client.send(\n new DescribeSnapshotsCommand({\n OwnerIds: [\"self\"],\n NextToken: snapToken,\n }),\n );\n if (resp.Snapshots) snapshots.push(...resp.Snapshots);\n snapToken = resp.NextToken;\n } while (snapToken);\n\n // Build a map: volumeId -> most recent snapshot time\n const latestSnapshotByVolume = new Map<string, number>();\n for (const snap of snapshots) {\n if (!snap.VolumeId || snap.State !== \"completed\") continue;\n const snapTime = snap.StartTime?.getTime() ?? 0;\n const existing = latestSnapshotByVolume.get(snap.VolumeId) ?? 0;\n if (snapTime > existing) {\n latestSnapshotByVolume.set(snap.VolumeId, snapTime);\n }\n }\n\n // Only check in-use volumes for snapshot coverage\n const inUseVolumes = volumes.filter((v) => v.State === \"in-use\");\n resourcesScanned += inUseVolumes.length;\n const now = Date.now();\n\n for (const vol of inUseVolumes) {\n const volId = vol.VolumeId ?? \"unknown\";\n const volArn = `arn:${partition}:ec2:${region}:${accountId}:volume/${volId}`;\n const latestSnap = latestSnapshotByVolume.get(volId);\n\n if (latestSnap === undefined) {\n // No snapshots at all\n findings.push(\n makeFinding({\n riskScore: 7.0,\n title: `EBS volume ${volId} has no snapshots`,\n resourceType: \"AWS::EC2::Volume\",\n resourceId: volId,\n resourceArn: volArn,\n region,\n description: `EBS volume \"${volId}\" (${vol.Size ?? \"?\"}GB, ${vol.VolumeType ?? \"unknown\"}) has no snapshots. Data cannot be recovered if the volume fails.`,\n impact:\n \"Complete data loss if the volume becomes unavailable. No backup exists for disaster recovery.\",\n remediationSteps: [\n \"Create a snapshot of the volume immediately.\",\n \"Set up automated snapshots using AWS Backup or Amazon Data Lifecycle Manager.\",\n ],\n }),\n );\n } else if (now - latestSnap > SEVEN_DAYS_MS) {\n const daysSince = Math.round((now - latestSnap) / (24 * 60 * 60 * 1000));\n findings.push(\n makeFinding({\n riskScore: 5.0,\n title: `EBS volume ${volId} has no recent snapshot (${daysSince} days old)`,\n resourceType: \"AWS::EC2::Volume\",\n resourceId: volId,\n resourceArn: volArn,\n region,\n description: `EBS volume \"${volId}\" (${vol.Size ?? \"?\"}GB) most recent snapshot is ${daysSince} days old, exceeding the 7-day threshold.`,\n impact:\n \"Recovery from the latest snapshot would lose up to ${daysSince} days of data.\",\n remediationSteps: [\n \"Create a fresh snapshot of the volume.\",\n \"Configure automated snapshot schedules using AWS Backup or Data Lifecycle Manager.\",\n ],\n }),\n );\n }\n }\n\n // --- S3 checks ---\n const s3Client = createClient(S3Client, region, ctx.credentials);\n\n let bucketNames: string[] = [];\n try {\n const listResp = await s3Client.send(new ListBucketsCommand({}));\n bucketNames = (listResp.Buckets ?? []).map((b) => b.Name).filter((n): n is string => !!n);\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`S3 bucket list failed: ${msg}`);\n }\n\n resourcesScanned += bucketNames.length;\n\n for (const name of bucketNames) {\n const arn = `arn:${partition}:s3:::${name}`;\n\n // Versioning check\n try {\n const ver = await s3Client.send(\n new GetBucketVersioningCommand({ Bucket: name }),\n );\n if (ver.Status !== \"Enabled\") {\n findings.push(\n makeFinding({\n riskScore: 3.0,\n title: `S3 bucket ${name} does not have versioning enabled`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region,\n description: `Bucket \"${name}\" versioning is ${ver.Status ?? \"not set\"}. Object deletion or overwrite is irreversible.`,\n impact:\n \"Accidental deletion or corruption of objects cannot be recovered without versioning.\",\n remediationSteps: [\n \"Enable versioning on the bucket.\",\n \"Consider adding lifecycle rules to manage version storage costs.\",\n ],\n }),\n );\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Bucket ${name} versioning check failed: ${msg}`);\n }\n\n // Cross-region replication check\n try {\n await s3Client.send(\n new GetBucketReplicationCommand({ Bucket: name }),\n );\n // If the call succeeds, replication is configured — no finding needed\n } catch (e: unknown) {\n if (\n e instanceof Error &&\n e.name === \"ReplicationConfigurationNotFoundError\"\n ) {\n findings.push(\n makeFinding({\n riskScore: 3.5,\n title: `S3 bucket ${name} has no cross-region replication`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region,\n description: `Bucket \"${name}\" does not have cross-region replication configured.`,\n impact:\n \"Data is stored in a single region. A regional outage could make the data unavailable.\",\n remediationSteps: [\n \"Enable cross-region replication to a bucket in another region.\",\n \"Ensure versioning is enabled (required for CRR).\",\n \"Consider S3 Replication Time Control for critical data.\",\n ],\n }),\n );\n } else {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Bucket ${name} replication check failed: ${msg}`);\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n SecurityHubClient,\n GetFindingsCommand,\n} from \"@aws-sdk/client-securityhub\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\nimport { getSecurityHubSource } from \"../utils/sh-source.js\";\n\nfunction shSeverityToScore(label: string): number | null {\n switch (label) {\n case \"CRITICAL\": return 9.5;\n case \"HIGH\": return 8.0;\n case \"MEDIUM\": return 5.5;\n case \"LOW\": return 3.0;\n case \"INFORMATIONAL\": return null; // skip\n default: return null;\n }\n}\n\nexport class SecurityHubFindingsScanner implements Scanner {\n readonly moduleName = \"security_hub_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n const client = createClient(SecurityHubClient, region, ctx.credentials);\n let nextToken: string | undefined;\n\n do {\n const resp = await client.send(\n new GetFindingsCommand({\n Filters: {\n WorkflowStatus: [\n { Value: \"NEW\", Comparison: \"EQUALS\" },\n { Value: \"NOTIFIED\", Comparison: \"EQUALS\" },\n ],\n RecordState: [{ Value: \"ACTIVE\", Comparison: \"EQUALS\" }],\n },\n MaxResults: 100,\n NextToken: nextToken,\n }),\n );\n\n const shFindings = resp.Findings ?? [];\n resourcesScanned += shFindings.length;\n\n for (const f of shFindings) {\n const severityLabel = f.Severity?.Label ?? \"INFORMATIONAL\";\n const score = shSeverityToScore(severityLabel);\n if (score === null) continue; // skip INFORMATIONAL\n\n const severity = severityFromScore(score);\n const resourceId = f.Resources?.[0]?.Id ?? \"unknown\";\n const resourceType = f.Resources?.[0]?.Type ?? \"AWS::Unknown\";\n const resourceArn = resourceId.startsWith(\"arn:\")\n ? resourceId\n : `arn:${partition}:securityhub:${region}:${accountId}:finding/${f.Id ?? \"unknown\"}`;\n\n const remediationSteps: string[] = [];\n const title = f.Title ?? \"Security Hub Finding\";\n\n // Check if Title is actually informative or just a KB/CVE number\n if (/^KB\\d+$/.test(title)) {\n remediationSteps.push(`Install Windows patch ${title} via WSUS or SSM Patch Manager`);\n remediationSteps.push(`Microsoft KB article: https://support.microsoft.com/help/${title}`);\n } else if (/^CVE-/.test(title)) {\n remediationSteps.push(`Fix vulnerability ${title}: update affected software to patched version`);\n } else {\n remediationSteps.push(title);\n }\n\n // Add documentation URL if available and useful\n if (f.Remediation?.Recommendation?.Url) {\n remediationSteps.push(`Documentation: ${f.Remediation.Recommendation.Url}`);\n }\n\n // Add Recommendation.Text only if it's not generic\n const recText = f.Remediation?.Recommendation?.Text ?? \"\";\n if (recText && ![\"See References\", \"None Provided\", \"\"].includes(recText.trim())) {\n remediationSteps.push(recText);\n }\n\n const finding: Finding = {\n severity,\n title: f.Title ?? \"Security Hub Finding\",\n resourceType,\n resourceId,\n resourceArn,\n region: f.Region ?? region,\n description: f.Description ?? f.Title ?? \"No description\",\n impact: `Source: ${f.ProductName ?? \"Security Hub\"} (${f.GeneratorId ?? \"unknown\"})`,\n riskScore: score,\n remediationSteps,\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId: f.AwsAccountId ?? accountId,\n };\n finding.source = getSecurityHubSource(finding);\n findings.push(finding);\n }\n\n nextToken = resp.NextToken;\n } while (nextToken);\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isNotEnabled =\n (err instanceof Error && err.name === \"InvalidAccessException\") ||\n msg.includes(\"not subscribed\") ||\n msg.includes(\"not enabled\");\n\n if (isNotEnabled) {\n warnings.push(\"Security Hub is not enabled in this region. Enable it to aggregate security findings.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Security Hub findings scan failed: ${msg}`,\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import type { Finding } from \"../types.js\";\n\n/** Extract source sub-category from a Security Hub finding's impact field. */\nexport function getSecurityHubSource(finding: Finding): string {\n const impact = finding.impact ?? \"\";\n const match = impact.match(/^Source:\\s*([^(]+)/);\n if (!match) return \"Other\";\n const product = match[1].trim();\n if (product === \"Security Hub\" || product.includes(\"Foundational\")) return \"FSBP\";\n if (product === \"Inspector\" || product.includes(\"Inspector\")) return \"Inspector\";\n if (product === \"GuardDuty\" || product.includes(\"GuardDuty\")) return \"GuardDuty\";\n if (product === \"Config\" || product.includes(\"Config\")) return \"Config\";\n if (product === \"IAM Access Analyzer\" || product.includes(\"Access Analyzer\")) return \"Access Analyzer\";\n return \"Other\";\n}\n","import {\n GuardDutyClient,\n ListDetectorsCommand,\n} from \"@aws-sdk/client-guardduty\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\n\n/**\n * Detection-only scanner: checks whether GuardDuty is enabled.\n * Actual findings are aggregated via Security Hub.\n */\nexport class GuardDutyFindingsScanner implements Scanner {\n readonly moduleName = \"guardduty_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const warnings: string[] = [];\n\n try {\n const client = createClient(GuardDutyClient, region, ctx.credentials);\n const resp = await client.send(new ListDetectorsCommand({}));\n const detectorIds = resp.DetectorIds ?? [];\n\n if (detectorIds.length === 0) {\n warnings.push(\"GuardDuty is not enabled in this region (no detectors found).\");\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n module: this.moduleName,\n status: \"error\",\n error: `GuardDuty detection check failed: ${msg}`,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n Inspector2Client,\n BatchGetAccountStatusCommand,\n} from \"@aws-sdk/client-inspector2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\n\n/**\n * Detection-only scanner: checks whether Inspector is enabled and which\n * resource scan types (EC2, ECR, Lambda, Lambda Code, Code Repository) are active.\n * Actual findings are aggregated via Security Hub.\n */\nexport class InspectorFindingsScanner implements Scanner {\n readonly moduleName = \"inspector_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const warnings: string[] = [];\n\n try {\n const client = createClient(Inspector2Client, region, ctx.credentials);\n const resp = await client.send(new BatchGetAccountStatusCommand({ accountIds: [] }));\n const account = resp.accounts?.[0];\n\n if (!account || account.state?.status !== \"ENABLED\") {\n warnings.push(\"Inspector is not enabled in this region. Enable it to scan for software vulnerabilities.\");\n } else {\n // Check individual resource scan types\n const rs = account.resourceState;\n const types: Array<{ name: string; status: string | undefined }> = [\n { name: \"EC2\", status: rs?.ec2?.status },\n { name: \"Lambda\", status: rs?.lambda?.status },\n { name: \"ECR\", status: rs?.ecr?.status },\n { name: \"Lambda Code\", status: rs?.lambdaCode?.status },\n { name: \"Code Repository\", status: rs?.codeRepository?.status },\n ];\n const disabled = types.filter((t) => t.status && t.status !== \"ENABLED\");\n if (disabled.length > 0) {\n warnings.push(\n `Inspector scan types not enabled: ${disabled.map((t) => t.name).join(\", \")}. Enable them for full vulnerability coverage.`,\n );\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const errName = err instanceof Error ? err.name : \"\";\n\n const isAccessDenied = errName === \"AccessDeniedException\" || msg.includes(\"AccessDeniedException\");\n if (isAccessDenied) {\n warnings.push(\"Insufficient permissions to access Inspector. Grant inspector2:BatchGetAccountStatus to check enablement.\");\n } else {\n warnings.push(\"Inspector is not enabled in this region. Enable it to scan for software vulnerabilities.\");\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n SupportClient,\n DescribeTrustedAdvisorChecksCommand,\n DescribeTrustedAdvisorCheckResultCommand,\n} from \"@aws-sdk/client-support\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction taStatusToScore(status: string): number | null {\n switch (status) {\n case \"error\": return 8.0; // RED = action required\n case \"warning\": return 5.5; // YELLOW = investigation recommended\n case \"ok\": return null; // GREEN = no issue\n case \"not_available\": return null;\n default: return null;\n }\n}\n\nexport class TrustedAdvisorFindingsScanner implements Scanner {\n readonly moduleName = \"trusted_advisor_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n // Trusted Advisor API endpoint: cn-north-1 for China, us-east-1 for standard\n const supportRegion = region.startsWith(\"cn-\") ? \"cn-north-1\" : \"us-east-1\";\n const clientConfig: any = { region: supportRegion };\n if (ctx.credentials) clientConfig.credentials = ctx.credentials;\n const client = new SupportClient(clientConfig);\n\n // Step 1: List security checks\n const checksResp = await client.send(\n new DescribeTrustedAdvisorChecksCommand({ language: \"en\" }),\n );\n const allChecks = checksResp.checks ?? [];\n const securityChecks = allChecks.filter((c) => c.category === \"security\");\n\n if (securityChecks.length === 0) {\n warnings.push(\"No Trusted Advisor security checks found.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n // Step 2: Get results for each security check\n for (const check of securityChecks) {\n if (!check.id) continue;\n\n try {\n const resultResp = await client.send(\n new DescribeTrustedAdvisorCheckResultCommand({\n checkId: check.id,\n }),\n );\n\n const result = resultResp.result;\n if (!result) continue;\n\n const status = result.status ?? \"not_available\";\n const score = taStatusToScore(status);\n\n resourcesScanned++;\n\n if (score === null) continue; // ok or not_available — skip\n\n // Map flagged resources to findings\n const flaggedResources = result.flaggedResources ?? [];\n\n if (flaggedResources.length === 0) {\n // Check-level finding without specific resources\n const severity = severityFromScore(score);\n findings.push({\n severity,\n title: `[Trusted Advisor] ${check.name ?? \"Security Check\"}`,\n resourceType: \"AWS::TrustedAdvisor::Check\",\n resourceId: check.id,\n resourceArn: `arn:${partition}:trustedadvisor:${region}:${accountId}:check/${check.id}`,\n region,\n description: check.description ?? check.name ?? \"Security check flagged\",\n impact: `Trusted Advisor status: ${status}`,\n riskScore: score,\n remediationSteps: [\n \"Review this Trusted Advisor check in the AWS console.\",\n \"Follow the recommended actions to resolve the flagged issue.\",\n ],\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId,\n });\n continue;\n }\n\n // Create findings for flagged resources (limit to first 25 per check)\n const metadata = check.metadata ?? [];\n for (const fr of flaggedResources.slice(0, 25)) {\n if (fr.isSuppressed) continue;\n\n const severity = severityFromScore(score);\n const resourceMeta = fr.metadata ?? [];\n\n // Try to extract resource ID from metadata\n const resourceIdIdx = metadata.indexOf(\"Resource ID\");\n const regionIdx = metadata.indexOf(\"Region\");\n const flaggedResourceId = resourceIdIdx >= 0 && resourceMeta[resourceIdIdx]\n ? resourceMeta[resourceIdIdx]\n : fr.resourceId ?? \"unknown\";\n const flaggedRegion = regionIdx >= 0 && resourceMeta[regionIdx]\n ? resourceMeta[regionIdx]\n : region;\n\n findings.push({\n severity,\n title: `[Trusted Advisor] ${check.name ?? \"Security Check\"}: ${flaggedResourceId}`,\n resourceType: \"AWS::TrustedAdvisor::FlaggedResource\",\n resourceId: flaggedResourceId,\n resourceArn: `arn:${partition}:trustedadvisor:${flaggedRegion}:${accountId}:check/${check.id}/${fr.resourceId ?? \"unknown\"}`,\n region: flaggedRegion,\n description: `${check.name}: ${resourceMeta.join(\" | \")}`,\n impact: `Trusted Advisor status: ${status} — ${check.name ?? \"security check\"}`,\n riskScore: score,\n remediationSteps: [\n `Review Trusted Advisor check: ${check.name}`,\n \"Follow the recommended actions in the AWS Trusted Advisor console.\",\n ],\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId,\n });\n }\n } catch (checkErr) {\n const checkMsg = checkErr instanceof Error ? checkErr.message : String(checkErr);\n warnings.push(`Trusted Advisor check ${check.name ?? check.id} failed: ${checkMsg}`);\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isSubscriptionRequired =\n msg.includes(\"SubscriptionRequiredException\") ||\n msg.includes(\"subscription\") ||\n msg.includes(\"AWS Premium Support\") ||\n (err instanceof Error && err.name === \"SubscriptionRequiredException\");\n\n if (isSubscriptionRequired) {\n warnings.push(\"Trusted Advisor requires AWS Business or Enterprise Support plan. Skipping.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Trusted Advisor scan failed: ${msg}`,\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n ConfigServiceClient,\n DescribeConfigurationRecordersCommand,\n} from \"@aws-sdk/client-config-service\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\n\n/**\n * Detection-only scanner: checks whether AWS Config is enabled.\n * Actual findings are aggregated via Security Hub.\n */\nexport class ConfigRulesFindingsScanner implements Scanner {\n readonly moduleName = \"config_rules_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const warnings: string[] = [];\n\n try {\n const client = createClient(ConfigServiceClient, region, ctx.credentials);\n const resp = await client.send(new DescribeConfigurationRecordersCommand({}));\n const recorders = resp.ConfigurationRecorders ?? [];\n\n if (recorders.length === 0) {\n warnings.push(\"AWS Config is not enabled in this region.\");\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n\n if (\n msg.includes(\"NoSuchConfigurationRecorder\") ||\n msg.includes(\"InsufficientDeliveryPolicy\") ||\n msg.includes(\"No Configuration Recorder\")\n ) {\n warnings.push(\"AWS Config is not enabled in this region.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Config Rules detection check failed: ${msg}`,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n AccessAnalyzerClient,\n ListAnalyzersCommand,\n} from \"@aws-sdk/client-accessanalyzer\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\n\n/**\n * Detection-only scanner: checks whether IAM Access Analyzer is enabled.\n * Actual findings are aggregated via Security Hub.\n */\nexport class AccessAnalyzerFindingsScanner implements Scanner {\n readonly moduleName = \"access_analyzer_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const warnings: string[] = [];\n\n try {\n const client = createClient(AccessAnalyzerClient, region, ctx.credentials);\n\n let analyzerToken: string | undefined;\n let hasActiveAnalyzer = false;\n\n do {\n const resp = await client.send(\n new ListAnalyzersCommand({ nextToken: analyzerToken }),\n );\n for (const analyzer of resp.analyzers ?? []) {\n if (analyzer.status === \"ACTIVE\") {\n hasActiveAnalyzer = true;\n break;\n }\n }\n if (hasActiveAnalyzer) break;\n analyzerToken = resp.nextToken;\n } while (analyzerToken);\n\n if (!hasActiveAnalyzer) {\n warnings.push(\"No IAM Access Analyzer found. Create an analyzer to detect external access to your resources.\");\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Access Analyzer detection check failed: ${msg}`,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n SSMClient,\n DescribeInstanceInformationCommand,\n DescribeInstancePatchStatesCommand,\n type InstanceInformation,\n type InstancePatchState,\n} from \"@aws-sdk/client-ssm\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nexport class PatchComplianceFindingsScanner implements Scanner {\n readonly moduleName = \"patch_compliance_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n const client = createClient(SSMClient, region, ctx.credentials);\n\n // Step 1: Get all managed instances\n let nextToken: string | undefined;\n const instances: InstanceInformation[] = [];\n\n do {\n const resp = await client.send(\n new DescribeInstanceInformationCommand({\n MaxResults: 50,\n NextToken: nextToken,\n }),\n );\n instances.push(...(resp.InstanceInformationList ?? []));\n nextToken = resp.NextToken;\n } while (nextToken);\n\n if (instances.length === 0) {\n warnings.push(\"No SSM-managed instances found in this region.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n resourcesScanned = instances.length;\n\n // Step 2: Get patch states in batches\n const instanceIds = instances.map((i) => i.InstanceId).filter(Boolean) as string[];\n const patchStateMap = new Map<string, InstancePatchState>();\n\n // DescribeInstancePatchStates supports up to 50 instances per call\n for (let i = 0; i < instanceIds.length; i += 50) {\n const batch = instanceIds.slice(i, i + 50);\n let patchToken: string | undefined;\n\n do {\n const patchResp = await client.send(\n new DescribeInstancePatchStatesCommand({\n InstanceIds: batch,\n NextToken: patchToken,\n }),\n );\n\n for (const ps of patchResp.InstancePatchStates ?? []) {\n if (ps.InstanceId) {\n patchStateMap.set(ps.InstanceId, ps);\n }\n }\n\n patchToken = patchResp.NextToken;\n } while (patchToken);\n }\n\n // Step 3: Generate findings for instances with missing/failed patches\n for (const instance of instances) {\n const instanceId = instance.InstanceId ?? \"unknown\";\n const platform = instance.PlatformName ?? instance.PlatformType ?? \"unknown\";\n const instanceArn = `arn:${partition}:ec2:${region}:${accountId}:instance/${instanceId}`;\n\n const patchState = patchStateMap.get(instanceId);\n\n if (!patchState) {\n // Instance not managed for patching — INFO-level finding\n const riskScore = 3.0;\n const severity = severityFromScore(riskScore);\n findings.push({\n severity,\n title: `Instance ${instanceId} has no patch compliance data`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instanceId,\n resourceArn: instanceArn,\n region,\n description: `Instance ${instanceId} (${platform}) is managed by SSM but has no patch compliance data. Patch Manager may not be configured for this instance.`,\n impact: \"Patch compliance status is unknown — vulnerabilities may exist.\",\n riskScore,\n remediationSteps: [\n \"Configure AWS Systems Manager Patch Manager for this instance.\",\n \"Create a patch baseline and maintenance window.\",\n \"Run a patch scan to establish compliance status.\",\n ],\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId,\n });\n continue;\n }\n\n const missingCount = patchState.MissingCount ?? 0;\n const failedCount = patchState.FailedCount ?? 0;\n const criticalNonCompliantCount = patchState.CriticalNonCompliantCount ?? 0;\n const securityNonCompliantCount = patchState.SecurityNonCompliantCount ?? 0;\n const otherNonCompliantCount = patchState.OtherNonCompliantCount ?? 0;\n const lastScanTime = patchState.OperationEndTime?.toISOString() ?? \"unknown\";\n\n if (\n missingCount === 0 &&\n failedCount === 0 &&\n criticalNonCompliantCount === 0 &&\n securityNonCompliantCount === 0 &&\n otherNonCompliantCount === 0\n ) {\n continue; // Instance is fully patched\n }\n\n // Determine severity based on patch issues\n let riskScore: number;\n if (criticalNonCompliantCount > 0 || securityNonCompliantCount > 0 || failedCount > 0) {\n riskScore = 7.5; // HIGH — critical/security patches missing or failed\n } else if (otherNonCompliantCount > 0) {\n riskScore = 5.5; // MEDIUM — other non-compliant patches\n } else {\n riskScore = 5.5; // MEDIUM — non-security patches missing\n }\n const severity = severityFromScore(riskScore);\n\n const titleParts: string[] = [];\n if (missingCount > 0) titleParts.push(`${missingCount} missing`);\n if (failedCount > 0) titleParts.push(`${failedCount} failed`);\n if (criticalNonCompliantCount > 0) titleParts.push(`${criticalNonCompliantCount} critical non-compliant`);\n if (securityNonCompliantCount > 0) titleParts.push(`${securityNonCompliantCount} security non-compliant`);\n if (otherNonCompliantCount > 0) titleParts.push(`${otherNonCompliantCount} other non-compliant`);\n\n const descParts = [\n `Instance: ${instanceId}`,\n `Platform: ${platform}`,\n `Missing patches: ${missingCount}`,\n `Failed patches: ${failedCount}`,\n `Critical non-compliant: ${criticalNonCompliantCount}`,\n `Security non-compliant: ${securityNonCompliantCount}`,\n `Other non-compliant: ${otherNonCompliantCount}`,\n `Last scan: ${lastScanTime}`,\n ];\n\n findings.push({\n severity,\n title: `Instance ${instanceId} has ${titleParts.join(\", \")} patches`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instanceId,\n resourceArn: instanceArn,\n region,\n description: descParts.join(\". \"),\n impact: `Instance has ${missingCount} missing and ${failedCount} failed patches — potential security vulnerabilities.`,\n riskScore,\n remediationSteps: [\n `Review patch compliance for instance ${instanceId} in the Systems Manager console.`,\n \"Apply missing patches using a maintenance window or manual patching.\",\n \"Investigate and resolve any failed patch installations.\",\n \"Consider enabling automatic patching through Patch Manager.\",\n ],\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId,\n });\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Patch compliance scan failed: ${msg}`,\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n EC2Client,\n DescribeInstancesCommand,\n type Instance,\n} from \"@aws-sdk/client-ec2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class Imdsv2EnforcementScanner implements Scanner {\n readonly moduleName = \"imdsv2_enforcement\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const client = createClient(EC2Client, region, ctx.credentials);\n\n // List all running EC2 instances\n const instances: Instance[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await client.send(\n new DescribeInstancesCommand({\n Filters: [{ Name: \"instance-state-name\", Values: [\"running\"] }],\n NextToken: nextToken,\n }),\n );\n if (resp.Reservations) {\n for (const reservation of resp.Reservations) {\n if (reservation.Instances) {\n instances.push(...reservation.Instances);\n }\n }\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n for (const instance of instances) {\n const instanceId = instance.InstanceId ?? \"unknown\";\n const instanceType = instance.InstanceType ?? \"unknown\";\n const state = instance.State?.Name ?? \"unknown\";\n const httpTokens = instance.MetadataOptions?.HttpTokens ?? \"unknown\";\n const hopLimit = instance.MetadataOptions?.HttpPutResponseHopLimit ?? 1;\n const instanceArn = `arn:${partition}:ec2:${region}:${accountId}:instance/${instanceId}`;\n\n if (httpTokens !== \"required\") {\n const description = [\n `EC2 instance ${instanceId} (type: ${instanceType}, state: ${state}) has HttpTokens set to \"${httpTokens}\".`,\n `IMDSv1 is accessible, allowing unauthenticated metadata requests.`,\n ];\n if (hopLimit > 1) {\n description.push(`HttpPutResponseHopLimit is ${hopLimit} (>1), which may allow containers to reach IMDS.`);\n }\n\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `EC2 instance ${instanceId} does not enforce IMDSv2`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instanceId,\n resourceArn: instanceArn,\n region,\n description: description.join(\" \"),\n impact: \"IMDSv1 allows attackers to steal IAM role credentials via SSRF attacks\",\n remediationSteps: [\n \"Enforce IMDSv2 by setting HttpTokens to 'required'.\",\n \"Run: aws ec2 modify-instance-metadata-options --instance-id \" + instanceId + \" --http-tokens required --http-endpoint enabled\",\n \"Set HttpPutResponseHopLimit to 1 unless running containers that need metadata access.\",\n \"Update launch templates and Auto Scaling groups to enforce IMDSv2 for new instances.\",\n ],\n }),\n );\n } else if (hopLimit > 1) {\n // IMDSv2 enforced but hop limit is elevated — informational warning\n warnings.push(\n `Instance ${instanceId} enforces IMDSv2 but HttpPutResponseHopLimit is ${hopLimit} (>1). Verify this is intentional for containerized workloads.`,\n );\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: instances.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n ElasticLoadBalancingV2Client,\n DescribeLoadBalancersCommand,\n type LoadBalancer,\n} from \"@aws-sdk/client-elastic-load-balancing-v2\";\nimport {\n WAFV2Client,\n GetWebACLForResourceCommand,\n} from \"@aws-sdk/client-wafv2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class WafCoverageScanner implements Scanner {\n readonly moduleName = \"waf_coverage\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const elbClient = createClient(ElasticLoadBalancingV2Client, region, ctx.credentials);\n const wafClient = createClient(WAFV2Client, region, ctx.credentials);\n\n // List all ELBv2 load balancers\n const loadBalancers: LoadBalancer[] = [];\n let marker: string | undefined;\n do {\n const resp = await elbClient.send(\n new DescribeLoadBalancersCommand({ Marker: marker }),\n );\n if (resp.LoadBalancers) {\n loadBalancers.push(...resp.LoadBalancers);\n }\n marker = resp.NextMarker;\n } while (marker);\n\n // Filter to internet-facing only\n const internetFacing = loadBalancers.filter((lb) => lb.Scheme === \"internet-facing\");\n\n for (const lb of internetFacing) {\n const lbName = lb.LoadBalancerName ?? \"unknown\";\n const lbArn = lb.LoadBalancerArn ?? \"unknown\";\n const lbType = lb.Type ?? \"unknown\";\n\n // WAF only applies to ALB (application), not NLB (network) or GLB (gateway)\n if (lbType !== \"application\") {\n warnings.push(\n `Skipping ${lbType} load balancer \"${lbName}\" — WAF Web ACL association is only supported for ALBs.`,\n );\n continue;\n }\n\n try {\n const wafResp = await wafClient.send(\n new GetWebACLForResourceCommand({ ResourceArn: lbArn }),\n );\n\n if (!wafResp.WebACL) {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `Internet-facing ALB ${lbName} has no WAF protection`,\n resourceType: \"AWS::ElasticLoadBalancingV2::LoadBalancer\",\n resourceId: lbName,\n resourceArn: lbArn,\n region,\n description: `Internet-facing Application Load Balancer \"${lbName}\" does not have a WAF Web ACL associated. Traffic is not inspected for common web exploits.`,\n impact: \"Without WAF, the ALB is exposed to SQL injection, XSS, and other OWASP Top 10 attacks\",\n remediationSteps: [\n \"Create a WAFv2 Web ACL with managed rule groups (e.g., AWSManagedRulesCommonRuleSet).\",\n \"Associate the Web ACL with the ALB using the REGIONAL scope.\",\n \"Enable WAF logging for visibility into blocked requests.\",\n \"Consider adding rate-based rules to mitigate DDoS at the application layer.\",\n ],\n }),\n );\n }\n } catch (wafErr: unknown) {\n const errMsg = wafErr instanceof Error ? wafErr.message : String(wafErr);\n const errName = wafErr instanceof Error ? (wafErr as any).name ?? \"\" : \"\";\n\n // Handle WAFv2 not available or access denied gracefully\n if (errName === \"WAFNonexistentItemException\") {\n // No Web ACL associated — same as null response\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `Internet-facing ALB ${lbName} has no WAF protection`,\n resourceType: \"AWS::ElasticLoadBalancingV2::LoadBalancer\",\n resourceId: lbName,\n resourceArn: lbArn,\n region,\n description: `Internet-facing Application Load Balancer \"${lbName}\" does not have a WAF Web ACL associated. Traffic is not inspected for common web exploits.`,\n impact: \"Without WAF, the ALB is exposed to SQL injection, XSS, and other OWASP Top 10 attacks\",\n remediationSteps: [\n \"Create a WAFv2 Web ACL with managed rule groups (e.g., AWSManagedRulesCommonRuleSet).\",\n \"Associate the Web ACL with the ALB using the REGIONAL scope.\",\n \"Enable WAF logging for visibility into blocked requests.\",\n \"Consider adding rate-based rules to mitigate DDoS at the application layer.\",\n ],\n }),\n );\n } else if (errName === \"AccessDeniedException\" || errName === \"WAFInvalidParameterException\") {\n warnings.push(\n `Could not check WAF for ALB \"${lbName}\": ${errMsg}. Ensure wafv2:GetWebACLForResource permission is granted.`,\n );\n } else {\n warnings.push(`Error checking WAF for ALB \"${lbName}\": ${errMsg}`);\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: internetFacing.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n const errName = err instanceof Error ? (err as any).name ?? \"\" : \"\";\n\n // If WAFv2 or ELBv2 is not available or access denied, return success with warning\n if (errName === \"AccessDeniedException\" || errName === \"UnrecognizedClientException\") {\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: [`WAF coverage check skipped: ${errMsg}`],\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n return {\n module: this.moduleName,\n status: \"error\",\n error: errMsg,\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import type { I18n } from \"./index.js\";\n\nexport const zhI18n: I18n = {\n // HTML Security Report\n securityReportTitle: \"AWS \\u5b89\\u5168\\u626b\\u63cf\\u62a5\\u544a\",\n securityScore: \"\\u5b89\\u5168\\u8bc4\\u5206\",\n critical: \"\\u4e25\\u91cd\",\n high: \"\\u9ad8\",\n medium: \"\\u4e2d\",\n low: \"\\u4f4e\",\n scanStatistics: \"\\u626b\\u63cf\\u7edf\\u8ba1\",\n module: \"\\u6a21\\u5757\",\n resources: \"\\u8d44\\u6e90\",\n findings: \"\\u53d1\\u73b0\",\n status: \"\\u72b6\\u6001\",\n allFindings: \"\\u6240\\u6709\\u53d1\\u73b0\",\n recommendations: \"\\u5efa\\u8bae\",\n unique: \"\\u53bb\\u91cd\",\n showMore: \"\\u663e\\u793a\\u66f4\\u591a\",\n noIssuesFound: \"\\u672a\\u53d1\\u73b0\\u5b89\\u5168\\u95ee\\u9898\\u3002\",\n allModulesClean: \"\\u6240\\u6709\\u6a21\\u5757\\u6b63\\u5e38\",\n generatedBy: \"\\u7531 AWS Security MCP Server \\u751f\\u6210\",\n informationalOnly: \"\\u672c\\u62a5\\u544a\\u4ec5\\u4f9b\\u53c2\\u8003\\u3002\",\n\n // MLPS Report\n mlpsTitle: \"\\u7b49\\u4fdd\\u4e09\\u7ea7\\u9884\\u68c0\\u62a5\\u544a\",\n mlpsDisclaimer:\n \"\\u672c\\u62a5\\u544a\\u4e3a\\u7b49\\u4fdd\\u4e09\\u7ea7\\u9884\\u68c0\\u53c2\\u8003\\uff0c\\u63d0\\u4f9b\\u4e91\\u5e73\\u53f0\\u914d\\u7f6e\\u68c0\\u67e5\\u6570\\u636e\\u4e0e\\u5efa\\u8bae\\u3002\\u5408\\u89c4\\u5224\\u5b9a\\uff08\\u7b26\\u5408/\\u90e8\\u5206\\u7b26\\u5408/\\u4e0d\\u7b26\\u5408\\uff09\\u9700\\u7531\\u6301\\u8bc1\\u6d4b\\u8bc4\\u673a\\u6784\\u6839\\u636e\\u5b9e\\u9645\\u60c5\\u51b5\\u786e\\u8ba4\\u3002\\uff08GB/T 22239-2019 \\u5b8c\\u6574\\u68c0\\u67e5\\u6e05\\u5355 184 \\u9879\\uff09\",\n checkedItems: \"\\u5df2\\u68c0\\u67e5\\u9879\",\n noIssues: \"\\u672a\\u53d1\\u73b0\\u95ee\\u9898\",\n issuesFound: \"\\u53d1\\u73b0\\u95ee\\u9898\",\n notChecked: \"\\u672a\\u68c0\\u67e5\",\n cloudProvider: \"\\u4e91\\u5e73\\u53f0\\u8d1f\\u8d23\",\n manualReview: \"\\u9700\\u4eba\\u5de5\\u8bc4\\u4f30\",\n notApplicable: \"\\u4e0d\\u9002\\u7528\",\n checkResult: \"\\u68c0\\u67e5\\u7ed3\\u679c\",\n noRelatedIssues: \"\\u68c0\\u67e5\\u7ed3\\u679c\\uff1a\\u672a\\u53d1\\u73b0\\u76f8\\u5173\\u95ee\\u9898\",\n issuesFoundCount: (n: number) =>\n `\\u68c0\\u67e5\\u7ed3\\u679c\\uff1a\\u53d1\\u73b0 ${n} \\u4e2a\\u76f8\\u5173\\u95ee\\u9898`,\n remediation: \"\\u5efa\\u8bae\",\n remediationItems: (n: number) =>\n `\\u5efa\\u8bae\\u6574\\u6539\\u9879\\uff08${n} \\u9879\\u53bb\\u91cd\\uff09`,\n showRemaining: (n: number) => `\\u663e\\u793a\\u5176\\u4f59 ${n} \\u9879`,\n\n // HW Defense Checklist\n hwChecklistTitle:\n \"\\ud83d\\udccb \\u62a4\\u7f51\\u884c\\u52a8\\u8865\\u5145\\u63d0\\u9192\\uff08\\u8d85\\u51fa\\u81ea\\u52a8\\u5316\\u626b\\u63cf\\u8303\\u56f4\\uff09\",\n hwChecklistSubtitle: \"\\u4ee5\\u4e0b\\u4e8b\\u9879\\u9700\\u8981\\u4eba\\u5de5\\u786e\\u8ba4\\u548c\\u6267\\u884c\\uff1a\",\n hwEmergencyIsolation: `\\u26a0\\ufe0f \\u5e94\\u6025\\u9694\\u79bb/\\u6b62\\u8840\\u65b9\\u6848\n \\u25a1 \\u51c6\\u5907\\u4e13\\u7528\\u9694\\u79bb\\u5b89\\u5168\\u7ec4\\uff08\\u65e0 Inbound/Outbound \\u89c4\\u5219\\uff09\n \\u25a1 \\u5236\\u5b9a\\u5b9e\\u4f8b\\u9694\\u79bb SOP\\uff1a\\u544a\\u8b66 \\u2192 \\u6392\\u67e5 \\u2192 \\u5c01\\u9501\\u653b\\u51fbIP \\u2192 \\u7f51\\u7edc\\u9694\\u79bb \\u2192 \\u5b89\\u5168\\u5904\\u7f6e \\u2192 \\u8bb0\\u5f55\\u653b\\u51fb\\u9879\n \\u25a1 \\u660e\\u786e\\u5404\\u7cfb\\u7edf\\uff08\\u751f\\u4ea7\\u6838\\u5fc3/\\u751f\\u4ea7\\u975e\\u6838\\u5fc3/\\u6d4b\\u8bd5/\\u5f00\\u53d1\\uff09\\u7684\\u5e94\\u6025\\u5904\\u7f6e\\u65b9\\u5f0f\n \\u25a1 \\u660e\\u786e\\u5404\\u9879\\u76ee\\u8d26\\u6237\\u53ca\\u8d44\\u6e90\\u7684\\u8d1f\\u8d23\\u4eba\\u4e0e\\u8054\\u7cfb\\u65b9\\u5f0f`,\n hwTestEnvShutdown: `\\u26a0\\ufe0f \\u6d4b\\u8bd5/\\u5f00\\u53d1\\u73af\\u5883\\u5904\\u7f6e\n \\u25a1 \\u975e\\u6838\\u5fc3\\u7cfb\\u7edf\\u5728\\u62a4\\u7f51\\u671f\\u95f4\\u5173\\u95ed\n \\u25a1 \\u6d4b\\u8bd5/\\u5f00\\u53d1\\u73af\\u5883\\u5173\\u95ed\\u6216\\u4e0e\\u751f\\u4ea7\\u4fdd\\u6301\\u540c\\u7b49\\u5b89\\u5168\\u57fa\\u7ebf\n \\u25a1 \\u786e\\u8ba4\\u54ea\\u4e9b\\u73af\\u5883\\u53ef\\u4ee5\\u7d27\\u6025\\u5173\\u505c\\uff0c\\u907f\\u514d\\u653b\\u51fb\\u6269\\u6563`,\n hwDutyTeam: `\\u26a0\\ufe0f \\u503c\\u5b88\\u56e2\\u961f\\u7ec4\\u5efa\n \\u25a1 7\\u00d724 \\u76d1\\u63a7\\u5feb\\u901f\\u54cd\\u5e94\\u56e2\\u961f\n \\u25a1 \\u6280\\u672f\\u4e0e\\u98ce\\u9669\\u5206\\u6790\\u7ec4\n \\u25a1 \\u5b89\\u5168\\u7b56\\u7565\\u4e0b\\u53d1\\u7ec4\n \\u25a1 \\u4e1a\\u52a1\\u54cd\\u5e94\\u7ec4\n \\u25a1 \\u660e\\u786e AWS TAM/Support \\u8054\\u7cfb\\u65b9\\u5f0f\\uff08ES/EOP \\u5ba2\\u6237\\uff09`,\n hwNetworkDiagram: `\\u26a0\\ufe0f \\u51fa\\u5165\\u7ad9\\u8def\\u5f84\\u67b6\\u6784\\u56fe\n \\u25a1 \\u786e\\u4fdd\\u6240\\u6709\\u4e92\\u8054\\u7f51/DX \\u4e13\\u7ebf\\u51fa\\u5165\\u7ad9\\u8def\\u5f84\\u5728\\u67b6\\u6784\\u56fe\\u4e2d\\u6e05\\u6670\\u6807\\u6ce8\n \\u25a1 \\u660e\\u786e\\u5404 ELB/Public EC2/S3/DX \\u7684\\u6570\\u636e\\u6d41\\u5411\n \\u25a1 \\u8bc6\\u522b\\u6240\\u6709\\u9762\\u5411\\u4e92\\u8054\\u7f51\\u7684\\u6570\\u636e\\u4ea4\\u4e92\\u63a5\\u53e3`,\n hwPentest: `\\u26a0\\ufe0f \\u4e3b\\u52a8\\u5f0f\\u6e17\\u900f\\u6d4b\\u8bd5\n \\u25a1 \\u62a4\\u7f51\\u524d\\u8054\\u7cfb\\u5b89\\u5168\\u5382\\u5546\\uff08\\u9752\\u85e4/\\u957f\\u4ead/\\u5fae\\u6b65\\u7b49\\uff09\\u8fdb\\u884c\\u6a21\\u62df\\u653b\\u51fb\\u6f14\\u7ec3\n \\u25a1 \\u57fa\\u4e8e\\u6e17\\u900f\\u6d4b\\u8bd5\\u62a5\\u544a\\u8fdb\\u884c\\u6b63\\u5f0f\\u62a4\\u7f51\\u524d\\u7684\\u5b89\\u5168\\u52a0\\u56fa\n \\u25a1 \\u5173\\u6ce8 AWS \\u5b89\\u5168\\u516c\\u544a\\uff08\\u5df2\\u77e5\\u6f0f\\u6d1e\\u4e0e\\u8865\\u4e01\\uff09`,\n hwWarRoom: `\\u26a0\\ufe0f WAR-ROOM \\u5b9e\\u65f6\\u6c9f\\u901a\n \\u25a1 \\u521b\\u5efa\\u62a4\\u7f51\\u671f\\u95f4\\u4e13\\u7528\\u6c9f\\u901a\\u6e20\\u9053\\uff08\\u4f01\\u5fae/\\u9489\\u9489/\\u98de\\u4e66/Chime\\uff09\n \\u25a1 \\u4e0e AWS TAM \\u5efa\\u7acb WAR-ROOM \\u8054\\u7cfb\\uff08\\u4f01\\u4e1a\\u7ea7\\u652f\\u6301\\u5ba2\\u6237\\uff09\n \\u25a1 \\u7edf\\u4e00\\u6848\\u4f8b\\u6807\\u9898\\u683c\\u5f0f\\uff1a\\u201c\\u3010\\u62a4\\u7f51\\u3011+ \\u95ee\\u9898\\u63cf\\u8ff0\\u201d`,\n hwCredentials: `\\u26a0\\ufe0f \\u5bc6\\u7801\\u4e0e\\u51ed\\u8bc1\\u7ba1\\u7406\n \\u25a1 \\u6240\\u6709 IAM \\u7528\\u6237\\u7ed1\\u5b9a MFA\n \\u25a1 AKSK \\u8f6e\\u8f6c\\u5468\\u671f \\u2264 90 \\u5929\n \\u25a1 \\u907f\\u514d\\u5171\\u4eab\\u8d26\\u6237\\u4f7f\\u7528\n \\u25a1 S3/Lambda/\\u5e94\\u7528\\u4ee3\\u7801\\u4e2d\\u65e0\\u660e\\u6587\\u5bc6\\u7801`,\n hwPostOptimization: `\\u26a0\\ufe0f \\u62a4\\u7f51\\u540e\\u4f18\\u5316\n \\u25a1 \\u9488\\u5bf9\\u653b\\u51fb\\u62a5\\u544a\\u9010\\u9879\\u5e94\\u7b54\\u4e0e\\u4fee\\u590d\n \\u25a1 \\u4e0e\\u5b89\\u5168\\u56e2\\u961f\\u5efa\\u7acb\\u5468\\u671f\\u6027\\u5b89\\u5168\\u7ef4\\u62a4\\u6d41\\u7a0b\n \\u25a1 \\u6301\\u7eed\\u8865\\u5168\\u5b89\\u5168\\u98ce\\u9669`,\n hwReference:\n \"\\u53c2\\u8003\\uff1aAWS \\u62a4\\u7f51\\u884c\\u52a8 Standard Operation Procedure (Compliance IEM)\",\n\n // Service Reminders\n serviceReminderTitle:\n \"\\u26a1 \\u4ee5\\u4e0b\\u5b89\\u5168\\u670d\\u52a1\\u672a\\u542f\\u7528\\uff0c\\u90e8\\u5206\\u68c0\\u67e5\\u65e0\\u6cd5\\u6267\\u884c\\uff1a\",\n serviceReminderFooter:\n \"\\u542f\\u7528\\u4ee5\\u4e0a\\u670d\\u52a1\\u540e\\u91cd\\u65b0\\u626b\\u63cf\\u53ef\\u83b7\\u5f97\\u66f4\\u5b8c\\u6574\\u7684\\u5b89\\u5168\\u8bc4\\u4f30\\u3002\",\n serviceImpact: \"\\u5f71\\u54cd\",\n serviceAction: \"\\u5efa\\u8bae\",\n\n // Common\n account: \"\\u8d26\\u6237\",\n region: \"\\u533a\\u57df\",\n scanTime: \"\\u626b\\u63cf\\u65f6\\u95f4\",\n duration: \"\\u8017\\u65f6\",\n severityDistribution: \"\\u4e25\\u91cd\\u6027\\u5206\\u5e03\",\n findingsByModule: \"\\u6309\\u6a21\\u5757\\u5206\\u7c7b\\u7684\\u53d1\\u73b0\",\n details: \"\\u8be6\\u60c5\",\n\n // Extended — HTML Security Report extras\n topHighestRiskFindings: (n: number) =>\n `\\u524d ${n} \\u9879\\u6700\\u9ad8\\u98ce\\u9669\\u53d1\\u73b0`,\n resource: \"\\u8d44\\u6e90\",\n impact: \"\\u5f71\\u54cd\",\n riskScore: \"\\u98ce\\u9669\\u8bc4\\u5206\",\n showRemainingFindings: (n: number) =>\n `\\u663e\\u793a\\u5269\\u4f59 ${n} \\u9879\\u53d1\\u73b0\\u2026`,\n trendTitle: \"30\\u65e5\\u8d8b\\u52bf\",\n findingsBySeverity: \"\\u6309\\u4e25\\u91cd\\u6027\\u5206\\u7c7b\\u7684\\u53d1\\u73b0\",\n showMoreCount: (n: number) =>\n `\\u663e\\u793a\\u5269\\u4f59 ${n} \\u9879\\u2026`,\n\n // Filter toolbar\n filterSeverity: \"\\u4e25\\u91cd\\u6027\\uff1a\",\n filterModule: \"\\u6a21\\u5757\\uff1a\",\n filterAll: \"\\u5168\\u90e8\",\n filterAllModules: \"\\u5168\\u90e8\\u6a21\\u5757\",\n filterCountTpl: \"\\u663e\\u793a {shown} / {total} \\u4e2a\\u53d1\\u73b0\",\n\n // Extended — MLPS extras\n // Markdown report\n executiveSummary: \"\\u6267\\u884c\\u6458\\u8981\",\n totalFindingsLabel: \"\\u53d1\\u73b0\\u603b\\u6570\",\n description: \"\\u63cf\\u8ff0\",\n priority: \"\\u4f18\\u5148\\u7ea7\",\n noFindingsForSeverity: (severity: string) => `\\u65e0${severity}\\u53d1\\u73b0\\u3002`,\n\n preCheckOverview: \"\\u9884\\u68c0\\u603b\\u89c8\",\n accountInfo: \"\\u8d26\\u6237\\u4fe1\\u606f\",\n checkedCount: (total: number, clean: number, issues: number) =>\n `\\u5df2\\u68c0\\u67e5: ${total} \\u9879\\uff08\\u672a\\u53d1\\u73b0\\u95ee\\u9898: ${clean} \\u9879 | \\u53d1\\u73b0\\u95ee\\u9898: ${issues} \\u9879\\uff09`,\n uncheckedCount: (n: number) =>\n `\\u672a\\u68c0\\u67e5: ${n} \\u9879\\uff08\\u5bf9\\u5e94\\u626b\\u63cf\\u6a21\\u5757\\u672a\\u8fd0\\u884c\\uff09`,\n cloudProviderCount: (n: number) => `\\u4e91\\u5e73\\u53f0\\u8d1f\\u8d23: ${n} \\u9879`,\n manualReviewCount: (n: number) => `\\u9700\\u4eba\\u5de5\\u8bc4\\u4f30: ${n} \\u9879`,\n naCount: (n: number) => `\\u4e0d\\u9002\\u7528: ${n} \\u9879`,\n naNote: (n: number) =>\n `\\u4e0d\\u9002\\u7528\\u9879: ${n} \\u9879\\uff08\\u7269\\u8054\\u7f51/\\u65e0\\u7ebf\\u7f51\\u7edc/\\u79fb\\u52a8\\u7ec8\\u7aef/\\u5de5\\u63a7\\u7cfb\\u7edf/\\u53ef\\u4fe1\\u9a8c\\u8bc1\\u7b49\\uff09`,\n unknownNote: (n: number) =>\n `\\uff08${n} \\u9879\\u672a\\u68c0\\u67e5\\uff0c\\u5bf9\\u5e94\\u626b\\u63cf\\u6a21\\u5757\\u672a\\u8fd0\\u884c\\uff09`,\n cloudItemsNote: (n: number) =>\n `\\u4ee5\\u4e0b ${n} \\u9879\\u7531 AWS \\u4e91\\u5e73\\u53f0\\u8d1f\\u8d23\\uff0c\\u6839\\u636e\\u5b89\\u5168\\u8d23\\u4efb\\u5171\\u62c5\\u6a21\\u578b\\u4e0d\\u5728\\u672c\\u62a5\\u544a\\u68c0\\u67e5\\u8303\\u56f4\\u5185\\u3002`,\n mlpsFooterGenerated: (version: string) =>\n `\\u7531 AWS Security MCP Server v${version} \\u751f\\u6210`,\n mlpsFooterDisclaimer:\n \"\\u672c\\u62a5\\u544a\\u4e3a\\u8bc1\\u636e\\u6536\\u96c6\\u53c2\\u8003\\uff0c\\u4e0d\\u5305\\u542b\\u5408\\u89c4\\u5224\\u5b9a\\u3002\\u5b8c\\u6574\\u7b49\\u4fdd\\u6d4b\\u8bc4\\u9700\\u7531\\u6301\\u8bc1\\u6d4b\\u8bc4\\u673a\\u6784\\u6267\\u884c\\u3002\",\n andMore: (n: number) => `... \\u53ca\\u5176\\u4ed6 ${n} \\u9879`,\n remediationByPriority:\n \"\\u5efa\\u8bae\\u6574\\u6539\\u9879\\uff08\\u6309\\u4f18\\u5148\\u7ea7\\uff09\",\n affectedResources: (n: number) => `\\u6d89\\u53ca ${n} \\u4e2a\\u8d44\\u6e90`,\n installWindowsPatches: (n: number, kbs: string) => `\\u5b89\\u88c5 ${n} \\u4e2a Windows \\u8865\\u4e01 (${kbs})`,\n mlpsCategorySection: {\n \"\\u5b89\\u5168\\u7269\\u7406\\u73af\\u5883\": \"\\u4e00\\u3001\\u5b89\\u5168\\u7269\\u7406\\u73af\\u5883\",\n \"\\u5b89\\u5168\\u901a\\u4fe1\\u7f51\\u7edc\": \"\\u4e8c\\u3001\\u5b89\\u5168\\u901a\\u4fe1\\u7f51\\u7edc\",\n \"\\u5b89\\u5168\\u533a\\u57df\\u8fb9\\u754c\": \"\\u4e09\\u3001\\u5b89\\u5168\\u533a\\u57df\\u8fb9\\u754c\",\n \"\\u5b89\\u5168\\u8ba1\\u7b97\\u73af\\u5883\": \"\\u56db\\u3001\\u5b89\\u5168\\u8ba1\\u7b97\\u73af\\u5883\",\n \"\\u5b89\\u5168\\u7ba1\\u7406\\u4e2d\\u5fc3\": \"\\u4e94\\u3001\\u5b89\\u5168\\u7ba1\\u7406\\u4e2d\\u5fc3\",\n },\n\n // Module display names\n moduleNames: {\n service_detection: \"安全服务检测\",\n secret_exposure: \"密钥暴露\",\n ssl_certificate: \"SSL 证书\",\n dns_dangling: \"悬挂 DNS\",\n network_reachability: \"网络可达性\",\n iam_privilege_escalation: \"IAM 提权分析\",\n public_access_verify: \"公网访问验证\",\n tag_compliance: \"标签合规\",\n idle_resources: \"闲置资源\",\n disaster_recovery: \"灾备评估\",\n security_hub_findings: \"Security Hub\",\n guardduty_findings: \"GuardDuty\",\n inspector_findings: \"Inspector\",\n trusted_advisor_findings: \"Trusted Advisor\",\n config_rules_findings: \"Config Rules\",\n access_analyzer_findings: \"Access Analyzer\",\n patch_compliance_findings: \"补丁合规\",\n imdsv2_enforcement: \"IMDSv2 强制\",\n waf_coverage: \"WAF 覆盖\",\n // Security Hub sub-categories\n \"sh:FSBP\": \"安全最佳实践\",\n \"sh:Inspector\": \"软件漏洞\",\n \"sh:GuardDuty\": \"威胁检测\",\n \"sh:Config\": \"配置合规\",\n \"sh:Access Analyzer\": \"外部访问\",\n \"sh:Other\": \"其他安全发现\",\n },\n\n // Security Hub sub-categories\n securityHubSubCategories: {\n FSBP: { label: \"安全最佳实践\" },\n Inspector: { label: \"软件漏洞\" },\n GuardDuty: { label: \"威胁检测\" },\n Config: { label: \"配置合规\" },\n \"Access Analyzer\": { label: \"外部访问\" },\n Other: { label: \"其他安全发现\" },\n },\n\n // Service Recommendations\n notEnabled: \"\\u672a\\u542f\\u7528\",\n serviceRecommendations: {\n security_hub_findings: {\n icon: \"\\ud83d\\udd34\",\n service: \"Security Hub\",\n impact:\n \"\\u65e0\\u6cd5\\u83b7\\u53d6 300+ \\u9879\\u81ea\\u52a8\\u5316\\u5b89\\u5168\\u68c0\\u67e5\\uff08FSBP/CIS/PCI DSS \\u6807\\u51c6\\uff09\",\n action:\n \"\\u542f\\u7528 Security Hub \\u83b7\\u5f97\\u6700\\u5168\\u9762\\u7684\\u5b89\\u5168\\u6001\\u52bf\\u8bc4\\u4f30\",\n },\n guardduty_findings: {\n icon: \"\\ud83d\\udd34\",\n service: \"GuardDuty\",\n impact:\n \"\\u65e0\\u6cd5\\u68c0\\u6d4b\\u5a01\\u80c1\\u6d3b\\u52a8\\uff08\\u6076\\u610f IP\\u3001\\u5f02\\u5e38 API \\u8c03\\u7528\\u3001\\u52a0\\u5bc6\\u8d27\\u5e01\\u6316\\u77ff\\u7b49\\uff09\",\n action:\n \"\\u542f\\u7528 GuardDuty \\u83b7\\u5f97\\u6301\\u7eed\\u5a01\\u80c1\\u68c0\\u6d4b\\u80fd\\u529b\",\n },\n inspector_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"Inspector\",\n impact:\n \"\\u65e0\\u6cd5\\u626b\\u63cf EC2/Lambda/\\u5bb9\\u5668\\u7684\\u8f6f\\u4ef6\\u6f0f\\u6d1e\\uff08CVE\\uff09\",\n action:\n \"\\u542f\\u7528 Inspector \\u53d1\\u73b0\\u5df2\\u77e5\\u5b89\\u5168\\u6f0f\\u6d1e\",\n },\n trusted_advisor_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"Trusted Advisor\",\n impact:\n \"\\u65e0\\u6cd5\\u83b7\\u53d6 AWS \\u6700\\u4f73\\u5b9e\\u8df5\\u5b89\\u5168\\u68c0\\u67e5\",\n action:\n \"\\u5347\\u7ea7\\u81f3 Business/Enterprise Support \\u8ba1\\u5212\\u4ee5\\u4f7f\\u7528 Trusted Advisor \\u5b89\\u5168\\u68c0\\u67e5\",\n },\n config_rules_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"AWS Config\",\n impact:\n \"\\u65e0\\u6cd5\\u68c0\\u67e5\\u8d44\\u6e90\\u914d\\u7f6e\\u5408\\u89c4\\u72b6\\u6001\",\n action:\n \"\\u542f\\u7528 AWS Config \\u5e76\\u914d\\u7f6e Config Rules\",\n },\n access_analyzer_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"IAM Access Analyzer\",\n impact:\n \"\\u65e0\\u6cd5\\u68c0\\u6d4b\\u8d44\\u6e90\\u662f\\u5426\\u88ab\\u5916\\u90e8\\u8d26\\u53f7\\u6216\\u516c\\u7f51\\u8bbf\\u95ee\",\n action:\n \"\\u521b\\u5efa IAM Access Analyzer\\uff08\\u8d26\\u6237\\u7ea7\\u6216\\u7ec4\\u7ec7\\u7ea7\\uff09\",\n },\n patch_compliance_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"SSM Patch Manager\",\n impact:\n \"\\u65e0\\u6cd5\\u68c0\\u67e5\\u5b9e\\u4f8b\\u8865\\u4e01\\u5408\\u89c4\\u72b6\\u6001\",\n action:\n \"\\u5b89\\u88c5 SSM Agent \\u5e76\\u914d\\u7f6e Patch Manager\",\n },\n },\n\n // HW Checklist (full composite)\n hwChecklist: `\n\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\n\\ud83d\\udccb \\u62a4\\u7f51\\u884c\\u52a8\\u8865\\u5145\\u63d0\\u9192\\uff08\\u8d85\\u51fa\\u81ea\\u52a8\\u5316\\u626b\\u63cf\\u8303\\u56f4\\uff09\n\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\n\n\\u4ee5\\u4e0b\\u4e8b\\u9879\\u9700\\u8981\\u4eba\\u5de5\\u786e\\u8ba4\\u548c\\u6267\\u884c\\uff1a\n\n\\u26a0\\ufe0f \\u5e94\\u6025\\u9694\\u79bb/\\u6b62\\u8840\\u65b9\\u6848\n \\u25a1 \\u51c6\\u5907\\u4e13\\u7528\\u9694\\u79bb\\u5b89\\u5168\\u7ec4\\uff08\\u65e0 Inbound/Outbound \\u89c4\\u5219\\uff09\n \\u25a1 \\u5236\\u5b9a\\u5b9e\\u4f8b\\u9694\\u79bb SOP\\uff1a\\u544a\\u8b66 \\u2192 \\u6392\\u67e5 \\u2192 \\u5c01\\u9501\\u653b\\u51fbIP \\u2192 \\u7f51\\u7edc\\u9694\\u79bb \\u2192 \\u5b89\\u5168\\u5904\\u7f6e \\u2192 \\u8bb0\\u5f55\\u653b\\u51fb\\u9879\n \\u25a1 \\u660e\\u786e\\u5404\\u7cfb\\u7edf\\uff08\\u751f\\u4ea7\\u6838\\u5fc3/\\u751f\\u4ea7\\u975e\\u6838\\u5fc3/\\u6d4b\\u8bd5/\\u5f00\\u53d1\\uff09\\u7684\\u5e94\\u6025\\u5904\\u7f6e\\u65b9\\u5f0f\n \\u25a1 \\u660e\\u786e\\u5404\\u9879\\u76ee\\u8d26\\u6237\\u53ca\\u8d44\\u6e90\\u7684\\u8d1f\\u8d23\\u4eba\\u4e0e\\u8054\\u7cfb\\u65b9\\u5f0f\n\n\\u26a0\\ufe0f \\u6d4b\\u8bd5/\\u5f00\\u53d1\\u73af\\u5883\\u5904\\u7f6e\n \\u25a1 \\u975e\\u6838\\u5fc3\\u7cfb\\u7edf\\u5728\\u62a4\\u7f51\\u671f\\u95f4\\u5173\\u95ed\n \\u25a1 \\u6d4b\\u8bd5/\\u5f00\\u53d1\\u73af\\u5883\\u5173\\u95ed\\u6216\\u4e0e\\u751f\\u4ea7\\u4fdd\\u6301\\u540c\\u7b49\\u5b89\\u5168\\u57fa\\u7ebf\n \\u25a1 \\u786e\\u8ba4\\u54ea\\u4e9b\\u73af\\u5883\\u53ef\\u4ee5\\u7d27\\u6025\\u5173\\u505c\\uff0c\\u907f\\u514d\\u653b\\u51fb\\u6269\\u6563\n\n\\u26a0\\ufe0f \\u503c\\u5b88\\u56e2\\u961f\\u7ec4\\u5efa\n \\u25a1 7\\u00d724 \\u76d1\\u63a7\\u5feb\\u901f\\u54cd\\u5e94\\u56e2\\u961f\n \\u25a1 \\u6280\\u672f\\u4e0e\\u98ce\\u9669\\u5206\\u6790\\u7ec4\n \\u25a1 \\u5b89\\u5168\\u7b56\\u7565\\u4e0b\\u53d1\\u7ec4\n \\u25a1 \\u4e1a\\u52a1\\u54cd\\u5e94\\u7ec4\n \\u25a1 \\u660e\\u786e AWS TAM/Support \\u8054\\u7cfb\\u65b9\\u5f0f\\uff08ES/EOP \\u5ba2\\u6237\\uff09\n\n\\u26a0\\ufe0f \\u51fa\\u5165\\u7ad9\\u8def\\u5f84\\u67b6\\u6784\\u56fe\n \\u25a1 \\u786e\\u4fdd\\u6240\\u6709\\u4e92\\u8054\\u7f51/DX \\u4e13\\u7ebf\\u51fa\\u5165\\u7ad9\\u8def\\u5f84\\u5728\\u67b6\\u6784\\u56fe\\u4e2d\\u6e05\\u6670\\u6807\\u6ce8\n \\u25a1 \\u660e\\u786e\\u5404 ELB/Public EC2/S3/DX \\u7684\\u6570\\u636e\\u6d41\\u5411\n \\u25a1 \\u8bc6\\u522b\\u6240\\u6709\\u9762\\u5411\\u4e92\\u8054\\u7f51\\u7684\\u6570\\u636e\\u4ea4\\u4e92\\u63a5\\u53e3\n\n\\u26a0\\ufe0f \\u4e3b\\u52a8\\u5f0f\\u6e17\\u900f\\u6d4b\\u8bd5\n \\u25a1 \\u62a4\\u7f51\\u524d\\u8054\\u7cfb\\u5b89\\u5168\\u5382\\u5546\\uff08\\u9752\\u85e4/\\u957f\\u4ead/\\u5fae\\u6b65\\u7b49\\uff09\\u8fdb\\u884c\\u6a21\\u62df\\u653b\\u51fb\\u6f14\\u7ec3\n \\u25a1 \\u57fa\\u4e8e\\u6e17\\u900f\\u6d4b\\u8bd5\\u62a5\\u544a\\u8fdb\\u884c\\u6b63\\u5f0f\\u62a4\\u7f51\\u524d\\u7684\\u5b89\\u5168\\u52a0\\u56fa\n \\u25a1 \\u5173\\u6ce8 AWS \\u5b89\\u5168\\u516c\\u544a\\uff08\\u5df2\\u77e5\\u6f0f\\u6d1e\\u4e0e\\u8865\\u4e01\\uff09\n\n\\u26a0\\ufe0f WAR-ROOM \\u5b9e\\u65f6\\u6c9f\\u901a\n \\u25a1 \\u521b\\u5efa\\u62a4\\u7f51\\u671f\\u95f4\\u4e13\\u7528\\u6c9f\\u901a\\u6e20\\u9053\\uff08\\u4f01\\u5fae/\\u9489\\u9489/\\u98de\\u4e66/Chime\\uff09\n \\u25a1 \\u4e0e AWS TAM \\u5efa\\u7acb WAR-ROOM \\u8054\\u7cfb\\uff08\\u4f01\\u4e1a\\u7ea7\\u652f\\u6301\\u5ba2\\u6237\\uff09\n \\u25a1 \\u7edf\\u4e00\\u6848\\u4f8b\\u6807\\u9898\\u683c\\u5f0f\\uff1a\\u201c\\u3010\\u62a4\\u7f51\\u3011+ \\u95ee\\u9898\\u63cf\\u8ff0\\u201d\n\n\\u26a0\\ufe0f \\u5bc6\\u7801\\u4e0e\\u51ed\\u8bc1\\u7ba1\\u7406\n \\u25a1 \\u6240\\u6709 IAM \\u7528\\u6237\\u7ed1\\u5b9a MFA\n \\u25a1 AKSK \\u8f6e\\u8f6c\\u5468\\u671f \\u2264 90 \\u5929\n \\u25a1 \\u907f\\u514d\\u5171\\u4eab\\u8d26\\u6237\\u4f7f\\u7528\n \\u25a1 S3/Lambda/\\u5e94\\u7528\\u4ee3\\u7801\\u4e2d\\u65e0\\u660e\\u6587\\u5bc6\\u7801\n\n\\u26a0\\ufe0f \\u62a4\\u7f51\\u540e\\u4f18\\u5316\n \\u25a1 \\u9488\\u5bf9\\u653b\\u51fb\\u62a5\\u544a\\u9010\\u9879\\u5e94\\u7b54\\u4e0e\\u4fee\\u590d\n \\u25a1 \\u4e0e\\u5b89\\u5168\\u56e2\\u961f\\u5efa\\u7acb\\u5468\\u671f\\u6027\\u5b89\\u5168\\u7ef4\\u62a4\\u6d41\\u7a0b\n \\u25a1 \\u6301\\u7eed\\u8865\\u5168\\u5b89\\u5168\\u98ce\\u9669\n\n\\u53c2\\u8003\\uff1aAWS \\u62a4\\u7f51\\u884c\\u52a8 Standard Operation Procedure (Compliance IEM)\n`,\n};\n","import type { I18n } from \"./index.js\";\n\nexport const enI18n: I18n = {\n // HTML Security Report\n securityReportTitle: \"AWS Security Scan Report\",\n securityScore: \"Security Score\",\n critical: \"Critical\",\n high: \"High\",\n medium: \"Medium\",\n low: \"Low\",\n scanStatistics: \"Scan Statistics\",\n module: \"Module\",\n resources: \"Resources\",\n findings: \"Findings\",\n status: \"Status\",\n allFindings: \"All Findings\",\n recommendations: \"Recommendations\",\n unique: \"unique\",\n showMore: \"Show more\",\n noIssuesFound: \"No security issues found.\",\n allModulesClean: \"All modules clean\",\n generatedBy: \"Generated by AWS Security MCP Server\",\n informationalOnly: \"This report is for informational purposes only.\",\n\n // MLPS Report\n mlpsTitle: \"MLPS Level 3 Pre-Check Report\",\n mlpsDisclaimer:\n \"This report is for MLPS Level 3 pre-check reference, providing cloud platform configuration check data and recommendations. Compliance determination (compliant/partially compliant/non-compliant) must be confirmed by a certified assessment institution. (GB/T 22239-2019 full checklist: 184 items)\",\n checkedItems: \"Checked Items\",\n noIssues: \"No Issues Found\",\n issuesFound: \"Issues Found\",\n notChecked: \"Not Checked\",\n cloudProvider: \"Cloud Provider Responsible\",\n manualReview: \"Manual Review Required\",\n notApplicable: \"Not Applicable\",\n checkResult: \"Check Result\",\n noRelatedIssues: \"Check Result: No related issues found\",\n issuesFoundCount: (n: number) =>\n `Check Result: Found ${n} related issue${n === 1 ? \"\" : \"s\"}`,\n remediation: \"Remediation\",\n remediationItems: (n: number) =>\n `Remediation Items (${n} unique)`,\n showRemaining: (n: number) => `Show remaining ${n} items`,\n\n // HW Defense Checklist\n hwChecklistTitle:\n \"\\ud83d\\udccb Cyber Defense Drill Supplementary Reminders (Beyond Automated Scanning)\",\n hwChecklistSubtitle:\n \"The following items require manual verification and execution:\",\n hwEmergencyIsolation: `\\u26a0\\ufe0f Emergency Isolation / Incident Response Plan\n \\u25a1 Prepare dedicated isolation security groups (no Inbound/Outbound rules)\n \\u25a1 Establish instance isolation SOP: Alert \\u2192 Investigate \\u2192 Block attacker IP \\u2192 Network isolation \\u2192 Security response \\u2192 Log attack details\n \\u25a1 Define emergency response procedures for each system (production core/non-core/test/dev)\n \\u25a1 Identify responsible personnel and contacts for each project account and resource`,\n hwTestEnvShutdown: `\\u26a0\\ufe0f Test/Development Environment Handling\n \\u25a1 Shut down non-critical systems during the drill period\n \\u25a1 Shut down test/dev environments or maintain same security baseline as production\n \\u25a1 Confirm which environments can be emergency-stopped to prevent attack propagation`,\n hwDutyTeam: `\\u26a0\\ufe0f On-Duty Team Formation\n \\u25a1 7\\u00d724 monitoring and rapid response team\n \\u25a1 Technical and risk analysis team\n \\u25a1 Security policy deployment team\n \\u25a1 Business response team\n \\u25a1 Confirm AWS TAM/Support contact information (ES/EOP customers)`,\n hwNetworkDiagram: `\\u26a0\\ufe0f Ingress/Egress Path Architecture Diagram\n \\u25a1 Ensure all Internet/DX dedicated line ingress/egress paths are clearly marked in architecture diagrams\n \\u25a1 Clarify data flow for each ELB/Public EC2/S3/DX\n \\u25a1 Identify all internet-facing data interaction interfaces`,\n hwPentest: `\\u26a0\\ufe0f Proactive Penetration Testing\n \\u25a1 Contact security vendors for simulated attack drills before the exercise\n \\u25a1 Conduct security hardening based on penetration test reports\n \\u25a1 Monitor AWS security advisories (known vulnerabilities and patches)`,\n hwWarRoom: `\\u26a0\\ufe0f WAR-ROOM Real-Time Communication\n \\u25a1 Create dedicated communication channels for the drill period (Teams/Slack/Chime)\n \\u25a1 Establish WAR-ROOM connection with AWS TAM (Enterprise Support customers)\n \\u25a1 Standardize case title format: \"[CyberDrill] + Issue Description\"`,\n hwCredentials: `\\u26a0\\ufe0f Password & Credential Management\n \\u25a1 All IAM users must have MFA enabled\n \\u25a1 Access key rotation cycle \\u2264 90 days\n \\u25a1 Avoid shared account usage\n \\u25a1 No plaintext passwords in S3/Lambda/application code`,\n hwPostOptimization: `\\u26a0\\ufe0f Post-Drill Optimization\n \\u25a1 Address and remediate each item from the attack report\n \\u25a1 Establish periodic security maintenance processes with the security team\n \\u25a1 Continuously fill security risk gaps`,\n hwReference:\n \"Reference: AWS Cyber Defense Drill Standard Operation Procedure (Compliance IEM)\",\n\n // Service Reminders\n serviceReminderTitle:\n \"\\u26a1 The following security services are not enabled; some checks cannot be performed:\",\n serviceReminderFooter:\n \"Re-scan after enabling the above services for a more complete security assessment.\",\n serviceImpact: \"Impact\",\n serviceAction: \"Action\",\n\n // Common\n account: \"Account\",\n region: \"Region\",\n scanTime: \"Scan Time\",\n duration: \"Duration\",\n severityDistribution: \"Severity Distribution\",\n findingsByModule: \"Findings by Module\",\n details: \"Details\",\n\n // Extended \\u2014 HTML Security Report extras\n topHighestRiskFindings: (n: number) =>\n `Top ${n} Highest Risk Findings`,\n resource: \"Resource\",\n impact: \"Impact\",\n riskScore: \"Risk Score\",\n showRemainingFindings: (n: number) =>\n `Show remaining ${n} findings\\u2026`,\n trendTitle: \"30-Day Trends\",\n findingsBySeverity: \"Findings by Severity\",\n showMoreCount: (n: number) =>\n `Show ${n} more\\u2026`,\n\n // Filter toolbar\n filterSeverity: \"Severity:\",\n filterModule: \"Module:\",\n filterAll: \"All\",\n filterAllModules: \"All Modules\",\n filterCountTpl: \"Showing {shown} / {total} findings\",\n\n // Extended \\u2014 MLPS extras\n // Markdown report\n executiveSummary: \"Executive Summary\",\n totalFindingsLabel: \"Total Findings\",\n description: \"Description\",\n priority: \"Priority\",\n noFindingsForSeverity: (severity: string) => `No ${severity.toLowerCase()} findings.`,\n\n preCheckOverview: \"Pre-Check Overview\",\n accountInfo: \"Account Information\",\n checkedCount: (total: number, clean: number, issues: number) =>\n `Checked: ${total} items (No issues: ${clean} | Issues found: ${issues})`,\n uncheckedCount: (n: number) =>\n `Not checked: ${n} items (corresponding scan modules not run)`,\n cloudProviderCount: (n: number) =>\n `Cloud provider responsible: ${n} items`,\n manualReviewCount: (n: number) =>\n `Manual review required: ${n} items`,\n naCount: (n: number) => `Not applicable: ${n} items`,\n naNote: (n: number) =>\n `Not applicable: ${n} items (IoT/wireless networks/mobile terminals/ICS/trusted verification, etc.)`,\n unknownNote: (n: number) =>\n `(${n} items not checked \\u2014 corresponding scan modules not run)`,\n cloudItemsNote: (n: number) =>\n `The following ${n} items are the responsibility of the AWS cloud platform and are outside the scope of this report per the shared responsibility model.`,\n mlpsFooterGenerated: (version: string) =>\n `Generated by AWS Security MCP Server v${version}`,\n mlpsFooterDisclaimer:\n \"This report is for evidence collection reference and does not include compliance determination. A complete MLPS assessment must be conducted by a certified assessment institution.\",\n andMore: (n: number) => `\\u2026 and ${n} more`,\n remediationByPriority: \"Remediation Items (by Priority)\",\n affectedResources: (n: number) => `${n} resource${n === 1 ? \"\" : \"s\"} affected`,\n installWindowsPatches: (n: number, kbs: string) => `Install ${n} Windows patch${n === 1 ? \"\" : \"es\"} (${kbs})`,\n mlpsCategorySection: {\n \"\\u5b89\\u5168\\u7269\\u7406\\u73af\\u5883\": \"I. Physical Environment Security\",\n \"\\u5b89\\u5168\\u901a\\u4fe1\\u7f51\\u7edc\": \"II. Communication Network Security\",\n \"\\u5b89\\u5168\\u533a\\u57df\\u8fb9\\u754c\": \"III. Area Boundary Security\",\n \"\\u5b89\\u5168\\u8ba1\\u7b97\\u73af\\u5883\": \"IV. Computing Environment Security\",\n \"\\u5b89\\u5168\\u7ba1\\u7406\\u4e2d\\u5fc3\": \"V. Security Management Center\",\n },\n\n // Module display names\n moduleNames: {\n service_detection: \"Security Service Detection\",\n secret_exposure: \"Secret Exposure\",\n ssl_certificate: \"SSL Certificate\",\n dns_dangling: \"Dangling DNS\",\n network_reachability: \"Network Reachability\",\n iam_privilege_escalation: \"IAM Privilege Escalation\",\n public_access_verify: \"Public Access Verification\",\n tag_compliance: \"Tag Compliance\",\n idle_resources: \"Idle Resources\",\n disaster_recovery: \"Disaster Recovery\",\n security_hub_findings: \"Security Hub\",\n guardduty_findings: \"GuardDuty\",\n inspector_findings: \"Inspector\",\n trusted_advisor_findings: \"Trusted Advisor\",\n config_rules_findings: \"Config Rules\",\n access_analyzer_findings: \"Access Analyzer\",\n patch_compliance_findings: \"Patch Compliance\",\n imdsv2_enforcement: \"IMDSv2 Enforcement\",\n waf_coverage: \"WAF Coverage\",\n // Security Hub sub-categories\n \"sh:FSBP\": \"Security Best Practices\",\n \"sh:Inspector\": \"Software Vulnerabilities\",\n \"sh:GuardDuty\": \"Threat Detection\",\n \"sh:Config\": \"Configuration Compliance\",\n \"sh:Access Analyzer\": \"External Access\",\n \"sh:Other\": \"Other Security Findings\",\n },\n\n // Security Hub sub-categories\n securityHubSubCategories: {\n FSBP: { label: \"Security Best Practices\" },\n Inspector: { label: \"Software Vulnerabilities\" },\n GuardDuty: { label: \"Threat Detection\" },\n Config: { label: \"Configuration Compliance\" },\n \"Access Analyzer\": { label: \"External Access\" },\n Other: { label: \"Other Security Findings\" },\n },\n\n // Service Recommendations\n notEnabled: \"Not Enabled\",\n serviceRecommendations: {\n security_hub_findings: {\n icon: \"\\ud83d\\udd34\",\n service: \"Security Hub\",\n impact:\n \"Cannot obtain 300+ automated security checks (FSBP/CIS/PCI DSS standards)\",\n action:\n \"Enable Security Hub for the most comprehensive security posture assessment\",\n },\n guardduty_findings: {\n icon: \"\\ud83d\\udd34\",\n service: \"GuardDuty\",\n impact:\n \"Cannot detect threat activity (malicious IPs, anomalous API calls, crypto mining, etc.)\",\n action:\n \"Enable GuardDuty for continuous threat detection\",\n },\n inspector_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"Inspector\",\n impact:\n \"Cannot scan EC2/Lambda/container software vulnerabilities (CVEs)\",\n action:\n \"Enable Inspector to discover known security vulnerabilities\",\n },\n trusted_advisor_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"Trusted Advisor\",\n impact:\n \"Cannot obtain AWS best practice security checks\",\n action:\n \"Upgrade to Business/Enterprise Support plan to use Trusted Advisor security checks\",\n },\n config_rules_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"AWS Config\",\n impact:\n \"Cannot check resource configuration compliance status\",\n action:\n \"Enable AWS Config and configure Config Rules\",\n },\n access_analyzer_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"IAM Access Analyzer\",\n impact:\n \"Cannot detect whether resources are accessed by external accounts or public networks\",\n action:\n \"Create IAM Access Analyzer (account-level or organization-level)\",\n },\n patch_compliance_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"SSM Patch Manager\",\n impact:\n \"Cannot check instance patch compliance status\",\n action:\n \"Install SSM Agent and configure Patch Manager\",\n },\n },\n\n // HW Checklist (full composite)\n hwChecklist: `\n\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\n\\ud83d\\udccb Cyber Defense Drill Supplementary Reminders (Beyond Automated Scanning)\n\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\n\nThe following items require manual verification and execution:\n\n\\u26a0\\ufe0f Emergency Isolation / Incident Response Plan\n \\u25a1 Prepare dedicated isolation security groups (no Inbound/Outbound rules)\n \\u25a1 Establish instance isolation SOP: Alert \\u2192 Investigate \\u2192 Block attacker IP \\u2192 Network isolation \\u2192 Security response \\u2192 Log attack details\n \\u25a1 Define emergency response procedures for each system (production core/non-core/test/dev)\n \\u25a1 Identify responsible personnel and contacts for each project account and resource\n\n\\u26a0\\ufe0f Test/Development Environment Handling\n \\u25a1 Shut down non-critical systems during the drill period\n \\u25a1 Shut down test/dev environments or maintain same security baseline as production\n \\u25a1 Confirm which environments can be emergency-stopped to prevent attack propagation\n\n\\u26a0\\ufe0f On-Duty Team Formation\n \\u25a1 7\\u00d724 monitoring and rapid response team\n \\u25a1 Technical and risk analysis team\n \\u25a1 Security policy deployment team\n \\u25a1 Business response team\n \\u25a1 Confirm AWS TAM/Support contact information (ES/EOP customers)\n\n\\u26a0\\ufe0f Ingress/Egress Path Architecture Diagram\n \\u25a1 Ensure all Internet/DX dedicated line ingress/egress paths are clearly marked in architecture diagrams\n \\u25a1 Clarify data flow for each ELB/Public EC2/S3/DX\n \\u25a1 Identify all internet-facing data interaction interfaces\n\n\\u26a0\\ufe0f Proactive Penetration Testing\n \\u25a1 Contact security vendors for simulated attack drills before the exercise\n \\u25a1 Conduct security hardening based on penetration test reports\n \\u25a1 Monitor AWS security advisories (known vulnerabilities and patches)\n\n\\u26a0\\ufe0f WAR-ROOM Real-Time Communication\n \\u25a1 Create dedicated communication channels for the drill period (Teams/Slack/Chime)\n \\u25a1 Establish WAR-ROOM connection with AWS TAM (Enterprise Support customers)\n \\u25a1 Standardize case title format: \"[CyberDrill] + Issue Description\"\n\n\\u26a0\\ufe0f Password & Credential Management\n \\u25a1 All IAM users must have MFA enabled\n \\u25a1 Access key rotation cycle \\u2264 90 days\n \\u25a1 Avoid shared account usage\n \\u25a1 No plaintext passwords in S3/Lambda/application code\n\n\\u26a0\\ufe0f Post-Drill Optimization\n \\u25a1 Address and remediate each item from the attack report\n \\u25a1 Establish periodic security maintenance processes with the security team\n \\u25a1 Continuously fill security risk gaps\n\nReference: AWS Cyber Defense Drill Standard Operation Procedure (Compliance IEM)\n`,\n};\n","export type Lang = \"zh\" | \"en\";\n\nexport interface I18n {\n // HTML Security Report\n securityReportTitle: string;\n securityScore: string;\n critical: string;\n high: string;\n medium: string;\n low: string;\n scanStatistics: string;\n module: string;\n resources: string;\n findings: string;\n status: string;\n allFindings: string;\n recommendations: string;\n unique: string;\n showMore: string;\n noIssuesFound: string;\n allModulesClean: string;\n generatedBy: string;\n informationalOnly: string;\n\n // MLPS Report\n mlpsTitle: string;\n mlpsDisclaimer: string;\n checkedItems: string;\n noIssues: string;\n issuesFound: string;\n notChecked: string;\n cloudProvider: string;\n manualReview: string;\n notApplicable: string;\n checkResult: string;\n noRelatedIssues: string;\n issuesFoundCount: (n: number) => string;\n remediation: string;\n remediationItems: (n: number) => string;\n showRemaining: (n: number) => string;\n\n // HW Defense Checklist\n hwChecklistTitle: string;\n hwChecklistSubtitle: string;\n hwEmergencyIsolation: string;\n hwTestEnvShutdown: string;\n hwDutyTeam: string;\n hwNetworkDiagram: string;\n hwPentest: string;\n hwWarRoom: string;\n hwCredentials: string;\n hwPostOptimization: string;\n hwReference: string;\n\n // Service Reminders\n serviceReminderTitle: string;\n serviceReminderFooter: string;\n serviceImpact: string;\n serviceAction: string;\n\n // Common\n account: string;\n region: string;\n scanTime: string;\n duration: string;\n severityDistribution: string;\n findingsByModule: string;\n details: string;\n\n // ---------------------------------------------------------------------------\n // Extended fields (beyond the base interface spec) needed for full coverage\n // ---------------------------------------------------------------------------\n\n // HTML Security Report extras\n topHighestRiskFindings: (n: number) => string;\n resource: string;\n impact: string;\n riskScore: string;\n showRemainingFindings: (n: number) => string;\n trendTitle: string;\n findingsBySeverity: string;\n showMoreCount: (n: number) => string;\n\n // Filter toolbar\n filterSeverity: string;\n filterModule: string;\n filterAll: string;\n filterAllModules: string;\n filterCountTpl: string;\n\n // Markdown report\n executiveSummary: string;\n totalFindingsLabel: string;\n description: string;\n priority: string;\n noFindingsForSeverity: (severity: string) => string;\n\n // MLPS extras\n preCheckOverview: string;\n accountInfo: string;\n checkedCount: (total: number, clean: number, issues: number) => string;\n uncheckedCount: (n: number) => string;\n cloudProviderCount: (n: number) => string;\n manualReviewCount: (n: number) => string;\n naCount: (n: number) => string;\n naNote: (n: number) => string;\n unknownNote: (n: number) => string;\n cloudItemsNote: (n: number) => string;\n mlpsFooterGenerated: (version: string) => string;\n mlpsFooterDisclaimer: string;\n andMore: (n: number) => string;\n remediationByPriority: string;\n affectedResources: (n: number) => string;\n installWindowsPatches: (n: number, kbs: string) => string;\n mlpsCategorySection: Record<string, string>;\n\n // Module display names (unified across all report formats)\n moduleNames: Record<string, string>;\n\n // Security Hub sub-categories\n securityHubSubCategories: Record<string, { label: string }>;\n\n // Service recommendations (per service)\n notEnabled: string;\n serviceRecommendations: Record<\n string,\n { icon: string; service: string; impact: string; action: string }\n >;\n\n // HW Checklist (full composite text)\n hwChecklist: string;\n}\n\nimport { zhI18n } from \"./zh.js\";\nimport { enI18n } from \"./en.js\";\n\nconst translations: Record<Lang, I18n> = {\n zh: zhI18n,\n en: enI18n,\n};\n\nexport function getI18n(lang: Lang = \"zh\"): I18n {\n return translations[lang] ?? translations.zh;\n}\n","import type { FullScanResult, Finding, Severity } from \"../types.js\";\nimport { getI18n, type Lang } from \"../i18n/index.js\";\n\nconst SEVERITY_ICON: Record<Severity, string> = {\n CRITICAL: \"\\ud83d\\udd34\",\n HIGH: \"\\ud83d\\udfe0\",\n MEDIUM: \"\\ud83d\\udfe1\",\n LOW: \"\\ud83d\\udfe2\",\n};\n\nconst SEVERITY_ORDER: Severity[] = [\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"];\n\nfunction formatDuration(start: string, end: string): string {\n const ms = new Date(end).getTime() - new Date(start).getTime();\n if (ms < 1000) return `${ms}ms`;\n const secs = Math.round(ms / 1000);\n if (secs < 60) return `${secs}s`;\n const mins = Math.floor(secs / 60);\n const remainSecs = secs % 60;\n return `${mins}m ${remainSecs}s`;\n}\n\nexport function generateMarkdownReport(scanResults: FullScanResult, lang?: Lang): string {\n const t = getI18n(lang ?? \"zh\");\n const { summary, modules, accountId, region, scanStart, scanEnd } =\n scanResults;\n const date = scanStart.split(\"T\")[0];\n const duration = formatDuration(scanStart, scanEnd);\n\n const sevLabel: Record<Severity, string> = {\n CRITICAL: t.critical,\n HIGH: t.high,\n MEDIUM: t.medium,\n LOW: t.low,\n };\n\n function renderFinding(f: Finding): string {\n const steps = f.remediationSteps\n .map((s, i) => ` ${i + 1}. ${s}`)\n .join(\"\\n\");\n\n return [\n `#### ${f.title}`,\n `- **${t.resource}:** ${f.resourceId} (\\`${f.resourceArn}\\`)`,\n `- **${t.description}:** ${f.description}`,\n `- **${t.impact}:** ${f.impact}`,\n `- **${t.riskScore}:** ${f.riskScore}/10`,\n `- **${t.remediation}:**`,\n steps,\n `- **${t.priority}:** ${f.priority}`,\n ].join(\"\\n\");\n }\n\n const lines: string[] = [];\n\n lines.push(`# ${t.securityReportTitle} \\u2014 ${date}`);\n lines.push(\"\");\n\n // Executive Summary\n lines.push(`## ${t.executiveSummary}`);\n lines.push(`- **${t.account}:** ${accountId}`);\n lines.push(`- **${t.region}:** ${region}`);\n lines.push(`- **${t.duration}:** ${duration}`);\n lines.push(\n `- **${t.totalFindingsLabel}:** ${summary.totalFindings} (${SEVERITY_ICON.CRITICAL} ${summary.critical} ${t.critical} | ${SEVERITY_ICON.HIGH} ${summary.high} ${t.high} | ${SEVERITY_ICON.MEDIUM} ${summary.medium} ${t.medium} | ${SEVERITY_ICON.LOW} ${summary.low} ${t.low})`,\n );\n lines.push(\"\");\n\n // Edge case: no findings\n if (summary.totalFindings === 0) {\n lines.push(`## ${t.findingsBySeverity}`);\n lines.push(\"\");\n lines.push(`\\u2705 ${t.noIssuesFound}`);\n lines.push(\"\");\n } else {\n // Collect all findings\n const allFindings: Finding[] = modules.flatMap((m) => m.findings);\n\n // Group by severity\n const grouped = new Map<Severity, Finding[]>();\n for (const sev of SEVERITY_ORDER) {\n grouped.set(sev, []);\n }\n for (const f of allFindings) {\n grouped.get(f.severity)!.push(f);\n }\n\n lines.push(`## ${t.findingsBySeverity}`);\n lines.push(\"\");\n\n for (const sev of SEVERITY_ORDER) {\n const findings = grouped.get(sev)!;\n const icon = SEVERITY_ICON[sev];\n lines.push(`### ${icon} ${sevLabel[sev]}`);\n lines.push(\"\");\n\n if (findings.length === 0) {\n lines.push(t.noFindingsForSeverity(sevLabel[sev]));\n lines.push(\"\");\n continue;\n }\n\n // Sort by riskScore descending\n findings.sort((a, b) => b.riskScore - a.riskScore);\n for (const f of findings) {\n lines.push(renderFinding(f));\n lines.push(\"\");\n }\n }\n }\n\n // Scan Statistics\n lines.push(`## ${t.scanStatistics}`);\n lines.push(\n `| ${t.module} | ${t.resources} | ${t.findings} | ${t.status} |`,\n );\n lines.push(\"|--------|------------------|----------|--------|\");\n for (const m of modules) {\n const status = m.status === \"success\" ? \"\\u2705\" : \"\\u274c\";\n lines.push(\n `| ${t.moduleNames[m.module] ?? m.module} | ${m.resourcesScanned} | ${m.findingsCount} | ${status} |`,\n );\n }\n lines.push(\"\");\n\n // Recommendations\n if (summary.totalFindings > 0) {\n const allFindings: Finding[] = modules.flatMap((m) => m.findings);\n allFindings.sort((a, b) => b.riskScore - a.riskScore);\n\n lines.push(`## ${t.recommendations}`);\n for (let i = 0; i < allFindings.length; i++) {\n const f = allFindings[i];\n lines.push(`${i + 1}. [${f.priority}] ${f.title}: ${f.remediationSteps[0] ?? \"Review and remediate.\"}`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n","[\n {\n \"id\": \"L3-PES1-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"物理位置选择\",\n \"controlEn\": \"Physical Location Alteration\",\n \"requirementCn\": \"机房场地应选择在具有防震、防风和防雨等能力的建筑内\",\n \"requirementEn\": \"The computer room should be located in buildings with the ability to be shockproof, windproof and rainproof\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-02\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"物理位置选择\",\n \"controlEn\": \"Physical Location Alteration\",\n \"requirementCn\": \"机房场地应避免设在建筑物的顶层或地下室,否则应加强防水和防潮措施\",\n \"requirementEn\": \"The computer room should avoid being located at the top of the building or the basement, otherwise waterproof and moisture-proof measures should be strengthened.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-03\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"物理访问控制\",\n \"controlEn\": \"Physical Access Control\",\n \"requirementCn\": \"机房出入口应配置电子门禁系统,控制、鉴别和记录进入的人员\",\n \"requirementEn\": \"Entrance and exit of the computer room should be equipped with an electronic access control system to control, identify and record the incoming personnel.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-04\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防盗窃和防破坏\",\n \"controlEn\": \"Anti-theft and Anti-vandalism\",\n \"requirementCn\": \"应将设备或主要部件进行固定,并设置明显的不易除去的标识\",\n \"requirementEn\": \"Device or main components should be fixed and marked with obvious labels that are difficult to remove\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-05\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防盗窃和防破坏\",\n \"controlEn\": \"Anti-theft and Anti-vandalism\",\n \"requirementCn\": \"应将通信线缆铺设在隐蔽安全处\",\n \"requirementEn\": \"The communication cable should be laid in a safe and concealed place\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-06\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防盗窃和防破坏\",\n \"controlEn\": \"Anti-theft and Anti-vandalism\",\n \"requirementCn\": \"应设置机房防盗报警系统或设置有专人值守的视频监控系统\",\n \"requirementEn\": \"A computer room anti-theft alarm system or a video surveillance system with a special person should be set up.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-07\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防雷击\",\n \"controlEn\": \"Lightning Protection\",\n \"requirementCn\": \"应将各类机柜、设施和设备等通过接地系统安全接地\",\n \"requirementEn\": \"All types of cabinets, facilities and equipment should be safely grounded through the grounding system\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-08\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防雷击\",\n \"controlEn\": \"Lightning Protection\",\n \"requirementCn\": \"应采取措施防止感应雷,例如设置防雷保安器或过压保护装置等\",\n \"requirementEn\": \"Measures should be taken to prevent inductive lightning, such as set up lightning protection or overvoltage protection devices.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-09\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防火\",\n \"controlEn\": \"Fire Protection\",\n \"requirementCn\": \"机房应设置火灾自动消防系统,能够自动检测火情、自动报警,并自动灭火\",\n \"requirementEn\": \"Automatic fire protection system which can automatically detect, alarm and extinguish should be set up.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-10\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防火\",\n \"controlEn\": \"Fire Protection\",\n \"requirementCn\": \"机房及相关的工作房间和辅助房应采用具有耐火等级的建筑材料\",\n \"requirementEn\": \"The computer room and related work rooms and auxiliary rooms shall be constructed of fire-resistant building materials\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-11\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防火\",\n \"controlEn\": \"Fire Protection\",\n \"requirementCn\": \"应对机房划分区域进行管理,区域和区域之间设置隔离防火措施\",\n \"requirementEn\": \"The computer room should be managed dividedly, and set fire prevention measures for each region\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-12\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防水和防潮\",\n \"controlEn\": \"Waterproof and Moisture Proof\",\n \"requirementCn\": \"应采取措施防止雨水通过机房窗户、屋顶和墙壁渗透\",\n \"requirementEn\": \"Measures should be taken to avoid rainwater penetrating through the windows, roof and walls of the computer room\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-13\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防水和防潮\",\n \"controlEn\": \"Waterproof and Moisture Proof\",\n \"requirementCn\": \"应采取措施防止机房内水蒸气结露和地下积水的转移与渗透\",\n \"requirementEn\": \"Measures should be taken to prevent water vapor condensation, and to prevent transfer and penetration of underground water in the computer room\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-14\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防水和防潮\",\n \"controlEn\": \"Waterproof and Moisture Proof\",\n \"requirementCn\": \"应安装对水敏感的检测仪表或元件,对机房进行防水检测和报警\",\n \"requirementEn\": \"Water-sensitive detection instruments or components should be installed to conduct waterproof detection and alarm for the computer room.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-15\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防静电\",\n \"controlEn\": \"Anti-static\",\n \"requirementCn\": \"应采用防静电地板或地面并采用必要的接地防静电措施\",\n \"requirementEn\": \"Anti-static floor or ground should be used and necessary grounding anti-static measures should be adopted\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-16\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防静电\",\n \"controlEn\": \"Anti-static\",\n \"requirementCn\": \"应采取措施防止静电的产生,例如采用静电消除器、佩戴防静电手环等\",\n \"requirementEn\": \"Measures such as use static eliminators and wear anti-static wrist straps should be taken to prevent from generating static electricity.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-17\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"温湿度控制\",\n \"controlEn\": \"Temperature and Humidity Control\",\n \"requirementCn\": \"应设置温湿度自动调节设施,使机房温湿度的变化在设备运行所允许的范围之内\",\n \"requirementEn\": \"Temperature and humidity automatic adjustment facilities should be set up so that the temperature and humidity changes are within the allowable range of equipment operation.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-18\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电力供应\",\n \"controlEn\": \"Electricity Supply\",\n \"requirementCn\": \"应在机房供电线路上配置稳压器和过电压防护设备\",\n \"requirementEn\": \"Voltage stabilizer and overvoltage protection equipment should be configured for the power supply line of the computer room\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-19\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电力供应\",\n \"controlEn\": \"Electricity Supply\",\n \"requirementCn\": \"应提供短期的备用电力供应,至少满足设备在断电情况下的正常运行要求\",\n \"requirementEn\": \"A short-term backup power supply shall be provided to meet the normal operational requirements of the equipment in the event of a power outage\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-20\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电力供应\",\n \"controlEn\": \"Electricity Supply\",\n \"requirementCn\": \"应设置冗余或并行的电力电缆线路为计算机系统供电\",\n \"requirementEn\": \"Equip backup or parallel power cable lines to power the computer system when necessary.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-21\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电磁防护\",\n \"controlEn\": \"Electromagnetic Protection\",\n \"requirementCn\": \"电源线和通信线缆应隔离铺设,避免互相干扰\",\n \"requirementEn\": \"Power cables and communication cables should be laid isolated to avoid mutual interference\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-22\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电磁防护\",\n \"controlEn\": \"Electromagnetic Protection\",\n \"requirementCn\": \"应对关键设备实施电磁屏蔽\",\n \"requirementEn\": \"Electromagnetic shielding should be implemented for critical equipment.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-CNS1-01\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应保证网络设备的业务处理能力满足业务高峰期需要\",\n \"requirementEn\": \"Service processing capability of network should be guaranteed to meet the peak business needs\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的互联网接入满足业务高峰需求;客户数据中心和亚马逊云之间的连接例如VPN,专线的处理能力需要客户根据业务规划;VPC内部网络服务有自身的限制,开Case提升限制;EC2自身的网络处理能力可以根据业务需求进行选择\"\n },\n {\n \"id\": \"L3-CNS1-02\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应保证网络各个部分的带宽满足业务高峰期需要\",\n \"requirementEn\": \"Ensure that the bandwidth of each part of the network meets the peak business needs\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的互联网接入满足业务高峰需求;客户数据中心和亚马逊云之间的连接例如VPN,专线的处理能力需要客户根据业务规划;VPC内部网络服务有自身的限制,开Case提升限制;EC2自身的网络处理能力可以根据业务需求进行选择\"\n },\n {\n \"id\": \"L3-CNS1-03\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应划分不同的网络区域,并按照方便管理和控制的原则为各网络区域分配地址\",\n \"requirementEn\": \"Different network areas should be divided, and addresses should be assigned to each network area in accordance with the principle of convenient management and control\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"利用VPC进行区域和地址划分\"\n },\n {\n \"id\": \"L3-CNS1-04\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应避免将重要网络区域部署在边界处,重要网络区域与其他网络区域之间应采取可靠的技术隔离手段\",\n \"requirementEn\": \"Critical network areas should not be deployed at the network boundaries or without border protection, and reliable technical isolation should be used between important network areas and other network areas\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. AWS侧采用防火墙或者Network ACL(建议确认global region设计)\\n2. On-premise采用防火墙\"\n },\n {\n \"id\": \"L3-CNS1-05\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应提供通信线路、关键网络设备和关键计算设备的硬件冗余,保证系统的可用性\",\n \"requirementEn\": \"The communication lines and hardware of critical network equipment should be adequately backed up to ensure system availability.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"服务确保多可用区部署以及多区域部署;多条专线接入到不同的专线接入点确保高可用\"\n },\n {\n \"id\": \"L3-CNS1-06\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"通信传输\",\n \"controlEn\": \"Communication\",\n \"requirementCn\": \"应采用校验技术或密码技术保证通信过程中数据的完整性\",\n \"requirementEn\": \"Verification techniques or cryptographic techniques should be used to ensure the integrity of the data during communication\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"开启传输加密\"\n },\n {\n \"id\": \"L3-CNS1-07\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"通信传输\",\n \"controlEn\": \"Communication\",\n \"requirementCn\": \"应采用密码技术保证通信过程中数据的保密性\",\n \"requirementEn\": \"Cryptographic techniques should be used to ensure the confidentiality of the data during communication\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"启用SSL/TLS传输加密,利用ACM管理传输加密的密钥\"\n },\n {\n \"id\": \"L3-CNS1-08\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"可信验证\",\n \"controlEn\": \"Trusted Verification\",\n \"requirementCn\": \"可基于可信根对通信设备的系统引导程序、系统程序、重要配置参数和通信应用程序等进行可信验证,并在应用程序的关键执行环节进行动态可信验证,在检测到其可信性受到破坏后进行报警,并将验证结果形成审计记录送至安全管理中心\",\n \"requirementEn\": \"Trusted verification, based on the trusted root, can be applied to system boot program, system program, important configuration parameters, and communication applications of the communication device, and dynamic trusted verification can be used in the key execution of the application, and when detecting the credibility thereof. After being damaged, an alarm is issued, and after detecting that its credibility has been damaged, an alarm should be issued and the verification result should be sent to the Security Management Center.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS1-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应保证跨越边界的访问和数据流通过边界防护设备提供的受控接口进行通信\",\n \"requirementEn\": \"It should be ensured that access and data flows across the boundary are communicated through a controlled interface provided by the border protection device.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应能够对非授权设备私自联到内部网络的行为进行限制或检查\",\n \"requirementEn\": \"It should be able to restrict or check the behavior of unauthorized devices connected to the internal network\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应能够对内部用户非授权联到外部网络的行为进行限制或检查\",\n \"requirementEn\": \"It should be able to restrict or inspect the behavior of internal users who are privately linked to the external network\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 利用NAT 或者 NAT Gateway\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 启用VPC Endpoint 保证通过私有网络访问AWS服务\"\n },\n {\n \"id\": \"L3-ABS1-04\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应限制无线网络的使用,确保无线网络通过受控的边界防护设备接入内部网络\",\n \"requirementEn\": \"The use of the wireless network should be limited to ensure that the wireless network accesses the internal network through controlled border protection equipment.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS1-05\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在网络边界或区域之间根据访问控制策略设置访问控制规则,默认情况下除允许通信外受控接口拒绝所有通信\",\n \"requirementEn\": \"Access control rules should be set between network boundaries or regions based on access control policies, and the controlled interfaces should reject any communication by default except for those that allow communication\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"采用安全组或者Network ACL,按照最小暴露原则设置\"\n },\n {\n \"id\": \"L3-ABS1-06\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应删除多余或无效的访问控制规则,优化访问控制列表,并保证访问控制规则数量最小化\",\n \"requirementEn\": \"Extra or invalid access control rules should be removed to optimize the access control lists, and the number of access control rules should be minimized\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"采用安全组或者Network ACL,按照最小暴露原则设置\"\n },\n {\n \"id\": \"L3-ABS1-07\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应对源地址、目的地址、源端口、目的端口和协议等进行检查,以允许/拒绝数据包进出\",\n \"requirementEn\": \"Check the source address, destination address, source port, destination port, protocol, etc. to allow/deny packets in and out\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 利用VPC Flow log 对进出VPC的通讯进行分析\\n5. 必要时可以启用VPC Traffic Mirror,并利用专业分析软件进行流量分析\"\n },\n {\n \"id\": \"L3-ABS1-08\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应能根据会话状态信息为进出数据流提供明确的允许/拒绝访问的能力\",\n \"requirementEn\": \"Explicit ability to allow/deny access to incoming and outgoing data streams should be provided based on session state information\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-09\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应对进出网络的数据流实现基于应用协议和应用内容的访问控制\",\n \"requirementEn\": \"Access control based on application protocols and application content should be applied to data flows to and from the network.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\\"\"\n },\n {\n \"id\": \"L3-ABS1-10\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应在关键网络节点处检测、防止或限制从外部发起的网络攻击行为\",\n \"requirementEn\": \"Externally initiated cyber attacks should be detected, prevented or restricted at critical network nodes\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-11\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应在关键网络节点处检测、防止或限制从内部发起的网络攻击行为\",\n \"requirementEn\": \"Internally initiated cyber attacks should be detected, prevented or restricted at critical network nodes\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用GuardDuty\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-12\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应采取技术措施对网络行为进行分析,实现对网络攻击特别是新型网络攻击行为的分析\",\n \"requirementEn\": \"Technical measures should be taken to analyze the network behavior, as well as analyze network attacks, especially the new types of attacks.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-ABS1-13\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"当检测到攻击行为时,记录攻击源IP、攻击类型、攻击目的、攻击时间,在发生严重入侵事件时应提供报警\",\n \"requirementEn\": \"When an attack is detected, the attack source IP, attack type, attack purpose, and attack time should be recorded, and alarm when a serious intrusion occurs.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-14\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"恶意代码和垃圾邮件防范\",\n \"controlEn\": \"Malicious Code and Spam Prevention\",\n \"requirementCn\": \"应在关键网络节点处对恶意代码进行检测和清除,并维护恶意代码防护机制的升级和更新\",\n \"requirementEn\": \"Malicious code should be detected and purged at key network nodes, and the upgrade and update of malicious code protection mechanism should be maintained.\",\n \"referenceStatus\": \"不符合 Gap Exist\",\n \"referenceComment\": \"1.使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n2.在操作系统安装第三方安全防护和杀毒软件\"\n },\n {\n \"id\": \"L3-ABS1-15\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"恶意代码和垃圾邮件防范\",\n \"controlEn\": \"Malicious Code and Spam Prevention\",\n \"requirementCn\": \"应在关键网络节点处对垃圾邮件进行检测和防护,并维护垃圾邮件防护机制的升级和更新\",\n \"requirementEn\": \"Spam should be detected and protect at critical network nodes and upgrades and update of spam protection mechanisms should be maintained.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS1-16\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应在网络边界、重要网络节点进行安全审计,审计覆盖到每个用户,对重要的用户行为和重要安全事件进行审计\",\n \"requirementEn\": \"Security audits should be conducted at network borders and important network nodes, and audits should be covered to each user to audit important user behaviors and important security incidents\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. IAM\\n2,堡垒机(session manager或者第三方的堡垒机)\"\n },\n {\n \"id\": \"L3-ABS1-17\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"审计记录应包括事件的日期和时间、用户、事件类型、事件是否成功及其他与审计相关的信息\",\n \"requirementEn\": \"The audit record should include the event date and time, user, event type, success or failure of the event, and other audit-related information\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail\"\n },\n {\n \"id\": \"L3-ABS1-18\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应对审计记录进行保护,定期备份,避免受到未预期的删除、修改或覆盖等\",\n \"requirementEn\": \"Audit records should be protected and backed up regularly to avoid unintended deletions, modifications or overwrites.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail\"\n },\n {\n \"id\": \"L3-ABS1-19\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应能对远程访问的用户行为、访问互联网的用户行为等单独进行行为审计和数据分析\",\n \"requirementEn\": \"It should be possible to conduct separate behavioral audits and data analysis on user behaviors of remote access, user behaviors of accessing the Internet, and so on.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. CloudTraiil\\n2. S3和ALB Access Logs\\n3.使用第三方的下一代防火墙,并结合GLWB进行高可用部署或者上网行为管理产品\"\n },\n {\n \"id\": \"L3-ABS1-20\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"可信验证\",\n \"controlEn\": \"Trusted Verification\",\n \"requirementCn\": \"可基于可信根对边界设备的系统引导程序、系统程序、重要配置参数和边界防护应用程序等进行可信验证,并在应用程序的关键执行环节进行动态可信验证,在检测到其可信性受到破坏后进行报警, 并将验证结果形成审计记录送至安全管理中心\",\n \"requirementEn\": \"Trusted verification, based on the trusted root, can be applied to system boot program, system program, important configuration parameters, and network border protection applications of the network border devices, and dynamic trusted verification can be used in the key execution of the application, and when detecting the credibility thereof. After being damaged, an alarm is issued, and after detecting that its credibility has been damaged, an alarm should be issued and the verification result should be sent to the Security Management Center.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES1-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换\",\n \"requirementEn\": \"The logged-in user should be identified and authenticated. And the identity shall be unique. The identity authentication information should have complexity requirements and be replaced periodically.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-CES1-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"应具有登录失败处理功能,应配置并启用结束会话、限制非法登录次数和当登录连接超时自动退出等相关措施\",\n \"requirementEn\": \"It should have the login failure processing function, and configure and enable the functions of end session, limit the number of illegal logins, and automatically exit when the login connection times out\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 第三方的堡垒机\\n2.AWS平台可考虑基于CLoudTrail日志+Cloudwatch Alarm + Lambda实现\"\n },\n {\n \"id\": \"L3-CES1-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"当进行远程管理时,应采取必要措施防止鉴别信息在网络传输过程中被窃听\",\n \"requirementEn\": \"Necessary measures should be taken to prevent the authentication information from being eavesdropped during network transmission when performing remote management.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 启用传输层加密\\n2. 利用SSH和加密的RDP进行访问EC2\"\n },\n {\n \"id\": \"L3-CES1-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"应采用口令、密码技术、生物技术等两种或两种以上组合的鉴别技术对用户进行身份鉴别, 且其中一种鉴别技术至少应使用密码技术来实现\",\n \"requirementEn\": \"Two or more authentication technologies, e.g. password, cryptography, biotechnology and etc., should be used to identify users, and at least one of them should be implemented by cryptography.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"启用MFA\"\n },\n {\n \"id\": \"L3-CES1-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应对登录的用户分配账号和权限\",\n \"requirementEn\": \"Accounts and permissions should be assigned to the logged in user\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"\\\"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\\\"\"\n },\n {\n \"id\": \"L3-CES1-06\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应重命名或删除默认账户,修改默认账户的默认口令\",\n \"requirementEn\": \"The default account should be renamed or deleted, and the default password of the default account should be changed.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"管理流程\"\n },\n {\n \"id\": \"L3-CES1-07\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应及时删除或停用多余的、过期的账号,避免共享账号的存在\",\n \"requirementEn\": \"The redundant and expired accounts should be deleted or deactivated in time and share accounts is not allowed\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-CES1-08\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应授予管理用户所需的最小权限,实现管理用户的权限分离\",\n \"requirementEn\": \"Administrator access should be reduced to an absolute minimum to achieve separation of administrator privileges\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-CES1-09\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则\",\n \"requirementEn\": \"The access control policy should be configured by the authorized subject, and the access control policy stipulates the access rules of the subject to the object\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"支持基于人员和基于资源的权限分配\"\n },\n {\n \"id\": \"L3-CES1-10\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级\",\n \"requirementEn\": \"The granularity of access control should be at the user level or process level, and the object is at the file and database table level\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-CES1-11\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应对敏感信息资源设置安全标记,并控制主体对有安全标记信息资源的访问\",\n \"requirementEn\": \"Set security tokens for sensitive information resources and control the subject's access to resources with security-tagged information.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"需要应用层面先进行敏感信息的分类,然后利用Tag或者Metadata对数据进行标记,然后利用控制访问策略进行管控\"\n },\n {\n \"id\": \"L3-CES1-12\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应启用安全审计功能,审计覆盖到每个用户,对重要的用户行为和重要安全事件进行审计\",\n \"requirementEn\": \"Security auditing should be enabled, and covers each user, important user behaviors and security incidents\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. CloudTrail \\n2. CloudWatch\\n3. AWS Config 或者 Palo Alto的Prisma Cloud\"\n },\n {\n \"id\": \"L3-CES1-13\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"审计记录应包括事件的日期和时间、用户、事件类型、事件是否成功及其他与审计相关的信息\",\n \"requirementEn\": \"The audit record should include the event date and time, user, event type, success or failure of the event, and other audit-related information\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. CloudTrail \\n2. CloudWatch\\n3. AWS Config 或者 Palo Alto的Prisma Cloud\"\n },\n {\n \"id\": \"L3-CES1-14\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应对审计记录进行保护,定期备份,避免受到未预期的删除、修改或覆盖等\",\n \"requirementEn\": \"Audit records should be protected and backed up regularly to avoid unintended deletions, modifications or overwrites.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. CloudTrail \\n2. CloudWatch\\n3. AWS Config 或者 Palo Alto的Prisma Cloud\"\n },\n {\n \"id\": \"L3-CES1-15\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应对审计进程进行保护,防止未经授权的中断\",\n \"requirementEn\": \"The audit record time shall be synchronized with an accurate time source within the system to ensure the correctness of the audit analysis.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. CloudTrail \\n2. CloudWatch\\n3. AWS Config 或者 Palo Alto的Prisma Cloud\"\n },\n {\n \"id\": \"L3-CES1-17\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应遵循最小安装的原则,仅安装需要的组件和应用程序\",\n \"requirementEn\": \"Follow the principle of minimum installation, and install only the required components and applications.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-CES1-18\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应关闭不需要的系统服务、默认共享和高危端口\",\n \"requirementEn\": \"Unneeded system services, default shares, and high-risk ports should be turned off\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-CES1-19\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应通过设定终端接入方式或网络地址范围对通过网络进行管理的管理终端进行限制\",\n \"requirementEn\": \"The management terminal managed through the network should be restricted by setting the terminal access mode or network address range\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-CES1-20\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应提供数据有效性检验功能,保证通过人机接口输入或通过通信接口输入的内容符合系统设定要求\",\n \"requirementEn\": \"The data validity check function shall be provided to ensure that the content input through the human machine interface or input through the communication interface complies with the system setting requirements\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-CES1-21\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能发现可能存在的漏洞,并在经过充分测试评估后,及时修补漏洞\",\n \"requirementEn\": \"It should be able to identify possible vulnerabilities and fix the vulnerabilities in time after thorough testing and evaluation\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 启用WAF\\n2. 启用GuardDuty\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-CES1-22\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测到对重要节点进行入侵的行为,并在发生严重入侵事件时提供报警\",\n \"requirementEn\": \"It should be able to detect intrusions on important nodes and alert when there is serious intrusion.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 启用WAF\\n2. 启用GuardDuty\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 操作系统层安装第三方安全防护软件\"\n },\n {\n \"id\": \"L3-CES1-23\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"恶意代码防范\",\n \"controlEn\": \"Malicious Code Prevention\",\n \"requirementCn\": \"应采用免受恶意代码攻击的技术措施或主动免疫可信验证机制及时识别入侵和病毒行为,并将其有效阻断\",\n \"requirementEn\": \"Intrusion and virus behavior should be identified and effectively blocked by technical measures against malicious code attacks or active immune trusted authentication mechanisms.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 启用WAF\\n2. 启用GuardDuty\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 操作系统层安装第三方杀毒产品\"\n },\n {\n \"id\": \"L3-CES1-24\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"可信验证\",\n \"controlEn\": \"Trusted Verification\",\n \"requirementCn\": \"可基于可信根对计算设备的系统引导程序、系统程序、重要配置参数和应用程序等进行可信验证, 并在应用程序的关键执行环节进行动态可信验证,在检测到其可信性受到破坏后进行报警,并将验证 结果形成审计记录送至安全管理中心\",\n \"requirementEn\": \"Trusted verification, based on the trusted root, can be applied to system boot program, system program, important configuration parameters, and applications of the computing devices, and dynamic trusted verification can be used in the key execution of the application, and when detecting the credibility thereof. After being damaged, an alarm is issued, and after detecting that its credibility has been damaged, an alarm should be issued and the verification result should be sent to the Security Management Center.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES1-25\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性\",\n \"controlEn\": \"Data Confidentiality\",\n \"requirementCn\": \"应采用校验技术或密码技术保证重要数据在传输过程中的完整性,包括但不限于鉴别数据、重要业务数据、重要审计数据、重要配置数据、重要视频数据和重要个人信息等\",\n \"requirementEn\": \"Verification techniques or cryptographic techniques should be used to ensure the integrity of important data during transmission, including but not limited to authentication data, important business data, important audit data, important configuration data, important video data and important personal information\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 启用传输加密,并且可以利用Amazon ACM管理密钥\\n2. S3 会验证已上传对象的完整性\\n3. 按照第三方防篡改软件\"\n },\n {\n \"id\": \"L3-CES1-26\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性\",\n \"controlEn\": \"Data Confidentiality\",\n \"requirementCn\": \"应采用校验技术或密码技术保证重要数据在存储过程中的完整性,包括但不限于鉴别数据、重要业务数据、重要审计数据、重要配置数据、重要视频数据和重要个人信息等\",\n \"requirementEn\": \"Verification techniques or cryptographic techniques should be used to ensure the integrity of important data when stored including but not limited to authentication data, important business data, important audit data, important configuration data, important video data and important personal information\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 启用传输加密,并且可以利用Amazon ACM管理密钥\\n2. S3 会验证已上传对象的完整性\\n3. 按照第三方防篡改软件\"\n },\n {\n \"id\": \"L3-CES1-27\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据保密性\",\n \"controlEn\": \"Data Integrity\",\n \"requirementCn\": \"应采用密码技术保证重要数据在传输过程中的保密性,包括但不限于鉴别数据、重要业务数据和重要个人信息等\",\n \"requirementEn\": \"Cryptographic technology should be used to ensure the confidentiality of important data during transmission, including but not limited to authentication data, important business data and important personal information\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"启用KMS\"\n },\n {\n \"id\": \"L3-CES1-28\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据保密性\",\n \"controlEn\": \"Data Integrity\",\n \"requirementCn\": \"应采用密码技术保证重要数据在存储过程中的保密性,包括但不限于鉴别数据、重要业务数据和重要个人信息等\",\n \"requirementEn\": \"Cryptographic technology should be used to ensure the confidentiality of important data when stored, including but not limited to authentication data, important business data and important personal information\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"启用KMS\"\n },\n {\n \"id\": \"L3-CES1-29\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应提供重要数据的本地数据备份与恢复功能\",\n \"requirementEn\": \"Local data backup and recovery functions for important data should be provided\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 存储服务原生支持多副本,客户可以通过快照的方式对数据进行额外备份\\n2. 利用AWS Backup 中心化管理备份的工具。也可以使用AWS各服务中相应的备份功能,单独管理\"\n },\n {\n \"id\": \"L3-CES1-30\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应提供异地实时备份功能,利用通信网络将重要数据实时备份至备份场地\",\n \"requirementEn\": \"Remote real-time backup function should be provided, and use the communication network to back up important data to the backup site in real time\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 存储服务原生支持多副本,客户可以通过快照的方式对数据进行额外备份\\n2. 利用AWS Backup 中心化管理备份的工具。也可以使用AWS各服务中相应的备份功能,单独管理\\n3. 配置快照和S3跨区域数据复制\"\n },\n {\n \"id\": \"L3-CES1-31\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应提供重要数据处理系统的热冗余,保证系统的高可用性\",\n \"requirementEn\": \"Redundancy of critical data processing systems should be provided to ensure high system availability.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"\\\"1. 存储服务原生支持多副本,客户可以通过快照的方式对数据进行额外备份\\n2. 利用AWS Backup 中心化管理备份的工具。也可以使用AWS各服务中相应的备份功能,单独管理\\\"\"\n },\n {\n \"id\": \"L3-CES1-32\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"剩余信息保护\",\n \"controlEn\": \"Residual Information Protection\",\n \"requirementCn\": \"应保证鉴别信息所在的存储空间被释放或重新分配前得到完全清除\",\n \"requirementEn\": \"Ensure that the storage space where the authentication information is located is completely cleared before being released or redistributed\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. AWS 存储服务的数据清除策略在等保云扩展要求中覆盖\"\n },\n {\n \"id\": \"L3-CES1-33\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"剩余信息保护\",\n \"controlEn\": \"Residual Information Protection\",\n \"requirementCn\": \"应保证存有敏感数据的存储空间被释放或重新分配前得到完全清除\",\n \"requirementEn\": \"Ensure that the storage space containing sensitive data is completely cleared before being released or redistributed.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. AWS 存储服务的数据清除策略在等保云扩展要求中覆盖\"\n },\n {\n \"id\": \"L3-CES1-34\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"个人信息保护\",\n \"controlEn\": \"Personal Information Protection\",\n \"requirementCn\": \"应仅采集和保存业务必需的用户个人信息\",\n \"requirementEn\": \"Only personal information necessary for the business should be collected and stored\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"应用侧行为,AWS不主动采集和保存用户个人信息\"\n },\n {\n \"id\": \"L3-CES1-35\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"个人信息保护\",\n \"controlEn\": \"Personal Information Protection\",\n \"requirementCn\": \"应禁止未授权访问和非法使用用户个人信息\",\n \"requirementEn\": \"Unauthorized access and illegal use of user's personal information should be prohibited.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"应用侧行为,AWS不主动采集和保存用户个人信息\"\n },\n {\n \"id\": \"L3-SMC1-01\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"系统管理\",\n \"controlEn\": \"System Management\",\n \"requirementCn\": \"应对系统管理员进行身份鉴别,只允许其通过特定的命令或操作界面进行系统管理操作,并对这些操作进行审计\",\n \"requirementEn\": \"The system administrator should be authenticated and only allowed to perform system management operations through specific commands or operation interfaces. These operations need to be audited\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-02\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"系统管理\",\n \"controlEn\": \"System Management\",\n \"requirementCn\": \"应通过系统管理员对系统的资源和运行进行配置、控制和管理,包括用户身份、系统资源配置、系统加载和启动、系统运行的异常处理、数据和设备的备份与恢复等\",\n \"requirementEn\": \"The configuration, control, and management of system resources and operations should be performed by system administrators, including user identity, system resource configuration, system loading and startup, system operation exception handling, data and device backup and recovery.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-03\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"审计管理\",\n \"controlEn\": \"Audit Management\",\n \"requirementCn\": \"应对审计管理员进行身份鉴别,只允许其通过特定的命令或操作界面进行安全审计操作,并对这些操作进行审计\",\n \"requirementEn\": \"The audit administrator should be authenticated and only allowed to perform security audit operations through specific commands or operation interfaces. These operations need to be audited\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-04\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"审计管理\",\n \"controlEn\": \"Audit Management\",\n \"requirementCn\": \"应通过审计管理员对审计记录应进行分析,并根据分析结果进行处理,包括根据安全审计策略对审计记录进行存储、管理和查询等\",\n \"requirementEn\": \"The audit administrator should analyze the audit records and dispose them according to the analysis results. The disposals include storage, management and query of the audit records according to the security audit policy.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-05\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"安全管理\",\n \"controlEn\": \"Security Management\",\n \"requirementCn\": \"应对安全管理员进行身份鉴别,只允许其通过特定的命令或操作界面进行安全管理操作,并对这些操作进行审计\",\n \"requirementEn\": \"The security administrator should be authenticated and only allowed to perform security management operations through specific commands or operation interfaces. These operations need to be audited\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-06\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"安全管理\",\n \"controlEn\": \"Security Management\",\n \"requirementCn\": \"应通过安全管理员对系统中的安全策略进行配置,包括安全参数的设置,主体、客体进行统一安全标记,对主体进行授权,配置可信验证策略等\",\n \"requirementEn\": \"The security policy should be configured by the security administrator, including the setting of security parameters, the unified security mark of the subject and the object, the authorization and trusted authentication policy configuration of the subject.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-07\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应划分出特定的管理区域,对分布在网络中的安全设备或安全组件进行管控\",\n \"requirementEn\": \"A specific network management area should be divided to control the security devices or security components distributed in the network\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"利用Firewall Manager可以对WAF进行统一管理\\nGuardDuty可以跨账号统一管理安全发现\\nCloudTrail可以集中对跨账号进行分析\\nSecurityHub可以跨账号统一进行安全发现\"\n },\n {\n \"id\": \"L3-SMC1-08\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应能够建立一条安全的信息传输路径,对网络中的安全设备或安全组件进行管理\",\n \"requirementEn\": \"A secure information transmission channel should be established to manage security devices or security components in the network\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"利用Firewall Manager可以对WAF进行统一管理\\nGuardDuty可以跨账号统一管理安全发现\\nCloudTrail可以集中对跨账号进行分析\\nSecurityHub可以跨账号统一进行安全发现\"\n },\n {\n \"id\": \"L3-SMC1-09\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应对网络链路、安全设备、网络设备和服务器等的运行状况进行集中监测\",\n \"requirementEn\": \"Centralized monitoring of network links, security devices, network devices and servers should be carried out.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudWatch和Splunk进行统一监测\"\n },\n {\n \"id\": \"L3-SMC1-10\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应对分散在各个设备上的审计数据进行收集汇总和集中分析,并保证审计记录的留存时间符合法律法规要求\",\n \"requirementEn\": \"The audit data scattered on various equipment should be collected, summarized and centralized analyzed, and the retention time of audit records should be guaranteed to meet the requirements of laws and regulations.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail\"\n },\n {\n \"id\": \"L3-SMC1-11\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应对安全策略、恶意代码、补丁升级等安全相关事项进行集中管理\",\n \"requirementEn\": \"Security policy, malicious code, patch upgrade and other security related matters should be centrally managed.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"需要第三方防入侵和防病毒支持\"\n },\n {\n \"id\": \"L3-SMC1-12\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应能对网络中发生的各类安全事件进行识别、报警和分析\",\n \"requirementEn\": \"Various types of security incidents occurring in the network can be identified, alerted, and analyzed.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudWatch和Splunk进行统一报警和分析\"\n },\n {\n \"id\": \"L3-PES2-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"基础设施位置\",\n \"controlEn\": \"Location of Infrastructure\",\n \"requirementCn\": \"应保证云计算基础设施位于中国境内\",\n \"requirementEn\": \"Ensure that the cloud computing infrastructure is located in China.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1.参考安全责任共担模型\\n2. AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CNS2-01\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应保证云计算平台不承载高于其安全保护等级的业务应用系统\",\n \"requirementEn\": \"Ensure that the cloud computing platform shall not carry business application systems higher than its security protection level.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1.参考安全责任共担模型\\n2. AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CNS2-02\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应实现不同云服务客户虚拟网络之间的隔离\",\n \"requirementEn\": \"It should implement the independence between different cloud service customer virtual networks.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CNS2-03\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应具有根据云服务客户业务需求提供通信传输、边界防护、入侵防范等安全机制的能力\",\n \"requirementEn\": \"It should have the ability to provide security mechanisms, such as communication transmission, border protection and intrusion prevention, based on the business requirements of cloud service customers.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-CNS2-04\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应具有根据云服务客户业务需求自主设置安全策略的能力,包括定义访问路径、选择安全组件、配置安全策略\",\n \"requirementEn\": \"It should have the ability to independently set security policies based on the business requirements of cloud service customers, including defining access paths, selecting security components and configuring security policies.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CNS2-05\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应提供开放接口或开放性安全服务,允许云服务客户接入第三方安全产品或在云计算平台选择第三方安全服务\",\n \"requirementEn\": \"It should provide open interfaces or open security services to allow cloud service customers to access third-party security products or select third-party security services on cloud computing platforms.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-ABS2-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在虚拟化网络边界部署访问控制机制,并设置访问控制规则\",\n \"requirementEn\": \"It should deploy access control mechanisms at the boundaries of the virtualized network and set access control rules.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-ABS2-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在不同等级的网络区域边界部署访问控制机制,设置访问控制规则\",\n \"requirementEn\": \"It should deploy access control mechanisms at different levels of network area boundaries and set access control rules.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-ABS2-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测到云服务客户发起的网络攻击行为,并能记录攻击类型、攻击时间、攻击流量等\",\n \"requirementEn\": \"It should be able to detect the network attack behavior initiated by cloud service customers, and record the attack type, attack time, attack traffic, etc.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-ABS2-04\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测到对虚拟网络节点的网络攻击行为,并能记录攻击类型、攻击时间、攻击流量等\",\n \"requirementEn\": \"It should be able to detect the network attack behavior of virtual network nodes and record the attack type, attack time, attack traffic, etc.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-ABS2-05\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测到虚拟机与宿主机、虚拟机与虚拟机之间的异常流量\",\n \"requirementEn\": \"It should be able to detect abnormal traffic between virtual machines and hosts, and between virtual machines and virtual machines.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-ABS2-06\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应在检测到网络攻击行为、异常流量情况时进行告警\",\n \"requirementEn\": \"It should give an alarm when network attack and abnormal traffic are detected.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-ABS2-07\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应对云服务商和云服务客户在远程管理时执行的特权命令进行审计,至少包括虚拟机删除、虚拟机重启\",\n \"requirementEn\": \"Audit the privileged commands executed by the cloud service provider and cloud service customers while remote administration, including at least virtual machine deletion and virtual machine restart.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail and CloudWatch\"\n },\n {\n \"id\": \"L3-ABS2-08\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应保证云服务商对云服务客户系统和数据的操作可被云服务客户审计\",\n \"requirementEn\": \"Ensure that operations of cloud service providers on cloud service customer systems and data can be audited by cloud service customers.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail\"\n },\n {\n \"id\": \"L3-CES2-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"当远程管理云计算平台中设备时,管理终端和云计算平台之间应建立双向身份验证机制\",\n \"requirementEn\": \"It should establish a mutual authentication mechanism between the management terminal and the cloud computing platform, when remotely managing devices in a cloud computing platform.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\\n3. 利用SSH和加密的RDP进行访问EC2\\n4. 堡垒机\"\n },\n {\n \"id\": \"L3-CES2-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应保证当虚拟机迁移时,访问控制策略随其迁移\",\n \"requirementEn\": \"Ensure that access control policies migrate with the virtual machine as it migrates.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\\n3. 利用SSH和加密的RDP进行访问EC2\\n4. 堡垒机\"\n },\n {\n \"id\": \"L3-CES2-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应允许云服务客户设置不同虚拟机之间的访问控制策略\",\n \"requirementEn\": \"It should allow cloud service customers to set access control policies between different virtual machines.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\\n3. 利用SSH和加密的RDP进行访问EC2\\n4. 堡垒机\"\n },\n {\n \"id\": \"L3-CES2-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测虚拟机之间的资源隔离失效,并进行告警\",\n \"requirementEn\": \"It should be able to detect and alert resource isolation failures between virtual machines.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测非授权新建虚拟机或者重新启用虚拟机,并进行告警\",\n \"requirementEn\": \"It should be able to detect and alert unauthorized new or re-enabled virtual machines.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"可通过cloudtrail检测非授权的新建机器行为,并进行告警\"\n },\n {\n \"id\": \"L3-CES2-06\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测恶意代码感染及在虚拟机间蔓延的情况,并进行告警\",\n \"requirementEn\": \"It should be able to detect and alert malicious code infections and spread between virtual machines.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范和杀毒产品\"\n },\n {\n \"id\": \"L3-CES2-07\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"镜像和快照保护\",\n \"controlEn\": \"Image and Snapshot Protection\",\n \"requirementCn\": \"应针对重要业务系统提供加固的操作系统镜像或操作系统安全加固服务\",\n \"requirementEn\": \"It should provide hardened operating system mirroring or operating system security hardening services for critical business systems.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"若不使用AWS镜像,需要自行加固\"\n },\n {\n \"id\": \"L3-CES2-08\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"镜像和快照保护\",\n \"controlEn\": \"Image and Snapshot Protection\",\n \"requirementCn\": \"应提供虚拟机镜像、快照完整性校验功能,防止虚拟机镜像被恶意篡改\",\n \"requirementEn\": \"It should provide virtual machine image and snapshot integrity check function to prevent malicious tampering of virtual machine image.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"若不使用AWS镜像,需要自行加固\"\n },\n {\n \"id\": \"L3-CES2-09\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"镜像和快照保护\",\n \"controlEn\": \"Image and Snapshot Protection\",\n \"requirementCn\": \"应采取密码技术或其他技术手段防止虚拟机镜像、快照中可能存在的敏感资源被非法访问\",\n \"requirementEn\": \"It should adopt cryptography or other techniques to prevent unauthorized access to sensitive resources that may exist in virtual machine images and snapshots.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"利用KMS对快照进行加密\"\n },\n {\n \"id\": \"L3-CES2-10\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性和保密性\",\n \"controlEn\": \"Data Integrity and Confidentiality\",\n \"requirementCn\": \"应确保云服务客户数据、用户个人信息等存储于中国境内,如需出境应遵循国家相关规定\",\n \"requirementEn\": \"Ensure that cloud service customer data and user personal information are stored in China, and follow relevant national regulations when cross-border transferring.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-11\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性和保密性\",\n \"controlEn\": \"Data Integrity and Confidentiality\",\n \"requirementCn\": \"应确保只有在云服务客户授权下,云服务商或第三方才具有云服务客户数据的管理权限\",\n \"requirementEn\": \"Ensure that the cloud service provider or a third party has the right to manage the cloud service customer data only under the authorization of the cloud service customer.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-12\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性和保密性\",\n \"controlEn\": \"Data Integrity and Confidentiality\",\n \"requirementCn\": \"应使用校验码或密码技术确保虚拟机迁移过程中重要数据的完整性,并在检测到完整性受到破坏时采取必要的恢复措施\",\n \"requirementEn\": \"It should adopt checksum or cryptographic techniques to ensure the integrity of important data during virtual machine migration and take necessary recovery measures when integrity is detected to be compromised.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"传输加密 - ACM\\n存储静态加密 - KMS\\n快照备份服务\"\n },\n {\n \"id\": \"L3-CES2-13\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性和保密性\",\n \"controlEn\": \"Data Integrity and Confidentiality\",\n \"requirementCn\": \"应支持云服务客户部署密钥管理解决方案,保证云服务客户自行实现数据的加解密过程\",\n \"requirementEn\": \"It should support cloud service customers to deploy key management solutions to ensure that cloud service customers can implement the data encryption and decryption process by themselves.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"传输加密 - ACM\\n存储静态加密 - KMS\"\n },\n {\n \"id\": \"L3-CES2-14\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"云服务客户应在本地保存其业务数据的备份\",\n \"requirementEn\": \"Ensure cloud service customers keep a backup of their business data locally.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"请确认是否必须\"\n },\n {\n \"id\": \"L3-CES2-15\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应提供查询云服务客户数据及备份存储位置的能力\",\n \"requirementEn\": \"It should provide the ability to query cloud service customer data and back up storage locations.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-16\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"云服务商的云存储服务应保证云服务客户数据存在若干个可用的副本,各副本之间的内容应保持一致\",\n \"requirementEn\": \"The cloud storage service of the cloud service provider It should ensure that there are several available copies of the customer data of the cloud service, and the contents of each copy It should be consistent.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-17\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应为云服务客户将业务系统及数据迁移到其他云计算平台和本地系统提供技术手段,并协助完成迁移过程\",\n \"requirementEn\": \"It should provide technical means for cloud service customers to migrate business systems and data to other cloud computing platforms and local systems and assist in the migration process.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"请确认是否必须\"\n },\n {\n \"id\": \"L3-CES2-18\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"剩余信息保护\",\n \"controlEn\": \"Residual Information Protection\",\n \"requirementCn\": \"应保证虚拟机所使用的内存和存储空间回收时得到完全清除\",\n \"requirementEn\": \"Ensure that the memory and storage space used by the virtual machine is completely cleared when reclaimed.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖,不同存储服务均提供数据完全删除或者擦除的方法\"\n },\n {\n \"id\": \"L3-CES2-19\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"剩余信息保护\",\n \"controlEn\": \"Residual Information Protection\",\n \"requirementCn\": \"云服务客户删除业务应用数据时,云计算平台应将云存储中所有副本删除\",\n \"requirementEn\": \"The cloud computing platform It should delete all copies in the cloud storage, when a cloud service customer deletes business application data.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖,不同存储服务均提供数据完全删除或者擦除的方法\"\n },\n {\n \"id\": \"L3-SMC2-01\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应能对物理资源和虚拟资源按照策略做统一管理调度与分配\",\n \"requirementEn\": \"It should be able to uniformly manage and allocate physical resources and virtual resources according to the policy.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-SMC2-02\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应保证云计算平台管理流量与云服务客户业务流量分离\",\n \"requirementEn\": \"Ensure the separation of cloud computing platform management traffic and cloud service customer business traffic.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-SMC2-03\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应根据云服务商和云服务客户的职责划分,收集各自控制部分的审计数据并实现各自的集中审计\",\n \"requirementEn\": \"It should collect the audit data of each control part and implement centralized audit of each control part, according to the responsibilities of cloud service providers and cloud service customers.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1.参考安全责任共担模型\\n2. AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-SMC2-04\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应根据云服务商和云服务客户的职责划分,实现各自控制部分,包括虚拟化网络、虚拟机、虚拟化安全设备等的运行状况的集中监测\",\n \"requirementEn\": \"According to the responsibilities of cloud service providers and cloud service customers, It should realize centralized monitoring of the operation status of their respective control parts, including virtualized networks, virtual machines and virtualized security devices.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1.参考安全责任共担模型\\n2. AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-PES3-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"无线接入点的物理位置\",\n \"controlEn\": \"Location of Wireless Access Point\",\n \"requirementCn\": \"应为无线接入设备的安装选择合理位置,避免过度覆盖和电磁干扰\",\n \"requirementEn\": \"Choose a reasonable location for the installation of wireless access equipment to avoid excessive coverage and electromagnetic interference\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应保证有线网络与无线网络边界之间的访问和数据流通过无线接入网关设备\",\n \"requirementEn\": \"Ensure access and data flow between the wired network and the wireless network boundary pass through the wireless access gateway device\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"无线接入设备应开启接入认证功能,并支持采用认证服务器认证或国家密码管理机构批准的密码模块进行认证\",\n \"requirementEn\": \"Wireless access devices should turn on access authentication function and support to use the authentication server or cryptographic module approved by the State Cryptography Authority of China (SCA).\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测到非授权无线接入设备和非授权移动终端的接入行为\",\n \"requirementEn\": \"Unauthorized wireless access devices and unauthorized mobile terminals should be detected\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-04\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测到针对无线接入设备的网络扫描、DDoS 攻击、密钥破解、中间人攻击和欺骗攻击等行为\",\n \"requirementEn\": \"It should be able to detect network scanning, DDoS attacks, key cracking, man-in-the-middle attacks and deception attacks against wireless access devices.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-05\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测到无线接入设备的 SSID 广播、WPS 等高风险功能的开启状态\",\n \"requirementEn\": \"It should be able to detect the use status of high-risk functions such as SSID broadcast and WPS of the wireless access device.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-06\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应禁用无线接入设备和无线接入网关存在风险的功能,如:SSID 广播、WEP 认证等\",\n \"requirementEn\": \"Disable high risk functions of the wireless access device and the wireless access gateway, such as SSID broadcast, WEP authentication, etc.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-07\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应禁止多个 AP 使用同一个认证密钥\",\n \"requirementEn\": \"Multiple APs should be prohibited from using the same authentication key\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-08\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够阻断非授权无线接入设备或非授权移动终端\",\n \"requirementEn\": \"It should be able to block the unauthorized wireless access devices or unauthorized mobile terminals\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动终端管控\",\n \"controlEn\": \"Mobile Terminal Control\",\n \"requirementCn\": \"应保证移动终端安装、注册并运行终端管理客户端软件\",\n \"requirementEn\": \"The mobile terminal should be guaranteed to install, register and run the terminal management client software.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动终端管控\",\n \"controlEn\": \"Mobile Terminal Control\",\n \"requirementCn\": \"移动终端应接受移动终端管理服务端的设备生命周期管理、设备远程控制,如:远程锁定、远程擦除等\",\n \"requirementEn\": \"The mobile terminal shall accept the device lifecycle management and remote control from the mobile terminal management server, such as remote locking, remote erasing, etc.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动应用管控\",\n \"controlEn\": \"Mobile Application Control\",\n \"requirementCn\": \"应具有选择应用软件安装、运行的功能\",\n \"requirementEn\": \"It should provide the function which allows to select application software to install and run\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动应用管控\",\n \"controlEn\": \"Mobile Application Control\",\n \"requirementCn\": \"应只允许指定证书签名的应用软件安装和运行\",\n \"requirementEn\": \"Only applications that have specify certificate and signature should be allowed to install and run\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动应用管控\",\n \"controlEn\": \"Mobile Application Control\",\n \"requirementCn\": \"应具有软件白名单功能,应能根据白名单控制应用软件安装、运行\",\n \"requirementEn\": \"It should provide the software whitelist function, and the installation and operation of applications should be controlled according to the whitelist\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES4-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"感知节点设备物理防护\",\n \"controlEn\": \"Physical Protection of Sensor Node\",\n \"requirementCn\": \"感知节点设备所处的物理环境应不对感知节点设备造成物理破坏,如挤压、强振动\",\n \"requirementEn\": \"The physical environment in which the sensor node is located should not cause physical damage to the sensor node, such as extrusion and strong vibration.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES4-02\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"感知节点设备物理防护\",\n \"controlEn\": \"Physical Protection of Sensor Node\",\n \"requirementCn\": \"感知节点设备在工作状态所处物理环境应能正确反映环境状态(如温湿度传感器不能安装在阳光直射区域)\",\n \"requirementEn\": \"The physical environment in which the sensor node is in working status should correctly reflect the environmental state (for example, the temperature and humidity sensor cannot be installed in a direct sunlight area)\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES4-03\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"感知节点设备物理防护\",\n \"controlEn\": \"Physical Protection of Sensor Node\",\n \"requirementCn\": \"感知节点设备在工作状态所处物理环境应不对感知节点设备的正常工作造成影响,如强干扰、阻挡屏蔽等\",\n \"requirementEn\": \"The physical environment in which the sensor node is located should not affect the normal operation of the sensor node, such as strong interference, blocking shielding, etc.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES4-04\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"感知节点设备物理防护\",\n \"controlEn\": \"Physical Protection of Sensor Node\",\n \"requirementCn\": \"关键感知节点设备应具有可供长时间工作的电力供应(关键网关节点设备应具有持久稳定的电力供应能力)\",\n \"requirementEn\": \"Critical sensor nodes should have a power supply for long periods of time (critical gateway node should have a durable and stable power supply capability)\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS4-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"接入控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应保证只有授权的感知节点可以接入\",\n \"requirementEn\": \"Ensured that only authorized sensor nodes can access\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS4-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够限制与感知节点通信的目标地址,以避免对陌生地址的攻击行为\",\n \"requirementEn\": \"The target address to communicate with the sensor node should be restricted, thus avoiding attacks to unfamiliar addresses\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS4-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够限制与网关节点通信的目标地址,以避免对陌生地址的攻击行为\",\n \"requirementEn\": \"The target address to communicate with the gateway node should be restricted, thus avoiding attacks to unfamiliar addresses\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"感知节点设备安全\",\n \"controlEn\": \"Sensor Node Security\",\n \"requirementCn\": \"应保证只有授权的用户可以对感知节点设备上的软件应用进行配置或变更\",\n \"requirementEn\": \"Ensured that only authorized users can configure or change software applications on the sensor node device.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"感知节点设备安全\",\n \"controlEn\": \"Sensor Node Security\",\n \"requirementCn\": \"应具有对其连接的网关节点设备(包括读卡器)进行身份标识和鉴别的能力\",\n \"requirementEn\": \"It should be able to identify and authenticate the gateway nodes (including card readers) to which they are connected\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"感知节点设备安全\",\n \"controlEn\": \"Sensor Node Security\",\n \"requirementCn\": \"应具有对其连接的其他感知节点设备(包括路由节点)进行身份标识和鉴别的能力\",\n \"requirementEn\": \"It should be able to identify and authenticate other connected node (including routing nodes) to which they are connected\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"应设置最大并发连接数\",\n \"requirementEn\": \"The maximum number of concurrent connections of the gateway node should be set.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"应具备对合法连接设备(包括终端节点、路由节点、数据处理中心)进行标识和鉴别的能力\",\n \"requirementEn\": \"Ability to identify and authenticate legitimate connected devices (including endpoints, routing nodes, data processing centers)\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-06\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"应具备过滤非法节点和伪造节点所发送的数据的能力\",\n \"requirementEn\": \"It should be able to filter data sent by illegal and forged nodes\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-07\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"授权用户应能够在设备使用过程中对关键密钥进行在线更新\",\n \"requirementEn\": \"Authorized users should be able to update critical keys online during device use\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-08\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"授权用户应能够在设备使用过程中对关键配置参数进行在线更新\",\n \"requirementEn\": \"Authorized users should be able to update critical configuration parameters online while the device is in use\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-09\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"抗数据重放\",\n \"controlEn\": \"Anti-data Playback\",\n \"requirementCn\": \"应能够鉴别数据的新鲜性,避免历史数据的重放攻击\",\n \"requirementEn\": \"Identify the freshness of data and avoid replay attacks of historical data\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-10\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"抗数据重放\",\n \"controlEn\": \"Anti-data Playback\",\n \"requirementCn\": \"应能够鉴别历史数据的非法修改,避免数据的修改重放攻击\",\n \"requirementEn\": \"Identifies illegal modification of historical data to avoid data modification and replay attacks\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-11\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据融合处理\",\n \"controlEn\": \"Data Aggregation Processing\",\n \"requirementCn\": \"应对来自传感网的数据进行数据融合处理,使不同种类的数据可以在同一个平台被使用\",\n \"requirementEn\": \"Data from the sensor network should be aggregated to make different types of data be used on the same platform\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES5-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"室外控制设备物理防护\",\n \"controlEn\": \"Physical Protection of Outdoor Control Equipment\",\n \"requirementCn\": \"室外控制设备应放置于采用铁板或其他防火材料制作的箱体或装置中并紧固箱体或装置具有透风、散热、防盗、防雨和防火能力等\",\n \"requirementEn\": \"The outdoor control equipment shall be placed in a box or device made of iron plates or other fireproof materials and fastened to the cabinet or device to have ventilation, heat dissipation, anti-theft, rainproof and fireproof capabilities, etc.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES5-02\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"室外控制设备物理防护\",\n \"controlEn\": \"Physical Protection of Outdoor Control Equipment\",\n \"requirementCn\": \"室外控制设备放置应远离强电磁干扰、强热源等环境,如无法避免应及时做好应急处置及检修, 保证设备正常运行\",\n \"requirementEn\": \"The outdoor control equipment should be placed away from strong electromagnetic interference, strong heat source and other extreme environments. If it is unavoidable, emergency treatment and maintenance should be done in time to ensure the normal operation of the equipment.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CNS5-01\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"工业控制系统与企业其他系统之间应划分为两个区域,区域间应采用单向的技术隔离手段\",\n \"requirementEn\": \"The industrial control system and other systems of the enterprise should be divided into two areas, and one-way technical isolation should be adopted between the areas.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CNS5-02\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"工业控制系统内部应根据业务特点划分为不同的安全域,安全域之间应采用技术隔离手段\",\n \"requirementEn\": \"The industrial control system should be intenally divided into different security domains according to the business feature. Technical isolation should be adopted between different security domains.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CNS5-03\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"涉及实时控制和数据传输的工业控制系统,应使用独立的网络设备组网,在物理层面上实现与其它数据网及外部公共信息网的安全隔离\",\n \"requirementEn\": \"Industrial control systems involving real-time control and data transmission should use independent network equipment to set up a network to achieve secure isolation from other data networks and external public information networks at physical level.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CNS5-04\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"通信传输\",\n \"controlEn\": \"Communication Transmission\",\n \"requirementCn\": \"在工业控制系统内使用广域网进行控制指令或相关数据交换的应采用加密认证技术手段实现身份认证、访问控制和数据加密传输\",\n \"requirementEn\": \"If WAN is used in industrial control system to control instructions or exchange related data, encryption and authentication technology should be adopted to realize identity authentication, access control and data encryption transmission\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在工业控制系统与企业其他系统之间部署访问控制设备,配置访问控制策略,禁止任何穿越区域边界的 E-Mail、Web、Telnet、Rlogin、FTP 等通用网络服务\",\n \"requirementEn\": \"The access control device should be deployed between the industrial control system and other enterprise systems, and the access control policy should be configured to prohibit any common network services such as E-Mail, Web, Telnet, Rlogin, and FTP that traverse the boundary of the area.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在工业控制系统内安全域和安全域之间的边界防护机制失效时,及时进行报警\",\n \"requirementEn\": \"The alarm should be promptly issued when the boundary protection mechanism between different security domains fails in the industrial control system.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"拨号使用控制\",\n \"controlEn\": \"Dail-up Use Control\",\n \"requirementCn\": \"工业控制系统确需使用拨号访问服务的,应限制具有拨号访问权限的用户数量,并采取用户身份鉴别和访问控制等措施\",\n \"requirementEn\": \"If the industrial control system needs to use the dial-up access service, it should limit the number of users with dial-up access rights, and take measures such as user identity authentication and access control.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-04\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"拨号使用控制\",\n \"controlEn\": \"Dail-up Use Control\",\n \"requirementCn\": \"拨号服务器和客户端均应使用经安全加固的操作系统,并采取数字证书认证、传输加密和访问控制等措施\",\n \"requirementEn\": \"Both the dial-up server and the client should use a security-hardened operating system and take measures such as digital certificate authentication, transport encryption, and access control.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-05\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"无线使用控制\",\n \"controlEn\": \"Wireless Use Control\",\n \"requirementCn\": \"应对所有参与无线通信的用户(人员、软件进程或者设备)提供唯一性标识和鉴别\",\n \"requirementEn\": \"Provide unique identification and authentication to all users (personnel, software processes or devices) involved in wireless communications\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-06\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"无线使用控制\",\n \"controlEn\": \"Wireless Use Control\",\n \"requirementCn\": \"应对所有参与无线通信的用户(人员、软件进程或者设备)进行授权以及执行使用进行限制\",\n \"requirementEn\": \"Restrictions on the authorization and execution of all users (personnel, software processes or devices) involved in wireless communication\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-07\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"无线使用控制\",\n \"controlEn\": \"Wireless Use Control\",\n \"requirementCn\": \"应对无线通信采取传输加密的安全措施,实现传输报文的机密性保护\",\n \"requirementEn\": \"Security measures for transmission encryption should be adopted for wireless communication to achieve confidentiality protection of transmitted messages.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-08\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"无线使用控制\",\n \"controlEn\": \"Wireless Use Control\",\n \"requirementCn\": \"对采用无线通信技术进行控制的工业控制系统,应能识别其物理环境中发射的未经授权的无线设备,报告未经授权试图接入或干扰控制系统的行为\",\n \"requirementEn\": \"Industrial control systems that use wireless communication technology should be able to identify unauthorized wireless devices transmitted in their physical environment and report unauthorized attempts to access or interfere with control systems.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"控制设备自身应实现相应级别安全通用要求提出的身份鉴别、访问控制和安全审计等安全要求,如受条件限制控制设备无法实现上述要求,应由其上位控制或管理设备实现同等功能或通过管理手段控制\",\n \"requirementEn\": \"The control device itself shall implement the security requirements such as identity authentication, access control and security audit proposed by the corresponding level of security general requirements. If the above requirements cannot be implemented by restricted conditions, the equivalent function should be implemented by its upper class control or controlled by management means\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"应在经过充分测试评估后,在不影响系统安全稳定运行的情况下对控制设备进行补丁更新、固件更新等工作\",\n \"requirementEn\": \"After sufficient testing and evaluation, patches and firmware update can be applied to the control equipment which should not affect the safe and stable operation of the system.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"应关闭或拆除控制设备的软盘驱动、光盘驱动、USB 接口、串行口或多余网口等,确需保留的必须通过相关的技术措施实施严格的监控管理\",\n \"requirementEn\": \"The floppy disk drive, CD-ROM drive, USB interface, serial port or redundant network port of the control device should be turned off or removed. It should be strictly monitored and managed through relevant technical measures if any of them are indeed to retain.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"应使用专用设备和专用软件对控制设备进行更新\",\n \"requirementEn\": \"Control equipment should be updated with dedicated equipment and software\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"应保证控制设备在上线前经过安全性检测,避免控制设备固件中存在恶意代码程序\",\n \"requirementEn\": \"It should be ensured that the control device is tested for security before going online, and there is no malicious code program in the control device firmware.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n }\n]","/**\n * MLPS Level 3 (等保三级) GB/T 22239-2019 full checklist mapping.\n *\n * Each of the 184 checks is classified into one of four types:\n * auto — scanner modules can evaluate pass/fail automatically\n * cloud_provider — AWS (cloud platform) is responsible; compliant by default\n * manual — requires manual verification or third-party tools\n * not_applicable — N/A for cloud-only environments (IoT, ICS, wireless, mobile, trusted verification)\n */\n\nimport checklistJson from \"./mlps3-full-checklist.json\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface MlpsChecklistItem {\n id: string;\n categoryCn: string;\n categoryEn: string;\n controlCn: string;\n controlEn: string;\n requirementCn: string;\n requirementEn: string;\n referenceStatus: string;\n referenceComment: string;\n}\n\nexport interface MlpsCheckMapping {\n id: string;\n type: \"auto\" | \"cloud_provider\" | \"manual\" | \"not_applicable\";\n /** For auto: which scanner modules to check */\n modules?: string[];\n /** For auto: specific Security Hub control IDs to match (e.g. \"EC2.2\", \"IAM.7\") */\n securityHubControlIds?: string[];\n /** For auto: keywords to match in finding title/description (use securityHubControlIds when possible) */\n findingPatterns?: string[];\n /** For manual: guidance text */\n guidance?: string;\n /** For cloud_provider: brief note */\n note?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Full checklist data (imported from JSON, bundled by tsup/esbuild)\n// ---------------------------------------------------------------------------\n\nexport const MLPS3_FULL_CHECKLIST: MlpsChecklistItem[] =\n checklistJson as MlpsChecklistItem[];\n\n// ---------------------------------------------------------------------------\n// Category ordering for the report\n// ---------------------------------------------------------------------------\n\nexport const MLPS3_CATEGORY_ORDER = [\n \"安全物理环境\",\n \"安全通信网络\",\n \"安全区域边界\",\n \"安全计算环境\",\n \"安全管理中心\",\n] as const;\n\nexport const MLPS3_CATEGORY_SECTION: Record<string, string> = {\n \"安全物理环境\": \"一、安全物理环境\",\n \"安全通信网络\": \"二、安全通信网络\",\n \"安全区域边界\": \"三、安全区域边界\",\n \"安全计算环境\": \"四、安全计算环境\",\n \"安全管理中心\": \"五、安全管理中心\",\n};\n\n// ---------------------------------------------------------------------------\n// Mapping: 184 checks → type + modules/patterns/guidance\n// ---------------------------------------------------------------------------\n\nexport const MLPS3_CHECK_MAPPING: MlpsCheckMapping[] = [\n // =========================================================================\n // 安全物理环境 — L3-PES1-* (22 items) → cloud_provider\n // =========================================================================\n { id: \"L3-PES1-01\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-02\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-03\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-04\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-05\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-06\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-07\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-08\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-09\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-10\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-11\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-12\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-13\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-14\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-15\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-16\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-17\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-18\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-19\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-20\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-21\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-22\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n\n // L3-PES2-01 (Cloud extension — physical infra in China)\n { id: \"L3-PES2-01\", type: \"cloud_provider\", note: \"AWS 中国区基础设施位于中国境内\" },\n\n // L3-PES3-01 (Wireless — N/A)\n { id: \"L3-PES3-01\", type: \"not_applicable\" },\n\n // L3-PES4-* (IoT sensor — N/A)\n { id: \"L3-PES4-01\", type: \"not_applicable\" },\n { id: \"L3-PES4-02\", type: \"not_applicable\" },\n { id: \"L3-PES4-03\", type: \"not_applicable\" },\n { id: \"L3-PES4-04\", type: \"not_applicable\" },\n\n // L3-PES5-* (Industrial control outdoor — N/A)\n { id: \"L3-PES5-01\", type: \"not_applicable\" },\n { id: \"L3-PES5-02\", type: \"not_applicable\" },\n\n // =========================================================================\n // 安全通信网络 — L3-CNS1-* (8 items)\n // =========================================================================\n { id: \"L3-CNS1-01\", type: \"cloud_provider\", note: \"AWS 负责网络设备处理能力\" },\n { id: \"L3-CNS1-02\", type: \"cloud_provider\", note: \"AWS 负责网络带宽\" },\n {\n id: \"L3-CNS1-03\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.2\"],\n },\n {\n id: \"L3-CNS1-04\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.2\", \"EC2.18\", \"EC2.19\"],\n },\n { id: \"L3-CNS1-05\", type: \"cloud_provider\", note: \"AWS 多可用区/多区域冗余\" },\n {\n id: \"L3-CNS1-06\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-CNS1-07\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n { id: \"L3-CNS1-08\", type: \"not_applicable\" },\n\n // L3-CNS2-* (Cloud extension communication — 5 items)\n { id: \"L3-CNS2-01\", type: \"cloud_provider\", note: \"AWS 等保涵盖\" },\n { id: \"L3-CNS2-02\", type: \"cloud_provider\", note: \"VPC 实现虚拟网络隔离\" },\n {\n id: \"L3-CNS2-03\",\n type: \"auto\",\n modules: [\"network_reachability\", \"waf_coverage\", \"guardduty_findings\"],\n },\n { id: \"L3-CNS2-04\", type: \"cloud_provider\", note: \"AWS 支持自主安全策略配置\" },\n { id: \"L3-CNS2-05\", type: \"cloud_provider\", note: \"AWS Marketplace 支持第三方产品\" },\n\n // L3-CNS5-* (Industrial control communication — N/A)\n { id: \"L3-CNS5-01\", type: \"not_applicable\" },\n { id: \"L3-CNS5-02\", type: \"not_applicable\" },\n { id: \"L3-CNS5-03\", type: \"not_applicable\" },\n { id: \"L3-CNS5-04\", type: \"not_applicable\" },\n\n // =========================================================================\n // 安全区域边界 — L3-ABS1-* (20 items)\n // =========================================================================\n {\n id: \"L3-ABS1-01\",\n type: \"auto\",\n modules: [\"network_reachability\", \"waf_coverage\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-02\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-03\",\n type: \"manual\",\n guidance: \"需确认 NAT Gateway、VPC Endpoint 配置,限制内部用户非授权外联\",\n },\n { id: \"L3-ABS1-04\", type: \"not_applicable\" },\n {\n id: \"L3-ABS1-05\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-06\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-07\",\n type: \"auto\",\n modules: [\"network_reachability\", \"waf_coverage\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-08\",\n type: \"manual\",\n guidance: \"需启用 WAF 或部署第三方下一代防火墙实现基于会话状态的访问控制\",\n },\n {\n id: \"L3-ABS1-09\",\n type: \"manual\",\n guidance: \"需启用 WAF 或部署第三方下一代防火墙实现基于应用协议的访问控制\",\n },\n {\n id: \"L3-ABS1-10\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\", \"inspector_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"GuardDuty.1\"],\n },\n {\n id: \"L3-ABS1-11\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\", \"inspector_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"GuardDuty.1\"],\n },\n {\n id: \"L3-ABS1-12\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\", \"inspector_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"GuardDuty.1\"],\n },\n {\n id: \"L3-ABS1-13\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-ABS1-14\",\n type: \"manual\",\n guidance: \"需在操作系统安装第三方杀毒软件,或部署下一代防火墙进行恶意代码检测\",\n },\n { id: \"L3-ABS1-15\", type: \"not_applicable\" },\n {\n id: \"L3-ABS1-16\",\n type: \"auto\",\n modules: [\"service_detection\", \"config_rules_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-ABS1-17\",\n type: \"auto\",\n modules: [\"service_detection\", \"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-ABS1-18\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.4\", \"CloudTrail.5\", \"CloudTrail.6\", \"CloudTrail.7\"],\n },\n {\n id: \"L3-ABS1-19\",\n type: \"manual\",\n guidance: \"需配置 S3 Access Log、ALB Access Log,或部署上网行为管理产品进行远程访问行为审计\",\n },\n { id: \"L3-ABS1-20\", type: \"not_applicable\" },\n\n // L3-ABS2-* (Cloud extension boundary — 8 items)\n {\n id: \"L3-ABS2-01\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS2-02\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS2-03\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-ABS2-04\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-ABS2-05\",\n type: \"auto\",\n modules: [\"guardduty_findings\"],\n },\n {\n id: \"L3-ABS2-06\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-ABS2-07\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-ABS2-08\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n\n // L3-ABS3-* (Wireless boundary — N/A)\n { id: \"L3-ABS3-01\", type: \"not_applicable\" },\n { id: \"L3-ABS3-02\", type: \"not_applicable\" },\n { id: \"L3-ABS3-03\", type: \"not_applicable\" },\n { id: \"L3-ABS3-04\", type: \"not_applicable\" },\n { id: \"L3-ABS3-05\", type: \"not_applicable\" },\n { id: \"L3-ABS3-06\", type: \"not_applicable\" },\n { id: \"L3-ABS3-07\", type: \"not_applicable\" },\n { id: \"L3-ABS3-08\", type: \"not_applicable\" },\n\n // L3-ABS4-* (IoT boundary — N/A)\n { id: \"L3-ABS4-01\", type: \"not_applicable\" },\n { id: \"L3-ABS4-02\", type: \"not_applicable\" },\n { id: \"L3-ABS4-03\", type: \"not_applicable\" },\n\n // L3-ABS5-* (Industrial control boundary — N/A)\n { id: \"L3-ABS5-01\", type: \"not_applicable\" },\n { id: \"L3-ABS5-02\", type: \"not_applicable\" },\n { id: \"L3-ABS5-03\", type: \"not_applicable\" },\n { id: \"L3-ABS5-04\", type: \"not_applicable\" },\n { id: \"L3-ABS5-05\", type: \"not_applicable\" },\n { id: \"L3-ABS5-06\", type: \"not_applicable\" },\n { id: \"L3-ABS5-07\", type: \"not_applicable\" },\n { id: \"L3-ABS5-08\", type: \"not_applicable\" },\n\n // =========================================================================\n // 安全计算环境 — L3-CES1-* (34 items, no CES1-16)\n // =========================================================================\n {\n id: \"L3-CES1-01\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"access_analyzer_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.7\", \"IAM.10\", \"IAM.11\"],\n },\n {\n id: \"L3-CES1-02\",\n type: \"manual\",\n guidance: \"需配置堡垒机或通过 CloudTrail + CloudWatch Alarm + Lambda 实现登录失败处理\",\n },\n {\n id: \"L3-CES1-03\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-CES1-04\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"IAM.5\", \"IAM.6\"],\n },\n {\n id: \"L3-CES1-05\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"access_analyzer_findings\"],\n },\n {\n id: \"L3-CES1-06\",\n type: \"manual\",\n guidance: \"需确认已重命名或删除默认账户(如 root 直接登录),修改默认口令\",\n },\n {\n id: \"L3-CES1-07\",\n type: \"auto\",\n modules: [\"security_hub_findings\", \"access_analyzer_findings\"],\n securityHubControlIds: [\"IAM.3\", \"IAM.4\", \"IAM.22\"],\n },\n {\n id: \"L3-CES1-08\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.1\", \"IAM.21\"],\n },\n {\n id: \"L3-CES1-09\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"access_analyzer_findings\"],\n },\n {\n id: \"L3-CES1-10\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.1\", \"IAM.21\"],\n },\n {\n id: \"L3-CES1-11\",\n type: \"manual\",\n guidance: \"需在应用层对敏感信息进行分类,利用 Tag 或 Metadata 标记数据,配合访问控制策略管控\",\n },\n {\n id: \"L3-CES1-12\",\n type: \"auto\",\n modules: [\"service_detection\", \"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-CES1-13\",\n type: \"auto\",\n modules: [\"service_detection\", \"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-CES1-14\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.4\", \"CloudTrail.5\", \"CloudTrail.6\", \"CloudTrail.7\"],\n },\n {\n id: \"L3-CES1-15\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.4\", \"CloudTrail.5\"],\n },\n // Note: L3-CES1-16 does not exist in the standard\n {\n id: \"L3-CES1-17\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-CES1-18\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-CES1-19\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-CES1-20\",\n type: \"manual\",\n guidance: \"需启用 WAF 规则进行输入验证,或在应用层实现数据有效性检验\",\n },\n {\n id: \"L3-CES1-21\",\n type: \"auto\",\n modules: [\"inspector_findings\", \"patch_compliance_findings\"],\n },\n {\n id: \"L3-CES1-22\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-CES1-23\",\n type: \"manual\",\n guidance: \"需在操作系统层安装第三方杀毒产品;可结合 GuardDuty 检测恶意行为\",\n },\n { id: \"L3-CES1-24\", type: \"not_applicable\" },\n {\n id: \"L3-CES1-25\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-CES1-26\",\n type: \"manual\",\n guidance: \"需安装第三方防篡改软件;S3 可利用对象校验确保完整性\",\n },\n {\n id: \"L3-CES1-27\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-CES1-28\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"S3.4\", \"EC2.7\", \"RDS.3\"],\n },\n {\n id: \"L3-CES1-29\",\n type: \"auto\",\n modules: [\"disaster_recovery\"],\n },\n {\n id: \"L3-CES1-30\",\n type: \"auto\",\n modules: [\"disaster_recovery\"],\n },\n {\n id: \"L3-CES1-31\",\n type: \"auto\",\n modules: [\"disaster_recovery\"],\n },\n { id: \"L3-CES1-32\", type: \"cloud_provider\", note: \"AWS 存储服务数据清除策略覆盖\" },\n { id: \"L3-CES1-33\", type: \"cloud_provider\", note: \"AWS 存储服务数据清除策略覆盖\" },\n {\n id: \"L3-CES1-34\",\n type: \"manual\",\n guidance: \"应用侧行为 — 需确认仅采集和保存业务必需的用户个人信息\",\n },\n {\n id: \"L3-CES1-35\",\n type: \"manual\",\n guidance: \"应用侧行为 — 需确认禁止未授权访问和非法使用用户个人信息\",\n },\n\n // L3-CES2-* (Cloud extension computing — 19 items)\n {\n id: \"L3-CES2-01\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"IAM.5\", \"IAM.6\"],\n },\n { id: \"L3-CES2-02\", type: \"cloud_provider\", note: \"AWS 确保 VM 迁移时访问控制随迁\" },\n {\n id: \"L3-CES2-03\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n { id: \"L3-CES2-04\", type: \"cloud_provider\", note: \"AWS 负责虚拟化资源隔离\" },\n {\n id: \"L3-CES2-05\",\n type: \"auto\",\n modules: [\"guardduty_findings\"],\n },\n {\n id: \"L3-CES2-06\",\n type: \"manual\",\n guidance: \"需部署第三方入侵防范和杀毒产品检测虚拟机间恶意代码蔓延\",\n },\n {\n id: \"L3-CES2-07\",\n type: \"manual\",\n guidance: \"若不使用 AWS 官方镜像,需自行加固操作系统\",\n },\n {\n id: \"L3-CES2-08\",\n type: \"manual\",\n guidance: \"若不使用 AWS 官方镜像,需自行校验镜像和快照完整性\",\n },\n {\n id: \"L3-CES2-09\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"EC2.7\"],\n },\n { id: \"L3-CES2-10\", type: \"cloud_provider\", note: \"AWS 中国区数据存储于中国境内\" },\n { id: \"L3-CES2-11\", type: \"cloud_provider\", note: \"AWS 仅在客户授权下管理数据\" },\n { id: \"L3-CES2-12\", type: \"cloud_provider\", note: \"AWS 确保 VM 迁移数据完整性\" },\n {\n id: \"L3-CES2-13\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"KMS.4\"],\n },\n { id: \"L3-CES2-14\", type: \"not_applicable\" },\n { id: \"L3-CES2-15\", type: \"cloud_provider\", note: \"AWS 支持查询数据及备份存储位置\" },\n { id: \"L3-CES2-16\", type: \"cloud_provider\", note: \"AWS 存储服务保证多副本一致\" },\n { id: \"L3-CES2-17\", type: \"not_applicable\" },\n { id: \"L3-CES2-18\", type: \"cloud_provider\", note: \"AWS 确保 VM 内存和存储空间回收时完全清除\" },\n { id: \"L3-CES2-19\", type: \"cloud_provider\", note: \"AWS 确保删除数据时清除所有副本\" },\n\n // L3-CES3-* (Mobile — N/A)\n { id: \"L3-CES3-01\", type: \"not_applicable\" },\n { id: \"L3-CES3-02\", type: \"not_applicable\" },\n { id: \"L3-CES3-03\", type: \"not_applicable\" },\n { id: \"L3-CES3-04\", type: \"not_applicable\" },\n { id: \"L3-CES3-05\", type: \"not_applicable\" },\n\n // L3-CES4-* (IoT sensor/gateway — N/A)\n { id: \"L3-CES4-01\", type: \"not_applicable\" },\n { id: \"L3-CES4-02\", type: \"not_applicable\" },\n { id: \"L3-CES4-03\", type: \"not_applicable\" },\n { id: \"L3-CES4-04\", type: \"not_applicable\" },\n { id: \"L3-CES4-05\", type: \"not_applicable\" },\n { id: \"L3-CES4-06\", type: \"not_applicable\" },\n { id: \"L3-CES4-07\", type: \"not_applicable\" },\n { id: \"L3-CES4-08\", type: \"not_applicable\" },\n { id: \"L3-CES4-09\", type: \"not_applicable\" },\n { id: \"L3-CES4-10\", type: \"not_applicable\" },\n { id: \"L3-CES4-11\", type: \"not_applicable\" },\n\n // L3-CES5-* (Industrial control — N/A)\n { id: \"L3-CES5-01\", type: \"not_applicable\" },\n { id: \"L3-CES5-02\", type: \"not_applicable\" },\n { id: \"L3-CES5-03\", type: \"not_applicable\" },\n { id: \"L3-CES5-04\", type: \"not_applicable\" },\n { id: \"L3-CES5-05\", type: \"not_applicable\" },\n\n // =========================================================================\n // 安全管理中心 — L3-SMC1-* (12 items)\n // =========================================================================\n {\n id: \"L3-SMC1-01\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.4\", \"IAM.6\"],\n },\n {\n id: \"L3-SMC1-02\",\n type: \"auto\",\n modules: [\"security_hub_findings\", \"config_rules_findings\"],\n securityHubControlIds: [\"Config.1\"],\n },\n {\n id: \"L3-SMC1-03\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.4\", \"IAM.6\"],\n },\n {\n id: \"L3-SMC1-04\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-SMC1-05\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.4\", \"IAM.6\"],\n },\n {\n id: \"L3-SMC1-06\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.1\", \"IAM.21\"],\n },\n {\n id: \"L3-SMC1-07\",\n type: \"auto\",\n modules: [\"service_detection\"],\n findingPatterns: [\"Security Hub\"],\n },\n {\n id: \"L3-SMC1-08\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-SMC1-09\",\n type: \"manual\",\n guidance: \"需配置 CloudWatch 集中监控平台,结合 SNS 进行告警通知\",\n },\n {\n id: \"L3-SMC1-10\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-SMC1-11\",\n type: \"manual\",\n guidance: \"需部署第三方防入侵和防病毒产品进行安全策略、恶意代码、补丁升级集中管理\",\n },\n {\n id: \"L3-SMC1-12\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"GuardDuty.1\"],\n },\n\n // L3-SMC2-* (Cloud extension management center — 4 items)\n { id: \"L3-SMC2-01\", type: \"cloud_provider\", note: \"AWS 负责统一管理调度和分配\" },\n { id: \"L3-SMC2-02\", type: \"cloud_provider\", note: \"AWS 确保管理流量与业务流量分离\" },\n { id: \"L3-SMC2-03\", type: \"cloud_provider\", note: \"AWS 基于责任共担模型实现集中审计\" },\n { id: \"L3-SMC2-04\", type: \"cloud_provider\", note: \"AWS 基于责任共担模型实现集中监测\" },\n];\n\n// ---------------------------------------------------------------------------\n// Lookup helper — build an index for fast access\n// ---------------------------------------------------------------------------\n\nconst _mappingIndex = new Map<string, MlpsCheckMapping>();\nfor (const m of MLPS3_CHECK_MAPPING) {\n _mappingIndex.set(m.id, m);\n}\n\nexport function getMappingById(id: string): MlpsCheckMapping | undefined {\n return _mappingIndex.get(id);\n}\n","import type { FullScanResult, Finding } from \"../types.js\";\nimport {\n MLPS3_FULL_CHECKLIST,\n MLPS3_CHECK_MAPPING,\n MLPS3_CATEGORY_ORDER,\n MLPS3_CATEGORY_SECTION,\n getMappingById,\n type MlpsChecklistItem,\n type MlpsCheckMapping,\n} from \"../data/mlps3-check-mapping.js\";\nimport { getI18n, type Lang } from \"../i18n/index.js\";\n\n// Re-export for use by html-report and tests\nexport {\n MLPS3_FULL_CHECKLIST,\n MLPS3_CHECK_MAPPING,\n MLPS3_CATEGORY_ORDER,\n MLPS3_CATEGORY_SECTION,\n getMappingById,\n type MlpsChecklistItem,\n type MlpsCheckMapping,\n} from \"../data/mlps3-check-mapping.js\";\n\n// ---------------------------------------------------------------------------\n// Full-checklist evaluation result\n// ---------------------------------------------------------------------------\n\nexport type FullCheckStatus = \"clean\" | \"issues\" | \"unknown\" | \"cloud_provider\" | \"manual\" | \"not_applicable\";\n\nexport interface FullCheckResult {\n item: MlpsChecklistItem;\n mapping: MlpsCheckMapping;\n status: FullCheckStatus;\n relatedFindings: Finding[];\n}\n\n/**\n * Evaluate a single checklist item against scan results.\n */\nexport function evaluateFullCheck(\n item: MlpsChecklistItem,\n mapping: MlpsCheckMapping,\n allFindings: Finding[],\n scanModules: Array<{ module: string; status: string }>,\n): FullCheckResult {\n if (mapping.type === \"cloud_provider\") {\n return { item, mapping, status: \"cloud_provider\", relatedFindings: [] };\n }\n if (mapping.type === \"not_applicable\") {\n return { item, mapping, status: \"not_applicable\", relatedFindings: [] };\n }\n if (mapping.type === \"manual\") {\n return { item, mapping, status: \"manual\", relatedFindings: [] };\n }\n\n // Type \"auto\" — check modules present and evaluate findings\n const mods = mapping.modules ?? [];\n\n const allModulesPresent = mods.every((mod) =>\n scanModules.some((m) => m.module === mod && m.status === \"success\"),\n );\n\n if (!allModulesPresent) {\n return { item, mapping, status: \"unknown\", relatedFindings: [] };\n }\n\n let relatedFindings: Finding[];\n\n if (mapping.securityHubControlIds?.length) {\n // Hybrid: security_hub_findings filtered by specific control IDs,\n // other scanner modules matched at module level (all findings count)\n relatedFindings = allFindings.filter((f) => {\n if (!mods.includes(f.module ?? \"\")) return false;\n if (f.module === \"security_hub_findings\") {\n return mapping.securityHubControlIds!.some((id) => f.title.includes(id));\n }\n return true;\n });\n } else if (mapping.findingPatterns?.length) {\n // Pattern-based matching (for service_detection or other special cases)\n const patterns = mapping.findingPatterns;\n relatedFindings = allFindings.filter((f) => {\n if (!mods.includes(f.module ?? \"\")) return false;\n const text = `${f.title} ${f.description}`.toLowerCase();\n return patterns.some((pattern) => text.includes(pattern.toLowerCase()));\n });\n } else {\n // Module-level: any findings from mapped modules = fail\n relatedFindings = allFindings.filter((f) => mods.includes(f.module ?? \"\"));\n }\n\n // Evidence collection: clean (0 findings) or issues (1+ findings)\n const status: FullCheckStatus = relatedFindings.length === 0 ? \"clean\" : \"issues\";\n\n return { item, mapping, status, relatedFindings };\n}\n\n/**\n * Evaluate all 184 checks from the full GB/T 22239-2019 checklist.\n */\nexport function evaluateAllFullChecks(\n scanResults: FullScanResult,\n): FullCheckResult[] {\n const allFindings: Finding[] = scanResults.modules.flatMap((m) =>\n m.findings.map((f) => ({ ...f, module: f.module ?? m.module })),\n );\n const scanModules = scanResults.modules.map((m) => ({\n module: m.module,\n status: m.status,\n }));\n\n return MLPS3_FULL_CHECKLIST.map((item) => {\n const mapping = getMappingById(item.id);\n if (!mapping) {\n // Unmapped check — treat as manual\n return {\n item,\n mapping: { id: item.id, type: \"manual\" as const, guidance: \"未映射的检查项\" },\n status: \"manual\" as FullCheckStatus,\n relatedFindings: [],\n };\n }\n return evaluateFullCheck(item, mapping, allFindings, scanModules);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Legacy types and exports (kept for backward compatibility)\n// ---------------------------------------------------------------------------\n\nexport interface MlpsCheck {\n id: string;\n category: string;\n name: string;\n modules: string[];\n findingPatterns: string[];\n}\n\nexport const MLPS_CHECKS: MlpsCheck[] = [\n // 一、身份鉴别\n {\n id: \"8.1.4.1a\",\n category: \"身份鉴别\",\n name: \"密码策略\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"password policy\", \"password length\", \"complexity\", \"password expiry\", \"reuse prevention\", \"IAM.7\", \"IAM.10\"],\n },\n {\n id: \"8.1.4.1a\",\n category: \"身份鉴别\",\n name: \"密钥轮换\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"access key older\", \"access key rotated\", \"IAM.3\", \"IAM.4\"],\n },\n {\n id: \"8.1.4.1d\",\n category: \"身份鉴别\",\n name: \"双因素认证\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"MFA\", \"IAM.5\", \"IAM.6\"],\n },\n // 二、访问控制\n {\n id: \"8.1.4.2c\",\n category: \"访问控制\",\n name: \"最小权限\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n findingPatterns: [\n \"AdministratorAccess\", \"PowerUserAccess\", \"IAMFullAccess\",\n \"over-permissive\", \"privilege escalation\",\n \"self-grant\", \"iam:*\", \"create admin\", \"Lambda role passing\",\n \"CreateAccessKey\", \"AssumeRole\",\n ],\n },\n {\n id: \"8.1.4.2\",\n category: \"访问控制\",\n name: \"安全组\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n findingPatterns: [\"allows all ports\", \"allows SSH\", \"allows RDP\", \"MySQL\", \"PostgreSQL\", \"MongoDB\", \"Redis\", \"high-risk port\", \"security group\", \"EC2.18\", \"EC2.19\"],\n },\n // 三、安全审计\n {\n id: \"8.1.4.3a\",\n category: \"安全审计\",\n name: \"审计功能\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"CloudTrail\", \"not enabled\", \"multi-region\", \"not logging\", \"CloudTrail.1\"],\n },\n {\n id: \"8.1.4.3b\",\n category: \"安全审计\",\n name: \"审计完整性\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"log file validation\", \"log integrity\", \"log validation\", \"CloudTrail.4\", \"CloudTrail.5\"],\n },\n {\n id: \"8.1.4.3c\",\n category: \"安全审计\",\n name: \"审计保护\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"CloudTrail\", \"S3 bucket\", \"encryption\", \"versioning\", \"Block Public Access\", \"CloudTrail.6\", \"CloudTrail.7\"],\n },\n // 四、入侵防范\n {\n id: \"8.1.4.4a\",\n category: \"入侵防范\",\n name: \"GuardDuty 威胁检测\",\n modules: [\"service_detection\", \"guardduty_findings\"],\n findingPatterns: [\"GuardDuty\"],\n },\n {\n id: \"8.1.4.4a\",\n category: \"入侵防范\",\n name: \"Inspector 漏洞扫描\",\n modules: [\"service_detection\", \"inspector_findings\"],\n findingPatterns: [\"Inspector\", \"CVE-\"],\n },\n // 五、数据安全\n {\n id: \"8.1.4.5a\",\n category: \"数据安全\",\n name: \"传输加密\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n findingPatterns: [\"HTTPS\", \"TLS\", \"HTTP listener\", \"certificate\", \"ELB.1\"],\n },\n {\n id: \"8.1.4.5b\",\n category: \"数据安全\",\n name: \"S3 存储加密\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"no default encryption\", \"not encrypted\", \"S3.4\"],\n },\n {\n id: \"8.1.4.5b\",\n category: \"数据安全\",\n name: \"EBS 默认加密\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"EBS default encryption\", \"EC2.7\"],\n },\n {\n id: \"8.1.4.5b\",\n category: \"数据安全\",\n name: \"RDS 存储加密\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"storage is not encrypted\", \"RDS.3\"],\n },\n // 六、网络安全\n {\n id: \"8.1.3.1a\",\n category: \"网络安全\",\n name: \"网络架构\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"default VPC\", \"EC2.2\"],\n },\n {\n id: \"8.1.3.2a\",\n category: \"网络安全\",\n name: \"边界防护\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n findingPatterns: [\"allows all ports\", \"allows SSH\", \"allows RDP\", \"security group\", \"EC2.18\", \"EC2.19\"],\n },\n];\n\nexport const CATEGORY_ORDER = [\n \"身份鉴别\",\n \"访问控制\",\n \"安全审计\",\n \"入侵防范\",\n \"数据安全\",\n \"网络安全\",\n];\n\nexport const CATEGORY_SECTION: Record<string, string> = {\n \"身份鉴别\": \"一、身份鉴别\",\n \"访问控制\": \"二、访问控制\",\n \"安全审计\": \"三、安全审计\",\n \"入侵防范\": \"四、入侵防范\",\n \"数据安全\": \"五、数据安全\",\n \"网络安全\": \"六、网络安全\",\n};\n\nexport interface CheckResult {\n check: MlpsCheck;\n status: \"clean\" | \"issues\" | \"unknown\";\n relatedFindings: Finding[];\n}\n\nexport function evaluateCheck(\n check: MlpsCheck,\n allFindings: Finding[],\n scanModules: Array<{ module: string; status: string }>,\n): CheckResult {\n // Verify all required modules ran successfully\n const allModulesPresent = check.modules.every((mod) =>\n scanModules.some((m) => m.module === mod && m.status === \"success\"),\n );\n\n if (!allModulesPresent) {\n return { check, status: \"unknown\", relatedFindings: [] };\n }\n\n // Find findings from the relevant modules that match any of the patterns\n const relatedFindings = allFindings.filter((f) => {\n const moduleMatch = check.modules.some((mod) => f.module === mod);\n if (!moduleMatch) return false;\n\n const text = `${f.title} ${f.description}`.toLowerCase();\n return check.findingPatterns.some((pattern) =>\n text.includes(pattern.toLowerCase()),\n );\n });\n\n return {\n check,\n status: relatedFindings.length === 0 ? \"clean\" : \"issues\",\n relatedFindings,\n };\n}\n\nexport function generateMlps3Report(scanResults: FullScanResult, lang?: Lang): string {\n const t = getI18n(lang ?? \"zh\");\n const isEn = (lang ?? \"zh\") === \"en\";\n const { accountId, region, scanStart } = scanResults;\n const scanTime = scanStart.replace(\"T\", \" \").replace(/\\.\\d+Z$/, \" UTC\");\n\n // Evaluate all 184 checks from the full GB/T 22239-2019 checklist\n const results = evaluateAllFullChecks(scanResults);\n\n // Summary counts by type\n const autoResults = results.filter((r) => r.mapping.type === \"auto\");\n const autoClean = autoResults.filter((r) => r.status === \"clean\").length;\n const autoIssues = autoResults.filter((r) => r.status === \"issues\").length;\n const autoUnknown = autoResults.filter((r) => r.status === \"unknown\").length;\n const checkedTotal = autoClean + autoIssues;\n const cloudCount = results.filter((r) => r.status === \"cloud_provider\").length;\n const manualCount = results.filter((r) => r.status === \"manual\").length;\n const naCount = results.filter((r) => r.status === \"not_applicable\").length;\n\n // Helpers for language-aware item text\n const itemControl = (r: FullCheckResult) => isEn ? r.item.controlEn : r.item.controlCn;\n const itemReq = (r: FullCheckResult) => isEn ? r.item.requirementEn : r.item.requirementCn;\n\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${t.mlpsTitle}`);\n lines.push(`> **${t.mlpsDisclaimer}**`);\n lines.push(\"\");\n\n // Account info\n lines.push(`## ${t.accountInfo}`);\n lines.push(`- ${t.account}: ${accountId} | ${t.region}: ${region} | ${t.scanTime}: ${scanTime}`);\n lines.push(\"\");\n\n // Summary\n lines.push(`## ${t.preCheckOverview}`);\n lines.push(`- ${t.checkedCount(checkedTotal, autoClean, autoIssues)}`);\n if (autoUnknown > 0) {\n lines.push(`- ${t.uncheckedCount(autoUnknown)}`);\n }\n lines.push(`- ${t.cloudProviderCount(cloudCount)}`);\n lines.push(`- ${t.manualReviewCount(manualCount)}`);\n if (naCount > 0) {\n lines.push(`- ${t.naCount(naCount)}`);\n }\n lines.push(\"\");\n\n // Group results by categoryCn (skip N/A items)\n for (const category of MLPS3_CATEGORY_ORDER) {\n const sectionTitle = t.mlpsCategorySection[category] ?? category;\n const catResults = results.filter(\n (r) => r.item.categoryCn === category && r.status !== \"not_applicable\",\n );\n if (catResults.length === 0) continue;\n\n lines.push(`## ${sectionTitle}`);\n lines.push(\"\");\n\n // Group by control within category\n const controlMap = new Map<string, FullCheckResult[]>();\n for (const r of catResults) {\n const key = r.item.controlCn;\n if (!controlMap.has(key)) controlMap.set(key, []);\n controlMap.get(key)!.push(r);\n }\n\n for (const [_controlKey, controlResults] of controlMap) {\n const controlName = itemControl(controlResults[0]);\n lines.push(`### ${controlName}`);\n for (const r of controlResults) {\n const icon = r.status === \"clean\" ? \"\\u2705\"\n : r.status === \"issues\" ? \"\\u274c\"\n : r.status === \"unknown\" ? \"\\u26a0\\ufe0f\"\n : r.status === \"manual\" ? \"\\ud83d\\udccb\"\n : \"\\ud83c\\udfe2\";\n const suffix = r.status === \"unknown\" ? ` \\u2014 ${t.notChecked}`\n : r.status === \"manual\" ? ` \\u2014 ${r.mapping.guidance ?? t.manualReview}`\n : r.status === \"cloud_provider\" ? ` \\u2014 ${r.mapping.note ?? t.cloudProvider}`\n : r.status === \"clean\" ? ` ${t.noIssues}`\n : ` ${t.issuesFound}`;\n\n const reqText = itemReq(r);\n lines.push(`- [${icon}] ${r.item.id} ${reqText.slice(0, 60)}${reqText.length > 60 ? \"\\u2026\" : \"\"}${suffix}`);\n if (r.status === \"issues\" && r.relatedFindings.length > 0) {\n for (const f of r.relatedFindings.slice(0, 3)) {\n lines.push(` - ${f.severity}: ${f.title}`);\n }\n if (r.relatedFindings.length > 3) {\n lines.push(` - ${t.andMore(r.relatedFindings.length - 3)}`);\n }\n }\n }\n lines.push(\"\");\n }\n }\n\n // Remediation recommendations sorted by priority\n const failedResults = results.filter((r) => r.status === \"issues\");\n if (failedResults.length > 0) {\n lines.push(`## ${t.remediationByPriority}`);\n lines.push(\"\");\n\n // Collect all related findings from failed checks, deduplicate, sort by riskScore\n const allFailedFindings = new Map<string, Finding>();\n for (const r of failedResults) {\n for (const f of r.relatedFindings) {\n const key = `${f.resourceId}:${f.title}`;\n if (!allFailedFindings.has(key)) {\n allFailedFindings.set(key, f);\n }\n }\n }\n\n const sorted = [...allFailedFindings.values()].sort(\n (a, b) => b.riskScore - a.riskScore,\n );\n\n for (let i = 0; i < sorted.length; i++) {\n const f = sorted[i];\n const priority = f.riskScore >= 9.0 ? \"P0\" : f.riskScore >= 7.0 ? \"P1\" : f.riskScore >= 4.0 ? \"P2\" : \"P3\";\n const remediation = f.remediationSteps[0] ?? \"Review and remediate.\";\n lines.push(`${i + 1}. [${priority}] ${f.title} — ${remediation}`);\n }\n lines.push(\"\");\n }\n\n // N/A note\n if (naCount > 0) {\n lines.push(`> ${t.naNote(naCount)}`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n","import type { FullScanResult, Finding, Severity, DashboardHistoryEntry, ScanResult } from \"../types.js\";\nimport {\n evaluateAllFullChecks,\n MLPS3_CATEGORY_ORDER,\n type FullCheckResult,\n} from \"./mlps-report.js\";\nimport { VERSION } from \"../version.js\";\nimport { getI18n, type Lang } from \"../i18n/index.js\";\nimport { getSecurityHubSource } from \"../utils/sh-source.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction esc(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/** Escape HTML but render URLs as clickable links */\nfunction escWithLinks(s: string): string {\n const parts = s.split(/(https?:\\/\\/\\S+)/);\n return parts.map((part, i) => {\n if (i % 2 === 1) {\n return `<a href=\"${esc(part)}\" style=\"color:#60a5fa\" target=\"_blank\" rel=\"noopener\">${esc(part)}</a>`;\n }\n return esc(part);\n }).join(\"\");\n}\n\nfunction calcScore(summary: FullScanResult[\"summary\"]): number {\n const raw =\n 100 -\n summary.critical * 15 -\n summary.high * 5 -\n summary.medium * 2 -\n summary.low * 0.5;\n return Math.max(0, Math.min(100, Math.round(raw)));\n}\n\nfunction formatDuration(start: string, end: string): string {\n const ms = new Date(end).getTime() - new Date(start).getTime();\n if (ms < 1000) return `${ms}ms`;\n const secs = Math.round(ms / 1000);\n if (secs < 60) return `${secs}s`;\n return `${Math.floor(secs / 60)}m ${secs % 60}s`;\n}\n\nconst SEV_COLOR: Record<Severity, string> = {\n CRITICAL: \"#ef4444\",\n HIGH: \"#f97316\",\n MEDIUM: \"#eab308\",\n LOW: \"#22c55e\",\n};\n\nconst SEVERITY_ORDER: Severity[] = [\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"];\n\n/** Normalize a recommendation by replacing resource-specific identifiers with placeholders. */\nfunction getRecommendationTemplate(rem: string): string {\n return rem\n .replace(/\\b(i-[0-9a-f]+)\\b/g, '{instance}')\n .replace(/\\b(vol-[0-9a-f]+)\\b/g, '{volume}')\n .replace(/\\b(sg-[0-9a-f]+)\\b/g, '{sg}')\n .replace(/\\b(eipalloc-[0-9a-f]+)\\b/g, '{eip}')\n .replace(/\\b(arn:aws[-\\w]*:[^\"\\s]+)\\b/g, '{arn}')\n .replace(/\"[^\"]+\"/g, '{name}')\n .replace(/bucket \\S+/g, 'bucket {name}')\n .replace(/instance \\S+/g, 'instance {id}')\n .replace(/volume \\S+/g, 'volume {id}')\n .replace(/rule \\S+/g, 'rule {name}');\n}\n\nconst SECURITY_HUB_SUB_CAT_ORDER = [\"FSBP\", \"Inspector\", \"GuardDuty\", \"Config\", \"Access Analyzer\", \"Other\"];\n\nfunction scoreColor(score: number): string {\n if (score >= 80) return \"#22c55e\";\n if (score >= 50) return \"#eab308\";\n return \"#ef4444\";\n}\n\n// ---------------------------------------------------------------------------\n// Service Dependency Reminder\n// ---------------------------------------------------------------------------\n\n// SERVICE_RECOMMENDATIONS are now in the i18n module (t.serviceRecommendations)\n\nconst SERVICE_NOT_ENABLED_PATTERNS = [\n \"not enabled\",\n \"not found\",\n \"No IAM Access Analyzer\",\n \"No SSM-managed instances\",\n \"requires AWS Business or Enterprise Support\",\n \"not available\",\n \"is not enabled\",\n];\n\nfunction getDisabledServices(modules: ScanResult[], lang?: Lang): Array<{ icon: string; service: string; impact: string; action: string }> {\n const t = getI18n(lang ?? \"zh\");\n const disabled: Array<{ icon: string; service: string; impact: string; action: string }> = [];\n for (const mod of modules) {\n const rec = t.serviceRecommendations[mod.module];\n if (!rec) continue;\n if (!mod.warnings?.length) continue;\n const hasNotEnabled = mod.warnings.some((w) =>\n SERVICE_NOT_ENABLED_PATTERNS.some((p) => w.includes(p)),\n );\n if (hasNotEnabled) {\n disabled.push(rec);\n }\n }\n return disabled;\n}\n\nfunction buildServiceReminderHtml(modules: ScanResult[], lang?: Lang): string {\n const t = getI18n(lang ?? \"zh\");\n const disabled = getDisabledServices(modules, lang);\n if (disabled.length === 0) return \"\";\n\n const items = disabled.map((svc) => `\n <div style=\"margin-bottom:12px\">\n <div style=\"font-weight:600;font-size:15px\">${esc(svc.icon)} ${esc(svc.service)} ${esc(t.notEnabled)}</div>\n <div style=\"margin-left:28px;color:#cbd5e1;font-size:13px\">${esc(t.serviceImpact)}\\uff1a${esc(svc.impact)}</div>\n <div style=\"margin-left:28px;color:#cbd5e1;font-size:13px\">${esc(t.serviceAction)}\\uff1a${esc(svc.action)}</div>\n </div>`).join(\"\\n\");\n\n return `\n <section>\n <div style=\"background:#2d1f00;border:1px solid #b45309;border-radius:8px;padding:20px;margin-bottom:32px\">\n <div style=\"font-size:17px;font-weight:700;margin-bottom:12px\">${esc(t.serviceReminderTitle)}</div>\n ${items}\n <div style=\"margin-top:12px;font-size:13px;color:#fbbf24;font-weight:500\">${esc(t.serviceReminderFooter)}</div>\n </div>\n </section>`;\n}\n\n// ---------------------------------------------------------------------------\n// CSS\n// ---------------------------------------------------------------------------\n\nfunction sharedCss(): string {\n return `\n *{margin:0;padding:0;box-sizing:border-box}\n body{background:#0f172a;color:#f8fafc;font-family:Inter,system-ui,-apple-system,sans-serif;line-height:1.6;font-size:14px}\n .container{max-width:900px;margin:0 auto;padding:40px 24px}\n header{text-align:center;margin-bottom:40px;border-bottom:1px solid #334155;padding-bottom:24px}\n header h1{font-size:28px;font-weight:700;margin-bottom:8px;letter-spacing:-0.5px}\n .meta{color:#94a3b8;font-size:13px}\n .disclaimer{color:#94a3b8;font-size:12px;font-style:italic;margin-top:8px;max-width:640px;margin-left:auto;margin-right:auto}\n h2{font-size:20px;font-weight:600;margin:32px 0 16px;padding-bottom:8px;border-bottom:1px solid #334155}\n h3{font-size:16px;font-weight:600;margin:16px 0 8px}\n h4{font-size:14px;font-weight:600;margin:12px 0 4px}\n .card{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:20px;margin-bottom:16px}\n .summary{display:flex;gap:24px;margin-bottom:32px;flex-wrap:wrap}\n .score-card{background:#1e293b;border:1px solid #334155;border-radius:12px;padding:24px 32px;text-align:center;flex:0 0 auto}\n .score-value{font-size:48px;font-weight:700}\n .score-label{color:#94a3b8;font-size:13px;margin-top:4px}\n .severity-stats{display:flex;gap:12px;flex-wrap:wrap;flex:1;align-items:center;justify-content:center}\n .stat-card{border-radius:8px;padding:16px 20px;text-align:center;min-width:100px;border:1px solid #334155;background:#1e293b}\n .stat-count{font-size:28px;font-weight:700}\n .stat-label{font-size:12px;color:#94a3b8;margin-top:2px}\n .stat-critical .stat-count{color:#ef4444}\n .stat-high .stat-count{color:#f97316}\n .stat-medium .stat-count{color:#eab308}\n .stat-low .stat-count{color:#22c55e}\n .charts{display:flex;gap:24px;margin-bottom:32px;flex-wrap:wrap;justify-content:center}\n .chart-box{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:20px;flex:1;min-width:280px}\n .chart-title{font-size:14px;font-weight:600;margin-bottom:12px;text-align:center;color:#cbd5e1}\n .sev-critical{border-left-color:#ef4444}\n .sev-high{border-left-color:#f97316}\n .sev-medium{border-left-color:#eab308}\n .sev-low{border-left-color:#22c55e}\n .badge{display:inline-block;padding:2px 10px;border-radius:4px;font-size:11px;font-weight:700;letter-spacing:0.5px;color:#fff}\n .badge-critical{background:#ef4444}\n .badge-high{background:#f97316}\n .badge-medium{background:#eab308;color:#1e293b}\n .badge-low{background:#22c55e;color:#1e293b}\n .finding-title{font-size:15px;font-weight:600;margin-bottom:8px}\n .finding-detail{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n .finding-detail strong{color:#f8fafc}\n .remediation-steps{margin-top:8px;padding-left:20px}\n .remediation-steps li{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n table{width:100%;border-collapse:collapse;margin-bottom:16px}\n th{background:#334155;color:#f8fafc;padding:10px 12px;text-align:left;font-size:13px;font-weight:600}\n td{padding:8px 12px;border-bottom:1px solid #334155;font-size:13px;color:#cbd5e1}\n tr:hover td{background:rgba(51,65,85,0.3)}\n .recommendations ol{padding-left:24px}\n .recommendations li{margin-bottom:8px;color:#cbd5e1;font-size:13px}\n .priority-p0{color:#ef4444;font-weight:700}\n .priority-p1{color:#f97316;font-weight:700}\n .priority-p2{color:#eab308;font-weight:700}\n .priority-p3{color:#22c55e;font-weight:700}\n footer{margin-top:48px;padding-top:24px;border-top:1px solid #334155;text-align:center}\n footer p{color:#64748b;font-size:12px;margin-bottom:4px}\n .check-item{display:flex;align-items:flex-start;gap:8px;padding:8px 12px;border-radius:6px;margin-bottom:4px;font-size:14px}\n .check-pass{background:rgba(34,197,94,0.1)}\n .check-fail{background:rgba(239,68,68,0.1)}\n .check-unknown{background:rgba(148,163,184,0.1)}\n .check-icon{font-size:16px;flex-shrink:0}\n .check-name{font-weight:500}\n .check-findings{margin-left:28px;margin-top:4px}\n .check-findings li{color:#94a3b8;font-size:12px;margin-bottom:2px;list-style:none}\n .no-findings{text-align:center;padding:40px;color:#22c55e;font-size:18px;font-weight:600}\n .finding-fold{background:#1e293b;border:1px solid #334155;border-radius:8px;margin-bottom:12px;border-left:4px solid;overflow:hidden}\n .finding-fold>summary{cursor:pointer;padding:12px 20px;display:flex;align-items:center;gap:12px;list-style:none;user-select:none}\n .finding-fold>summary::-webkit-details-marker{display:none}\n .finding-fold>summary::marker{content:\"\"}\n .finding-fold>summary .badge{margin-bottom:0}\n .finding-fold>summary::after{content:\"\\\\25B6\";font-size:10px;color:#64748b;flex-shrink:0;transition:transform 0.2s}\n .finding-fold[open]>summary::after{transform:rotate(90deg)}\n .finding-fold[open]>summary{border-bottom:1px solid #334155}\n .finding-body{padding:12px 20px 16px}\n .finding-summary-title{font-weight:600;font-size:14px;flex:1}\n .finding-summary-score{color:#94a3b8;font-size:13px;font-weight:600;white-space:nowrap}\n .top5-card{display:flex;gap:16px;background:#1e293b;border:1px solid #334155;border-radius:12px;padding:24px;margin-bottom:16px;border-left:4px solid}\n .top5-card .badge{margin-bottom:0}\n .top5-rank{font-size:28px;font-weight:800;color:#475569;min-width:44px;display:flex;align-items:flex-start;justify-content:center}\n .top5-content{flex:1}\n .top5-title{font-size:17px;font-weight:700;margin:8px 0}\n .top5-detail{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n .top5-detail strong{color:#f8fafc}\n .top5-remediation{margin-top:8px;padding-left:20px}\n .top5-remediation li{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n .trend-section{margin-bottom:32px}\n .trend-chart{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:20px;margin-bottom:16px}\n .trend-title{font-size:14px;font-weight:600;margin-bottom:12px;text-align:center;color:#cbd5e1}\n .category-fold{background:#1e293b;border:1px solid #334155;border-radius:8px;margin-bottom:16px;overflow:hidden}\n .category-fold>summary{cursor:pointer;padding:16px 20px;display:flex;align-items:center;gap:12px;list-style:none;font-size:18px;font-weight:600;user-select:none}\n .category-fold>summary::-webkit-details-marker{display:none}\n .category-fold>summary::marker{content:\"\"}\n .category-fold>summary::after{content:\"\\\\25B6\";font-size:12px;color:#64748b;flex-shrink:0;transition:transform 0.2s}\n .category-fold[open]>summary::after{transform:rotate(90deg)}\n .category-fold[open]>summary{border-bottom:1px solid #334155}\n .category-body{padding:12px 20px 16px}\n .category-title{flex:1}\n .category-stats{display:inline-flex;gap:12px;font-size:13px}\n .category-stat-pass{color:#22c55e}\n .category-stat-fail{color:#ef4444}\n .category-stat-unknown{color:#94a3b8}\n .module-fold{background:#1e293b;border:1px solid #334155;border-radius:8px;margin-bottom:16px;overflow:hidden}\n .module-fold>summary{cursor:pointer;padding:16px 20px;display:flex;align-items:center;gap:12px;list-style:none;user-select:none;flex-wrap:wrap}\n .module-fold>summary::-webkit-details-marker{display:none}\n .module-fold>summary::marker{content:\"\"}\n .module-fold>summary h3{margin:0;font-size:16px}\n .module-fold>summary::after{content:\"\\\\25B6\";font-size:12px;color:#64748b;flex-shrink:0;transition:transform 0.2s;margin-left:auto}\n .module-fold[open]>summary::after{transform:rotate(90deg)}\n .module-fold[open]>summary{border-bottom:1px solid #334155}\n .module-body{padding:12px 20px 16px}\n .module-badges{display:inline-flex;gap:6px;flex-wrap:wrap}\n .severity-group{margin-bottom:16px}\n .severity-group-fold{margin-bottom:16px}\n .severity-group-fold>summary{cursor:pointer;padding:4px 0;list-style:none;user-select:none}\n .severity-group-fold>summary::-webkit-details-marker{display:none}\n .severity-group-fold>summary::marker{content:\"\"}\n .severity-group-fold>summary h4{margin:0;display:inline}\n .finding-card{display:flex;align-items:center;gap:8px;padding:8px 12px;margin-bottom:4px;border-radius:6px;border-left:4px solid #334155;background:rgba(30,41,59,0.5);flex-wrap:wrap}\n .finding-title-text{font-weight:600;font-size:13px;flex:1;min-width:200px}\n .finding-resource{color:#94a3b8;font-size:12px;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n .finding-card>details{width:100%;margin-top:4px}\n .finding-card>details>summary{cursor:pointer;font-size:12px;color:#60a5fa;user-select:none}\n .finding-card-body{padding:8px 0}\n .finding-card-body p{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n .finding-card-body ol{padding-left:20px}\n .finding-card-body li{color:#cbd5e1;font-size:13px;margin-bottom:2px}\n .rec-fold{background:#1e293b;border:1px solid #334155;border-radius:8px;margin-bottom:16px;overflow:hidden}\n .rec-fold>summary{cursor:pointer;padding:16px 20px;display:flex;align-items:center;gap:12px;list-style:none;user-select:none}\n .rec-fold>summary::-webkit-details-marker{display:none}\n .rec-fold>summary::marker{content:\"\"}\n .rec-fold>summary::after{content:\"\\\\25B6\";font-size:12px;color:#64748b;flex-shrink:0;transition:transform 0.2s;margin-left:auto}\n .rec-fold[open]>summary::after{transform:rotate(90deg)}\n .rec-fold[open]>summary{border-bottom:1px solid #334155}\n .rec-body{padding:12px 20px 16px}\n .rec-body ol{padding-left:24px}\n .rec-body li{margin-bottom:8px;color:#cbd5e1;font-size:13px}\n .rec-body .badge{margin-right:6px;vertical-align:middle}\n .filter-toolbar{display:flex;flex-wrap:wrap;gap:16px;align-items:center;margin-bottom:20px;padding:12px 16px;background:#1e293b;border:1px solid #334155;border-radius:8px}\n .filter-group{display:flex;align-items:center;gap:8px}\n .filter-label{color:#94a3b8;font-size:13px}\n .filter-btn{padding:4px 12px;border-radius:4px;border:1px solid #475569;background:transparent;color:#cbd5e1;cursor:pointer;font-size:13px}\n .filter-btn:hover{background:#334155}\n .filter-btn.active{background:#3b82f6;border-color:#3b82f6;color:#fff}\n .filter-select{padding:4px 8px;border-radius:4px;border:1px solid #475569;background:#0f172a;color:#cbd5e1;font-size:13px}\n .filter-count{color:#64748b;font-size:13px;margin-left:auto}\n @media print{\n .filter-toolbar{display:none !important}\n .finding-card,.module-fold{display:block !important}\n body{background:#fff;color:#1e293b;-webkit-print-color-adjust:exact;print-color-adjust:exact}\n .container{max-width:100%;padding:20px}\n .card,.score-card,.stat-card,.chart-box,.finding-fold,.top5-card,.trend-chart,.category-fold,.module-fold,.finding-card,.rec-fold{background:#fff;border:1px solid #e2e8f0}\n .badge{border:1px solid}\n header{border-bottom-color:#e2e8f0}\n h2{border-bottom-color:#e2e8f0}\n th{background:#f1f5f9;color:#1e293b}\n td{border-bottom-color:#e2e8f0;color:#475569}\n footer{border-top-color:#e2e8f0}\n .meta,.disclaimer{color:#64748b}\n .finding-detail,.top5-detail{color:#475569}\n .finding-detail strong,.top5-detail strong{color:#1e293b}\n .stat-label,.score-label{color:#64748b}\n .chart-title,.trend-title{color:#475569}\n .remediation-steps li,.top5-remediation li{color:#475569}\n .recommendations li{color:#475569}\n .finding-card-body p,.finding-card-body li{color:#475569}\n .finding-title-text{color:#1e293b}\n .finding-resource{color:#64748b}\n .check-findings li{color:#64748b}\n .finding-fold,.top5-card,.category-fold,.module-fold,.finding-card,.rec-fold{break-inside:avoid}\n .check-item{break-inside:avoid}\n svg text{fill:#1e293b !important}\n .finding-fold[open]>summary,.category-fold[open]>summary,.module-fold[open]>summary,.rec-fold[open]>summary{border-bottom-color:#e2e8f0}\n details{display:block}\n details>summary{display:block}\n details>:not(summary){display:block !important}\n }\n `;\n}\n\n// ---------------------------------------------------------------------------\n// SVG Charts\n// ---------------------------------------------------------------------------\n\nfunction donutChart(summary: FullScanResult[\"summary\"]): string {\n const total = summary.totalFindings;\n const r = 80;\n const circ = 2 * Math.PI * r; // ~502.65\n\n if (total === 0) {\n return [\n '<svg viewBox=\"0 0 200 200\" width=\"200\" height=\"200\">',\n ' <circle cx=\"100\" cy=\"100\" r=\"80\" fill=\"none\" stroke=\"#334155\" stroke-width=\"20\"/>',\n ' <text x=\"100\" y=\"105\" text-anchor=\"middle\" fill=\"#22c55e\" font-size=\"24\" font-weight=\"700\">0</text>',\n \"</svg>\",\n ].join(\"\\n\");\n }\n\n const segments: Array<{ count: number; color: string }> = [\n { count: summary.critical, color: SEV_COLOR.CRITICAL },\n { count: summary.high, color: SEV_COLOR.HIGH },\n { count: summary.medium, color: SEV_COLOR.MEDIUM },\n { count: summary.low, color: SEV_COLOR.LOW },\n ].filter((s) => s.count > 0);\n\n let offset = 0;\n const circles = segments.map((s) => {\n const arc = (s.count / total) * circ;\n const el = `<circle cx=\"100\" cy=\"100\" r=\"80\" fill=\"none\" stroke=\"${s.color}\" stroke-width=\"20\" stroke-dasharray=\"${arc.toFixed(2)} ${(circ - arc).toFixed(2)}\" stroke-dashoffset=\"${(-offset).toFixed(2)}\" transform=\"rotate(-90 100 100)\"/>`;\n offset += arc;\n return el;\n });\n\n return [\n '<svg viewBox=\"0 0 200 200\" width=\"200\" height=\"200\">',\n ...circles.map((c) => ` ${c}`),\n ` <text x=\"100\" y=\"105\" text-anchor=\"middle\" fill=\"#f8fafc\" font-size=\"28\" font-weight=\"700\">${total}</text>`,\n \"</svg>\",\n ].join(\"\\n\");\n}\n\nfunction barChart(modules: FullScanResult[\"modules\"], allCleanLabel = \"All modules clean\"): string {\n const withFindings = modules\n .filter((m) => m.findingsCount > 0)\n .sort((a, b) => b.findingsCount - a.findingsCount)\n .slice(0, 12);\n\n if (withFindings.length === 0) {\n return [\n '<svg viewBox=\"0 0 400 50\" width=\"100%\">',\n ` <text x=\"200\" y=\"30\" text-anchor=\"middle\" fill=\"#22c55e\" font-size=\"14\" font-weight=\"600\">${esc(allCleanLabel)}</text>`,\n \"</svg>\",\n ].join(\"\\n\");\n }\n\n const maxCount = withFindings[0].findingsCount;\n const barH = 22;\n const gap = 6;\n const labelW = 160;\n const maxBarW = 190;\n const height = withFindings.length * (barH + gap);\n\n const bars = withFindings.map((m, i) => {\n const y = i * (barH + gap);\n const w = Math.max(4, (m.findingsCount / maxCount) * maxBarW);\n const worstSev = m.findings.reduce<Severity>((worst, f) => {\n const idx = SEVERITY_ORDER.indexOf(f.severity);\n return idx < SEVERITY_ORDER.indexOf(worst) ? f.severity : worst;\n }, \"LOW\");\n const color = SEV_COLOR[worstSev];\n return [\n `<text x=\"${labelW - 8}\" y=\"${y + barH / 2 + 4}\" text-anchor=\"end\" fill=\"#94a3b8\" font-size=\"11\">${esc(m.module)}</text>`,\n `<rect x=\"${labelW}\" y=\"${y}\" width=\"${w.toFixed(1)}\" height=\"${barH}\" rx=\"3\" fill=\"${color}\" opacity=\"0.85\"/>`,\n `<text x=\"${labelW + w + 6}\" y=\"${y + barH / 2 + 4}\" fill=\"#f8fafc\" font-size=\"11\">${m.findingsCount}</text>`,\n ].join(\"\\n\");\n });\n\n return [\n `<svg viewBox=\"0 0 400 ${height}\" width=\"100%\">`,\n ...bars,\n \"</svg>\",\n ].join(\"\\n\");\n}\n\nfunction findingsTrendChart(history: DashboardHistoryEntry[]): string {\n const entries = history.slice(-30);\n if (entries.length < 2) return \"\";\n\n const W = 800;\n const H = 260;\n const pad = { top: 30, right: 20, bottom: 50, left: 50 };\n const plotW = W - pad.left - pad.right;\n const plotH = H - pad.top - pad.bottom;\n\n const maxVal = Math.max(\n 1,\n ...entries.flatMap((e) => [e.critical, e.high, e.medium, e.low]),\n );\n\n const xPos = (i: number) =>\n pad.left + (i / Math.max(1, entries.length - 1)) * plotW;\n const yPos = (v: number) => pad.top + plotH - (v / maxVal) * plotH;\n\n const lines: Array<{\n key: \"critical\" | \"high\" | \"medium\" | \"low\";\n color: string;\n label: string;\n }> = [\n { key: \"critical\", color: \"#ef4444\", label: \"Critical\" },\n { key: \"high\", color: \"#f97316\", label: \"High\" },\n { key: \"medium\", color: \"#eab308\", label: \"Medium\" },\n { key: \"low\", color: \"#22c55e\", label: \"Low\" },\n ];\n\n const polylines = lines\n .map((line) => {\n const pts = entries\n .map(\n (e, i) =>\n `${xPos(i).toFixed(1)},${yPos(e[line.key]).toFixed(1)}`,\n )\n .join(\" \");\n return `<polyline points=\"${pts}\" fill=\"none\" stroke=\"${line.color}\" stroke-width=\"2\" stroke-linejoin=\"round\"/>`;\n })\n .join(\"\\n \");\n\n const xLabels = entries\n .map((e, i) => {\n if (i % 5 !== 0 && i !== entries.length - 1) return \"\";\n return `<text x=\"${xPos(i).toFixed(1)}\" y=\"${H - 8}\" text-anchor=\"middle\" fill=\"#94a3b8\" font-size=\"10\">${e.date.slice(5)}</text>`;\n })\n .filter(Boolean)\n .join(\"\\n \");\n\n const ySteps = 5;\n const yLabels = Array.from({ length: ySteps + 1 }, (_, i) => {\n const val = Math.round((maxVal / ySteps) * i);\n return [\n `<text x=\"${pad.left - 8}\" y=\"${yPos(val).toFixed(1)}\" text-anchor=\"end\" fill=\"#94a3b8\" font-size=\"10\" dominant-baseline=\"middle\">${val}</text>`,\n `<line x1=\"${pad.left}\" y1=\"${yPos(val).toFixed(1)}\" x2=\"${W - pad.right}\" y2=\"${yPos(val).toFixed(1)}\" stroke=\"#334155\" stroke-width=\"0.5\"/>`,\n ].join(\"\\n \");\n }).join(\"\\n \");\n\n const legend = lines\n .map((line, i) => {\n const lx = pad.left + i * 110;\n return `<rect x=\"${lx}\" y=\"8\" width=\"14\" height=\"3\" rx=\"1\" fill=\"${line.color}\"/><text x=\"${lx + 18}\" y=\"12\" fill=\"#94a3b8\" font-size=\"10\">${line.label}</text>`;\n })\n .join(\"\\n \");\n\n return [\n `<svg viewBox=\"0 0 ${W} ${H}\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">`,\n ` ${legend}`,\n ` ${yLabels}`,\n ` ${polylines}`,\n ` ${xLabels}`,\n \"</svg>\",\n ].join(\"\\n\");\n}\n\nfunction scoreTrendChart(history: DashboardHistoryEntry[]): string {\n const entries = history.slice(-30);\n if (entries.length < 2) return \"\";\n\n const W = 800;\n const H = 220;\n const pad = { top: 20, right: 20, bottom: 50, left: 50 };\n const plotW = W - pad.left - pad.right;\n const plotH = H - pad.top - pad.bottom;\n\n const xPos = (i: number) =>\n pad.left + (i / Math.max(1, entries.length - 1)) * plotW;\n const yPos = (v: number) => pad.top + plotH - (v / 100) * plotH;\n\n const pts = entries\n .map((e, i) => `${xPos(i).toFixed(1)},${yPos(e.score).toFixed(1)}`)\n .join(\" \");\n\n const zones = [\n `<rect x=\"${pad.left}\" y=\"${yPos(100).toFixed(1)}\" width=\"${plotW}\" height=\"${(yPos(80) - yPos(100)).toFixed(1)}\" fill=\"#22c55e\" opacity=\"0.06\"/>`,\n `<rect x=\"${pad.left}\" y=\"${yPos(80).toFixed(1)}\" width=\"${plotW}\" height=\"${(yPos(50) - yPos(80)).toFixed(1)}\" fill=\"#eab308\" opacity=\"0.06\"/>`,\n `<rect x=\"${pad.left}\" y=\"${yPos(50).toFixed(1)}\" width=\"${plotW}\" height=\"${(yPos(0) - yPos(50)).toFixed(1)}\" fill=\"#ef4444\" opacity=\"0.06\"/>`,\n ].join(\"\\n \");\n\n const xLabels = entries\n .map((e, i) => {\n if (i % 5 !== 0 && i !== entries.length - 1) return \"\";\n return `<text x=\"${xPos(i).toFixed(1)}\" y=\"${H - 8}\" text-anchor=\"middle\" fill=\"#94a3b8\" font-size=\"10\">${e.date.slice(5)}</text>`;\n })\n .filter(Boolean)\n .join(\"\\n \");\n\n const yVals = [0, 25, 50, 75, 100];\n const yLabels = yVals\n .map(\n (val) =>\n `<text x=\"${pad.left - 8}\" y=\"${yPos(val).toFixed(1)}\" text-anchor=\"end\" fill=\"#94a3b8\" font-size=\"10\" dominant-baseline=\"middle\">${val}</text>\\n <line x1=\"${pad.left}\" y1=\"${yPos(val).toFixed(1)}\" x2=\"${W - pad.right}\" y2=\"${yPos(val).toFixed(1)}\" stroke=\"#334155\" stroke-width=\"0.5\"/>`,\n )\n .join(\"\\n \");\n\n return [\n `<svg viewBox=\"0 0 ${W} ${H}\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">`,\n ` ${zones}`,\n ` ${yLabels}`,\n ` <polyline points=\"${pts}\" fill=\"none\" stroke=\"#60a5fa\" stroke-width=\"2.5\" stroke-linejoin=\"round\"/>`,\n ` ${xLabels}`,\n \"</svg>\",\n ].join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// General HTML Report\n// ---------------------------------------------------------------------------\n\nexport function generateHtmlReport(\n scanResults: FullScanResult,\n history?: DashboardHistoryEntry[],\n lang?: Lang,\n): string {\n const t = getI18n(lang ?? \"zh\");\n const htmlLang = (lang ?? \"zh\") === \"zh\" ? \"zh-CN\" : \"en\";\n const { summary, modules, accountId, region, scanStart, scanEnd } =\n scanResults;\n const date = scanStart.split(\"T\")[0];\n const duration = formatDuration(scanStart, scanEnd);\n const score = calcScore(summary);\n\n const allFindings: Finding[] = modules.flatMap((m) =>\n m.findings.map((f) => ({ ...f, module: f.module ?? m.module })),\n );\n\n // Pre-compute Security Hub sub-categories for bar chart and stats table\n const shModule = modules.find(m => m.module === \"security_hub_findings\");\n const shSubCats: Array<{ key: string; label: string; count: number; findings: Finding[] }> = [];\n if (shModule && shModule.findingsCount > 0) {\n const catMap: Record<string, Finding[]> = {};\n for (const f of shModule.findings) {\n const cat = getSecurityHubSource(f);\n if (!catMap[cat]) catMap[cat] = [];\n catMap[cat].push(f);\n }\n for (const cat of SECURITY_HUB_SUB_CAT_ORDER) {\n const catFindings = catMap[cat];\n if (catFindings && catFindings.length > 0) {\n const meta = t.securityHubSubCategories[cat];\n const shLabel = t.moduleNames[`sh:${cat}`] ?? meta?.label ?? cat;\n shSubCats.push({\n key: cat,\n label: shLabel,\n count: catFindings.length,\n findings: catFindings,\n });\n }\n }\n }\n\n // Detection-only modules — their findings come via Security Hub sub-categories\n const DETECTION_ONLY_MODULES = new Set([\n \"guardduty_findings\",\n \"inspector_findings\",\n \"config_rules_findings\",\n \"access_analyzer_findings\",\n ]);\n\n // Expand SH module into sub-categories for bar chart, hide detection-only scanners\n const barChartModules: ScanResult[] = modules.flatMap(m => {\n if (DETECTION_ONLY_MODULES.has(m.module)) return [];\n if (m.module === \"security_hub_findings\" && shSubCats.length > 0) {\n return shSubCats.map(sc => ({\n ...m,\n module: t.moduleNames[`sh:${sc.key}`] ?? sc.key,\n findingsCount: sc.count,\n findings: sc.findings,\n }));\n }\n return [{ ...m, module: t.moduleNames[m.module] ?? m.module }];\n });\n\n // --- Top 5 Findings ---\n let top5Html = \"\";\n if (allFindings.length > 0) {\n const top5 = [...allFindings]\n .sort((a, b) => b.riskScore - a.riskScore)\n .slice(0, 5);\n const cards = top5\n .map(\n (f, i) => `\n <div class=\"top5-card sev-${esc(f.severity.toLowerCase())}\">\n <div class=\"top5-rank\">#${i + 1}</div>\n <div class=\"top5-content\">\n <span class=\"badge badge-${esc(f.severity.toLowerCase())}\">${esc(f.severity)}</span>\n <div class=\"top5-title\">${esc(f.title)}</div>\n <div class=\"top5-detail\"><strong>${t.resource}:</strong> ${esc(f.resourceId)}</div>\n <div class=\"top5-detail\"><strong>${t.impact}:</strong> ${esc(f.impact)}</div>\n <div class=\"top5-detail\"><strong>${t.riskScore}:</strong> ${f.riskScore}/10</div>\n <h4>${t.remediation}</h4>\n <ol class=\"top5-remediation\">${f.remediationSteps.map((s) => `<li>${escWithLinks(s)}</li>`).join(\"\")}</ol>\n </div>\n </div>`,\n )\n .join(\"\\n\");\n top5Html = `\n <section>\n <h2>${esc(t.topHighestRiskFindings(top5.length))}</h2>\n ${cards}\n </section>`;\n }\n\n // --- Findings HTML (grouped by module, then severity) ---\n let findingsHtml: string;\n let filterToolbarHtml = \"\";\n if (summary.totalFindings === 0) {\n findingsHtml = `<div class=\"no-findings\">${esc(t.noIssuesFound)}</div>`;\n } else {\n const FOLD_THRESHOLD = 20;\n\n const renderCard = (f: Finding, moduleKey: string): string => {\n const sev = f.severity.toLowerCase();\n return `<div class=\"finding-card sev-${esc(sev)}\" data-severity=\"${esc(f.severity)}\" data-module=\"${esc(moduleKey)}\">\n <span class=\"badge badge-${esc(sev)}\">${esc(f.severity)}</span>\n <span class=\"finding-title-text\">${esc(f.title)}</span>\n <span class=\"finding-resource\">${esc(f.resourceArn || f.resourceId)}</span>\n <details><summary>${t.details}</summary><div class=\"finding-card-body\">\n <p>${esc(f.description)}</p>\n <p><strong>${t.remediation}:</strong></p>\n <ol>${f.remediationSteps.map((s) => `<li>${escWithLinks(s)}</li>`).join(\"\")}</ol>\n </div></details>\n </div>`;\n };\n\n const renderCards = (findings: Finding[], moduleKey: string): string => {\n if (findings.length <= FOLD_THRESHOLD) {\n return findings.map(f => renderCard(f, moduleKey)).join(\"\\n\");\n }\n const first = findings.slice(0, FOLD_THRESHOLD).map(f => renderCard(f, moduleKey)).join(\"\\n\");\n const rest = findings.slice(FOLD_THRESHOLD).map(f => renderCard(f, moduleKey)).join(\"\\n\");\n return `${first}\\n<details><summary>${t.showRemainingFindings(findings.length - FOLD_THRESHOLD)}</summary>\\n${rest}\\n</details>`;\n };\n\n const SEV_EMOJI: Record<string, string> = {\n CRITICAL: \"🔴\",\n HIGH: \"🟠\",\n MEDIUM: \"🟡\",\n LOW: \"🔵\",\n };\n\n // Group findings by module\n const moduleMap = new Map<string, Finding[]>();\n for (const f of allFindings) {\n const mod = f.module ?? \"unknown\";\n if (!moduleMap.has(mod)) moduleMap.set(mod, []);\n moduleMap.get(mod)!.push(f);\n }\n\n // Expand security_hub_findings into per-sub-category entries, filter detection-only scanners\n const expandedEntries: Array<[string, Finding[], string | null]> = []; // [key, findings, subCatLabel]\n for (const [mod, findings] of moduleMap.entries()) {\n if (DETECTION_ONLY_MODULES.has(mod)) continue;\n if (mod === \"security_hub_findings\" && shSubCats.length > 0) {\n for (const sc of shSubCats) {\n expandedEntries.push([sc.key, sc.findings, sc.label]);\n }\n } else {\n expandedEntries.push([mod, findings, null]);\n }\n }\n\n // Sort modules: those with critical/high first, then by count\n const moduleEntries = expandedEntries.sort((a, b) => {\n const aHasCritHigh = a[1].some((f) => f.severity === \"CRITICAL\" || f.severity === \"HIGH\");\n const bHasCritHigh = b[1].some((f) => f.severity === \"CRITICAL\" || f.severity === \"HIGH\");\n if (aHasCritHigh !== bHasCritHigh) return aHasCritHigh ? -1 : 1;\n return b[1].length - a[1].length;\n });\n\n const renderSeverityGroups = (findings: Finding[], moduleKey: string): string => {\n return SEVERITY_ORDER.map((sev) => {\n const sevFindings = findings.filter((f) => f.severity === sev);\n if (sevFindings.length === 0) return \"\";\n sevFindings.sort((a, b) => b.riskScore - a.riskScore);\n\n const emoji = SEV_EMOJI[sev] ?? \"\";\n const label = sev.charAt(0) + sev.slice(1).toLowerCase();\n\n return `<details class=\"severity-group-fold\">\n <summary><h4>${emoji} ${label} (${sevFindings.length})</h4></summary>\n ${renderCards(sevFindings, moduleKey)}\n </details>`;\n }).filter(Boolean).join(\"\\n\");\n };\n\n const renderModuleBadges = (findings: Finding[]): string => {\n const sevCounts: Record<string, number> = { CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0 };\n for (const f of findings) sevCounts[f.severity]++;\n return SEVERITY_ORDER\n .filter((sev) => sevCounts[sev] > 0)\n .map((sev) => `<span class=\"badge badge-${sev.toLowerCase()}\">${sevCounts[sev]} ${sev.charAt(0) + sev.slice(1).toLowerCase()}</span>`)\n .join(\" \");\n };\n\n findingsHtml = moduleEntries.map(([modName, modFindings, subCatLabel]) => {\n const badges = renderModuleBadges(modFindings);\n const displayName = subCatLabel ?? (t.moduleNames[modName] ?? modName);\n\n return `<details class=\"module-fold\" data-module=\"${esc(modName)}\">\n <summary>\n <h3>🔒 ${esc(displayName)} (${modFindings.length})</h3>\n <span class=\"module-badges\">${badges}</span>\n </summary>\n <div class=\"module-body\">\n ${renderSeverityGroups(modFindings, modName)}\n </div>\n </details>`;\n }).join(\"\\n\");\n\n // --- Filter toolbar (module options from actual findings) ---\n const moduleOptions = moduleEntries.map(([modKey, , subCatLabel]) => {\n const label = subCatLabel ?? (t.moduleNames[modKey] ?? modKey);\n return `<option value=\"${esc(modKey)}\">${esc(label)}</option>`;\n }).join(\"\\n \");\n\n filterToolbarHtml = `<div class=\"filter-toolbar\" id=\"filterBar\">\n <div class=\"filter-group\">\n <span class=\"filter-label\">${esc(t.filterSeverity)}</span>\n <button class=\"filter-btn active\" data-severity=\"ALL\">${esc(t.filterAll)}</button>\n <button class=\"filter-btn\" data-severity=\"CRITICAL\">Critical</button>\n <button class=\"filter-btn\" data-severity=\"HIGH\">High</button>\n <button class=\"filter-btn\" data-severity=\"MEDIUM\">Medium</button>\n <button class=\"filter-btn\" data-severity=\"LOW\">Low</button>\n </div>\n <div class=\"filter-group\">\n <span class=\"filter-label\">${esc(t.filterModule)}</span>\n <select class=\"filter-select\" id=\"moduleFilter\">\n <option value=\"ALL\">${esc(t.filterAllModules)}</option>\n ${moduleOptions}\n </select>\n </div>\n <div class=\"filter-count\" id=\"filterCount\" data-tpl=\"${esc(t.filterCountTpl)}\"></div>\n </div>`;\n }\n\n // --- Trend Charts ---\n let trendHtml = \"\";\n if (history && history.length >= 2) {\n trendHtml = `\n <section class=\"trend-section\">\n <h2>${esc(t.trendTitle)}</h2>\n <div class=\"trend-chart\">\n <div class=\"trend-title\">${esc(t.findingsBySeverity)}</div>\n ${findingsTrendChart(history)}\n </div>\n <div class=\"trend-chart\">\n <div class=\"trend-title\">${esc(t.securityScore)}</div>\n ${scoreTrendChart(history)}\n </div>\n </section>`;\n }\n\n // --- Statistics table ---\n const isModuleDisabled = (m: ScanResult): string | undefined => {\n if (!m.warnings?.length) return undefined;\n const w = m.warnings.find((w) =>\n SERVICE_NOT_ENABLED_PATTERNS.some((p) => w.includes(p)),\n );\n return w;\n };\n\n const statsRows = modules\n .flatMap(\n (m) => {\n // Hide detection-only scanners — their data is in SH sub-categories\n if (DETECTION_ONLY_MODULES.has(m.module)) return [];\n // Replace security_hub_findings parent row with flat sub-category rows\n if (m.module === \"security_hub_findings\" && shSubCats.length > 0) {\n return shSubCats.map(sc =>\n `<tr><td>${esc(sc.label)}</td><td>${m.resourcesScanned}</td><td>${sc.count}</td><td>✓</td></tr>`,\n );\n }\n // Show N/A for disabled services\n const disabledWarning = isModuleDisabled(m);\n if (disabledWarning) {\n const rec = t.serviceRecommendations[m.module];\n const reason = rec ? rec.action : disabledWarning;\n return [`<tr><td>${esc(t.moduleNames[m.module] ?? m.module)}</td><td>-</td><td>-</td><td style=\"color:#eab308\">⚠ ${esc(reason)}</td></tr>`];\n }\n return [`<tr><td>${esc(t.moduleNames[m.module] ?? m.module)}</td><td>${m.resourcesScanned}</td><td>${m.findingsCount}</td><td>${m.status === \"success\" ? \"✓\" : \"✗\"}</td></tr>`];\n },\n )\n .join(\"\\n\");\n\n // --- Recommendations (deduplicated) ---\n let recsHtml = \"\";\n if (summary.totalFindings > 0) {\n const recMap = new Map<string, { text: string; severity: Severity; count: number; url?: string }>();\n const kbPatches: string[] = [];\n let kbSeverity: Severity = \"LOW\";\n let kbUrl: string | undefined;\n const cveList: string[] = [];\n let cveSeverity: Severity = \"LOW\";\n let cveUrl: string | undefined;\n const genericPatterns = [\"See References\", \"None Provided\", \"Review the finding\", \"Review and remediate.\"];\n\n for (const f of allFindings) {\n const rem = f.remediationSteps[0] ?? \"Review and remediate.\";\n const url = f.remediationSteps.find((s) => s.startsWith(\"Documentation:\"))?.replace(\"Documentation: \", \"\");\n\n // Skip generic remediation\n if (genericPatterns.some(p => rem.startsWith(p))) continue;\n\n // Group KB patches together\n const kbMatch = f.title.match(/KB\\d+/);\n if (kbMatch && (f.module === \"security_hub_findings\" || f.module === \"inspector_findings\")) {\n kbPatches.push(kbMatch[0]);\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(kbSeverity)) kbSeverity = f.severity;\n if (!kbUrl && url) kbUrl = url;\n continue;\n }\n\n // Group CVE vulnerabilities together\n const cveMatch = f.title.match(/CVE-[\\d-]+/);\n if (cveMatch && (f.module === \"security_hub_findings\" || f.module === \"inspector_findings\")) {\n cveList.push(cveMatch[0]);\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(cveSeverity)) cveSeverity = f.severity;\n if (!cveUrl && url) cveUrl = url;\n continue;\n }\n\n // Group Security Hub findings by control ID\n if (f.module === \"security_hub_findings\") {\n const controlMatch = f.title.match(/^([A-Z][A-Za-z0-9]*\\.\\d+)\\s/);\n if (controlMatch) {\n const controlId = controlMatch[1];\n const key = `ctrl:${controlId}`;\n const existing = recMap.get(key);\n if (existing) {\n existing.count++;\n if (!existing.url && url) existing.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existing.severity)) existing.severity = f.severity;\n } else {\n recMap.set(key, { text: `[${controlId}] ${rem}`, severity: f.severity, count: 1, url });\n }\n continue;\n }\n }\n\n // Template-based grouping for own scanner findings (not Security Hub/Inspector)\n if (f.module !== \"security_hub_findings\" && f.module !== \"inspector_findings\") {\n const template = getRecommendationTemplate(rem);\n if (template !== rem) {\n const templateKey = `tmpl:${f.module}:${template}`;\n const existingTmpl = recMap.get(templateKey);\n if (existingTmpl) {\n existingTmpl.count++;\n if (!existingTmpl.url && url) existingTmpl.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existingTmpl.severity)) {\n existingTmpl.severity = f.severity;\n }\n continue;\n }\n recMap.set(templateKey, { text: rem, severity: f.severity, count: 1, url });\n continue;\n }\n }\n\n // Default grouping by remediation text\n const existing = recMap.get(rem);\n if (existing) {\n existing.count++;\n if (!existing.url && url) existing.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existing.severity)) {\n existing.severity = f.severity;\n }\n } else {\n recMap.set(rem, { text: rem, severity: f.severity, count: 1, url });\n }\n }\n\n // Add grouped KB patches as a single entry\n if (kbPatches.length > 0) {\n const unique = [...new Set(kbPatches)];\n const kbList = unique.slice(0, 5).join(\", \") + (unique.length > 5 ? \", \\u2026\" : \"\");\n recMap.set(\"__kb__\", { text: t.installWindowsPatches(unique.length, kbList), severity: kbSeverity, count: 1, url: kbUrl });\n }\n\n // Add grouped CVE vulnerabilities as a single entry\n if (cveList.length > 0) {\n const unique = [...new Set(cveList)];\n const cveDisplay = unique.slice(0, 5).join(\", \") + (unique.length > 5 ? \", \\u2026\" : \"\");\n const cveText = (lang ?? \"zh\") === \"zh\"\n ? `\\u4fee\\u590d ${unique.length} \\u4e2a\\u8f6f\\u4ef6\\u6f0f\\u6d1e (${cveDisplay})\\uff0c\\u66f4\\u65b0\\u53d7\\u5f71\\u54cd\\u7684\\u8f6f\\u4ef6\\u5305\\u5230\\u6700\\u65b0\\u7248\\u672c`\n : `Fix ${unique.length} software vulnerabilities (${cveDisplay}) — update affected packages to latest patched versions`;\n recMap.set(\"__cve__\", { text: cveText, severity: cveSeverity, count: 1, url: cveUrl });\n }\n\n // Post-process: embed resource count for control-ID and template groups\n for (const [key, rec] of recMap) {\n if ((key.startsWith(\"ctrl:\") || key.startsWith(\"tmpl:\")) && rec.count > 1) {\n rec.text += ` \\u2014 ${t.affectedResources(rec.count)}`;\n rec.count = 1;\n }\n }\n\n const uniqueRecs = [...recMap.values()].sort((a, b) => {\n const sevDiff = SEVERITY_ORDER.indexOf(a.severity) - SEVERITY_ORDER.indexOf(b.severity);\n if (sevDiff !== 0) return sevDiff;\n return b.count - a.count;\n });\n\n const renderRec = (r: { text: string; severity: Severity; count: number; url?: string }): string => {\n const sev = r.severity.toLowerCase();\n const countLabel = r.count > 1 ? ` (× ${r.count})` : \"\";\n const linkHtml = r.url ? ` <a href=\"${esc(r.url)}\" style=\"color:#60a5fa\" target=\"_blank\" rel=\"noopener\">📖</a>` : \"\";\n return `<li><span class=\"badge badge-${esc(sev)}\">${esc(r.severity)}</span> ${esc(r.text)}${countLabel}${linkHtml}</li>`;\n };\n\n const TOP_N = 10;\n const topItems = uniqueRecs.slice(0, TOP_N).map(renderRec).join(\"\\n\");\n const remaining = uniqueRecs.slice(TOP_N);\n const moreHtml = remaining.length > 0\n ? `\\n<details><summary>${t.showMoreCount(remaining.length)}</summary>\\n${remaining.map(renderRec).join(\"\\n\")}\\n</details>`\n : \"\";\n\n recsHtml = `\n <details class=\"rec-fold\">\n <summary><h2 style=\"margin:0;border:0;display:inline\">${esc(t.recommendations)} (${uniqueRecs.length} ${esc(t.unique)})</h2></summary>\n <div class=\"rec-body\">\n <ol>${topItems}${moreHtml}</ol>\n </div>\n </details>`;\n }\n\n // --- Filter script (client-side JS) ---\n const filterScript = summary.totalFindings > 0 ? `<script>\n(function(){\n var activeSev='ALL',activeMod='ALL';\n var countEl=document.getElementById('filterCount');\n var tpl=countEl?countEl.getAttribute('data-tpl'):'';\n function apply(){\n var cards=document.querySelectorAll('.finding-card[data-severity]');\n var shown=0,total=cards.length;\n cards.forEach(function(c){\n var sevOk=activeSev==='ALL'||c.getAttribute('data-severity')===activeSev;\n var modOk=activeMod==='ALL'||c.getAttribute('data-module')===activeMod;\n c.style.display=(sevOk&&modOk)?'':'none';\n if(sevOk&&modOk)shown++;\n });\n if(countEl)countEl.textContent=tpl.replace('{shown}',shown).replace('{total}',total);\n document.querySelectorAll('.module-fold').forEach(function(f){\n var mod=f.getAttribute('data-module');\n if(activeMod!=='ALL'&&mod!==activeMod){f.style.display='none';return;}\n var hasVisible=f.querySelectorAll('.finding-card:not([style*=\"display: none\"])').length>0;\n f.style.display=hasVisible?'':'none';\n });\n document.querySelectorAll('.severity-group-fold').forEach(function(g){\n g.style.display=g.querySelectorAll('.finding-card:not([style*=\"display: none\"])').length?'':'none';\n });\n }\n document.querySelectorAll('.filter-btn[data-severity]').forEach(function(b){\n b.addEventListener('click',function(){\n document.querySelectorAll('.filter-btn[data-severity]').forEach(function(x){x.classList.remove('active')});\n b.classList.add('active');\n activeSev=b.getAttribute('data-severity');\n apply();\n });\n });\n var sel=document.getElementById('moduleFilter');\n if(sel)sel.addEventListener('change',function(){activeMod=sel.value;apply();});\n apply();\n})();\n<\\/script>` : \"\";\n\n return `<!DOCTYPE html>\n<html lang=\"${htmlLang}\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${esc(t.securityReportTitle)} — ${esc(date)}</title>\n<style>${sharedCss()}</style>\n</head>\n<body>\n<div class=\"container\">\n\n<header>\n <h1>🛡️ ${esc(t.securityReportTitle)}</h1>\n <div class=\"meta\">${esc(t.account)}: ${esc(accountId)} | ${esc(t.region)}: ${esc(region)} | ${esc(date)} | ${esc(t.duration)}: ${esc(duration)}</div>\n</header>\n\n<section class=\"summary\">\n <div class=\"score-card\">\n <div class=\"score-value\" style=\"color:${scoreColor(score)}\">${score}</div>\n <div class=\"score-label\">${esc(t.securityScore)}</div>\n </div>\n <div class=\"severity-stats\">\n <div class=\"stat-card stat-critical\"><div class=\"stat-count\">${summary.critical}</div><div class=\"stat-label\">${esc(t.critical)}</div></div>\n <div class=\"stat-card stat-high\"><div class=\"stat-count\">${summary.high}</div><div class=\"stat-label\">${esc(t.high)}</div></div>\n <div class=\"stat-card stat-medium\"><div class=\"stat-count\">${summary.medium}</div><div class=\"stat-label\">${esc(t.medium)}</div></div>\n <div class=\"stat-card stat-low\"><div class=\"stat-count\">${summary.low}</div><div class=\"stat-label\">${esc(t.low)}</div></div>\n </div>\n</section>\n\n<section class=\"charts\">\n <div class=\"chart-box\">\n <div class=\"chart-title\">${esc(t.severityDistribution)}</div>\n <div style=\"text-align:center\">${donutChart(summary)}</div>\n </div>\n <div class=\"chart-box\">\n <div class=\"chart-title\">${esc(t.findingsByModule)}</div>\n ${barChart(barChartModules, t.allModulesClean)}\n </div>\n</section>\n\n${trendHtml}\n\n${top5Html}\n\n${buildServiceReminderHtml(modules, lang)}\n\n<section>\n <h2>${esc(t.scanStatistics)}</h2>\n <table>\n <thead><tr><th>${esc(t.module)}</th><th>${esc(t.resources)}</th><th>${esc(t.findings)}</th><th>${esc(t.status)}</th></tr></thead>\n <tbody>${statsRows}</tbody>\n </table>\n</section>\n\n<section>\n <h2>${esc(t.allFindings)}</h2>\n ${filterToolbarHtml}\n ${findingsHtml}\n</section>\n\n${recsHtml}\n\n<footer>\n <p>${esc(t.generatedBy)} v${VERSION}</p>\n <p>${esc(t.informationalOnly)}</p>\n</footer>\n\n</div>\n${filterScript}\n</body>\n</html>`;\n}\n\n// ---------------------------------------------------------------------------\n// MLPS Level 3 HTML Report (等保三级) — Full GB/T 22239-2019 (184 items)\n// ---------------------------------------------------------------------------\n\nexport function generateMlps3HtmlReport(\n scanResults: FullScanResult,\n history?: DashboardHistoryEntry[],\n lang?: Lang,\n): string {\n const t = getI18n(lang ?? \"zh\");\n const htmlLang = (lang ?? \"zh\") === \"zh\" ? \"zh-CN\" : \"en\";\n const { accountId, region, scanStart } = scanResults;\n const date = scanStart.split(\"T\")[0];\n const scanTime = scanStart.replace(\"T\", \" \").replace(/\\.\\d+Z$/, \" UTC\");\n\n // Evaluate all 184 checks\n const results = evaluateAllFullChecks(scanResults);\n\n // Summary counts by type\n const autoResults = results.filter((r) => r.mapping.type === \"auto\");\n const autoClean = autoResults.filter((r) => r.status === \"clean\").length;\n const autoIssues = autoResults.filter((r) => r.status === \"issues\").length;\n const autoUnknown = autoResults.filter((r) => r.status === \"unknown\").length;\n const checkedTotal = autoClean + autoIssues;\n const cloudCount = results.filter((r) => r.status === \"cloud_provider\").length;\n const manualCount = results.filter((r) => r.status === \"manual\").length;\n const naCount = results.filter((r) => r.status === \"not_applicable\").length;\n\n // --- Trend Charts ---\n let trendHtml = \"\";\n if (history && history.length >= 2) {\n trendHtml = `\n <section class=\"trend-section\">\n <h2>${esc(t.trendTitle)}</h2>\n <div class=\"trend-chart\">\n <div class=\"trend-title\">${esc(t.findingsBySeverity)}</div>\n ${findingsTrendChart(history)}\n </div>\n <div class=\"trend-chart\">\n <div class=\"trend-title\">${esc(t.securityScore)}</div>\n ${scoreTrendChart(history)}\n </div>\n </section>`;\n }\n\n // Helper to pick item text by lang\n const isEn = (lang ?? \"zh\") === \"en\";\n const itemCat = (r: FullCheckResult) => isEn ? r.item.categoryEn : r.item.categoryCn;\n const itemControl = (r: FullCheckResult) => isEn ? r.item.controlEn : r.item.controlCn;\n const itemReq = (r: FullCheckResult) => isEn ? r.item.requirementEn : r.item.requirementCn;\n\n // --- Group results by categoryCn (key is always categoryCn for ordering) ---\n const categoryMap = new Map<string, FullCheckResult[]>();\n for (const r of results) {\n if (r.status === \"not_applicable\") continue; // N/A items excluded from domain sections\n const cat = r.item.categoryCn;\n if (!categoryMap.has(cat)) categoryMap.set(cat, []);\n categoryMap.get(cat)!.push(r);\n }\n\n // --- Build domain sections ---\n const categorySections = MLPS3_CATEGORY_ORDER\n .map((category) => {\n const sectionTitle = t.mlpsCategorySection[category] ?? category;\n const catResults = categoryMap.get(category);\n if (!catResults || catResults.length === 0) return \"\";\n\n // Check if ALL results in this category are cloud_provider\n const allCloud = catResults.every((r) => r.status === \"cloud_provider\");\n if (allCloud) {\n return `<details class=\"category-fold mlps-cloud-section\">\n <summary>\n <span class=\"category-title\">${esc(sectionTitle)}</span>\n <span class=\"category-stats\"><span class=\"category-stat-cloud\">\\ud83c\\udfe2 ${catResults.length} ${esc(t.cloudProvider)}</span></span>\n </summary>\n <div class=\"category-body\">\n <div class=\"mlps-cloud-note\">${esc(t.cloudItemsNote(catResults.length))}</div>\n ${catResults.map((r) => `<div class=\"check-item check-cloud\"><span class=\"check-icon\">\\ud83c\\udfe2</span><span class=\"check-name\">${esc(r.item.id)} ${esc(itemControl(r))}</span><span class=\"check-note\">${esc(r.mapping.note ?? \"\")}</span></div>`).join(\"\\n\")}\n </div>\n</details>`;\n }\n\n // Mixed category — compute stats\n const catClean = catResults.filter((r) => r.status === \"clean\").length;\n const catIssues = catResults.filter((r) => r.status === \"issues\").length;\n const catUnknown = catResults.filter((r) => r.status === \"unknown\").length;\n const catCloud = catResults.filter((r) => r.status === \"cloud_provider\").length;\n const catManual = catResults.filter((r) => r.status === \"manual\").length;\n\n const statsHtml = [\n catClean > 0 ? `<span class=\"category-stat-clean\">\\ud83d\\udfe2 ${catClean}</span>` : \"\",\n catIssues > 0 ? `<span class=\"category-stat-issues\">\\ud83d\\udd34 ${catIssues}</span>` : \"\",\n catUnknown > 0 ? `<span class=\"category-stat-unknown\">? ${catUnknown}</span>` : \"\",\n catCloud > 0 ? `<span class=\"category-stat-cloud\">\\ud83c\\udfe2 ${catCloud}</span>` : \"\",\n catManual > 0 ? `<span class=\"category-stat-manual\">\\ud83d\\udccb ${catManual}</span>` : \"\",\n ].filter(Boolean).join(\"\");\n\n // Group by control within category (key by controlCn for grouping stability)\n const controlMap = new Map<string, FullCheckResult[]>();\n for (const r of catResults) {\n const key = r.item.controlCn;\n if (!controlMap.has(key)) controlMap.set(key, []);\n controlMap.get(key)!.push(r);\n }\n\n const controlGroups = [...controlMap.entries()]\n .map(([_controlKey, controlResults]) => {\n const controlName = itemControl(controlResults[0]);\n // Cloud provider items in this control\n const cloudItems = controlResults.filter((r) => r.status === \"cloud_provider\");\n const nonCloudItems = controlResults.filter((r) => r.status !== \"cloud_provider\");\n\n let itemsHtml = \"\";\n\n // Render non-cloud items\n for (const r of nonCloudItems) {\n const icon = r.status === \"clean\" ? \"\\ud83d\\udfe2\"\n : r.status === \"issues\" ? \"\\ud83d\\udd34\"\n : r.status === \"unknown\" ? \"\\u2b1c\"\n : r.status === \"manual\" ? \"\\ud83d\\udccb\"\n : \"\\ud83c\\udfe2\";\n const cls = `check-${r.status === \"cloud_provider\" ? \"cloud\" : r.status}`;\n const suffix = r.status === \"unknown\" ? ` \\u2014 ${esc(t.notChecked)}`\n : r.status === \"manual\" ? ` \\u2014 ${esc(r.mapping.guidance ?? t.manualReview)}`\n : \"\";\n\n let findingsDetail = \"\";\n if (r.status === \"clean\") {\n findingsDetail = `<div class=\"check-detail\">${esc(t.noRelatedIssues)}</div>`;\n } else if (r.status === \"issues\" && r.relatedFindings.length > 0) {\n const fItems = r.relatedFindings\n .slice(0, 5)\n .map((f) => `<li>${esc(f.severity)}: ${esc(f.title)}</li>`);\n if (r.relatedFindings.length > 5) {\n fItems.push(`<li>${esc(t.andMore(r.relatedFindings.length - 5))}</li>`);\n }\n const remediationHint = r.relatedFindings[0]?.remediationSteps?.[0]\n ? `<p style=\"color:#fbbf24;font-size:12px;margin-top:4px\">${esc(t.remediation)}\\uff1a${escWithLinks(r.relatedFindings[0].remediationSteps[0])}</p>`\n : \"\";\n findingsDetail = `<div class=\"check-findings-wrap\"><details><summary>${esc(t.issuesFoundCount(r.relatedFindings.length))}</summary><ul class=\"check-findings\">${fItems.join(\"\")}</ul>${remediationHint}</details></div>`;\n }\n\n const reqText = itemReq(r);\n itemsHtml += `<div class=\"check-item ${cls}\"><span class=\"check-icon\">${icon}</span><span class=\"check-name\">${esc(r.item.id)} ${esc(reqText.slice(0, 60))}${reqText.length > 60 ? \"\\u2026\" : \"\"}${suffix}</span></div>\\n${findingsDetail}`;\n }\n\n // Render cloud items compactly\n if (cloudItems.length > 0) {\n for (const r of cloudItems) {\n const reqText = itemReq(r);\n itemsHtml += `<div class=\"check-item check-cloud\"><span class=\"check-icon\">\\ud83c\\udfe2</span><span class=\"check-name\">${esc(r.item.id)} ${esc(reqText.slice(0, 50))}${reqText.length > 50 ? \"\\u2026\" : \"\"}</span><span class=\"check-note\">${esc(t.cloudProvider)}</span></div>\\n`;\n }\n }\n\n const grpClean = controlResults.filter((r) => r.status === \"clean\").length;\n const grpIssues = controlResults.filter((r) => r.status === \"issues\").length;\n const grpUnknown = controlResults.filter((r) => r.status === \"unknown\").length;\n const grpCloud = controlResults.filter((r) => r.status === \"cloud_provider\").length;\n const grpManual = controlResults.filter((r) => r.status === \"manual\").length;\n\n const grpStats = [\n grpClean > 0 ? `<span class=\"category-stat-clean\">\\ud83d\\udfe2 ${grpClean}</span>` : \"\",\n grpIssues > 0 ? `<span class=\"category-stat-issues\">\\ud83d\\udd34 ${grpIssues}</span>` : \"\",\n grpUnknown > 0 ? `<span class=\"category-stat-unknown\">? ${grpUnknown}</span>` : \"\",\n grpCloud > 0 ? `<span class=\"category-stat-cloud\">\\ud83c\\udfe2 ${grpCloud}</span>` : \"\",\n grpManual > 0 ? `<span class=\"category-stat-manual\">\\ud83d\\udccb ${grpManual}</span>` : \"\",\n ].filter(Boolean).join(\" \");\n\n // Items with issues expanded by default, others collapsed\n const hasFailures = grpIssues > 0;\n return `<details class=\"severity-group-fold\"${hasFailures ? \" open\" : \"\"}><summary><h4>${esc(controlName)} <span class=\"category-stats\">${grpStats}</span></h4></summary>\\n${itemsHtml}\\n</details>`;\n })\n .join(\"\\n\");\n\n return `<details class=\"category-fold\">\n <summary>\n <span class=\"category-title\">${esc(sectionTitle)}</span>\n <span class=\"category-stats\">${statsHtml}</span>\n </summary>\n <div class=\"category-body\">${controlGroups}</div>\n</details>`;\n })\n .filter(Boolean)\n .join(\"\\n\");\n\n // --- Remediation for failed auto checks (deduplicated) ---\n const failedResults = results.filter((r) => r.status === \"issues\");\n let remediationHtml = \"\";\n if (failedResults.length > 0) {\n const mlpsRecMap = new Map<string, { text: string; severity: Severity; count: number; url?: string }>();\n const mlpsKbPatches: string[] = [];\n let mlpsKbSeverity: Severity = \"LOW\";\n let mlpsKbUrl: string | undefined;\n const mlpsCveList: string[] = [];\n let mlpsCveSeverity: Severity = \"LOW\";\n let mlpsCveUrl: string | undefined;\n const mlpsGenericPatterns = [\"See References\", \"None Provided\", \"Review the finding\", \"Review and remediate.\"];\n\n for (const r of failedResults) {\n for (const f of r.relatedFindings) {\n const rem = f.remediationSteps[0] ?? \"Review and remediate.\";\n const url = f.remediationSteps.find((s) => s.startsWith(\"Documentation:\"))?.replace(\"Documentation: \", \"\");\n\n // Skip generic remediation\n if (mlpsGenericPatterns.some(p => rem.startsWith(p))) continue;\n\n // Group KB patches\n const kbMatch = f.title.match(/KB\\d+/);\n if (kbMatch && (f.module === \"security_hub_findings\" || f.module === \"inspector_findings\")) {\n mlpsKbPatches.push(kbMatch[0]);\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(mlpsKbSeverity)) mlpsKbSeverity = f.severity;\n if (!mlpsKbUrl && url) mlpsKbUrl = url;\n continue;\n }\n\n // Group CVE vulnerabilities\n const cveMatch = f.title.match(/CVE-[\\d-]+/);\n if (cveMatch) {\n mlpsCveList.push(cveMatch[0]);\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(mlpsCveSeverity)) mlpsCveSeverity = f.severity;\n if (!mlpsCveUrl && url) mlpsCveUrl = url;\n continue;\n }\n\n // Group by control ID for Security Hub\n if (f.module === \"security_hub_findings\") {\n const controlMatch = f.title.match(/^([A-Z][A-Za-z0-9]*\\.\\d+)\\s/);\n if (controlMatch) {\n const controlId = controlMatch[1];\n const key = `ctrl:${controlId}`;\n const existing = mlpsRecMap.get(key);\n if (existing) {\n existing.count++;\n if (!existing.url && url) existing.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existing.severity)) existing.severity = f.severity;\n } else {\n mlpsRecMap.set(key, { text: `[${controlId}] ${rem}`, severity: f.severity, count: 1, url });\n }\n continue;\n }\n }\n\n // Template-based grouping for own scanner findings (not Security Hub/Inspector)\n if (f.module !== \"security_hub_findings\" && f.module !== \"inspector_findings\") {\n const template = getRecommendationTemplate(rem);\n if (template !== rem) {\n const templateKey = `tmpl:${f.module}:${template}`;\n const existingTmpl = mlpsRecMap.get(templateKey);\n if (existingTmpl) {\n existingTmpl.count++;\n if (!existingTmpl.url && url) existingTmpl.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existingTmpl.severity)) {\n existingTmpl.severity = f.severity;\n }\n continue;\n }\n mlpsRecMap.set(templateKey, { text: rem, severity: f.severity, count: 1, url });\n continue;\n }\n }\n\n const existing = mlpsRecMap.get(rem);\n if (existing) {\n existing.count++;\n if (!existing.url && url) existing.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existing.severity)) {\n existing.severity = f.severity;\n }\n } else {\n mlpsRecMap.set(rem, { text: rem, severity: f.severity, count: 1, url });\n }\n }\n }\n\n // Add grouped KB patches\n if (mlpsKbPatches.length > 0) {\n const unique = [...new Set(mlpsKbPatches)];\n const kbList = unique.slice(0, 5).join(\", \") + (unique.length > 5 ? \", \\u2026\" : \"\");\n mlpsRecMap.set(\"__kb__\", { text: t.installWindowsPatches(unique.length, kbList), severity: mlpsKbSeverity, count: 1, url: mlpsKbUrl });\n }\n\n if (mlpsCveList.length > 0) {\n const unique = [...new Set(mlpsCveList)];\n const cveDisplay = unique.slice(0, 5).join(\", \") + (unique.length > 5 ? \", \\u2026\" : \"\");\n const cveText = (lang ?? \"zh\") === \"zh\"\n ? `\\u4fee\\u590d ${unique.length} \\u4e2a\\u8f6f\\u4ef6\\u6f0f\\u6d1e (${cveDisplay})\\uff0c\\u66f4\\u65b0\\u53d7\\u5f71\\u54cd\\u7684\\u8f6f\\u4ef6\\u5305\\u5230\\u6700\\u65b0\\u7248\\u672c`\n : `Fix ${unique.length} software vulnerabilities (${cveDisplay}) \\u2014 update affected packages to latest patched versions`;\n mlpsRecMap.set(\"__cve__\", { text: cveText, severity: mlpsCveSeverity, count: 1, url: mlpsCveUrl });\n }\n\n // Post-process: embed resource count for control-ID and template groups\n for (const [key, rec] of mlpsRecMap) {\n if ((key.startsWith(\"ctrl:\") || key.startsWith(\"tmpl:\")) && rec.count > 1) {\n rec.text += ` \\u2014 ${t.affectedResources(rec.count)}`;\n rec.count = 1;\n }\n }\n\n const mlpsUniqueRecs = [...mlpsRecMap.values()].sort((a, b) => {\n const sevDiff = SEVERITY_ORDER.indexOf(a.severity) - SEVERITY_ORDER.indexOf(b.severity);\n if (sevDiff !== 0) return sevDiff;\n return b.count - a.count;\n });\n\n if (mlpsUniqueRecs.length > 0) {\n const renderMlpsRec = (r: { text: string; severity: Severity; count: number; url?: string }): string => {\n const sev = r.severity.toLowerCase();\n const countLabel = r.count > 1 ? ` (× ${r.count})` : \"\";\n const linkHtml = r.url ? ` <a href=\"${esc(r.url)}\" style=\"color:#60a5fa\" target=\"_blank\" rel=\"noopener\">📖</a>` : \"\";\n return `<li><span class=\"badge badge-${esc(sev)}\">${esc(r.severity)}</span> ${esc(r.text)}${countLabel}${linkHtml}</li>`;\n };\n\n const MLPS_TOP_N = 10;\n const mlpsTopItems = mlpsUniqueRecs.slice(0, MLPS_TOP_N).map(renderMlpsRec).join(\"\\n\");\n const mlpsRemaining = mlpsUniqueRecs.slice(MLPS_TOP_N);\n const mlpsMoreHtml = mlpsRemaining.length > 0\n ? `\\n<details><summary>${esc(t.showRemaining(mlpsRemaining.length))}…</summary>\\n${mlpsRemaining.map(renderMlpsRec).join(\"\\n\")}\\n</details>`\n : \"\";\n\n remediationHtml = `\n <details class=\"rec-fold\" open>\n <summary><h2 style=\"margin:0;border:0;display:inline\">${esc(t.remediationItems(mlpsUniqueRecs.length))}</h2></summary>\n <div class=\"rec-body\">\n <ol>${mlpsTopItems}${mlpsMoreHtml}</ol>\n </div>\n </details>`;\n }\n }\n\n // --- N/A count at bottom ---\n const naNote = naCount > 0\n ? `<p style=\"color:#64748b;font-size:13px;margin-top:24px\">${esc(t.naNote(naCount))}</p>`\n : \"\";\n\n const unknownNote =\n autoUnknown > 0\n ? `<div style=\"color:#94a3b8;font-size:12px;margin-top:8px\">${esc(t.unknownNote(autoUnknown))}</div>`\n : \"\";\n\n const mlpsCss = `\n .mlps-cloud-section>summary{color:#94a3b8}\n .mlps-cloud-note{color:#94a3b8;font-size:13px;margin-bottom:12px;font-style:italic}\n .check-cloud{background:rgba(148,163,184,0.08)}\n .check-cloud .check-note{color:#64748b;font-size:12px;margin-left:auto;white-space:nowrap}\n .check-manual{background:rgba(148,163,184,0.06)}\n .check-clean{background:rgba(34,197,94,0.1);border-left:3px solid #22c55e}\n .check-issues{background:rgba(239,68,68,0.1);border-left:3px solid #ef4444}\n .check-unknown{background:rgba(148,163,184,0.1);border-left:3px solid #94a3b8}\n .check-findings-wrap{margin-left:28px;margin-bottom:4px}\n .check-detail{color:#94a3b8;font-size:13px;margin-left:28px;margin-top:2px}\n .category-stat-clean{color:#22c55e}\n .category-stat-issues{color:#ef4444}\n .category-stat-cloud{color:#94a3b8}\n .category-stat-manual{color:#94a3b8}\n .mlps-summary-cards{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:32px}\n .mlps-summary-card{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:16px 20px;text-align:center;min-width:100px;flex:1}\n .mlps-summary-card .stat-count{font-size:28px;font-weight:700}\n .mlps-summary-card .stat-label{font-size:12px;color:#94a3b8;margin-top:2px}\n `;\n\n return `<!DOCTYPE html>\n<html lang=\"${htmlLang}\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${esc(t.mlpsTitle)} — ${esc(date)}</title>\n<style>${sharedCss()}${mlpsCss}</style>\n</head>\n<body>\n<div class=\"container\">\n\n<header>\n <h1>🛡️ ${esc(t.mlpsTitle)}</h1>\n <div class=\"disclaimer\">${esc(t.mlpsDisclaimer)}</div>\n <div class=\"meta\">${esc(t.account)}: ${esc(accountId)} | ${esc(t.region)}: ${esc(region)} | ${esc(t.scanTime)}: ${esc(scanTime)}</div>\n</header>\n\n<section class=\"summary\" style=\"display:block;text-align:center\">\n <div style=\"font-size:36px;font-weight:700;margin-bottom:12px\">\n <span style=\"color:#22c55e\">${autoClean}</span> <span style=\"color:#94a3b8;font-size:18px\">${esc(t.noIssues)}</span>\n <span style=\"color:#475569;margin:0 16px\">/</span>\n <span style=\"color:#ef4444\">${autoIssues}</span> <span style=\"color:#94a3b8;font-size:18px\">${esc(t.issuesFound)}</span>\n </div>\n <div class=\"mlps-summary-cards\" style=\"justify-content:center\">\n <div class=\"mlps-summary-card\"><div class=\"stat-count\" style=\"color:#60a5fa\">${checkedTotal}</div><div class=\"stat-label\">${esc(t.checkedItems)}</div></div>\n <div class=\"mlps-summary-card\"><div class=\"stat-count\" style=\"color:#94a3b8\">${cloudCount}</div><div class=\"stat-label\">\\ud83c\\udfe2 ${esc(t.cloudProvider)}</div></div>\n <div class=\"mlps-summary-card\"><div class=\"stat-count\" style=\"color:#eab308\">${manualCount}</div><div class=\"stat-label\">\\ud83d\\udccb ${esc(t.manualReview)}</div></div>\n ${naCount > 0 ? `<div class=\"mlps-summary-card\"><div class=\"stat-count\" style=\"color:#64748b\">${naCount}</div><div class=\"stat-label\">\\u2796 ${esc(t.notApplicable)}</div></div>` : \"\"}\n </div>\n</section>\n${unknownNote}\n\n${trendHtml}\n\n${buildServiceReminderHtml(scanResults.modules, lang)}\n\n${categorySections}\n\n${remediationHtml}\n\n${naNote}\n\n<footer>\n <p>${esc(t.mlpsFooterGenerated(VERSION))}</p>\n <p>${esc(t.mlpsFooterDisclaimer)}</p>\n</footer>\n\n</div>\n</body>\n</html>`;\n}\n","import { writeFileSync, readFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nimport type {\n FullScanResult,\n DashboardData,\n DashboardHistoryEntry,\n} from \"../types.js\";\n\nexport function calculateScore(summary: FullScanResult[\"summary\"]): number {\n const raw =\n 100 -\n summary.critical * 15 -\n summary.high * 5 -\n summary.medium * 2 -\n summary.low * 0.5;\n return Math.max(0, Math.min(100, raw));\n}\n\nexport function saveResults(\n scanResults: FullScanResult,\n outputDir?: string,\n): string {\n const baseDir = outputDir ?? join(homedir(), \".aws-security\");\n const today = scanResults.scanStart.slice(0, 10); // YYYY-MM-DD\n\n // Create directories\n const scanDir = join(baseDir, \"scans\", today);\n const dashboardDir = join(baseDir, \"dashboard\");\n mkdirSync(scanDir, { recursive: true });\n mkdirSync(dashboardDir, { recursive: true });\n\n // Write raw scan\n writeFileSync(join(scanDir, \"scan.json\"), JSON.stringify(scanResults, null, 2));\n\n // Read existing dashboard data\n const dataPath = join(dashboardDir, \"data.json\");\n let existing: DashboardData | null = null;\n if (existsSync(dataPath)) {\n try {\n existing = JSON.parse(readFileSync(dataPath, \"utf-8\")) as DashboardData;\n } catch {\n // Corrupt or invalid JSON — start fresh\n existing = null;\n }\n }\n\n // Build history entry for today\n const historyEntry: DashboardHistoryEntry = {\n date: today,\n score: calculateScore(scanResults.summary),\n critical: scanResults.summary.critical,\n high: scanResults.summary.high,\n medium: scanResults.summary.medium,\n low: scanResults.summary.low,\n totalFindings: scanResults.summary.totalFindings,\n };\n\n // Merge history: replace same-date entry or append\n let history = existing?.history ?? [];\n const idx = history.findIndex((h) => h.date === today);\n if (idx >= 0) {\n history[idx] = historyEntry;\n } else {\n history.push(historyEntry);\n }\n // Keep only last 30 entries\n history = history.slice(-30);\n\n // Build dashboard data\n const dashboardData: DashboardData = {\n lastScan: {\n scanStart: scanResults.scanStart,\n scanEnd: scanResults.scanEnd,\n region: scanResults.region,\n accountId: scanResults.accountId,\n summary: scanResults.summary,\n modules: scanResults.modules.map((m) => ({\n module: m.module,\n findingsCount: m.findingsCount,\n status: m.status,\n })),\n findings: scanResults.modules.flatMap((m) =>\n m.findings.map((f) => ({ ...f, module: m.module })),\n ),\n },\n history,\n meta: {\n generatedAt: new Date().toISOString(),\n version: \"1.0.0\",\n dataRetentionDays: 30,\n },\n };\n\n writeFileSync(dataPath, JSON.stringify(dashboardData, null, 2));\n return dataPath;\n}\n","export interface FindingsFilter {\n /** Filter Security Hub findings by category keywords (case-insensitive match on title/description/impact) */\n securityHubCategories?: string[];\n /** Filter GuardDuty findings by type prefix (matched against impact field) */\n guardDutyTypes?: string[];\n /** Filter Inspector findings by type (matched against impact field) */\n inspectorTypes?: string[];\n /** Filter by minimum severity */\n minSeverity?: string;\n}\n\nconst SEVERITY_ORDER: Record<string, number> = {\n LOW: 0,\n MEDIUM: 1,\n HIGH: 2,\n CRITICAL: 3,\n};\n\nexport function applyFindingsFilter(\n moduleName: string,\n findings: import(\"../types.js\").Finding[],\n filter: FindingsFilter,\n): import(\"../types.js\").Finding[] {\n let result = findings;\n\n // Apply severity filter\n if (filter.minSeverity) {\n const minLevel = SEVERITY_ORDER[filter.minSeverity.toUpperCase()] ?? 0;\n result = result.filter((f) => (SEVERITY_ORDER[f.severity] ?? 0) >= minLevel);\n }\n\n // Apply module-specific category filters\n if (moduleName === \"security_hub_findings\" && filter.securityHubCategories?.length) {\n const keywords = filter.securityHubCategories;\n result = result.filter((f) =>\n keywords.some((kw) => {\n const lower = kw.toLowerCase();\n return (\n f.title.toLowerCase().includes(lower) ||\n f.description.toLowerCase().includes(lower) ||\n f.impact.toLowerCase().includes(lower)\n );\n }),\n );\n }\n\n if (moduleName === \"guardduty_findings\" && filter.guardDutyTypes?.length) {\n const prefixes = filter.guardDutyTypes;\n result = result.filter((f) =>\n prefixes.some((prefix) => f.impact.includes(prefix)),\n );\n }\n\n if (moduleName === \"inspector_findings\" && filter.inspectorTypes?.length) {\n const types = filter.inspectorTypes;\n result = result.filter((f) =>\n types.some((t) => f.impact.includes(t)),\n );\n }\n\n return result;\n}\n\nexport const SCAN_GROUPS: Record<string, {\n name: string;\n description: string;\n modules: string[];\n reportType?: string;\n findingsFilter?: FindingsFilter;\n}> = {\n mlps3_precheck: {\n name: \"等保三级预检\",\n description: \"GB/T 22239-2019 等保三级 AWS 云租户层配置检查\",\n modules: [\"service_detection\", \"secret_exposure\", \"ssl_certificate\", \"dns_dangling\", \"network_reachability\", \"iam_privilege_escalation\", \"tag_compliance\", \"disaster_recovery\", \"security_hub_findings\", \"guardduty_findings\", \"inspector_findings\", \"trusted_advisor_findings\", \"config_rules_findings\", \"access_analyzer_findings\", \"patch_compliance_findings\", \"imdsv2_enforcement\", \"waf_coverage\"],\n reportType: \"mlps3\",\n },\n hw_defense: {\n name: \"护网蓝队加固\",\n description: \"护网前安全自查 — 攻击面+弱点评估\",\n modules: [\"service_detection\", \"secret_exposure\", \"network_reachability\", \"dns_dangling\", \"ssl_certificate\", \"iam_privilege_escalation\", \"security_hub_findings\", \"guardduty_findings\", \"inspector_findings\", \"config_rules_findings\", \"access_analyzer_findings\", \"patch_compliance_findings\", \"imdsv2_enforcement\", \"waf_coverage\"],\n findingsFilter: {\n guardDutyTypes: [\"Backdoor\", \"Trojan\", \"PenTest\", \"CryptoCurrency\"],\n minSeverity: \"MEDIUM\",\n },\n },\n exposure: {\n name: \"公网暴露面评估\",\n description: \"评估公网可达的资源和端口\",\n modules: [\"network_reachability\", \"dns_dangling\", \"public_access_verify\", \"ssl_certificate\", \"security_hub_findings\", \"access_analyzer_findings\", \"imdsv2_enforcement\", \"waf_coverage\"],\n findingsFilter: {\n securityHubCategories: [\"network\", \"public\", \"exposure\", \"port\"],\n },\n },\n data_encryption: {\n name: \"数据加密审计\",\n description: \"全面检查存储和传输加密状态\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n findingsFilter: {\n securityHubCategories: [\"encryption\", \"Encryption\"],\n },\n },\n least_privilege: {\n name: \"最小权限审计\",\n description: \"IAM 权限最小化评估\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\", \"access_analyzer_findings\"],\n findingsFilter: {\n securityHubCategories: [\"IAM\", \"iam\", \"access\", \"privilege\"],\n },\n },\n log_integrity: {\n name: \"日志完整性审计\",\n description: \"审计日志完整性和保护\",\n modules: [\"service_detection\", \"security_hub_findings\"],\n findingsFilter: {\n securityHubCategories: [\"logging\", \"CloudTrail\", \"audit\"],\n },\n },\n disaster_recovery: {\n name: \"灾备评估\",\n description: \"备份和灾备能力评估\",\n modules: [\"disaster_recovery\", \"security_hub_findings\"],\n },\n idle_resources: {\n name: \"闲置资源清理\",\n description: \"发现未使用的资源\",\n modules: [\"idle_resources\", \"trusted_advisor_findings\"],\n },\n tag_compliance: {\n name: \"资源标签合规\",\n description: \"检查必需标签\",\n modules: [\"tag_compliance\"],\n },\n new_account_baseline: {\n name: \"新账户基线检查\",\n description: \"新 AWS 账户安全基线\",\n modules: [\"service_detection\", \"secret_exposure\", \"iam_privilege_escalation\", \"security_hub_findings\", \"guardduty_findings\", \"access_analyzer_findings\", \"imdsv2_enforcement\"],\n },\n aggregation: {\n name: \"安全服务聚合\",\n description: \"从 Security Hub / GuardDuty / Inspector / Trusted Advisor / Config Rules / Access Analyzer / Patch Compliance 聚合所有安全发现\",\n modules: [\"security_hub_findings\", \"guardduty_findings\", \"inspector_findings\", \"trusted_advisor_findings\", \"config_rules_findings\", \"access_analyzer_findings\", \"patch_compliance_findings\"],\n },\n};\n","export const SECURITY_RULES_CONTENT = `# AWS Security Scan Modules & Rules (19 modules)\n\n## 1. Service Detection (service_detection)\nDetects which AWS security services are enabled and assesses overall security maturity.\n- **Security Hub not enabled** — Risk 7.5: Provides 300+ automated security checks.\n- **GuardDuty not enabled** — Risk 7.5: Provides continuous threat detection.\n- **Inspector not enabled** — Risk 6.0: Scans for software vulnerabilities.\n- **AWS Config not enabled** — Risk 6.0: Tracks configuration changes.\n- CloudTrail detection is included for coverage metrics.\n\n### Maturity Levels\n| Enabled Services | Level |\n|------------------|-------|\n| 0–1 | Basic |\n| 2–3 | Intermediate |\n| 4 | Advanced |\n| 5 | Comprehensive |\n\n## 2. Security Hub Findings (security_hub_findings)\nAggregates active findings from AWS Security Hub. Replaces individual config scanners (SG, S3, IAM, CloudTrail, RDS, EBS, VPC, etc.) with centralized compliance checks from FSBP, CIS, and PCI DSS standards.\n- Findings are filtered to ACTIVE + NEW/NOTIFIED workflow status.\n- Severity mapped: CRITICAL → 9.5, HIGH → 8.0, MEDIUM → 5.5, LOW → 3.0.\n- INFORMATIONAL findings are skipped.\n\n## 3. GuardDuty Findings (guardduty_findings)\nDetection-only: checks if GuardDuty is enabled in the region.\n- GuardDuty findings are aggregated via Security Hub (security_hub_findings module).\n- Reports whether GuardDuty detectors are active.\n\n## 4. Inspector Findings (inspector_findings)\nDetection-only: checks if Inspector is enabled in the region.\n- Inspector findings are aggregated via Security Hub (security_hub_findings module).\n- Reports whether Inspector scanning (EC2/Lambda) is active.\n\n## 5. Trusted Advisor Findings (trusted_advisor_findings)\nAggregates security checks from AWS Trusted Advisor.\n- Requires AWS Business or Enterprise Support plan.\n- In China regions, uses cn-north-1 as the Support API endpoint.\n- Status mapped: error (RED) → 8.0, warning (YELLOW) → 5.5, ok (GREEN) → skip.\n\n## 6. Secret Exposure (secret_exposure)\nChecks Lambda env vars and EC2 userData for exposed secrets (AWS keys, private keys, passwords).\n\n## 7. SSL Certificate (ssl_certificate)\nChecks ACM certificates for expiry, failed status, and upcoming renewals.\n\n## 8. Dangling DNS (dns_dangling)\nChecks Route53 CNAME records for dangling DNS (subdomain takeover risk).\n\n## 9. Network Reachability (network_reachability)\nAnalyzes true network reachability by combining Security Group + NACL rules for public EC2 instances.\n\n## 10. IAM Privilege Escalation (iam_privilege_escalation)\nDetects IAM privilege escalation paths — users/roles that can escalate to admin via policy manipulation, role creation, or service abuse.\n\n## 11. Public Access Verify (public_access_verify)\nVerifies actual public accessibility of resources marked as public (S3 HTTP check, RDS DNS resolution).\n\n## 12. Tag Compliance (tag_compliance)\nChecks EC2, RDS, and S3 resources for required tags (Environment, Project, Owner).\n\n## 13. Idle Resources (idle_resources)\nFinds unused/idle AWS resources (unattached EBS volumes, unused EIPs, stopped instances, unused security groups).\n\n## 14. Disaster Recovery (disaster_recovery)\nAssesses disaster recovery readiness — RDS Multi-AZ & backups, EBS snapshot coverage, S3 versioning & cross-region replication.\n\n## 15. Config Rules Findings (config_rules_findings)\nDetection-only: checks if AWS Config Rules are configured.\n- Config Rule compliance findings are aggregated via Security Hub (security_hub_findings module).\n- Reports whether Config is enabled and counts active rules.\n- Gracefully handles regions where AWS Config is not enabled.\n\n## 16. IAM Access Analyzer Findings (access_analyzer_findings)\nDetection-only: checks if IAM Access Analyzer is configured.\n- Access Analyzer findings are aggregated via Security Hub (security_hub_findings module).\n- Reports whether active analyzers exist.\n- Returns warning if no analyzer is configured.\n\n## 17. SSM Patch Compliance (patch_compliance_findings)\nChecks patch compliance status for SSM-managed instances.\n- Lists all managed instances via SSM.\n- Retrieves patch compliance state for each instance.\n- Missing security patches or failed patches → HIGH (7.5).\n- Missing non-security patches → MEDIUM (5.5).\n- Instances without patch data flagged as LOW (3.0) for visibility.\n- Includes platform info, missing/failed counts, and last scan time.\n\n## 18. IMDSv2 Enforcement (imdsv2_enforcement)\nChecks if EC2 instances enforce IMDSv2 (Instance Metadata Service v2).\n- Lists all running EC2 instances and checks MetadataOptions.HttpTokens.\n- **HttpTokens != \"required\"** — Risk 7.5: IMDSv1 allows credential theft via SSRF attacks.\n- Also checks HttpPutResponseHopLimit — values >1 on containerized workloads noted as warning.\n- Remediation: Set HttpTokens to \"required\" via modify-instance-metadata-options.\n\n## 19. WAF Coverage (waf_coverage)\nChecks if internet-facing ALBs have WAF Web ACL associated for protection.\n- Lists all ELBv2 load balancers, filters to internet-facing only.\n- For each internet-facing ALB, checks WAFv2 Web ACL association.\n- **No WAF Web ACL** — Risk 7.5: ALB exposed to SQL injection, XSS, and OWASP Top 10 attacks.\n- NLBs (L4) are skipped as WAF does not apply — noted in warnings.\n- Gracefully handles WAFv2 access denied or unavailable regions.\n`;\n\nexport const RISK_SCORING_CONTENT = `# Risk Scoring Model\n\n## Score Ranges\nEach finding is assigned a risk score from 0.0 to 10.0 based on potential impact and exploitability.\n\n| Score Range | Severity | Priority | Description |\n|-------------|----------|----------|-------------|\n| 9.0 – 10.0 | CRITICAL | P0 | Immediate action required. Active exploitation risk. |\n| 7.0 – 8.9 | HIGH | P1 | Address within 24-48 hours. Significant exposure. |\n| 4.0 – 6.9 | MEDIUM | P2 | Address within 1-2 weeks. Moderate risk. |\n| 0.0 – 3.9 | LOW | P3 | Address in next maintenance cycle. Minor risk. |\n\n## Severity Mapping\n\\`\\`\\`\nscore >= 9.0 → CRITICAL\nscore >= 7.0 → HIGH\nscore >= 4.0 → MEDIUM\nscore < 4.0 → LOW\n\\`\\`\\`\n\n## Priority Mapping\n\\`\\`\\`\nCRITICAL → P0 (Immediate)\nHIGH → P1 (Urgent)\nMEDIUM → P2 (Normal)\nLOW → P3 (Low)\n\\`\\`\\`\n\n## Scoring Factors\n- **Exploitability**: How easily can this misconfiguration be exploited?\n- **Blast radius**: What data or systems are at risk?\n- **Public exposure**: Is the resource internet-facing?\n- **Compliance**: Does this violate common compliance frameworks (CIS, SOC2)?\n- **Data sensitivity**: Could sensitive data be exposed or lost?\n\n## Examples\n- Root account without MFA → 10.0 (total account compromise risk)\n- Public S3 ACL → 9.5 (data breach via public access)\n- Missing encryption at rest → 6.0 (data exposure if storage is compromised)\n- Versioning disabled → 3.0 (data loss risk, low exploitability)\n`;\n","#!/usr/bin/env node\n\nimport { startServer } from \"../src/index.js\";\nimport { VERSION } from \"../src/version.js\";\n\nconst args = process.argv.slice(2);\nconst subcommand = args[0];\n\nconst HELP = `Usage: aws-security-mcp [command] [options]\n\nCommands:\n (default) Start MCP server (stdio, for Kiro/Claude Code)\n dashboard Start local HTTP server serving the security dashboard\n deploy-dashboard Deploy dashboard to an S3 bucket as a static website\n\nOptions:\n --region <region> AWS region (default: AWS_REGION env or us-east-1)\n --version Print version and exit\n --help, -h Show this help message\n\nDashboard options:\n --port <port> Port for local dashboard server (default: 3000)\n\nDeploy options:\n --bucket <name> S3 bucket name (required)\n --region <region> AWS region for the S3 bucket\n\nEnvironment variables:\n AWS_REGION Default AWS region\n AWS_DEFAULT_REGION Fallback default region\n\nThe MCP server communicates over stdio using the MCP protocol.`;\n\nif (args.includes(\"--help\") || args.includes(\"-h\")) {\n console.log(HELP);\n process.exit(0);\n}\n\nif (args.includes(\"--version\")) {\n console.log(`aws-security-mcp ${VERSION}`);\n process.exit(0);\n}\n\nfunction getArg(name: string): string | undefined {\n const idx = args.indexOf(name);\n if (idx !== -1 && args[idx + 1]) return args[idx + 1];\n return undefined;\n}\n\nfunction getRegion(): string {\n return (\n getArg(\"--region\") ??\n process.env.AWS_REGION ??\n process.env.AWS_DEFAULT_REGION ??\n \"us-east-1\"\n );\n}\n\nif (subcommand === \"dashboard\") {\n const port = Number(getArg(\"--port\")) || 3000;\n import(\"../src/commands/dashboard.js\").then(({ startDashboard }) => {\n startDashboard(port);\n });\n} else if (subcommand === \"deploy-dashboard\") {\n const bucket = getArg(\"--bucket\");\n if (!bucket) {\n console.error(\"Error: --bucket <name> is required for deploy-dashboard\");\n process.exit(1);\n }\n const region = getRegion();\n import(\"../src/commands/deploy-dashboard.js\").then(({ deployDashboard }) => {\n deployDashboard(bucket, region).catch((err) => {\n console.error(\"Deploy failed:\", err.message || err);\n process.exit(1);\n });\n });\n} else if (subcommand && !subcommand.startsWith(\"--\")) {\n console.error(`Unknown command: ${subcommand}`);\n console.error('Run \"aws-security-mcp --help\" for usage.');\n process.exit(1);\n} else {\n // Default: start MCP server\n const region = getRegion();\n startServer(region).catch((err) => {\n console.error(\"Fatal:\", err);\n process.exit(1);\n });\n}\n"],"mappings":"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","names":["createServer","join","existsSync","fileURLToPath","readFileSync","existsSync","copyFileSync","join","extname","fileURLToPath","S3Client","__dirname","__filename","STSClient","GetCallerIdentityCommand","STSClient","makeFinding","makeFinding","makeFinding","EC2Client","DescribeInstancesCommand","makeFinding","EC2Client","DescribeInstancesCommand","makeFinding","S3Client","dns","makeFinding","S3Client","dns","EC2Client","DescribeInstancesCommand","RDSClient","DescribeDBInstancesCommand","S3Client","ListBucketsCommand","makeFinding","EC2Client","DescribeInstancesCommand","RDSClient","DescribeDBInstancesCommand","S3Client","ListBucketsCommand","EC2Client","DescribeAddressesCommand","DescribeInstancesCommand","DescribeSecurityGroupsCommand","makeFinding","EC2Client","DescribeAddressesCommand","DescribeInstancesCommand","DescribeSecurityGroupsCommand","RDSClient","DescribeDBInstancesCommand","EC2Client","DescribeVolumesCommand","S3Client","ListBucketsCommand","makeFinding","RDSClient","DescribeDBInstancesCommand","EC2Client","DescribeVolumesCommand","S3Client","ListBucketsCommand","SecurityHubClient","SecurityHubClient","isNotEnabled","GuardDutyClient","ListDetectorsCommand","GuardDutyClient","ListDetectorsCommand","Inspector2Client","BatchGetAccountStatusCommand","Inspector2Client","BatchGetAccountStatusCommand","isAccessDenied","ConfigServiceClient","DescribeConfigurationRecordersCommand","ConfigServiceClient","DescribeConfigurationRecordersCommand","riskScore","severity","EC2Client","DescribeInstancesCommand","makeFinding","EC2Client","DescribeInstancesCommand","makeFinding","formatDuration","SEVERITY_ORDER","w","existing","SEVERITY_ORDER","readFileSync","join","SERVICE_NOT_ENABLED_PATTERNS","startDashboard","deployDashboard"]}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/dashboard.ts","../../src/commands/deploy-dashboard.ts","../../src/index.ts","../../src/version.ts","../../src/utils/aws-client.ts","../../src/utils/assume-role.ts","../../src/utils/org-accounts.ts","../../src/scanners/runner.ts","../../src/scanners/service-detection.ts","../../src/utils/risk-scoring.ts","../../src/scanners/secret-exposure.ts","../../src/scanners/ssl-certificate.ts","../../src/scanners/dns-dangling.ts","../../src/scanners/network-reachability.ts","../../src/scanners/iam-privilege-escalation.ts","../../src/scanners/public-access-verify.ts","../../src/scanners/tag-compliance.ts","../../src/scanners/idle-resources.ts","../../src/scanners/disaster-recovery.ts","../../src/scanners/security-hub-findings.ts","../../src/utils/sh-source.ts","../../src/scanners/guardduty-findings.ts","../../src/scanners/inspector-findings.ts","../../src/scanners/trusted-advisor-findings.ts","../../src/scanners/config-rules-findings.ts","../../src/scanners/access-analyzer-findings.ts","../../src/scanners/patch-compliance-findings.ts","../../src/scanners/imdsv2-enforcement.ts","../../src/scanners/waf-coverage.ts","../../src/i18n/zh.ts","../../src/i18n/en.ts","../../src/i18n/index.ts","../../src/tools/report-tool.ts","../../src/data/mlps3-full-checklist.json","../../src/data/mlps3-check-mapping.ts","../../src/tools/mlps-report.ts","../../src/tools/html-report.ts","../../src/tools/hw-report.ts","../../src/tools/save-results.ts","../../src/tools/scan-groups.ts","../../src/resources/index.ts","../../bin/aws-security-mcp.ts"],"sourcesContent":["import { createServer } from \"node:http\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, extname, resolve } from \"node:path\";\nimport { existsSync, copyFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { exec } from \"node:child_process\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = join(__filename, \"..\");\n\nconst MIME_TYPES: Record<string, string> = {\n \".html\": \"text/html\",\n \".js\": \"text/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n};\n\nexport function startDashboard(port = 3000): void {\n // dashboard/dist is two levels up from dist/src/commands/\n const dashboardDir = join(__dirname, \"../../dashboard/dist\");\n\n if (!existsSync(dashboardDir)) {\n console.error(\n `Dashboard not built. Run \"npm run build:dashboard\" first.\\n` +\n `Expected: ${dashboardDir}`,\n );\n process.exit(1);\n }\n\n // Copy real data.json if available\n const dataSource = join(\n process.env.HOME || process.env.USERPROFILE || \"~\",\n \".aws-security/dashboard/data.json\",\n );\n const dataDest = join(dashboardDir, \"data.json\");\n if (existsSync(dataSource)) {\n copyFileSync(dataSource, dataDest);\n console.log(`Loaded scan data from ${dataSource}`);\n } else {\n console.log(\n \"No scan data found at ~/.aws-security/dashboard/data.json — using bundled sample data\",\n );\n }\n\n const resolvedBase = resolve(dashboardDir);\n\n const server = createServer(async (req, res) => {\n const url = req.url?.split(\"?\")[0] ?? \"/\";\n let filePath = resolve(\n join(dashboardDir, url === \"/\" ? \"index.html\" : url),\n );\n\n // Ensure the resolved path is within dashboardDir\n if (!filePath.startsWith(resolvedBase + \"/\") && filePath !== resolvedBase) {\n res.writeHead(403);\n res.end(\"Forbidden\");\n return;\n }\n\n // SPA fallback: if file doesn't exist and isn't a static asset, serve index.html\n if (!existsSync(filePath)) {\n filePath = join(dashboardDir, \"index.html\");\n }\n\n try {\n const content = await readFile(filePath);\n const ext = extname(filePath);\n res.writeHead(200, {\n \"Content-Type\": MIME_TYPES[ext] || \"application/octet-stream\",\n });\n res.end(content);\n } catch {\n res.writeHead(404);\n res.end(\"Not found\");\n }\n });\n\n server.listen(port, () => {\n const url = `http://localhost:${port}`;\n console.log(`\\nAWS Security Dashboard: ${url}\\n`);\n console.log(\"Press Ctrl+C to stop.\\n\");\n\n // Try to open browser\n const cmd =\n process.platform === \"darwin\"\n ? \"open\"\n : process.platform === \"win32\"\n ? \"start\"\n : \"xdg-open\";\n exec(`${cmd} ${url}`, () => {\n // ignore errors — browser open is best-effort\n });\n });\n\n server.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n console.error(`Port ${port} is already in use. Try --port <other>`);\n process.exit(1);\n }\n throw err;\n });\n}\n","import { readdirSync, readFileSync, existsSync, copyFileSync } from \"node:fs\";\nimport { join, extname, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n S3Client,\n PutObjectCommand,\n PutBucketWebsiteCommand,\n PutBucketPolicyCommand,\n} from \"@aws-sdk/client-s3\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = join(__filename, \"..\");\n\nconst CONTENT_TYPES: Record<string, string> = {\n \".html\": \"text/html\",\n \".js\": \"text/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n};\n\nfunction collectFiles(dir: string): string[] {\n const files: string[] = [];\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...collectFiles(full));\n } else {\n files.push(full);\n }\n }\n return files;\n}\n\nexport async function deployDashboard(\n bucket: string,\n region: string,\n): Promise<void> {\n const dashboardDir = join(__dirname, \"../../dashboard/dist\");\n\n if (!existsSync(dashboardDir)) {\n console.error(\n `Dashboard not built. Run \"npm run build:dashboard\" first.\\n` +\n `Expected: ${dashboardDir}`,\n );\n process.exit(1);\n }\n\n // Copy real data.json if available\n const dataSource = join(\n process.env.HOME || process.env.USERPROFILE || \"~\",\n \".aws-security/dashboard/data.json\",\n );\n const dataDest = join(dashboardDir, \"data.json\");\n if (existsSync(dataSource)) {\n copyFileSync(dataSource, dataDest);\n console.log(`Loaded scan data from ${dataSource}`);\n } else {\n console.log(\n \"No scan data at ~/.aws-security/dashboard/data.json — deploying with bundled sample data\",\n );\n }\n\n const s3 = new S3Client({ region });\n\n // Configure static website hosting\n console.log(`Configuring s3://${bucket} for static website hosting...`);\n await s3.send(\n new PutBucketWebsiteCommand({\n Bucket: bucket,\n WebsiteConfiguration: {\n IndexDocument: { Suffix: \"index.html\" },\n ErrorDocument: { Key: \"index.html\" }, // SPA fallback\n },\n }),\n );\n\n // Set bucket policy for public read access\n const partition = region.startsWith(\"cn-\") ? \"aws-cn\" : \"aws\";\n console.log(`Setting public read bucket policy on s3://${bucket}...`);\n await s3.send(\n new PutBucketPolicyCommand({\n Bucket: bucket,\n Policy: JSON.stringify({\n Version: \"2012-10-17\",\n Statement: [\n {\n Sid: \"PublicReadGetObject\",\n Effect: \"Allow\",\n Principal: \"*\",\n Action: \"s3:GetObject\",\n Resource: `arn:${partition}:s3:::${bucket}/*`,\n },\n ],\n }),\n }),\n );\n\n // Upload all files\n const files = collectFiles(dashboardDir);\n console.log(`Uploading ${files.length} files to s3://${bucket}...`);\n\n for (const filePath of files) {\n const key = relative(dashboardDir, filePath);\n const ext = extname(filePath);\n const contentType = CONTENT_TYPES[ext] || \"application/octet-stream\";\n const body = readFileSync(filePath);\n\n await s3.send(\n new PutObjectCommand({\n Bucket: bucket,\n Key: key,\n Body: body,\n ContentType: contentType,\n }),\n );\n console.log(` ${key}`);\n }\n\n const domain = region.startsWith(\"cn-\") ? \"amazonaws.com.cn\" : \"amazonaws.com\";\n const websiteUrl = `http://${bucket}.s3-website.${region}.${domain}`;\n console.log(`\\nDashboard deployed successfully!`);\n console.log(`Website URL: ${websiteUrl}`);\n console.log(\n \"\\nNote: Ensure S3 Block Public Access is disabled on this bucket for the website to be accessible.\\n\",\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\n\nimport { VERSION } from \"./version.js\";\nimport type { Scanner } from \"./scanners/base.js\";\nimport { runAllScanners, runMultiAccountScanners } from \"./scanners/runner.js\";\nimport { ServiceDetectionScanner } from \"./scanners/service-detection.js\";\nimport type { ServiceDetectionResult } from \"./scanners/service-detection.js\";\nimport { SecretExposureScanner } from \"./scanners/secret-exposure.js\";\nimport { SslCertificateScanner } from \"./scanners/ssl-certificate.js\";\nimport { DnsDanglingScanner } from \"./scanners/dns-dangling.js\";\nimport { NetworkReachabilityScanner } from \"./scanners/network-reachability.js\";\nimport { IamPrivilegeEscalationScanner } from \"./scanners/iam-privilege-escalation.js\";\nimport { PublicAccessVerifyScanner } from \"./scanners/public-access-verify.js\";\nimport { TagComplianceScanner } from \"./scanners/tag-compliance.js\";\nimport { IdleResourcesScanner } from \"./scanners/idle-resources.js\";\nimport { DisasterRecoveryScanner } from \"./scanners/disaster-recovery.js\";\nimport { SecurityHubFindingsScanner } from \"./scanners/security-hub-findings.js\";\nimport { GuardDutyFindingsScanner } from \"./scanners/guardduty-findings.js\";\nimport { InspectorFindingsScanner } from \"./scanners/inspector-findings.js\";\nimport { TrustedAdvisorFindingsScanner } from \"./scanners/trusted-advisor-findings.js\";\nimport { ConfigRulesFindingsScanner } from \"./scanners/config-rules-findings.js\";\nimport { AccessAnalyzerFindingsScanner } from \"./scanners/access-analyzer-findings.js\";\nimport { PatchComplianceFindingsScanner } from \"./scanners/patch-compliance-findings.js\";\nimport { Imdsv2EnforcementScanner } from \"./scanners/imdsv2-enforcement.js\";\nimport { WafCoverageScanner } from \"./scanners/waf-coverage.js\";\nimport { generateMarkdownReport } from \"./tools/report-tool.js\";\nimport { generateMlps3Report } from \"./tools/mlps-report.js\";\nimport { generateHtmlReport, generateMlps3HtmlReport } from \"./tools/html-report.js\";\nimport { generateHwDefenseHtmlReport } from \"./tools/hw-report.js\";\nimport { saveResults } from \"./tools/save-results.js\";\nimport { SCAN_GROUPS, applyFindingsFilter } from \"./tools/scan-groups.js\";\nimport {\n SECURITY_RULES_CONTENT,\n RISK_SCORING_CONTENT,\n} from \"./resources/index.js\";\nimport { getPartition, getAccountId } from \"./utils/aws-client.js\";\nimport { listOrgAccounts } from \"./utils/org-accounts.js\";\nimport type { FullScanResult, ScanResult, ScanContext } from \"./types.js\";\nimport { getI18n, type Lang } from \"./i18n/index.js\";\nimport { readFileSync } from \"fs\";\nimport { join, dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nexport { type Lang } from \"./i18n/index.js\";\nexport { type Scanner } from \"./scanners/base.js\";\nexport { runAllScanners, runMultiAccountScanners } from \"./scanners/runner.js\";\nexport { assumeRole, buildRoleArn, getCurrentAccountId } from \"./utils/assume-role.js\";\nexport { listOrgAccounts, type OrgAccount } from \"./utils/org-accounts.js\";\nexport { generateMarkdownReport } from \"./tools/report-tool.js\";\nexport { generateHtmlReport, generateMlps3HtmlReport } from \"./tools/html-report.js\";\nexport { generateHwDefenseHtmlReport } from \"./tools/hw-report.js\";\nexport { saveResults, calculateScore } from \"./tools/save-results.js\";\nexport type {\n Finding,\n ScanResult,\n ScanContext,\n FullScanResult,\n DashboardData,\n DashboardHistoryEntry,\n Severity,\n Priority,\n} from \"./types.js\";\n\nconst MODULE_DESCRIPTIONS: Record<string, string> = {\n service_detection:\n \"Detects which AWS security services (Security Hub, GuardDuty, Inspector, Config) are enabled and assesses security maturity.\",\n secret_exposure:\n \"Checks Lambda env vars and EC2 userData for exposed secrets (AWS keys, private keys, passwords).\",\n ssl_certificate:\n \"Checks ACM certificates for expiry, failed status, and upcoming renewals.\",\n dns_dangling:\n \"Checks Route53 CNAME records for dangling DNS (subdomain takeover risk).\",\n network_reachability:\n \"Analyzes true network reachability by combining Security Group + NACL rules for public EC2 instances.\",\n iam_privilege_escalation:\n \"Detects IAM privilege escalation paths — users/roles that can escalate to admin via policy manipulation, role creation, or service abuse.\",\n public_access_verify:\n \"Verifies actual public accessibility of resources marked as public (S3 HTTP check, RDS DNS resolution).\",\n tag_compliance:\n \"Checks EC2, RDS, and S3 resources for required tags (Environment, Project, Owner).\",\n idle_resources:\n \"Finds unused/idle AWS resources (unattached EBS volumes, unused EIPs, stopped instances, unused security groups) that waste money and increase attack surface.\",\n disaster_recovery:\n \"Assesses disaster recovery readiness — RDS Multi-AZ & backups, EBS snapshot coverage, S3 versioning & cross-region replication.\",\n security_hub_findings:\n \"Aggregates active findings from AWS Security Hub — replaces individual config scanners with centralized compliance checks.\",\n guardduty_findings:\n \"Checks if GuardDuty is enabled. Findings are aggregated via Security Hub.\",\n inspector_findings:\n \"Checks if Inspector is enabled. Findings are aggregated via Security Hub.\",\n trusted_advisor_findings:\n \"Aggregates security checks from AWS Trusted Advisor — requires Business or Enterprise Support plan.\",\n config_rules_findings:\n \"Checks if AWS Config Rules are configured. Findings are aggregated via Security Hub.\",\n access_analyzer_findings:\n \"Checks if IAM Access Analyzer is configured. Findings are aggregated via Security Hub.\",\n patch_compliance_findings:\n \"Checks SSM Patch Manager compliance — managed instances with missing or failed security and system patches.\",\n imdsv2_enforcement:\n \"Checks if EC2 instances enforce IMDSv2 (HttpTokens: required) — IMDSv1 allows credential theft via SSRF.\",\n waf_coverage:\n \"Checks if internet-facing ALBs have WAF Web ACL associated for protection against common web exploits.\",\n};\n\nfunction getHwDefenseChecklist(lang?: Lang): string {\n return getI18n(lang ?? \"zh\").hwChecklist;\n}\n\n// SERVICE_RECOMMENDATIONS are now in the i18n module (t.serviceRecommendations)\n\nconst SERVICE_NOT_ENABLED_PATTERNS = [\n \"not enabled\",\n \"not found\",\n \"No IAM Access Analyzer\",\n \"No SSM-managed instances\",\n \"requires AWS Business or Enterprise Support\",\n \"not available\",\n \"is not enabled\",\n];\n\nfunction buildServiceReminder(modules: ScanResult[], lang?: Lang): string {\n const t = getI18n(lang ?? \"zh\");\n const disabledServices: Array<{ icon: string; service: string; impact: string; action: string }> = [];\n\n for (const mod of modules) {\n const rec = t.serviceRecommendations[mod.module];\n if (!rec) continue;\n if (!mod.warnings?.length) continue;\n\n const hasNotEnabled = mod.warnings.some((w) =>\n SERVICE_NOT_ENABLED_PATTERNS.some((p) => w.includes(p)),\n );\n if (hasNotEnabled) {\n disabledServices.push(rec);\n }\n }\n\n if (disabledServices.length === 0) return \"\";\n\n const lines = [\n \"\",\n t.serviceReminderTitle,\n \"\",\n ];\n\n for (const svc of disabledServices) {\n lines.push(`${svc.icon} ${svc.service} ${t.notEnabled}`);\n lines.push(` ${t.serviceImpact}: ${svc.impact}`);\n lines.push(` ${t.serviceAction}: ${svc.action}`);\n lines.push(\"\");\n }\n\n lines.push(t.serviceReminderFooter);\n\n return lines.join(\"\\n\");\n}\n\nfunction summarizeResult(result: FullScanResult, lang?: Lang): string {\n const { summary } = result;\n const lines = [\n `Scan complete for account ${result.accountId} in ${result.region}.`,\n `Total findings: ${summary.totalFindings} (${summary.critical} Critical, ${summary.high} High, ${summary.medium} Medium, ${summary.low} Low)`,\n `Modules: ${summary.modulesSuccess} succeeded, ${summary.modulesError} errored`,\n ];\n\n const reminder = buildServiceReminder(result.modules, lang);\n if (reminder) {\n lines.push(reminder);\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction summarizeScanResult(result: ScanResult): string {\n const lines = [\n `Module: ${result.module} — ${result.status}`,\n `Resources scanned: ${result.resourcesScanned}, Findings: ${result.findingsCount}`,\n ];\n if (result.warnings?.length) {\n lines.push(`Warnings: ${result.warnings.length}`);\n }\n return lines.join(\"\\n\");\n}\n\nasync function buildScanContext(region: string): Promise<ScanContext> {\n let accountId: string;\n try {\n accountId = await getAccountId(region);\n } catch {\n accountId = \"unknown\";\n }\n return { region, partition: getPartition(region), accountId };\n}\n\nexport function createServer(defaultRegion: string): McpServer {\n const server = new McpServer(\n { name: \"aws-security-mcp\", version: VERSION },\n { capabilities: { resources: {}, tools: {}, prompts: {} } },\n );\n\n const allScanners: Scanner[] = [\n new ServiceDetectionScanner(),\n new SecretExposureScanner(),\n new SslCertificateScanner(),\n new DnsDanglingScanner(),\n new NetworkReachabilityScanner(),\n new IamPrivilegeEscalationScanner(),\n new PublicAccessVerifyScanner(),\n new TagComplianceScanner(),\n new IdleResourcesScanner(),\n new DisasterRecoveryScanner(),\n new SecurityHubFindingsScanner(),\n new GuardDutyFindingsScanner(),\n new InspectorFindingsScanner(),\n new TrustedAdvisorFindingsScanner(),\n new ConfigRulesFindingsScanner(),\n new AccessAnalyzerFindingsScanner(),\n new PatchComplianceFindingsScanner(),\n new Imdsv2EnforcementScanner(),\n new WafCoverageScanner(),\n ];\n\n const scannerMap = new Map<string, Scanner>();\n for (const s of allScanners) {\n scannerMap.set(s.moduleName, s);\n }\n\n // --- Tools ---\n\n // 1. scan_all\n server.tool(\n \"scan_all\",\n \"Run all security scanners in parallel (including service detection). Read-only. Does not modify any AWS resources. Supports multi-account org scanning.\",\n {\n region: z.string().optional().describe(\"AWS region to scan (default: server region)\"),\n org_mode: z.boolean().optional().describe(\"Enable multi-account scanning via AWS Organizations\"),\n role_name: z.string().optional().describe(\"IAM role name to assume in child accounts (default: AWSSecurityMCPAudit)\"),\n account_ids: z.array(z.string()).optional().describe(\"Specific account IDs to scan (default: all org accounts)\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ region, org_mode, role_name, account_ids, lang }) => {\n try {\n const r = region ?? defaultRegion;\n let result: FullScanResult;\n\n if (org_mode) {\n result = await runMultiAccountScanners(allScanners, r, {\n orgMode: true,\n roleName: role_name ?? \"AWSSecurityMCPAudit\",\n accountIds: account_ids,\n });\n } else {\n result = await runAllScanners(allScanners, r);\n }\n\n return {\n content: [\n { type: \"text\", text: summarizeResult(result, lang ?? \"zh\") },\n { type: \"text\", text: JSON.stringify(result, null, 2) },\n ],\n };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // Individual scanner tools\n const individualScanners: Array<{ toolName: string; moduleName: string; label: string }> = [\n { toolName: \"detect_services\", moduleName: \"service_detection\", label: \"Security Service Detection\" },\n { toolName: \"scan_secret_exposure\", moduleName: \"secret_exposure\", label: \"Secret Exposure\" },\n { toolName: \"scan_ssl_certificate\", moduleName: \"ssl_certificate\", label: \"SSL Certificate\" },\n { toolName: \"scan_dns_dangling\", moduleName: \"dns_dangling\", label: \"Dangling DNS\" },\n { toolName: \"scan_network_reachability\", moduleName: \"network_reachability\", label: \"Network Reachability\" },\n { toolName: \"scan_iam_privilege_escalation\", moduleName: \"iam_privilege_escalation\", label: \"IAM Privilege Escalation\" },\n { toolName: \"scan_public_access_verify\", moduleName: \"public_access_verify\", label: \"Public Access Verify\" },\n { toolName: \"scan_tag_compliance\", moduleName: \"tag_compliance\", label: \"Tag Compliance\" },\n { toolName: \"scan_idle_resources\", moduleName: \"idle_resources\", label: \"Idle Resources\" },\n { toolName: \"scan_disaster_recovery\", moduleName: \"disaster_recovery\", label: \"Disaster Recovery\" },\n { toolName: \"scan_security_hub_findings\", moduleName: \"security_hub_findings\", label: \"Security Hub Findings\" },\n { toolName: \"scan_guardduty_findings\", moduleName: \"guardduty_findings\", label: \"GuardDuty Findings\" },\n { toolName: \"scan_inspector_findings\", moduleName: \"inspector_findings\", label: \"Inspector Findings\" },\n { toolName: \"scan_trusted_advisor_findings\", moduleName: \"trusted_advisor_findings\", label: \"Trusted Advisor Findings\" },\n { toolName: \"scan_config_rules_findings\", moduleName: \"config_rules_findings\", label: \"Config Rules Findings\" },\n { toolName: \"scan_access_analyzer_findings\", moduleName: \"access_analyzer_findings\", label: \"Access Analyzer Findings\" },\n { toolName: \"scan_patch_compliance_findings\", moduleName: \"patch_compliance_findings\", label: \"Patch Compliance Findings\" },\n { toolName: \"scan_imdsv2_enforcement\", moduleName: \"imdsv2_enforcement\", label: \"IMDSv2 Enforcement\" },\n { toolName: \"scan_waf_coverage\", moduleName: \"waf_coverage\", label: \"WAF Coverage\" },\n ];\n\n for (const { toolName, moduleName, label } of individualScanners) {\n server.tool(\n toolName,\n `Run ${label} security scanner only. Read-only. Does not modify any AWS resources.`,\n { region: z.string().optional().describe(\"AWS region to scan (default: server region)\") },\n async ({ region }) => {\n try {\n const r = region ?? defaultRegion;\n const ctx = await buildScanContext(r);\n const scanner = scannerMap.get(moduleName)!;\n const result: ScanResult = await scanner.scan(ctx);\n return {\n content: [\n { type: \"text\", text: summarizeScanResult(result) },\n { type: \"text\", text: JSON.stringify(result, null, 2) },\n ],\n };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n }\n\n // scan_group\n server.tool(\n \"scan_group\",\n \"Run a predefined group of security scanners for a specific scenario (e.g., MLPS compliance, network defense). Read-only. Supports multi-account org scanning.\",\n {\n group: z.string().describe(\"Scan group ID: mlps3_precheck, hw_defense, exposure, data_encryption, least_privilege, log_integrity, disaster_recovery, idle_resources, tag_compliance, new_account_baseline, aggregation\"),\n region: z.string().optional().describe(\"AWS region to scan (default: server region)\"),\n org_mode: z.boolean().optional().describe(\"Enable multi-account scanning via AWS Organizations\"),\n role_name: z.string().optional().describe(\"IAM role name to assume in child accounts (default: AWSSecurityMCPAudit)\"),\n account_ids: z.array(z.string()).optional().describe(\"Specific account IDs to scan (default: all org accounts)\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ group, region, org_mode, role_name, account_ids, lang }) => {\n try {\n const groupDef = SCAN_GROUPS[group];\n if (!groupDef) {\n const available = Object.keys(SCAN_GROUPS).join(\", \");\n return {\n content: [{ type: \"text\", text: `Error: Unknown scan group \"${group}\". Available groups: ${available}` }],\n isError: true,\n };\n }\n\n const r = region ?? defaultRegion;\n\n // Resolve scanners: \"ALL\" means all registered scanners\n let selectedScanners: Scanner[];\n const missingModules: string[] = [];\n\n if (groupDef.modules.includes(\"ALL\")) {\n selectedScanners = allScanners;\n } else {\n selectedScanners = [];\n for (const mod of groupDef.modules) {\n const scanner = scannerMap.get(mod);\n if (scanner) {\n selectedScanners.push(scanner);\n } else {\n missingModules.push(mod);\n }\n }\n }\n\n if (selectedScanners.length === 0) {\n return {\n content: [{ type: \"text\", text: `Error: No available scanners for group \"${group}\". Requested modules: ${groupDef.modules.join(\", \")}` }],\n isError: true,\n };\n }\n\n let result: FullScanResult;\n\n if (org_mode) {\n result = await runMultiAccountScanners(selectedScanners, r, {\n orgMode: true,\n roleName: role_name ?? \"AWSSecurityMCPAudit\",\n accountIds: account_ids,\n });\n } else {\n result = await runAllScanners(selectedScanners, r);\n }\n\n // Apply post-filter if the group defines one\n if (groupDef.findingsFilter) {\n for (const mod of result.modules) {\n const originalCount = mod.findings.length;\n mod.findings = applyFindingsFilter(mod.module, mod.findings, groupDef.findingsFilter);\n mod.findingsCount = mod.findings.length;\n if (mod.findings.length < originalCount) {\n const filtered = originalCount - mod.findings.length;\n if (!mod.warnings) mod.warnings = [];\n mod.warnings.push(`Post-filter removed ${filtered} finding(s) not matching group criteria.`);\n }\n }\n // Recalculate summary after filtering\n let critical = 0, high = 0, medium = 0, low = 0;\n for (const m of result.modules) {\n for (const f of m.findings) {\n switch (f.severity) {\n case \"CRITICAL\": critical++; break;\n case \"HIGH\": high++; break;\n case \"MEDIUM\": medium++; break;\n case \"LOW\": low++; break;\n }\n }\n }\n result.summary.totalFindings = critical + high + medium + low;\n result.summary.critical = critical;\n result.summary.high = high;\n result.summary.medium = medium;\n result.summary.low = low;\n }\n\n const lines: string[] = [\n `Scan group: ${groupDef.name} (${group})`,\n groupDef.description,\n \"\",\n summarizeResult(result, lang ?? \"zh\"),\n ];\n\n if (missingModules.length > 0) {\n lines.push(\"\");\n lines.push(`Warning: ${missingModules.length} requested module(s) not available: ${missingModules.join(\", \")}`);\n }\n\n const content: Array<{ type: \"text\"; text: string }> = [\n { type: \"text\", text: lines.join(\"\\n\") },\n { type: \"text\", text: JSON.stringify(result, null, 2) },\n ];\n\n if (group === \"hw_defense\") {\n // Append checklist to summary\n const summaryContent = content[0];\n if (summaryContent && summaryContent.type === \"text\") {\n summaryContent.text += \"\\n\\n\" + getHwDefenseChecklist(lang ?? \"zh\");\n summaryContent.text += \"\\n\\n💡 Tip: Call generate_hw_defense_report with these scan results to get a dedicated HTML report organized by HW Defense SOP checklist categories.\";\n }\n }\n\n return { content };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // list_groups\n server.tool(\n \"list_groups\",\n \"List available scan groups with descriptions. Read-only.\",\n async () => {\n try {\n const groups = Object.entries(SCAN_GROUPS).map(([id, def]) => ({\n id,\n name: def.name,\n description: def.description,\n modules: def.modules,\n reportType: def.reportType,\n }));\n return { content: [{ type: \"text\", text: JSON.stringify(groups, null, 2) }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // 9. generate_report\n server.tool(\n \"generate_report\",\n \"Generate a Markdown security report from scan results. Read-only. Does not modify any AWS resources.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_all\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results, lang }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const report = generateMarkdownReport(parsed, lang ?? \"zh\");\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // generate_mlps3_report\n server.tool(\n \"generate_mlps3_report\",\n \"Generate a GB/T 22239-2019 等保三级 compliance pre-check report from scan results. Best used with scan_group mlps3_precheck results. Read-only.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_group mlps3_precheck or scan_all\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results, lang }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const report = generateMlps3Report(parsed, lang ?? \"zh\");\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // generate_html_report\n server.tool(\n \"generate_html_report\",\n \"Generate a professional HTML security report. Save the output as an .html file.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_all\"),\n history: z.string().optional().describe(\"JSON string of DashboardHistoryEntry[] from dashboard data.json for 30-day trend charts\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results, history, lang }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const historyData = history ? JSON.parse(history) : undefined;\n const report = generateHtmlReport(parsed, historyData, lang ?? \"zh\");\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // generate_mlps3_html_report\n server.tool(\n \"generate_mlps3_html_report\",\n \"Generate a professional HTML MLPS Level 3 compliance report (等保三级). Save as .html file.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_group mlps3_precheck or scan_all\"),\n history: z.string().optional().describe(\"JSON string of DashboardHistoryEntry[] from dashboard data.json for 30-day trend charts\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results, history, lang }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const historyData = history ? JSON.parse(history) : undefined;\n const report = generateMlps3HtmlReport(parsed, historyData, lang ?? \"zh\");\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // generate_hw_defense_report\n server.tool(\n \"generate_hw_defense_report\",\n \"Generate an HTML report organized by HW Defense (护网) SOP checklist categories. Save as .html file.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_group hw_defense or scan_all\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results, lang }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const report = generateHwDefenseHtmlReport(parsed, lang ?? \"zh\");\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // 10. generate_maturity_report\n server.tool(\n \"generate_maturity_report\",\n \"Generate a security maturity assessment report from scan_all results. Requires service_detection module output. Read-only.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_all\"),\n lang: z.enum([\"zh\", \"en\"]).optional().describe(\"Report language (default: zh)\"),\n },\n async ({ scan_results }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const sdModule = parsed.modules.find((m) => m.module === \"service_detection\");\n if (!sdModule) {\n return {\n content: [{ type: \"text\", text: \"Error: scan results do not include service_detection module. Run scan_all first.\" }],\n isError: true,\n };\n }\n\n // Extract the serviceDetection data attached by the scanner\n const detection = (sdModule as ScanResult & { serviceDetection?: ServiceDetectionResult }).serviceDetection;\n\n if (!detection) {\n return {\n content: [{ type: \"text\", text: \"Error: service detection data is missing (possible JSON round-trip loss). Run scan_all to get fresh results with complete service detection data.\" }],\n isError: true,\n };\n }\n\n const serviceImpacts: Record<string, string> = {\n \"CloudTrail\": \"API activity logging\",\n \"Security Hub\": \"+300 security checks\",\n \"GuardDuty\": \"Threat detection\",\n \"Inspector\": \"Vulnerability scanning\",\n \"AWS Config\": \"Configuration tracking\",\n };\n const serviceFreeTrials: Record<string, boolean> = {\n \"Security Hub\": true,\n \"GuardDuty\": true,\n \"Inspector\": true,\n };\n\n const services = detection.services;\n const coveragePercent = detection.coveragePercent;\n const maturityLevel = detection.maturityLevel;\n\n const enabledCount = services.filter((s) => s.enabled === true).length;\n const knownCount = services.filter((s) => s.enabled !== null).length;\n const totalServices = services.length;\n\n // Build the report\n const lines: string[] = [];\n lines.push(\"# AWS Security Maturity Assessment\");\n lines.push(\"\");\n lines.push(`## Account: ${parsed.accountId} | Region: ${parsed.region}`);\n lines.push(\"\");\n lines.push(`## Security Service Coverage: ${coveragePercent}%`);\n lines.push(`## Maturity Level: ${maturityLevel.charAt(0).toUpperCase() + maturityLevel.slice(1)}`);\n lines.push(\"\");\n lines.push(\"### Service Status\");\n lines.push(\"\");\n lines.push(\"| Service | Status | Impact |\");\n lines.push(\"|---------|--------|--------|\");\n for (const svc of services) {\n const status = svc.enabled === true ? \"\\u2705 Enabled\" : svc.enabled === false ? \"\\u274c Not Enabled\" : \"\\u26a0\\ufe0f Unknown\";\n const impact = serviceImpacts[svc.name] ?? \"\";\n lines.push(`| ${svc.name} | ${status} | ${impact} |`);\n }\n\n const unknowns = services.filter((s) => s.enabled === null);\n if (unknowns.length > 0) {\n lines.push(\"\");\n lines.push(`> \\u26a0\\ufe0f ${unknowns.length} service(s) could not be checked (access denied or detection error). Re-run with appropriate permissions for accurate coverage.`);\n }\n\n // Recommendations\n const disabled = services.filter((s) => s.enabled === false);\n if (disabled.length > 0) {\n lines.push(\"\");\n lines.push(\"### Recommendations (Priority Order)\");\n lines.push(\"\");\n // Priority order: Security Hub, GuardDuty, Inspector, Config, CloudTrail\n const priorityOrder = [\"Security Hub\", \"GuardDuty\", \"Inspector\", \"AWS Config\", \"CloudTrail\"];\n const sorted = disabled.sort(\n (a, b) => priorityOrder.indexOf(a.name) - priorityOrder.indexOf(b.name),\n );\n let idx = 1;\n for (const svc of sorted) {\n const trial = serviceFreeTrials[svc.name] ? \" \\u2014 free trial available\" : \"\";\n lines.push(`${idx}. Enable ${svc.name}${trial}`);\n idx++;\n }\n }\n\n // Maturity roadmap\n lines.push(\"\");\n lines.push(\"### Maturity Roadmap\");\n lines.push(\"\");\n if (unknowns.length > 0) {\n lines.push(`- **Current**: ${maturityLevel.charAt(0).toUpperCase() + maturityLevel.slice(1)} (${enabledCount}/${knownCount} known services, ${unknowns.length} unknown)`);\n } else {\n lines.push(`- **Current**: ${maturityLevel.charAt(0).toUpperCase() + maturityLevel.slice(1)} (${enabledCount}/${totalServices} services)`);\n }\n\n if (maturityLevel !== \"comprehensive\") {\n const nextMilestones: Record<string, { level: string; target: number; suggestions: string[] }> = {\n basic: { level: \"Intermediate\", target: 2, suggestions: [\"Security Hub\", \"GuardDuty\"] },\n intermediate: { level: \"Advanced\", target: 4, suggestions: [\"Inspector\", \"AWS Config\"] },\n advanced: { level: \"Comprehensive\", target: 5, suggestions: [\"CloudTrail\"] },\n };\n const next = nextMilestones[maturityLevel];\n if (next) {\n const remaining = next.suggestions.filter((s) =>\n services.some((svc) => svc.name === s && !svc.enabled),\n );\n if (remaining.length > 0) {\n lines.push(`- **Next milestone**: ${next.level} (${next.target}/${knownCount}) \\u2014 enable ${remaining.join(\" + \")}`);\n }\n }\n lines.push(`- **Target**: Comprehensive (${knownCount}/${knownCount})`);\n }\n\n lines.push(\"\");\n\n const report = lines.join(\"\\n\");\n\n return { content: [{ type: \"text\", text: report }] };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n },\n );\n\n // 11. save_results\n server.tool(\n \"save_results\",\n \"Saves scan results to local disk or S3 for dashboard display. Does not modify any AWS resources.\",\n {\n scan_results: z.string().describe(\"JSON string of FullScanResult from scan_all\"),\n output_dir: z.string().optional().describe(\"Output directory (default: ~/.aws-security)\"),\n },\n async ({ scan_results, output_dir }) => {\n try {\n const parsed: FullScanResult = JSON.parse(scan_results);\n const dataPath = saveResults(parsed, output_dir);\n return {\n content: [\n { type: \"text\", text: `Dashboard data saved to ${dataPath}` },\n ],\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n },\n );\n\n // 11. list_modules\n server.tool(\n \"list_modules\",\n \"List available security scan modules with descriptions. Read-only. Does not modify any AWS resources.\",\n async () => {\n try {\n const modules = allScanners.map((s) => ({\n name: s.moduleName,\n description: MODULE_DESCRIPTIONS[s.moduleName] ?? s.moduleName,\n }));\n return { content: [{ type: \"text\", text: JSON.stringify(modules, null, 2) }] };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // list_org_accounts\n server.tool(\n \"list_org_accounts\",\n \"List all accounts in the AWS Organization. Useful for discovering accounts before multi-account scanning. Read-only.\",\n { region: z.string().optional().describe(\"AWS region (default: server region)\") },\n async ({ region }) => {\n try {\n const r = region ?? defaultRegion;\n const accounts = await listOrgAccounts(r);\n return {\n content: [\n { type: \"text\", text: `Found ${accounts.length} active account(s) in the organization.` },\n { type: \"text\", text: JSON.stringify(accounts, null, 2) },\n ],\n };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // get_setup_template\n server.tool(\n \"get_setup_template\",\n \"Returns the CloudFormation StackSet template for deploying the cross-account security audit IAM role. Read-only.\",\n {\n format: z.enum([\"yaml\", \"json\"]).optional().describe(\"Template format: yaml or json (default: yaml)\"),\n },\n async ({ format }) => {\n try {\n const ext = format === \"json\" ? \"json\" : \"yaml\";\n const templateFileName = `stackset-audit-role.${ext}`;\n // Try multiple locations for the template\n let templateContent: string;\n try {\n // When running from source\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const templatePath = join(currentDir, \"..\", \"templates\", templateFileName);\n templateContent = readFileSync(templatePath, \"utf-8\");\n } catch {\n try {\n // When running from dist\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const templatePath = join(currentDir, \"..\", \"..\", \"templates\", templateFileName);\n templateContent = readFileSync(templatePath, \"utf-8\");\n } catch {\n return {\n content: [{ type: \"text\", text: `Error: Template file ${templateFileName} not found. Ensure the templates/ directory is included in the package.` }],\n isError: true,\n };\n }\n }\n return {\n content: [\n { type: \"text\", text: `CloudFormation StackSet template (${ext.toUpperCase()}) for cross-account audit role:\\n\\nDeploy this as a StackSet from your Management Account to all member accounts.` },\n { type: \"text\", text: templateContent },\n ],\n };\n } catch (err) {\n return { content: [{ type: \"text\", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };\n }\n },\n );\n\n // --- Resources ---\n\n server.resource(\n \"security-rules\",\n \"security://rules\",\n { description: \"Describes all 19 scan modules and their check rules\", mimeType: \"text/markdown\" },\n async () => ({\n contents: [{ uri: \"security://rules\", text: SECURITY_RULES_CONTENT, mimeType: \"text/markdown\" }],\n }),\n );\n\n server.resource(\n \"risk-scoring\",\n \"security://risk-scoring\",\n { description: \"Describes the risk scoring model and severity/priority mapping\", mimeType: \"text/markdown\" },\n async () => ({\n contents: [{ uri: \"security://risk-scoring\", text: RISK_SCORING_CONTENT, mimeType: \"text/markdown\" }],\n }),\n );\n\n // --- Prompts ---\n\n server.prompt(\n \"security-scan\",\n \"Run a full AWS security scan workflow: scan all modules, generate a report, and summarize findings.\",\n async () => ({\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: \"Run scan_all to perform a full AWS security scan. Then take the JSON result and pass it to generate_report to create a Markdown report. Finally, summarize the top findings and recommend immediate actions based on priority.\",\n },\n },\n ],\n }),\n );\n\n server.prompt(\n \"analyze-finding\",\n \"Deep analysis of a specific security finding.\",\n { finding: z.string().describe(\"JSON string of a single Finding object to analyze\") },\n async ({ finding }) => ({\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Analyze this AWS security finding in depth. Explain the risk, potential attack vectors, blast radius, and provide detailed step-by-step remediation guidance.\\n\\nFinding:\\n${finding}`,\n },\n },\n ],\n }),\n );\n\n server.prompt(\n \"hw_defense_checklist\",\n \"护网行动完整检查清单 — 包含自动化扫描项和人工检查项\",\n async () => ({\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `请基于以下护网行动检查清单,帮助我制定护网准备计划:\\n\\n${getHwDefenseChecklist(\"zh\")}\\n\\n自动化扫描部分请使用 scan_group hw_defense 执行。以上人工检查项请逐项确认并提供具体建议。`,\n },\n },\n ],\n }),\n );\n\n return server;\n}\n\nexport async function startServer(defaultRegion: string): Promise<void> {\n const server = createServer(defaultRegion);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","export const VERSION = \"0.7.2\";\n","import { STSClient, GetCallerIdentityCommand } from \"@aws-sdk/client-sts\";\n\nlet cachedAccountId: string | undefined;\n\nexport function getPartition(region: string): string {\n if (region.startsWith(\"cn-\")) return \"aws-cn\";\n if (region.startsWith(\"us-gov-\")) return \"aws-us-gov\";\n return \"aws\";\n}\n\nexport function getIamRegion(region: string): string {\n // IAM is global in standard AWS (us-east-1) but regional in China\n if (region.startsWith(\"cn-\")) return region;\n return \"us-east-1\";\n}\n\nexport async function getAccountId(region?: string): Promise<string> {\n if (cachedAccountId) return cachedAccountId;\n\n const stsRegion = region ?? \"us-east-1\";\n const sts = new STSClient({ region: stsRegion });\n const response = await sts.send(new GetCallerIdentityCommand({}));\n cachedAccountId = response.Account ?? \"unknown\";\n return cachedAccountId;\n}\n\nexport function createClient<T>(\n ClientClass: new (config: any) => T,\n region?: string,\n credentials?: { accessKeyId: string; secretAccessKey: string; sessionToken: string },\n): T {\n const config: any = { region: region ?? \"us-east-1\" };\n if (credentials) config.credentials = credentials;\n return new ClientClass(config);\n}\n","import { STSClient, AssumeRoleCommand, GetCallerIdentityCommand } from \"@aws-sdk/client-sts\";\n\nexport async function getCurrentAccountId(region: string): Promise<string> {\n const sts = new STSClient({ region });\n const result = await sts.send(new GetCallerIdentityCommand({}));\n return result.Account!;\n}\n\nexport const DEFAULT_EXTERNAL_ID = \"aws-security-mcp-audit\";\n\nexport async function assumeRole(roleArn: string, region: string, options?: {\n sessionName?: string;\n externalId?: string;\n}): Promise<{\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken: string;\n}> {\n const sessionName = options?.sessionName ?? \"aws-security-mcp\";\n const externalId = options?.externalId ?? DEFAULT_EXTERNAL_ID;\n const sts = new STSClient({ region });\n const result = await sts.send(new AssumeRoleCommand({\n RoleArn: roleArn,\n RoleSessionName: sessionName,\n ExternalId: externalId,\n DurationSeconds: 3600,\n }));\n return {\n accessKeyId: result.Credentials!.AccessKeyId!,\n secretAccessKey: result.Credentials!.SecretAccessKey!,\n sessionToken: result.Credentials!.SessionToken!,\n };\n}\n\nexport function buildRoleArn(accountId: string, roleName: string, partition = \"aws\"): string {\n return `arn:${partition}:iam::${accountId}:role/${roleName}`;\n}\n","import { OrganizationsClient, ListAccountsCommand } from \"@aws-sdk/client-organizations\";\n\nexport interface OrgAccount {\n id: string;\n name: string;\n email: string;\n status: string;\n}\n\nexport async function listOrgAccounts(region: string): Promise<OrgAccount[]> {\n // Organizations API must use specific endpoints\n // Global: us-east-1, China: cn-northwest-1\n const orgRegion = region.startsWith(\"cn-\") ? \"cn-northwest-1\" : \"us-east-1\";\n const client = new OrganizationsClient({ region: orgRegion });\n const accounts: OrgAccount[] = [];\n let nextToken: string | undefined;\n\n do {\n const result = await client.send(new ListAccountsCommand({ NextToken: nextToken }));\n for (const acct of result.Accounts || []) {\n if (acct.Status === \"ACTIVE\") {\n accounts.push({\n id: acct.Id!,\n name: acct.Name || \"\",\n email: acct.Email || \"\",\n status: acct.Status!,\n });\n }\n }\n nextToken = result.NextToken;\n } while (nextToken);\n\n return accounts;\n}\n","import { FullScanResult, ScanResult, ScanContext, AwsCredentials } from \"../types.js\";\nimport { Scanner } from \"./base.js\";\nimport { getAccountId, getPartition } from \"../utils/aws-client.js\";\nimport { assumeRole, buildRoleArn } from \"../utils/assume-role.js\";\nimport { listOrgAccounts, type OrgAccount } from \"../utils/org-accounts.js\";\n\n/** Aggregation scanners that already pull cross-account data — run once from admin account */\nconst AGGREGATION_MODULES = new Set([\n \"security_hub_findings\",\n \"guardduty_findings\",\n \"inspector_findings\",\n \"config_rules_findings\",\n \"access_analyzer_findings\",\n]);\n\nfunction buildSummary(modules: ScanResult[]) {\n let critical = 0;\n let high = 0;\n let medium = 0;\n let low = 0;\n let modulesSuccess = 0;\n let modulesError = 0;\n\n for (const m of modules) {\n if (m.status === \"success\") {\n modulesSuccess++;\n } else {\n modulesError++;\n }\n for (const f of m.findings) {\n switch (f.severity) {\n case \"CRITICAL\": critical++; break;\n case \"HIGH\": high++; break;\n case \"MEDIUM\": medium++; break;\n case \"LOW\": low++; break;\n }\n }\n }\n\n return {\n totalFindings: critical + high + medium + low,\n critical,\n high,\n medium,\n low,\n modulesSuccess,\n modulesError,\n };\n}\n\nasync function runScannersWithContext(\n scanners: Scanner[],\n ctx: ScanContext,\n): Promise<ScanResult[]> {\n const settled = await Promise.allSettled(scanners.map((s) => s.scan(ctx)));\n\n return settled.map((result, i) => {\n if (result.status === \"fulfilled\") {\n // Stamp accountId on all findings\n for (const f of result.value.findings) {\n if (!f.accountId) f.accountId = ctx.accountId;\n if (!f.accountAlias && ctx.accountAlias) f.accountAlias = ctx.accountAlias;\n }\n return result.value;\n }\n return {\n module: scanners[i].moduleName,\n status: \"error\" as const,\n error: result.reason instanceof Error ? result.reason.message : String(result.reason),\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: 0,\n findings: [],\n };\n });\n}\n\nexport async function runAllScanners(\n scanners: Scanner[],\n region: string,\n): Promise<FullScanResult> {\n const scanStart = new Date().toISOString();\n\n // Best-effort accountId retrieval — don't let STS failure break the whole scan\n let accountId: string;\n try {\n accountId = await getAccountId(region);\n } catch {\n accountId = \"unknown\";\n }\n\n const partition = getPartition(region);\n const ctx: ScanContext = { region, partition, accountId };\n\n const modules = await runScannersWithContext(scanners, ctx);\n\n const scanEnd = new Date().toISOString();\n\n return {\n scanStart,\n scanEnd,\n region,\n accountId,\n modules,\n summary: buildSummary(modules),\n };\n}\n\nexport interface MultiAccountOptions {\n orgMode: boolean;\n roleName: string;\n accountIds?: string[];\n}\n\nexport async function runMultiAccountScanners(\n scanners: Scanner[],\n region: string,\n opts: MultiAccountOptions,\n): Promise<FullScanResult> {\n const scanStart = new Date().toISOString();\n const partition = getPartition(region);\n\n // Get current (admin) account ID\n let adminAccountId: string;\n try {\n adminAccountId = await getAccountId(region);\n } catch {\n adminAccountId = \"unknown\";\n }\n\n // Discover org accounts\n let accounts: OrgAccount[];\n try {\n accounts = await listOrgAccounts(region);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n // Graceful fallback: scan current account only, with clear warning\n const result = await runAllScanners(scanners, region);\n if (result.modules.length > 0) {\n if (!result.modules[0].warnings) result.modules[0].warnings = [];\n result.modules[0].warnings.unshift(`org_mode enabled but Organizations listing failed: ${errMsg}. Scanning current account only.`);\n }\n return result;\n }\n\n // Filter to specific accounts if requested\n if (opts.accountIds?.length) {\n const idSet = new Set(opts.accountIds);\n accounts = accounts.filter((a) => idSet.has(a.id));\n }\n\n // Separate aggregation vs per-account scanners\n const aggregationScanners = scanners.filter((s) => AGGREGATION_MODULES.has(s.moduleName));\n const perAccountScanners = scanners.filter((s) => !AGGREGATION_MODULES.has(s.moduleName));\n\n const allModules: ScanResult[] = [];\n\n // 1. Run aggregation scanners ONCE from admin account (they already aggregate cross-account)\n if (aggregationScanners.length > 0) {\n const adminCtx: ScanContext = { region, partition, accountId: adminAccountId };\n const aggResults = await runScannersWithContext(aggregationScanners, adminCtx);\n allModules.push(...aggResults);\n }\n\n // 2. Run per-account scanners for each account\n for (const account of accounts) {\n let credentials: AwsCredentials | undefined;\n let accountAlias = account.name;\n\n // Skip assume-role for the admin account itself\n if (account.id !== adminAccountId) {\n try {\n const roleArn = buildRoleArn(account.id, opts.roleName, partition);\n credentials = await assumeRole(roleArn, region);\n } catch (err) {\n // Record a failed module for this account\n allModules.push({\n module: `assume_role_${account.id}`,\n status: \"error\",\n error: `Failed to assume role in account ${account.id} (${account.name}): ${err instanceof Error ? err.message : String(err)}`,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: 0,\n findings: [],\n });\n continue;\n }\n }\n\n const ctx: ScanContext = {\n region,\n partition,\n accountId: account.id,\n accountAlias,\n credentials,\n };\n\n const accountResults = await runScannersWithContext(perAccountScanners, ctx);\n allModules.push(...accountResults);\n }\n\n const scanEnd = new Date().toISOString();\n\n // Post-filter: if account_ids was specified, filter aggregation findings too\n if (opts.accountIds?.length) {\n const idSet = new Set(opts.accountIds);\n for (const mod of allModules) {\n if (AGGREGATION_MODULES.has(mod.module)) {\n mod.findings = mod.findings.filter((f) => !f.accountId || idSet.has(f.accountId));\n mod.findingsCount = mod.findings.length;\n }\n }\n }\n\n return {\n scanStart,\n scanEnd,\n region,\n accountId: adminAccountId,\n modules: allModules,\n summary: buildSummary(allModules),\n };\n}\n","import {\n SecurityHubClient,\n DescribeHubCommand,\n} from \"@aws-sdk/client-securityhub\";\nimport {\n GuardDutyClient,\n ListDetectorsCommand,\n} from \"@aws-sdk/client-guardduty\";\nimport {\n Inspector2Client,\n BatchGetAccountStatusCommand,\n} from \"@aws-sdk/client-inspector2\";\nimport {\n ConfigServiceClient,\n DescribeConfigurationRecordersCommand,\n} from \"@aws-sdk/client-config-service\";\nimport {\n CloudTrailClient,\n DescribeTrailsCommand,\n} from \"@aws-sdk/client-cloudtrail\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nexport interface ServiceStatus {\n name: string;\n enabled: boolean | null; // null = unknown (access denied or detection error)\n details?: string;\n recommendation?: string;\n freeTrialAvailable?: boolean;\n}\n\nexport interface ServiceDetectionResult {\n services: ServiceStatus[];\n coveragePercent: number;\n maturityLevel: \"basic\" | \"intermediate\" | \"advanced\" | \"comprehensive\";\n}\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction isAccessDenied(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const name = (err as Error & { name?: string }).name ?? \"\";\n const code = (err as Error & { Code?: string }).Code ?? \"\";\n return (\n name === \"AccessDeniedException\" ||\n name === \"UnauthorizedAccess\" ||\n name === \"AccessDenied\" ||\n code === \"AccessDeniedException\" ||\n code === \"AccessDenied\" ||\n name === \"ForbiddenException\" ||\n // AWS SDK v3 uses __type or $metadata for some errors\n (err.message?.includes(\"is not authorized to perform\") ?? false) ||\n (err.message?.includes(\"Access Denied\") ?? false)\n );\n}\n\nfunction isNotEnabled(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n return (\n err.name === \"InvalidAccessException\" || // Security Hub specific\n err.name === \"DisabledException\" ||\n err.message.includes(\"not enabled\") ||\n err.message.includes(\"not subscribed\")\n );\n}\n\nfunction computeMaturityLevel(\n enabledCount: number,\n): \"basic\" | \"intermediate\" | \"advanced\" | \"comprehensive\" {\n if (enabledCount >= 5) return \"comprehensive\";\n if (enabledCount >= 4) return \"advanced\";\n if (enabledCount >= 2) return \"intermediate\";\n return \"basic\";\n}\n\nexport class ServiceDetectionScanner implements Scanner {\n readonly moduleName = \"service_detection\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n const services: ServiceStatus[] = [];\n\n // --- CloudTrail ---\n try {\n const ct = createClient(CloudTrailClient, region, ctx.credentials);\n const resp = await ct.send(new DescribeTrailsCommand({}));\n const trails = resp.trailList ?? [];\n if (trails.length > 0) {\n services.push({\n name: \"CloudTrail\",\n enabled: true,\n details: `${trails.length} trail(s) configured`,\n });\n } else {\n services.push({\n name: \"CloudTrail\",\n enabled: false,\n recommendation: \"Create a multi-region trail for API logging\",\n });\n // CloudTrail is checked by service detection only for coverage assessment.\n }\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"CloudTrail: insufficient permissions to check status\");\n services.push({ name: \"CloudTrail\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"CloudTrail\",\n enabled: false,\n recommendation: \"Create a multi-region trail for API logging\",\n });\n // CloudTrail is checked by service detection only for coverage assessment\n } else {\n warnings.push(`CloudTrail detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"CloudTrail\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // --- Security Hub ---\n try {\n const sh = createClient(SecurityHubClient, region, ctx.credentials);\n await sh.send(new DescribeHubCommand({}));\n services.push({\n name: \"Security Hub\",\n enabled: true,\n details: \"Enabled with automated security checks\",\n });\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"Security Hub: insufficient permissions to check status\");\n services.push({ name: \"Security Hub\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"Security Hub\",\n enabled: false,\n recommendation: \"Enable Security Hub for 300+ automated security checks\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: \"AWS Security Hub is not enabled\",\n resourceType: \"AWS::SecurityHub::Hub\",\n resourceId: \"securityhub\",\n resourceArn: `arn:${partition}:securityhub:${region}:${accountId}:hub/default`,\n region,\n description:\n \"AWS Security Hub is not enabled in this region. Security Hub provides a comprehensive view of security alerts and compliance status.\",\n impact:\n \"Enables 300+ automated security checks across AWS services. Without it, security findings are fragmented across individual services.\",\n remediationSteps: [\n \"Open the AWS Security Hub console.\",\n \"Click 'Go to Security Hub' and enable it.\",\n \"Enable the AWS Foundational Security Best Practices standard.\",\n \"Security Hub offers a 30-day free trial.\",\n ],\n }),\n );\n } else {\n warnings.push(`Security Hub detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"Security Hub\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // --- GuardDuty ---\n try {\n const gd = createClient(GuardDutyClient, region, ctx.credentials);\n const resp = await gd.send(new ListDetectorsCommand({}));\n const detectors = resp.DetectorIds ?? [];\n if (detectors.length > 0) {\n services.push({\n name: \"GuardDuty\",\n enabled: true,\n details: `${detectors.length} detector(s) active`,\n });\n } else {\n services.push({\n name: \"GuardDuty\",\n enabled: false,\n recommendation: \"Enable GuardDuty for continuous threat detection\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: \"Amazon GuardDuty is not enabled\",\n resourceType: \"AWS::GuardDuty::Detector\",\n resourceId: \"guardduty\",\n resourceArn: `arn:${partition}:guardduty:${region}:${accountId}:detector/none`,\n region,\n description:\n \"Amazon GuardDuty is not enabled in this region. GuardDuty provides intelligent threat detection by analyzing CloudTrail, VPC Flow Logs, and DNS logs.\",\n impact:\n \"Provides continuous threat detection for account compromise, instance compromise, and malicious reconnaissance. Without it, many attack patterns go undetected.\",\n remediationSteps: [\n \"Open the Amazon GuardDuty console.\",\n \"Click 'Get Started' and enable GuardDuty.\",\n \"GuardDuty offers a 30-day free trial.\",\n \"Consider enabling S3 protection and EKS protection add-ons.\",\n ],\n }),\n );\n }\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"GuardDuty: insufficient permissions to check status\");\n services.push({ name: \"GuardDuty\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"GuardDuty\",\n enabled: false,\n recommendation: \"Enable GuardDuty for continuous threat detection\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: \"Amazon GuardDuty is not enabled\",\n resourceType: \"AWS::GuardDuty::Detector\",\n resourceId: \"guardduty\",\n resourceArn: `arn:${partition}:guardduty:${region}:${accountId}:detector/none`,\n region,\n description:\n \"Amazon GuardDuty is not enabled in this region. GuardDuty provides intelligent threat detection by analyzing CloudTrail, VPC Flow Logs, and DNS logs.\",\n impact:\n \"Provides continuous threat detection for account compromise, instance compromise, and malicious reconnaissance. Without it, many attack patterns go undetected.\",\n remediationSteps: [\n \"Open the Amazon GuardDuty console.\",\n \"Click 'Get Started' and enable GuardDuty.\",\n \"GuardDuty offers a 30-day free trial.\",\n \"Consider enabling S3 protection and EKS protection add-ons.\",\n ],\n }),\n );\n } else {\n warnings.push(`GuardDuty detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"GuardDuty\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // --- Inspector ---\n try {\n const insp = createClient(Inspector2Client, region, ctx.credentials);\n const resp = await insp.send(new BatchGetAccountStatusCommand({ accountIds: [accountId] }));\n const accounts = resp.accounts ?? [];\n const active = accounts.some((a) => {\n const s = a.state?.status;\n if (s === \"ENABLED\" || s === \"ENABLING\") return true;\n // Also check individual resource type scanning states (ec2, ecr, lambda, lambdaCode, codeRepository)\n const rs = a.resourceState as Record<string, { status?: string } | undefined> | undefined;\n if (!rs) return false;\n return [\"ec2\", \"ecr\", \"lambda\", \"lambdaCode\", \"codeRepository\"].some(\n (k) => rs[k]?.status === \"ENABLED\",\n );\n });\n if (active) {\n services.push({\n name: \"Inspector\",\n enabled: true,\n details: \"Vulnerability scanning active\",\n });\n } else {\n services.push({\n name: \"Inspector\",\n enabled: false,\n recommendation: \"Enable Inspector to scan for software vulnerabilities\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: \"Amazon Inspector is not enabled\",\n resourceType: \"AWS::Inspector2::AccountStatus\",\n resourceId: \"inspector\",\n resourceArn: `arn:${partition}:inspector2:${region}:${accountId}:account`,\n region,\n description:\n \"Amazon Inspector is not enabled in this region. Inspector automatically discovers and scans EC2 instances, containers, and Lambda functions for software vulnerabilities.\",\n impact:\n \"Scans for software vulnerabilities in EC2 instances, container images, and Lambda functions. Without it, known CVEs may go undetected.\",\n remediationSteps: [\n \"Open the Amazon Inspector console.\",\n \"Click 'Get Started' and enable Inspector.\",\n \"Inspector offers a 15-day free trial.\",\n \"Enable scanning for EC2, ECR, and Lambda as appropriate.\",\n ],\n }),\n );\n }\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"Inspector: insufficient permissions to check status\");\n services.push({ name: \"Inspector\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"Inspector\",\n enabled: false,\n recommendation: \"Enable Inspector to scan for software vulnerabilities\",\n freeTrialAvailable: true,\n });\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: \"Amazon Inspector is not enabled\",\n resourceType: \"AWS::Inspector2::AccountStatus\",\n resourceId: \"inspector\",\n resourceArn: `arn:${partition}:inspector2:${region}:${accountId}:account`,\n region,\n description:\n \"Amazon Inspector is not enabled in this region. Inspector automatically discovers and scans EC2 instances, containers, and Lambda functions for software vulnerabilities.\",\n impact:\n \"Scans for software vulnerabilities in EC2 instances, container images, and Lambda functions. Without it, known CVEs may go undetected.\",\n remediationSteps: [\n \"Open the Amazon Inspector console.\",\n \"Click 'Get Started' and enable Inspector.\",\n \"Inspector offers a 15-day free trial.\",\n \"Enable scanning for EC2, ECR, and Lambda as appropriate.\",\n ],\n }),\n );\n } else {\n warnings.push(`Inspector detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"Inspector\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // --- AWS Config ---\n try {\n const cfg = createClient(ConfigServiceClient, region, ctx.credentials);\n const resp = await cfg.send(new DescribeConfigurationRecordersCommand({}));\n const recorders = resp.ConfigurationRecorders ?? [];\n if (recorders.length > 0) {\n services.push({\n name: \"AWS Config\",\n enabled: true,\n details: `${recorders.length} recorder(s) configured`,\n });\n } else {\n services.push({\n name: \"AWS Config\",\n enabled: false,\n recommendation: \"Enable AWS Config to track configuration changes\",\n });\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: \"AWS Config is not enabled\",\n resourceType: \"AWS::Config::ConfigurationRecorder\",\n resourceId: \"config\",\n resourceArn: `arn:${partition}:config:${region}:${accountId}:configuration-recorder/none`,\n region,\n description:\n \"AWS Config is not enabled in this region. Config continuously records resource configurations and enables compliance auditing.\",\n impact:\n \"Tracks configuration changes and enables compliance rules. Without it, configuration drift and non-compliant resources go undetected.\",\n remediationSteps: [\n \"Open the AWS Config console.\",\n \"Click 'Get Started' and configure a recorder.\",\n \"Select the resource types to record.\",\n \"Configure an S3 bucket for configuration snapshots.\",\n ],\n }),\n );\n }\n } catch (err) {\n if (isAccessDenied(err)) {\n warnings.push(\"AWS Config: insufficient permissions to check status\");\n services.push({ name: \"AWS Config\", enabled: null, details: \"Access denied\" });\n } else if (isNotEnabled(err)) {\n services.push({\n name: \"AWS Config\",\n enabled: false,\n recommendation: \"Enable AWS Config to track configuration changes\",\n });\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: \"AWS Config is not enabled\",\n resourceType: \"AWS::Config::ConfigurationRecorder\",\n resourceId: \"config\",\n resourceArn: `arn:${partition}:config:${region}:${accountId}:configuration-recorder/none`,\n region,\n description:\n \"AWS Config is not enabled in this region. Config continuously records resource configurations and enables compliance auditing.\",\n impact:\n \"Tracks configuration changes and enables compliance rules. Without it, configuration drift and non-compliant resources go undetected.\",\n remediationSteps: [\n \"Open the AWS Config console.\",\n \"Click 'Get Started' and configure a recorder.\",\n \"Select the resource types to record.\",\n \"Configure an S3 bucket for configuration snapshots.\",\n ],\n }),\n );\n } else {\n warnings.push(`AWS Config detection failed: ${err instanceof Error ? err.message : String(err)}`);\n services.push({ name: \"AWS Config\", enabled: null, details: \"Detection error\" });\n }\n }\n\n // Compute coverage and maturity (exclude unknown services from coverage denominator)\n const knownServices = services.filter((s) => s.enabled !== null);\n const enabledCount = services.filter((s) => s.enabled === true).length;\n const coveragePercent = knownServices.length > 0 ? Math.round((enabledCount / knownServices.length) * 100) : 0;\n const maturityLevel = computeMaturityLevel(enabledCount);\n\n const detectionResult: ServiceDetectionResult = {\n services,\n coveragePercent,\n maturityLevel,\n };\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: services.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n // Attach the structured detection result as a custom property via the findings metadata\n ...({ serviceDetection: detectionResult } as Record<string, unknown>),\n } as ScanResult & { serviceDetection: ServiceDetectionResult };\n }\n}\n","import { Severity, Priority } from \"../types.js\";\n\nexport function severityFromScore(score: number): Severity {\n if (score >= 9.0) return \"CRITICAL\";\n if (score >= 7.0) return \"HIGH\";\n if (score >= 4.0) return \"MEDIUM\";\n return \"LOW\";\n}\n\nexport function priorityFromSeverity(severity: Severity): Priority {\n switch (severity) {\n case \"CRITICAL\": return \"P0\";\n case \"HIGH\": return \"P1\";\n case \"MEDIUM\": return \"P2\";\n case \"LOW\": return \"P3\";\n }\n}\n","import {\n LambdaClient,\n ListFunctionsCommand,\n type FunctionConfiguration,\n} from \"@aws-sdk/client-lambda\";\nimport {\n EC2Client,\n DescribeInstancesCommand,\n DescribeInstanceAttributeCommand,\n type Instance,\n} from \"@aws-sdk/client-ec2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nconst SECRET_PATTERNS: Array<{ name: string; pattern: RegExp; matchType: \"value\" | \"name\" }> = [\n { name: \"AWS Access Key\", pattern: /AKIA[0-9A-Z]{16}/, matchType: \"value\" },\n { name: \"Private Key\", pattern: /-----BEGIN.*PRIVATE KEY-----/, matchType: \"value\" },\n { name: \"Password in env var\", pattern: /^(PASSWORD|PASSWD|DB_PASSWORD|SECRET|API_KEY|APIKEY|TOKEN|AUTH_TOKEN)$/i, matchType: \"name\" },\n];\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class SecretExposureScanner implements Scanner {\n readonly moduleName = \"secret_exposure\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n // --- Lambda functions ---\n try {\n const lambda = createClient(LambdaClient, region, ctx.credentials);\n const functions: FunctionConfiguration[] = [];\n let marker: string | undefined;\n do {\n const resp = await lambda.send(\n new ListFunctionsCommand({ Marker: marker }),\n );\n if (resp.Functions) functions.push(...resp.Functions);\n marker = resp.NextMarker;\n } while (marker);\n\n resourcesScanned += functions.length;\n\n for (const fn of functions) {\n const fnName = fn.FunctionName ?? \"unknown\";\n const fnArn =\n fn.FunctionArn ??\n `arn:${partition}:lambda:${region}:${accountId}:function:${fnName}`;\n const envVars = fn.Environment?.Variables ?? {};\n\n for (const [varName, varValue] of Object.entries(envVars)) {\n for (const sp of SECRET_PATTERNS) {\n if (sp.matchType === \"name\") {\n if (sp.pattern.test(varName)) {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `Lambda ${fnName} has suspicious env var \"${varName}\"`,\n resourceType: \"AWS::Lambda::Function\",\n resourceId: fnName,\n resourceArn: fnArn,\n region,\n description: `Lambda function \"${fnName}\" has an environment variable named \"${varName}\" which may contain a secret.`,\n impact:\n \"Secrets in Lambda environment variables are visible to anyone with lambda:GetFunctionConfiguration permission and may leak through logs.\",\n remediationSteps: [\n \"Move the secret to AWS Secrets Manager or SSM Parameter Store (SecureString).\",\n \"Update the Lambda function to fetch the secret at runtime.\",\n \"Rotate the exposed credential immediately.\",\n ],\n }),\n );\n }\n } else {\n // match value\n if (sp.pattern.test(varValue)) {\n const riskScore = sp.name === \"AWS Access Key\" ? 9.5 : 9.0;\n findings.push(\n makeFinding({\n riskScore,\n title: `Lambda ${fnName} env var contains ${sp.name}`,\n resourceType: \"AWS::Lambda::Function\",\n resourceId: fnName,\n resourceArn: fnArn,\n region,\n description: `Lambda function \"${fnName}\" has an environment variable containing a ${sp.name} pattern.`,\n impact:\n \"Hard-coded credentials in Lambda environment variables can be extracted by any principal with read access to the function configuration.\",\n remediationSteps: [\n \"Remove the hard-coded credential from environment variables.\",\n \"Use AWS Secrets Manager or SSM Parameter Store (SecureString) instead.\",\n \"Rotate the exposed credential immediately.\",\n \"Review CloudTrail logs for unauthorized use of the credential.\",\n ],\n }),\n );\n }\n }\n }\n }\n }\n } catch (e: unknown) {\n warnings.push(`Lambda scan error: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n // --- EC2 userData ---\n try {\n const ec2 = createClient(EC2Client, region, ctx.credentials);\n const instances: Instance[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await ec2.send(\n new DescribeInstancesCommand({ NextToken: nextToken }),\n );\n for (const res of resp.Reservations ?? []) {\n if (res.Instances) instances.push(...res.Instances);\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n resourcesScanned += instances.length;\n\n for (const inst of instances) {\n const instId = inst.InstanceId ?? \"unknown\";\n const instArn = `arn:${partition}:ec2:${region}:${accountId}:instance/${instId}`;\n\n let userData: string | undefined;\n try {\n const attrResp = await ec2.send(\n new DescribeInstanceAttributeCommand({\n InstanceId: instId,\n Attribute: \"userData\",\n }),\n );\n const raw = attrResp.UserData?.Value;\n if (raw) {\n userData = Buffer.from(raw, \"base64\").toString(\"utf-8\");\n }\n } catch (e: unknown) {\n warnings.push(`Could not read userData for ${instId}: ${e instanceof Error ? e.message : String(e)}`);\n continue;\n }\n\n if (!userData) continue;\n\n for (const sp of SECRET_PATTERNS) {\n if (sp.matchType === \"name\") continue; // name-matching doesn't apply to userData\n if (sp.pattern.test(userData)) {\n const riskScore = sp.name === \"AWS Access Key\" ? 9.5 : 8.0;\n findings.push(\n makeFinding({\n riskScore,\n title: `EC2 ${instId} userData contains ${sp.name}`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: instArn,\n region,\n description: `EC2 instance \"${instId}\" has user data containing a ${sp.name} pattern.`,\n impact:\n \"Instance user data is accessible to anyone with ec2:DescribeInstanceAttribute permission and from the instance metadata service.\",\n remediationSteps: [\n \"Remove the secret from instance user data.\",\n \"Use IAM instance profiles for AWS API access instead of embedding keys.\",\n \"Use Secrets Manager or SSM Parameter Store for other secrets.\",\n \"Rotate the exposed credential immediately.\",\n ],\n }),\n );\n }\n }\n }\n } catch (e: unknown) {\n warnings.push(`EC2 userData scan error: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n ACMClient,\n ListCertificatesCommand,\n DescribeCertificateCommand,\n type CertificateSummary,\n} from \"@aws-sdk/client-acm\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class SslCertificateScanner implements Scanner {\n readonly moduleName = \"ssl_certificate\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const client = createClient(ACMClient, region, ctx.credentials);\n\n // List all certificates\n const certs: CertificateSummary[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await client.send(\n new ListCertificatesCommand({ NextToken: nextToken }),\n );\n if (resp.CertificateSummaryList) {\n certs.push(...resp.CertificateSummaryList);\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n for (const cert of certs) {\n const certArn = cert.CertificateArn ?? \"unknown\";\n const domainName = cert.DomainName ?? \"unknown\";\n\n let detail;\n try {\n const descResp = await client.send(\n new DescribeCertificateCommand({ CertificateArn: certArn }),\n );\n detail = descResp.Certificate;\n } catch (e: unknown) {\n warnings.push(`Could not describe certificate ${certArn}: ${e instanceof Error ? e.message : String(e)}`);\n continue;\n }\n\n if (!detail) continue;\n\n const status = detail.Status ?? \"UNKNOWN\";\n const inUseBy = detail.InUseBy ?? [];\n const inUseStr = inUseBy.length > 0 ? ` In use by ${inUseBy.length} resource(s).` : \" Not currently in use.\";\n\n // Check for FAILED status\n if (status === \"FAILED\") {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `Certificate for ${domainName} is in FAILED status`,\n resourceType: \"AWS::ACM::Certificate\",\n resourceId: domainName,\n resourceArn: certArn,\n region,\n description: `ACM certificate for \"${domainName}\" has status FAILED.${inUseStr}`,\n impact:\n \"The certificate failed validation and cannot be used for TLS termination. Services relying on it may lose HTTPS protection.\",\n remediationSteps: [\n \"Check the failure reason in the ACM console.\",\n \"Request a new certificate with correct domain validation.\",\n \"If using DNS validation, ensure the CNAME records are correctly configured.\",\n ],\n }),\n );\n continue;\n }\n\n // Check expiry (only for ISSUED certificates)\n if (status === \"ISSUED\" && detail.NotAfter) {\n const now = new Date();\n const expiryDate = new Date(detail.NotAfter);\n const daysUntilExpiry = Math.floor(\n (expiryDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24),\n );\n\n if (daysUntilExpiry < 0) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `Certificate for ${domainName} has expired`,\n resourceType: \"AWS::ACM::Certificate\",\n resourceId: domainName,\n resourceArn: certArn,\n region,\n description: `ACM certificate for \"${domainName}\" expired ${Math.abs(daysUntilExpiry)} days ago.${inUseStr}`,\n impact:\n \"Expired certificates cause TLS errors for end users. Browsers will display security warnings and block access.\",\n remediationSteps: [\n \"Renew or replace the certificate immediately.\",\n \"If using ACM-managed renewal, check why automatic renewal failed.\",\n \"Verify domain validation records are still in place.\",\n ],\n }),\n );\n } else if (daysUntilExpiry < 30) {\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: `Certificate for ${domainName} expires in ${daysUntilExpiry} days`,\n resourceType: \"AWS::ACM::Certificate\",\n resourceId: domainName,\n resourceArn: certArn,\n region,\n description: `ACM certificate for \"${domainName}\" expires in ${daysUntilExpiry} days (${expiryDate.toISOString().split(\"T\")[0]}).${inUseStr}`,\n impact:\n \"Certificate will expire soon. If not renewed, services will experience TLS errors.\",\n remediationSteps: [\n \"Verify ACM automatic renewal is working (check renewal status).\",\n \"If imported certificate, prepare and import the renewed certificate.\",\n \"Set up CloudWatch alarms for certificate expiry.\",\n ],\n }),\n );\n } else if (daysUntilExpiry < 90) {\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `Certificate for ${domainName} expires in ${daysUntilExpiry} days`,\n resourceType: \"AWS::ACM::Certificate\",\n resourceId: domainName,\n resourceArn: certArn,\n region,\n description: `ACM certificate for \"${domainName}\" expires in ${daysUntilExpiry} days (${expiryDate.toISOString().split(\"T\")[0]}).${inUseStr}`,\n impact:\n \"Certificate is approaching expiry. Plan renewal to avoid service disruption.\",\n remediationSteps: [\n \"Verify ACM automatic renewal is configured and working.\",\n \"If imported certificate, begin the renewal process.\",\n \"Consider setting up monitoring for certificate expiry dates.\",\n ],\n }),\n );\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: certs.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n Route53Client,\n ListHostedZonesCommand,\n ListResourceRecordSetsCommand,\n type HostedZone,\n type ResourceRecordSet,\n} from \"@aws-sdk/client-route-53\";\nimport {\n S3Client,\n HeadBucketCommand,\n} from \"@aws-sdk/client-s3\";\nimport { promises as dns } from \"dns\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction extractS3BucketName(target: string): string | null {\n // Matches: bucket.s3.amazonaws.com, bucket.s3-website-us-east-1.amazonaws.com,\n // bucket.s3.cn-north-1.amazonaws.com.cn, etc.\n const s3Pattern = /^([^.]+)\\.s3[.-]/;\n const m = target.match(s3Pattern);\n return m ? m[1] : null;\n}\n\nfunction classifyTarget(target: string): \"s3\" | \"elb\" | \"cloudfront\" | null {\n if (/\\.s3[.-](.*\\.)?amazonaws\\.com(\\.cn)?\\.?$/.test(target)) return \"s3\";\n if (/\\.elb\\.amazonaws\\.com(\\.cn)?\\.?$/.test(target)) return \"elb\";\n if (/\\.cloudfront\\.net\\.?$/.test(target)) return \"cloudfront\";\n return null;\n}\n\nasync function dnsResolves(hostname: string): Promise<boolean> {\n try {\n // Remove trailing dot for DNS lookup\n const h = hostname.endsWith(\".\") ? hostname.slice(0, -1) : hostname;\n await dns.resolve(h);\n return true;\n } catch {\n return false;\n }\n}\n\nexport class DnsDanglingScanner implements Scanner {\n readonly moduleName = \"dns_dangling\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n const route53 = createClient(Route53Client, region, ctx.credentials);\n\n // List hosted zones\n const zones: HostedZone[] = [];\n let marker: string | undefined;\n do {\n const resp = await route53.send(\n new ListHostedZonesCommand({ Marker: marker }),\n );\n if (resp.HostedZones) zones.push(...resp.HostedZones);\n marker = resp.IsTruncated ? resp.NextMarker : undefined;\n } while (marker);\n\n for (const zone of zones) {\n const zoneId = zone.Id ?? \"unknown\";\n const zoneName = zone.Name ?? \"unknown\";\n const shortZoneId = zoneId.replace(\"/hostedzone/\", \"\");\n\n // List record sets\n const records: ResourceRecordSet[] = [];\n let nextName: string | undefined;\n let nextType: string | undefined;\n do {\n const resp = await route53.send(\n new ListResourceRecordSetsCommand({\n HostedZoneId: shortZoneId,\n StartRecordName: nextName,\n StartRecordType: nextType as ResourceRecordSet[\"Type\"],\n }),\n );\n if (resp.ResourceRecordSets) records.push(...resp.ResourceRecordSets);\n if (resp.IsTruncated) {\n nextName = resp.NextRecordName;\n nextType = resp.NextRecordType;\n } else {\n nextName = undefined;\n nextType = undefined;\n }\n } while (nextName);\n\n // Filter CNAME records\n const cnameRecords = records.filter(\n (r) => r.Type === \"CNAME\" && r.ResourceRecords && r.ResourceRecords.length > 0,\n );\n\n resourcesScanned += cnameRecords.length;\n\n for (const record of cnameRecords) {\n const recordName = record.Name ?? \"unknown\";\n const target = record.ResourceRecords![0].Value ?? \"\";\n const recordArn = `arn:${partition}:route53:::hostedzone/${shortZoneId}`;\n const targetType = classifyTarget(target);\n\n if (targetType === \"s3\") {\n // Check if S3 bucket exists\n const bucketName = extractS3BucketName(target);\n if (bucketName) {\n let bucketExists = false;\n try {\n const s3 = createClient(S3Client, region, ctx.credentials);\n await s3.send(new HeadBucketCommand({ Bucket: bucketName }));\n bucketExists = true;\n } catch (e: unknown) {\n const errName = (e as { name?: string }).name ?? \"\";\n // 404 / NoSuchBucket = doesn't exist; 403 = exists but no access\n if (errName === \"Forbidden\" || errName === \"AccessDenied\" || errName === \"403\") {\n bucketExists = true;\n }\n }\n\n if (!bucketExists) {\n findings.push(\n makeFinding({\n riskScore: 9.5,\n title: `CNAME ${recordName} points to non-existent S3 bucket \"${bucketName}\"`,\n resourceType: \"AWS::Route53::RecordSet\",\n resourceId: recordName,\n resourceArn: recordArn,\n region,\n description: `DNS record \"${recordName}\" in zone \"${zoneName}\" has a CNAME to S3 bucket \"${bucketName}\" which does not exist. An attacker can claim this bucket for subdomain takeover.`,\n impact:\n \"Critical subdomain takeover vulnerability. An attacker can create the S3 bucket and serve arbitrary content on your domain, enabling phishing, cookie theft, and reputation damage.\",\n remediationSteps: [\n \"Immediately create the S3 bucket to prevent takeover.\",\n \"Remove the dangling DNS record if the bucket is no longer needed.\",\n \"Audit all CNAME records pointing to S3 buckets.\",\n ],\n }),\n );\n }\n }\n } else if (targetType === \"elb\") {\n const resolves = await dnsResolves(target);\n if (!resolves) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `CNAME ${recordName} points to non-resolving ELB`,\n resourceType: \"AWS::Route53::RecordSet\",\n resourceId: recordName,\n resourceArn: recordArn,\n region,\n description: `DNS record \"${recordName}\" in zone \"${zoneName}\" has a CNAME to ELB \"${target}\" which does not resolve. The load balancer may have been deleted.`,\n impact:\n \"Potential subdomain takeover if the ELB DNS name can be re-registered. Dangling DNS records indicate resource lifecycle gaps.\",\n remediationSteps: [\n \"Remove the dangling DNS record.\",\n \"If the ELB was deleted, clean up all associated DNS records.\",\n \"Implement automated DNS record cleanup when decommissioning resources.\",\n ],\n }),\n );\n }\n } else if (targetType === \"cloudfront\") {\n const resolves = await dnsResolves(target);\n if (!resolves) {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `CNAME ${recordName} points to non-resolving CloudFront distribution`,\n resourceType: \"AWS::Route53::RecordSet\",\n resourceId: recordName,\n resourceArn: recordArn,\n region,\n description: `DNS record \"${recordName}\" in zone \"${zoneName}\" has a CNAME to CloudFront \"${target}\" which does not resolve. The distribution may have been deleted.`,\n impact:\n \"Potential subdomain takeover via CloudFront. An attacker may create a distribution with this alternate domain name.\",\n remediationSteps: [\n \"Remove the dangling DNS record.\",\n \"If the CloudFront distribution was deleted, clean up associated DNS records.\",\n \"Use CloudFront Origin Access Identity to limit exposure.\",\n ],\n }),\n );\n }\n } else if (targetType === null) {\n // Generic CNAME — just check if it resolves\n const resolves = await dnsResolves(target);\n if (!resolves) {\n findings.push(\n makeFinding({\n riskScore: 5.0,\n title: `CNAME ${recordName} target does not resolve`,\n resourceType: \"AWS::Route53::RecordSet\",\n resourceId: recordName,\n resourceArn: recordArn,\n region,\n description: `DNS record \"${recordName}\" in zone \"${zoneName}\" has a CNAME to \"${target}\" which does not resolve.`,\n impact:\n \"Orphaned DNS record pointing to a non-existent target. May indicate incomplete resource cleanup.\",\n remediationSteps: [\n \"Verify the target resource still exists.\",\n \"Remove the DNS record if it is no longer needed.\",\n \"Implement DNS record lifecycle management.\",\n ],\n }),\n );\n }\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n EC2Client,\n DescribeInstancesCommand,\n DescribeSecurityGroupsCommand,\n DescribeNetworkAclsCommand,\n DescribeAddressesCommand,\n type Instance,\n type SecurityGroup,\n type NetworkAcl,\n type IpPermission,\n type NetworkAclEntry,\n} from \"@aws-sdk/client-ec2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nconst HIGH_RISK_PORTS: Record<number, string> = {\n 22: \"SSH\",\n 3389: \"RDP\",\n 3306: \"MySQL\",\n 5432: \"PostgreSQL\",\n 1433: \"MSSQL\",\n 27017: \"MongoDB\",\n 6379: \"Redis\",\n 9200: \"Elasticsearch\",\n 11211: \"Memcached\",\n};\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction sgAllowsPort(sgs: SecurityGroup[], port: number): boolean {\n for (const sg of sgs) {\n for (const perm of sg.IpPermissions ?? []) {\n if (permissionAllowsWorldPort(perm, port)) return true;\n }\n }\n return false;\n}\n\nfunction sgAllowsAllPorts(sgs: SecurityGroup[]): boolean {\n for (const sg of sgs) {\n for (const perm of sg.IpPermissions ?? []) {\n if (isAllPorts(perm) && hasWorldCidr(perm)) return true;\n }\n }\n return false;\n}\n\nfunction permissionAllowsWorldPort(perm: IpPermission, port: number): boolean {\n if (!hasWorldCidr(perm)) return false;\n const from = perm.FromPort ?? -1;\n const to = perm.ToPort ?? -1;\n if (from === -1 && to === -1) return true; // all traffic\n return port >= from && port <= to;\n}\n\nfunction hasWorldCidr(perm: IpPermission): boolean {\n const hasIpv4 = (perm.IpRanges ?? []).some((r) => r.CidrIp === \"0.0.0.0/0\");\n const hasIpv6 = (perm.Ipv6Ranges ?? []).some((r) => r.CidrIpv6 === \"::/0\");\n return hasIpv4 || hasIpv6;\n}\n\nfunction isAllPorts(perm: IpPermission): boolean {\n const from = perm.FromPort ?? -1;\n const to = perm.ToPort ?? -1;\n return (from === -1 && to === -1) || (from === 0 && to === 65535);\n}\n\nfunction naclAllowsPort(nacl: NetworkAcl, port: number): boolean {\n // NACL rules are evaluated in order (lowest rule number first)\n // We check inbound rules only (Egress === false)\n const inboundRules = (nacl.Entries ?? [])\n .filter((e) => e.Egress === false)\n .sort((a, b) => (a.RuleNumber ?? 0) - (b.RuleNumber ?? 0));\n\n for (const rule of inboundRules) {\n if (naclRuleMatchesPort(rule, port) && naclRuleMatchesWorldCidr(rule)) {\n // RuleAction \"allow\" or \"deny\"\n return rule.RuleAction === \"allow\";\n }\n }\n // Default: deny\n return false;\n}\n\nfunction naclRuleMatchesPort(rule: NetworkAclEntry, port: number): boolean {\n // Protocol -1 means all traffic\n if (rule.Protocol === \"-1\") return true;\n // Protocol 6 = TCP, 17 = UDP\n if (rule.Protocol !== \"6\" && rule.Protocol !== \"17\") return false;\n const from = rule.PortRange?.From ?? 0;\n const to = rule.PortRange?.To ?? 65535;\n return port >= from && port <= to;\n}\n\nfunction naclRuleMatchesWorldCidr(rule: NetworkAclEntry): boolean {\n return rule.CidrBlock === \"0.0.0.0/0\" || rule.Ipv6CidrBlock === \"::/0\";\n}\n\nexport class NetworkReachabilityScanner implements Scanner {\n readonly moduleName = \"network_reachability\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const client = createClient(EC2Client, region, ctx.credentials);\n\n // Get EIPs for lookup\n const eipMap = new Map<string, string>(); // instanceId -> EIP\n try {\n const eipResp = await client.send(new DescribeAddressesCommand({}));\n for (const addr of eipResp.Addresses ?? []) {\n if (addr.InstanceId && addr.PublicIp) {\n eipMap.set(addr.InstanceId, addr.PublicIp);\n }\n }\n } catch (e: unknown) {\n warnings.push(`Could not list Elastic IPs: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n // Get instances\n const instances: Instance[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await client.send(\n new DescribeInstancesCommand({ NextToken: nextToken }),\n );\n for (const res of resp.Reservations ?? []) {\n if (res.Instances) instances.push(...res.Instances);\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n // Filter to instances with public IPs or EIPs\n const publicInstances = instances.filter((inst) => {\n const instId = inst.InstanceId ?? \"\";\n return inst.PublicIpAddress || eipMap.has(instId);\n });\n\n // Collect all SG IDs and subnet IDs\n const sgIds = new Set<string>();\n const subnetIds = new Set<string>();\n for (const inst of publicInstances) {\n for (const sg of inst.SecurityGroups ?? []) {\n if (sg.GroupId) sgIds.add(sg.GroupId);\n }\n if (inst.SubnetId) subnetIds.add(inst.SubnetId);\n }\n\n // Fetch all referenced SGs\n const sgMap = new Map<string, SecurityGroup>();\n if (sgIds.size > 0) {\n const sgResp = await client.send(\n new DescribeSecurityGroupsCommand({\n GroupIds: [...sgIds],\n }),\n );\n for (const sg of sgResp.SecurityGroups ?? []) {\n if (sg.GroupId) sgMap.set(sg.GroupId, sg);\n }\n }\n\n // Fetch NACLs for referenced subnets\n const subnetNaclMap = new Map<string, NetworkAcl>(); // subnetId -> NACL\n if (subnetIds.size > 0) {\n let naclToken: string | undefined;\n const allNacls: NetworkAcl[] = [];\n do {\n const naclResp = await client.send(\n new DescribeNetworkAclsCommand({\n Filters: [{ Name: \"association.subnet-id\", Values: [...subnetIds] }],\n NextToken: naclToken,\n }),\n );\n if (naclResp.NetworkAcls) allNacls.push(...naclResp.NetworkAcls);\n naclToken = naclResp.NextToken;\n } while (naclToken);\n\n for (const nacl of allNacls) {\n for (const assoc of nacl.Associations ?? []) {\n if (assoc.SubnetId) {\n subnetNaclMap.set(assoc.SubnetId, nacl);\n }\n }\n }\n }\n\n // Analyze each public instance\n for (const inst of publicInstances) {\n const instId = inst.InstanceId ?? \"unknown\";\n const instArn = `arn:${partition}:ec2:${region}:${accountId}:instance/${instId}`;\n const publicIp = inst.PublicIpAddress ?? eipMap.get(instId) ?? \"unknown\";\n const subnetId = inst.SubnetId ?? \"\";\n\n // Get this instance's SGs\n const instSgs: SecurityGroup[] = [];\n for (const sg of inst.SecurityGroups ?? []) {\n if (sg.GroupId) {\n const fullSg = sgMap.get(sg.GroupId);\n if (fullSg) instSgs.push(fullSg);\n }\n }\n\n const nacl = subnetNaclMap.get(subnetId);\n\n // Check each high-risk port\n for (const [portStr, portName] of Object.entries(HIGH_RISK_PORTS)) {\n const port = Number(portStr);\n const sgAllows = sgAllowsPort(instSgs, port);\n const naclAllows = nacl ? naclAllowsPort(nacl, port) : true; // if no NACL info, assume allow\n\n if (sgAllows && naclAllows) {\n findings.push(\n makeFinding({\n riskScore: 9.5,\n title: `EC2 ${instId} (${publicIp}): ${portName} (${port}) reachable from internet`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: instArn,\n region,\n description: `EC2 instance \"${instId}\" has public IP ${publicIp} and both its security group(s) and subnet NACL allow inbound ${portName} (port ${port}) from the internet.`,\n impact:\n `${portName} is directly reachable from the internet, enabling brute-force, exploitation, or unauthorized access.`,\n remediationSteps: [\n `Restrict security group inbound rules for port ${port} to specific IPs.`,\n \"Use Systems Manager Session Manager or a bastion host instead of direct access.\",\n \"Add NACL deny rules for high-risk ports as an additional layer.\",\n \"Enable VPC Flow Logs to monitor connection attempts.\",\n ],\n }),\n );\n } else if (sgAllows && !naclAllows) {\n findings.push(\n makeFinding({\n riskScore: 2.0,\n title: `EC2 ${instId}: ${portName} (${port}) allowed by SG but blocked by NACL`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: instArn,\n region,\n description: `EC2 instance \"${instId}\" (${publicIp}) has security group rules allowing ${portName} (port ${port}) from the internet, but the subnet NACL blocks it.`,\n impact:\n \"Currently protected by NACL, but the SG is overly permissive. NACL changes could expose the port.\",\n remediationSteps: [\n `Tighten the security group rules for port ${port} to match the intended access.`,\n \"Do not rely solely on NACLs for access control.\",\n ],\n }),\n );\n }\n }\n\n // Check for all-ports open via SG + NACL\n if (sgAllowsAllPorts(instSgs)) {\n // Check if NACL is also wide open (allows common ports)\n const naclOpen = nacl ? naclAllowsPort(nacl, 80) : true; // proxy check with port 80\n if (naclOpen) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `EC2 ${instId} (${publicIp}): all ports reachable from internet`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: instArn,\n region,\n description: `EC2 instance \"${instId}\" has public IP ${publicIp} and its security group allows all ports from the internet with no NACL restriction.`,\n impact:\n \"All services on this instance are exposed to the internet, creating a large attack surface.\",\n remediationSteps: [\n \"Replace the all-ports SG rule with specific port rules.\",\n \"Implement NACL rules to restrict inbound traffic as defense in depth.\",\n \"Audit all services running on the instance.\",\n ],\n }),\n );\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: publicInstances.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n IAMClient,\n ListUsersCommand,\n ListAttachedUserPoliciesCommand,\n GetPolicyCommand,\n GetPolicyVersionCommand,\n ListUserPoliciesCommand,\n GetUserPolicyCommand,\n type User,\n} from \"@aws-sdk/client-iam\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient, getIamRegion } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\ninterface PolicyStatement {\n Effect?: string;\n Action?: string | string[];\n Resource?: string | string[];\n}\n\nfunction extractActions(doc: unknown): string[] {\n const actions: string[] = [];\n if (!doc || typeof doc !== \"object\") return actions;\n const policy = doc as { Statement?: PolicyStatement | PolicyStatement[] };\n const stmts = Array.isArray(policy.Statement)\n ? policy.Statement\n : policy.Statement\n ? [policy.Statement]\n : [];\n\n for (const stmt of stmts) {\n if (stmt.Effect !== \"Allow\") continue;\n const acts = Array.isArray(stmt.Action)\n ? stmt.Action\n : stmt.Action\n ? [stmt.Action]\n : [];\n actions.push(...acts);\n }\n return actions.map((a) => a.toLowerCase());\n}\n\nfunction hasAction(actions: string[], pattern: string): boolean {\n const pat = pattern.toLowerCase();\n return actions.some((a) => {\n if (a === \"*\") return true;\n if (a === pat) return true;\n // Wildcard match: \"iam:*\" matches \"iam:createrole\"\n if (a.endsWith(\"*\")) {\n const prefix = a.slice(0, -1);\n if (pat.startsWith(prefix)) return true;\n }\n return false;\n });\n}\n\nexport class IamPrivilegeEscalationScanner implements Scanner {\n readonly moduleName = \"iam_privilege_escalation\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n const iamRegion = getIamRegion(region);\n\n warnings.push(\n \"Note: This scanner currently checks IAM users only. Role and group policy analysis will be added in a future version.\",\n );\n\n try {\n const client = createClient(IAMClient, iamRegion, ctx.credentials);\n\n // List all IAM users\n const users: User[] = [];\n let marker: string | undefined;\n do {\n const resp = await client.send(\n new ListUsersCommand({ Marker: marker }),\n );\n if (resp.Users) users.push(...resp.Users);\n marker = resp.IsTruncated ? resp.Marker : undefined;\n } while (marker);\n\n for (const user of users) {\n const userName = user.UserName ?? \"unknown\";\n const userArn =\n user.Arn ??\n `arn:${partition}:iam::${accountId}:user/${userName}`;\n\n // Collect all allowed actions from both managed and inline policies\n const allActions: string[] = [];\n\n // 1. Check attached (managed) policies\n try {\n const attachedResp = await client.send(\n new ListAttachedUserPoliciesCommand({ UserName: userName }),\n );\n for (const policy of attachedResp.AttachedPolicies ?? []) {\n const policyArn = policy.PolicyArn;\n if (!policyArn) continue;\n try {\n const policyResp = await client.send(\n new GetPolicyCommand({ PolicyArn: policyArn }),\n );\n const versionId =\n policyResp.Policy?.DefaultVersionId ?? \"v1\";\n const versionResp = await client.send(\n new GetPolicyVersionCommand({\n PolicyArn: policyArn,\n VersionId: versionId,\n }),\n );\n const doc = versionResp.PolicyVersion?.Document;\n if (doc) {\n const parsed = JSON.parse(decodeURIComponent(doc));\n allActions.push(...extractActions(parsed));\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(\n `Could not read policy ${policyArn} for user ${userName}: ${msg}`,\n );\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(\n `Could not list attached policies for user ${userName}: ${msg}`,\n );\n }\n\n // 2. Check inline policies\n try {\n const inlineResp = await client.send(\n new ListUserPoliciesCommand({ UserName: userName }),\n );\n for (const policyName of inlineResp.PolicyNames ?? []) {\n try {\n const inlinePolicyResp = await client.send(\n new GetUserPolicyCommand({\n UserName: userName,\n PolicyName: policyName,\n }),\n );\n const doc = inlinePolicyResp.PolicyDocument;\n if (doc) {\n const parsed = JSON.parse(decodeURIComponent(doc));\n allActions.push(...extractActions(parsed));\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(\n `Could not read inline policy ${policyName} for user ${userName}: ${msg}`,\n );\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(\n `Could not list inline policies for user ${userName}: ${msg}`,\n );\n }\n\n if (allActions.length === 0) continue;\n\n // Check for wildcard iam:* or full wildcard *\n if (\n hasAction(allActions, \"iam:*\") ||\n allActions.includes(\"*\")\n ) {\n findings.push(\n makeFinding({\n riskScore: 9.0,\n title: `IAM user ${userName} has iam:* wildcard permissions`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has wildcard IAM permissions (iam:* or *), granting full control over identity and access management.`,\n impact:\n \"The user can create, modify, or delete any IAM resource including creating admin users, modifying policies, and escalating privileges without restriction.\",\n remediationSteps: [\n `Remove wildcard IAM permissions from user \"${userName}\".`,\n \"Replace with specific, least-privilege IAM permissions.\",\n \"Use IAM Access Analyzer to identify actually used permissions.\",\n ],\n }),\n );\n // Skip further checks — wildcard already covers everything\n continue;\n }\n\n // Self-grant admin: iam:PutUserPolicy or iam:AttachUserPolicy\n if (\n hasAction(allActions, \"iam:putuserpolicy\") ||\n hasAction(allActions, \"iam:attachuserpolicy\")\n ) {\n findings.push(\n makeFinding({\n riskScore: 9.5,\n title: `IAM user ${userName} can self-grant admin via policy attachment`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has iam:PutUserPolicy or iam:AttachUserPolicy, allowing them to attach AdministratorAccess or any policy to themselves.`,\n impact:\n \"The user can escalate to full administrator access by attaching an admin policy to their own account.\",\n remediationSteps: [\n `Remove iam:PutUserPolicy and iam:AttachUserPolicy from user \"${userName}\".`,\n \"Use permission boundaries to restrict policy attachment scope.\",\n \"Require MFA for sensitive IAM operations via condition keys.\",\n ],\n }),\n );\n }\n\n // Create admin roles: iam:CreateRole + iam:AttachRolePolicy\n if (\n hasAction(allActions, \"iam:createrole\") &&\n hasAction(allActions, \"iam:attachrolepolicy\")\n ) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `IAM user ${userName} can create admin roles`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has both iam:CreateRole and iam:AttachRolePolicy, allowing creation of new roles with admin policies.`,\n impact:\n \"The user can create a new IAM role with AdministratorAccess and assume it to gain full account access.\",\n remediationSteps: [\n `Restrict iam:CreateRole and iam:AttachRolePolicy with resource conditions for user \"${userName}\".`,\n \"Use permission boundaries on all created roles.\",\n \"Monitor IAM role creation via CloudTrail alerts.\",\n ],\n }),\n );\n }\n\n // PassRole + Lambda escalation: iam:PassRole + lambda:CreateFunction\n if (\n hasAction(allActions, \"iam:passrole\") &&\n hasAction(allActions, \"lambda:createfunction\")\n ) {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `IAM user ${userName} can escalate via Lambda role passing`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has iam:PassRole and lambda:CreateFunction, allowing them to create a Lambda function with an admin role.`,\n impact:\n \"The user can pass a high-privilege role to a Lambda function and invoke it to execute actions beyond their own permissions.\",\n remediationSteps: [\n `Restrict iam:PassRole to specific role ARNs for user \"${userName}\".`,\n \"Use condition keys to limit which roles can be passed to Lambda.\",\n \"Implement SCP guardrails for privilege escalation paths.\",\n ],\n }),\n );\n }\n\n // Create access keys for other users: iam:CreateAccessKey\n if (hasAction(allActions, \"iam:createaccesskey\")) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `IAM user ${userName} can create access keys for other users`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has iam:CreateAccessKey, which allows creating access keys for any IAM user unless restricted by resource conditions.`,\n impact:\n \"The user can impersonate other IAM users (including admins) by generating access keys on their behalf.\",\n remediationSteps: [\n `Restrict iam:CreateAccessKey to the user's own ARN using a resource condition.`,\n \"Implement SCP to prevent cross-user key creation.\",\n \"Monitor CreateAccessKey events in CloudTrail.\",\n ],\n }),\n );\n }\n\n // STS AssumeRole on admin roles\n if (hasAction(allActions, \"sts:assumerole\")) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `IAM user ${userName} can assume roles (potential admin escalation)`,\n resourceType: \"AWS::IAM::User\",\n resourceId: userName,\n resourceArn: userArn,\n region: \"global\",\n description: `User \"${userName}\" has sts:AssumeRole, which may allow assuming high-privilege or admin roles if not restricted by resource ARN.`,\n impact:\n \"The user can escalate privileges by assuming roles with higher permissions than their own.\",\n remediationSteps: [\n `Restrict sts:AssumeRole to specific role ARNs for user \"${userName}\".`,\n \"Require MFA for assuming sensitive roles via role trust policy conditions.\",\n \"Audit which roles this user can assume and their permission levels.\",\n ],\n }),\n );\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: users.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n S3Client,\n ListBucketsCommand,\n GetPublicAccessBlockCommand,\n GetBucketAclCommand,\n GetBucketPolicyStatusCommand,\n GetBucketLocationCommand,\n} from \"@aws-sdk/client-s3\";\nimport {\n RDSClient,\n DescribeDBInstancesCommand,\n type DBInstance,\n} from \"@aws-sdk/client-rds\";\nimport dns from \"node:dns\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction s3Endpoint(bucket: string, region: string): string {\n const suffix = region.startsWith(\"cn-\")\n ? \"amazonaws.com.cn\"\n : \"amazonaws.com\";\n return `https://${bucket}.s3.${region}.${suffix}/`;\n}\n\nasync function getBucketRegion(\n client: S3Client,\n bucketName: string,\n defaultRegion: string,\n warnings: string[],\n): Promise<string> {\n try {\n const resp = await client.send(\n new GetBucketLocationCommand({ Bucket: bucketName }),\n );\n const loc = String(resp.LocationConstraint ?? \"\") || \"us-east-1\";\n return loc;\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Failed to detect region for bucket ${bucketName}, using ${defaultRegion}: ${msg}`);\n return defaultRegion;\n }\n}\n\nasync function isBucketMarkedPublic(\n client: S3Client,\n bucketName: string,\n warnings: string[],\n): Promise<boolean | \"skip\"> {\n // Check if Block Public Access is off AND (public ACL or public policy)\n let bpaBlocks = false;\n try {\n const bpa = await client.send(\n new GetPublicAccessBlockCommand({ Bucket: bucketName }),\n );\n const cfg = bpa.PublicAccessBlockConfiguration;\n bpaBlocks = !!(\n cfg?.BlockPublicAcls &&\n cfg?.IgnorePublicAcls &&\n cfg?.BlockPublicPolicy &&\n cfg?.RestrictPublicBuckets\n );\n } catch (e: unknown) {\n if (\n e instanceof Error &&\n e.name === \"NoSuchPublicAccessBlockConfiguration\"\n ) {\n bpaBlocks = false;\n } else {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Could not check public access for bucket ${bucketName}: ${msg}`);\n return \"skip\";\n }\n }\n\n if (bpaBlocks) return false;\n\n // Check ACL for public grants\n try {\n const acl = await client.send(\n new GetBucketAclCommand({ Bucket: bucketName }),\n );\n for (const grant of acl.Grants ?? []) {\n const uri = grant.Grantee?.URI ?? \"\";\n if (uri.includes(\"AllUsers\") || uri.includes(\"AuthenticatedUsers\")) {\n return true;\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Could not check ACL for bucket ${bucketName}: ${msg}`);\n }\n\n // Check bucket policy status\n try {\n const policyStatus = await client.send(\n new GetBucketPolicyStatusCommand({ Bucket: bucketName }),\n );\n if (policyStatus.PolicyStatus?.IsPublic) return true;\n } catch (e: unknown) {\n // NoSuchBucketPolicy is expected for buckets without policies\n if (e instanceof Error && !e.name.includes(\"NoSuchBucketPolicy\")) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Could not check policy status for bucket ${bucketName}: ${msg}`);\n }\n }\n\n return false;\n}\n\nfunction isPrivateIp(ip: string): boolean {\n if (ip.startsWith(\"10.\")) return true;\n if (ip.startsWith(\"192.168.\")) return true;\n if (ip.startsWith(\"172.\")) {\n const second = parseInt(ip.split(\".\")[1], 10);\n return second >= 16 && second <= 31;\n }\n if (ip.startsWith(\"127.\")) return true;\n return false;\n}\n\nexport class PublicAccessVerifyScanner implements Scanner {\n readonly moduleName = \"public_access_verify\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n // --- S3 public access verification ---\n try {\n const s3Client = createClient(S3Client, region, ctx.credentials);\n const listResp = await s3Client.send(new ListBucketsCommand({}));\n const buckets = listResp.Buckets ?? [];\n\n for (const bucket of buckets) {\n const name = bucket.Name ?? \"unknown\";\n const arn = `arn:${partition}:s3:::${name}`;\n\n const bucketRegion = await getBucketRegion(s3Client, name, region, warnings);\n const bucketClient =\n bucketRegion === region\n ? s3Client\n : createClient(S3Client, bucketRegion, ctx.credentials);\n\n const markedPublic = await isBucketMarkedPublic(bucketClient, name, warnings);\n if (markedPublic === \"skip\" || !markedPublic) continue;\n\n resourcesScanned++;\n const url = s3Endpoint(name, bucketRegion);\n\n try {\n const resp = await fetch(url, {\n method: \"HEAD\",\n signal: AbortSignal.timeout(5000),\n });\n\n if (resp.ok || resp.status === 200) {\n findings.push(\n makeFinding({\n riskScore: 9.5,\n title: `S3 bucket ${name} is publicly readable (verified)`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region: bucketRegion,\n description: `HTTP HEAD to ${url} returned status ${resp.status}. The bucket is confirmed publicly accessible from the internet.`,\n impact:\n \"Anyone on the internet can read objects from this bucket, potentially exposing sensitive data.\",\n remediationSteps: [\n \"Enable Block Public Access on the bucket immediately.\",\n \"Review and remove public ACL grants and public bucket policies.\",\n \"Audit bucket contents for sensitive data exposure.\",\n ],\n }),\n );\n } else if (resp.status === 403) {\n findings.push(\n makeFinding({\n riskScore: 2.0,\n title: `S3 bucket ${name} is marked public but returns 403 (blocked)`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region: bucketRegion,\n description: `Bucket \"${name}\" has public ACL/policy configuration but HTTP access returns 403 Forbidden, likely blocked by other controls.`,\n impact:\n \"Currently not accessible, but the public configuration is a risk if blocking controls are removed.\",\n remediationSteps: [\n \"Clean up the public ACL or policy to match the intended access model.\",\n \"Enable Block Public Access to formalize the restriction.\",\n ],\n }),\n );\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`HTTP check for bucket ${name} failed: ${msg}`);\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`S3 public access verification failed: ${msg}`);\n }\n\n // --- RDS public DNS verification ---\n try {\n const rdsClient = createClient(RDSClient, region, ctx.credentials);\n const instances: DBInstance[] = [];\n let marker: string | undefined;\n do {\n const resp = await rdsClient.send(\n new DescribeDBInstancesCommand({ Marker: marker }),\n );\n if (resp.DBInstances) instances.push(...resp.DBInstances);\n marker = resp.Marker;\n } while (marker);\n\n for (const db of instances) {\n if (!db.PubliclyAccessible) continue;\n\n const dbId = db.DBInstanceIdentifier ?? \"unknown\";\n const dbArn =\n db.DBInstanceArn ??\n `arn:${partition}:rds:${region}:${accountId}:db/${dbId}`;\n const endpoint = db.Endpoint?.Address;\n if (!endpoint) continue;\n\n resourcesScanned++;\n\n try {\n const addresses = await dns.promises.resolve4(endpoint);\n const hasPublicIp = addresses.some((ip) => !isPrivateIp(ip));\n\n if (hasPublicIp) {\n findings.push(\n makeFinding({\n riskScore: 8.0,\n title: `RDS instance ${dbId} endpoint resolves to public IP (verified)`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS endpoint ${endpoint} resolves to public IP(s): ${addresses.join(\", \")}. The database is network-reachable from the internet.`,\n impact:\n \"The database can be reached from the public internet, making it vulnerable to brute-force, credential stuffing, and exploitation of database vulnerabilities.\",\n remediationSteps: [\n \"Set PubliclyAccessible to false on the RDS instance.\",\n \"Move the instance to a private subnet.\",\n \"Use VPN or bastion host for database access.\",\n \"Restrict security group inbound rules to known IPs.\",\n ],\n }),\n );\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`DNS resolution for RDS ${dbId} (${endpoint}) failed: ${msg}`);\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`RDS public access verification failed: ${msg}`);\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n EC2Client,\n DescribeInstancesCommand,\n type Instance,\n} from \"@aws-sdk/client-ec2\";\nimport {\n RDSClient,\n DescribeDBInstancesCommand,\n type DBInstance,\n} from \"@aws-sdk/client-rds\";\nimport {\n S3Client,\n ListBucketsCommand,\n GetBucketTaggingCommand,\n} from \"@aws-sdk/client-s3\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nconst DEFAULT_REQUIRED_TAGS = [\"Environment\", \"Project\", \"Owner\"];\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nfunction getMissingTags(\n tags: Array<{ Key?: string; Value?: string }>,\n requiredTags: string[],\n): string[] {\n const tagKeys = new Set(tags.map((t) => t.Key ?? \"\"));\n return requiredTags.filter((rt) => !tagKeys.has(rt));\n}\n\nexport class TagComplianceScanner implements Scanner {\n readonly moduleName = \"tag_compliance\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n const requiredTags = DEFAULT_REQUIRED_TAGS;\n\n try {\n // --- EC2 instances ---\n try {\n const ec2Client = createClient(EC2Client, region, ctx.credentials);\n const instances: Instance[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await ec2Client.send(\n new DescribeInstancesCommand({ NextToken: nextToken }),\n );\n for (const res of resp.Reservations ?? []) {\n if (res.Instances) instances.push(...res.Instances);\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n resourcesScanned += instances.length;\n\n for (const instance of instances) {\n const id = instance.InstanceId ?? \"unknown\";\n const arn = `arn:${partition}:ec2:${region}:${accountId}:instance/${id}`;\n const tags = instance.Tags ?? [];\n const missing = getMissingTags(tags, requiredTags);\n\n if (missing.length > 0) {\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `EC2 instance ${id} missing required tags: ${missing.join(\", \")}`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: id,\n resourceArn: arn,\n region,\n description: `EC2 instance \"${id}\" is missing the following required tags: ${missing.join(\", \")}.`,\n impact:\n \"Resources without proper tags cannot be tracked for cost allocation, ownership, or compliance purposes.\",\n remediationSteps: [\n `Add the missing tags (${missing.join(\", \")}) to instance ${id}.`,\n \"Implement AWS Config rules or Tag Policies to enforce tagging.\",\n \"Use AWS Tag Editor for bulk tagging operations.\",\n ],\n }),\n );\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`EC2 tag compliance check failed: ${msg}`);\n }\n\n // --- RDS instances ---\n try {\n const rdsClient = createClient(RDSClient, region, ctx.credentials);\n const dbInstances: DBInstance[] = [];\n let marker: string | undefined;\n do {\n const resp = await rdsClient.send(\n new DescribeDBInstancesCommand({ Marker: marker }),\n );\n if (resp.DBInstances) dbInstances.push(...resp.DBInstances);\n marker = resp.Marker;\n } while (marker);\n\n resourcesScanned += dbInstances.length;\n\n for (const db of dbInstances) {\n const dbId = db.DBInstanceIdentifier ?? \"unknown\";\n const dbArn =\n db.DBInstanceArn ??\n `arn:${partition}:rds:${region}:${accountId}:db/${dbId}`;\n const tags = (db.TagList ?? []).map((t) => ({\n Key: t.Key,\n Value: t.Value,\n }));\n const missing = getMissingTags(tags, requiredTags);\n\n if (missing.length > 0) {\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `RDS instance ${dbId} missing required tags: ${missing.join(\", \")}`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS instance \"${dbId}\" is missing the following required tags: ${missing.join(\", \")}.`,\n impact:\n \"Resources without proper tags cannot be tracked for cost allocation, ownership, or compliance purposes.\",\n remediationSteps: [\n `Add the missing tags (${missing.join(\", \")}) to RDS instance ${dbId}.`,\n \"Implement AWS Config rules or Tag Policies to enforce tagging.\",\n \"Use AWS Tag Editor for bulk tagging operations.\",\n ],\n }),\n );\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`RDS tag compliance check failed: ${msg}`);\n }\n\n // --- S3 buckets ---\n try {\n const s3Client = createClient(S3Client, region, ctx.credentials);\n const listResp = await s3Client.send(new ListBucketsCommand({}));\n const buckets = listResp.Buckets ?? [];\n resourcesScanned += buckets.length;\n\n for (const bucket of buckets) {\n const name = bucket.Name ?? \"unknown\";\n const arn = `arn:${partition}:s3:::${name}`;\n\n try {\n const taggingResp = await s3Client.send(\n new GetBucketTaggingCommand({ Bucket: name }),\n );\n const tags = (taggingResp.TagSet ?? []).map((t) => ({\n Key: t.Key,\n Value: t.Value,\n }));\n const missing = getMissingTags(tags, requiredTags);\n\n if (missing.length > 0) {\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `S3 bucket ${name} missing required tags: ${missing.join(\", \")}`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region: \"global\",\n description: `S3 bucket \"${name}\" is missing the following required tags: ${missing.join(\", \")}.`,\n impact:\n \"Resources without proper tags cannot be tracked for cost allocation, ownership, or compliance purposes.\",\n remediationSteps: [\n `Add the missing tags (${missing.join(\", \")}) to bucket ${name}.`,\n \"Implement AWS Config rules or Tag Policies to enforce tagging.\",\n \"Use AWS Tag Editor for bulk tagging operations.\",\n ],\n }),\n );\n }\n } catch (e: unknown) {\n if (\n e instanceof Error &&\n e.name === \"NoSuchTagSet\"\n ) {\n // No tags at all — all required tags are missing\n findings.push(\n makeFinding({\n riskScore: 4.0,\n title: `S3 bucket ${name} missing required tags: ${requiredTags.join(\", \")}`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region: \"global\",\n description: `S3 bucket \"${name}\" has no tags configured. Missing all required tags: ${requiredTags.join(\", \")}.`,\n impact:\n \"Resources without proper tags cannot be tracked for cost allocation, ownership, or compliance purposes.\",\n remediationSteps: [\n `Add the required tags (${requiredTags.join(\", \")}) to bucket ${name}.`,\n \"Implement AWS Config rules or Tag Policies to enforce tagging.\",\n \"Use AWS Tag Editor for bulk tagging operations.\",\n ],\n }),\n );\n } else {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`S3 tag check for ${name} failed: ${msg}`);\n }\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`S3 tag compliance check failed: ${msg}`);\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n EC2Client,\n DescribeVolumesCommand,\n DescribeAddressesCommand,\n DescribeInstancesCommand,\n DescribeNetworkInterfacesCommand,\n DescribeSecurityGroupsCommand,\n type Volume,\n type Address,\n type Instance,\n type SecurityGroup,\n} from \"@aws-sdk/client-ec2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class IdleResourcesScanner implements Scanner {\n readonly moduleName = \"idle_resources\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const client = createClient(EC2Client, region, ctx.credentials);\n let resourcesScanned = 0;\n\n // 1. Unattached EBS volumes (State = \"available\")\n const volumes: Volume[] = [];\n let volToken: string | undefined;\n do {\n const resp = await client.send(\n new DescribeVolumesCommand({ NextToken: volToken }),\n );\n if (resp.Volumes) volumes.push(...resp.Volumes);\n volToken = resp.NextToken;\n } while (volToken);\n\n resourcesScanned += volumes.length;\n\n for (const vol of volumes) {\n if (vol.State === \"available\") {\n const volId = vol.VolumeId ?? \"unknown\";\n findings.push(\n makeFinding({\n riskScore: 3.0,\n title: `EBS volume ${volId} is unattached`,\n resourceType: \"AWS::EC2::Volume\",\n resourceId: volId,\n resourceArn: `arn:${partition}:ec2:${region}:${accountId}:volume/${volId}`,\n region,\n description: `EBS volume \"${volId}\" (${vol.Size ?? \"?\"}GB, ${vol.VolumeType ?? \"unknown\"}) is in \"available\" state with no attachments.`,\n impact:\n \"Unattached volumes incur storage costs and may contain sensitive data that is no longer actively managed.\",\n remediationSteps: [\n \"Determine if the volume is still needed.\",\n \"If not needed, create a snapshot for archival and delete the volume.\",\n \"If needed, attach it to the appropriate instance.\",\n ],\n }),\n );\n }\n }\n\n // 2. Unused Elastic IPs (not associated with any instance)\n let addresses: Address[] = [];\n try {\n const addrResp = await client.send(new DescribeAddressesCommand({}));\n addresses = addrResp.Addresses ?? [];\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Elastic IP check failed: ${msg}`);\n }\n\n resourcesScanned += addresses.length;\n\n for (const addr of addresses) {\n if (!addr.AssociationId) {\n const allocId = addr.AllocationId ?? \"unknown\";\n const publicIp = addr.PublicIp ?? \"unknown\";\n findings.push(\n makeFinding({\n riskScore: 2.0,\n title: `Elastic IP ${publicIp} is not associated`,\n resourceType: \"AWS::EC2::EIP\",\n resourceId: allocId,\n resourceArn: `arn:${partition}:ec2:${region}:${accountId}:elastic-ip/${allocId}`,\n region,\n description: `Elastic IP ${publicIp} (${allocId}) is allocated but not associated with any instance or network interface.`,\n impact:\n \"Unused Elastic IPs cost ~$3.60/month each and represent unnecessary spend.\",\n remediationSteps: [\n \"Associate the EIP with an instance or network interface if needed.\",\n \"Release the EIP if it is no longer required.\",\n ],\n }),\n );\n }\n }\n\n // 3. Stopped EC2 instances (>30 days)\n const instances: Instance[] = [];\n let instToken: string | undefined;\n do {\n const instResp = await client.send(\n new DescribeInstancesCommand({ NextToken: instToken }),\n );\n for (const res of instResp.Reservations ?? []) {\n if (res.Instances) instances.push(...res.Instances);\n }\n instToken = instResp.NextToken;\n } while (instToken);\n\n resourcesScanned += instances.length;\n const now = Date.now();\n\n for (const inst of instances) {\n if (inst.State?.Name === \"stopped\") {\n const instId = inst.InstanceId ?? \"unknown\";\n const reason = inst.StateTransitionReason ?? \"\";\n const stoppedTime = reason ? parseStopTime(reason) : null;\n\n if (!stoppedTime) {\n warnings.push(\n `Could not determine stop date for instance ${instId}. StateTransitionReason: ${reason}`,\n );\n continue;\n }\n\n const stoppedDays = Math.round(\n (now - stoppedTime) / (24 * 60 * 60 * 1000),\n );\n\n if (stoppedDays > 30) {\n findings.push(\n makeFinding({\n riskScore: 3.0,\n title: `EC2 instance ${instId} has been stopped for ${stoppedDays} days`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instId,\n resourceArn: `arn:${partition}:ec2:${region}:${accountId}:instance/${instId}`,\n region,\n description: `EC2 instance \"${instId}\" (${inst.InstanceType ?? \"unknown\"}) is in stopped state for ${stoppedDays} days. Attached EBS volumes continue to incur charges.`,\n impact:\n \"Stopped instances still incur EBS storage costs and may contain stale configurations or unpatched AMIs.\",\n remediationSteps: [\n \"Determine if the instance is still needed.\",\n \"If not needed, create an AMI for archival and terminate the instance.\",\n \"If needed temporarily, consider using a launch template for on-demand recreation.\",\n ],\n }),\n );\n }\n }\n }\n\n // 4. Unused Security Groups (not attached to any ENI)\n const securityGroups: SecurityGroup[] = [];\n let sgToken: string | undefined;\n do {\n const sgResp = await client.send(\n new DescribeSecurityGroupsCommand({ NextToken: sgToken }),\n );\n if (sgResp.SecurityGroups) securityGroups.push(...sgResp.SecurityGroups);\n sgToken = sgResp.NextToken;\n } while (sgToken);\n\n // Find all SGs referenced by ENIs\n const usedSgIds = new Set<string>();\n let eniToken: string | undefined;\n do {\n const eniResp = await client.send(\n new DescribeNetworkInterfacesCommand({ NextToken: eniToken }),\n );\n for (const eni of eniResp.NetworkInterfaces ?? []) {\n for (const group of eni.Groups ?? []) {\n if (group.GroupId) usedSgIds.add(group.GroupId);\n }\n }\n eniToken = eniResp.NextToken;\n } while (eniToken);\n\n resourcesScanned += securityGroups.length;\n\n for (const sg of securityGroups) {\n const sgId = sg.GroupId ?? \"unknown\";\n // Skip default security groups — they cannot be deleted\n if (sg.GroupName === \"default\") continue;\n\n if (!usedSgIds.has(sgId)) {\n findings.push(\n makeFinding({\n riskScore: 2.0,\n title: `Security group ${sgId} is not attached to any resource`,\n resourceType: \"AWS::EC2::SecurityGroup\",\n resourceId: sgId,\n resourceArn: `arn:${partition}:ec2:${region}:${sg.OwnerId ?? accountId}:security-group/${sgId}`,\n region,\n description: `Security group \"${sg.GroupName}\" (${sgId}) is not associated with any network interface.`,\n impact:\n \"Unused security groups add clutter and may cause confusion during security reviews.\",\n remediationSteps: [\n \"Verify the security group is not referenced by other resources (e.g., launch templates).\",\n \"Delete the security group if it is no longer needed.\",\n ],\n }),\n );\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n\n/**\n * Parse the stop time from EC2 StateTransitionReason.\n * Format: \"User initiated (2024-01-15 08:30:00 GMT)\"\n */\nfunction parseStopTime(reason: string): number | null {\n const match = reason.match(/\\((\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\w+)\\)/);\n if (!match) return null;\n const parsed = Date.parse(match[1]);\n return isNaN(parsed) ? null : parsed;\n}\n","import {\n RDSClient,\n DescribeDBInstancesCommand,\n type DBInstance,\n} from \"@aws-sdk/client-rds\";\nimport {\n EC2Client,\n DescribeVolumesCommand,\n DescribeSnapshotsCommand,\n type Volume,\n type Snapshot,\n} from \"@aws-sdk/client-ec2\";\nimport {\n S3Client,\n ListBucketsCommand,\n GetBucketVersioningCommand,\n GetBucketReplicationCommand,\n} from \"@aws-sdk/client-s3\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nconst SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class DisasterRecoveryScanner implements Scanner {\n readonly moduleName = \"disaster_recovery\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n let resourcesScanned = 0;\n\n // --- RDS checks ---\n const rdsClient = createClient(RDSClient, region, ctx.credentials);\n const instances: DBInstance[] = [];\n let marker: string | undefined;\n do {\n const resp = await rdsClient.send(\n new DescribeDBInstancesCommand({ Marker: marker }),\n );\n if (resp.DBInstances) instances.push(...resp.DBInstances);\n marker = resp.Marker;\n } while (marker);\n\n resourcesScanned += instances.length;\n\n for (const db of instances) {\n const dbId = db.DBInstanceIdentifier ?? \"unknown\";\n const dbArn =\n db.DBInstanceArn ??\n `arn:${partition}:rds:${region}:${accountId}:db/${dbId}`;\n const engine = db.Engine ?? \"unknown\";\n\n // MultiAZ check\n if (!db.MultiAZ) {\n findings.push(\n makeFinding({\n riskScore: 6.0,\n title: `RDS instance ${dbId} is not Multi-AZ`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS instance \"${dbId}\" (${engine}) does not have Multi-AZ deployment enabled.`,\n impact:\n \"Single-AZ deployments have no automatic failover. An AZ outage will cause downtime and potential data loss.\",\n remediationSteps: [\n \"Enable Multi-AZ deployment for the RDS instance.\",\n \"This provides automatic failover to a standby in a different AZ.\",\n ],\n }),\n );\n }\n\n // Backup retention check\n const retention = db.BackupRetentionPeriod ?? 0;\n if (retention === 0) {\n findings.push(\n makeFinding({\n riskScore: 5.5,\n title: `RDS instance ${dbId} has automated backups disabled`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS instance \"${dbId}\" (${engine}) has backup retention period set to 0 (disabled).`,\n impact:\n \"No automated backups or point-in-time recovery. Data loss from failures or corruption is unrecoverable.\",\n remediationSteps: [\n \"Set the backup retention period to at least 7 days.\",\n \"Consider cross-region backup replication for critical databases.\",\n ],\n }),\n );\n } else if (retention < 7) {\n findings.push(\n makeFinding({\n riskScore: 5.5,\n title: `RDS instance ${dbId} backup retention is only ${retention} day(s)`,\n resourceType: \"AWS::RDS::DBInstance\",\n resourceId: dbId,\n resourceArn: dbArn,\n region,\n description: `RDS instance \"${dbId}\" (${engine}) has backup retention period of ${retention} day(s), below the recommended 7 days.`,\n impact:\n \"Short retention windows limit point-in-time recovery options and may not meet compliance requirements.\",\n remediationSteps: [\n \"Increase the backup retention period to at least 7 days.\",\n \"For production databases, consider 14-35 days retention.\",\n ],\n }),\n );\n }\n }\n\n // --- EBS snapshot checks ---\n const ec2Client = createClient(EC2Client, region, ctx.credentials);\n\n const volumes: Volume[] = [];\n let volToken: string | undefined;\n do {\n const resp = await ec2Client.send(\n new DescribeVolumesCommand({ NextToken: volToken }),\n );\n if (resp.Volumes) volumes.push(...resp.Volumes);\n volToken = resp.NextToken;\n } while (volToken);\n\n // Get all snapshots owned by this account\n const snapshots: Snapshot[] = [];\n let snapToken: string | undefined;\n do {\n const resp = await ec2Client.send(\n new DescribeSnapshotsCommand({\n OwnerIds: [\"self\"],\n NextToken: snapToken,\n }),\n );\n if (resp.Snapshots) snapshots.push(...resp.Snapshots);\n snapToken = resp.NextToken;\n } while (snapToken);\n\n // Build a map: volumeId -> most recent snapshot time\n const latestSnapshotByVolume = new Map<string, number>();\n for (const snap of snapshots) {\n if (!snap.VolumeId || snap.State !== \"completed\") continue;\n const snapTime = snap.StartTime?.getTime() ?? 0;\n const existing = latestSnapshotByVolume.get(snap.VolumeId) ?? 0;\n if (snapTime > existing) {\n latestSnapshotByVolume.set(snap.VolumeId, snapTime);\n }\n }\n\n // Only check in-use volumes for snapshot coverage\n const inUseVolumes = volumes.filter((v) => v.State === \"in-use\");\n resourcesScanned += inUseVolumes.length;\n const now = Date.now();\n\n for (const vol of inUseVolumes) {\n const volId = vol.VolumeId ?? \"unknown\";\n const volArn = `arn:${partition}:ec2:${region}:${accountId}:volume/${volId}`;\n const latestSnap = latestSnapshotByVolume.get(volId);\n\n if (latestSnap === undefined) {\n // No snapshots at all\n findings.push(\n makeFinding({\n riskScore: 7.0,\n title: `EBS volume ${volId} has no snapshots`,\n resourceType: \"AWS::EC2::Volume\",\n resourceId: volId,\n resourceArn: volArn,\n region,\n description: `EBS volume \"${volId}\" (${vol.Size ?? \"?\"}GB, ${vol.VolumeType ?? \"unknown\"}) has no snapshots. Data cannot be recovered if the volume fails.`,\n impact:\n \"Complete data loss if the volume becomes unavailable. No backup exists for disaster recovery.\",\n remediationSteps: [\n \"Create a snapshot of the volume immediately.\",\n \"Set up automated snapshots using AWS Backup or Amazon Data Lifecycle Manager.\",\n ],\n }),\n );\n } else if (now - latestSnap > SEVEN_DAYS_MS) {\n const daysSince = Math.round((now - latestSnap) / (24 * 60 * 60 * 1000));\n findings.push(\n makeFinding({\n riskScore: 5.0,\n title: `EBS volume ${volId} has no recent snapshot (${daysSince} days old)`,\n resourceType: \"AWS::EC2::Volume\",\n resourceId: volId,\n resourceArn: volArn,\n region,\n description: `EBS volume \"${volId}\" (${vol.Size ?? \"?\"}GB) most recent snapshot is ${daysSince} days old, exceeding the 7-day threshold.`,\n impact:\n \"Recovery from the latest snapshot would lose up to ${daysSince} days of data.\",\n remediationSteps: [\n \"Create a fresh snapshot of the volume.\",\n \"Configure automated snapshot schedules using AWS Backup or Data Lifecycle Manager.\",\n ],\n }),\n );\n }\n }\n\n // --- S3 checks ---\n const s3Client = createClient(S3Client, region, ctx.credentials);\n\n let bucketNames: string[] = [];\n try {\n const listResp = await s3Client.send(new ListBucketsCommand({}));\n bucketNames = (listResp.Buckets ?? []).map((b) => b.Name).filter((n): n is string => !!n);\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`S3 bucket list failed: ${msg}`);\n }\n\n resourcesScanned += bucketNames.length;\n\n for (const name of bucketNames) {\n const arn = `arn:${partition}:s3:::${name}`;\n\n // Versioning check\n try {\n const ver = await s3Client.send(\n new GetBucketVersioningCommand({ Bucket: name }),\n );\n if (ver.Status !== \"Enabled\") {\n findings.push(\n makeFinding({\n riskScore: 3.0,\n title: `S3 bucket ${name} does not have versioning enabled`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region,\n description: `Bucket \"${name}\" versioning is ${ver.Status ?? \"not set\"}. Object deletion or overwrite is irreversible.`,\n impact:\n \"Accidental deletion or corruption of objects cannot be recovered without versioning.\",\n remediationSteps: [\n \"Enable versioning on the bucket.\",\n \"Consider adding lifecycle rules to manage version storage costs.\",\n ],\n }),\n );\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Bucket ${name} versioning check failed: ${msg}`);\n }\n\n // Cross-region replication check\n try {\n await s3Client.send(\n new GetBucketReplicationCommand({ Bucket: name }),\n );\n // If the call succeeds, replication is configured — no finding needed\n } catch (e: unknown) {\n if (\n e instanceof Error &&\n e.name === \"ReplicationConfigurationNotFoundError\"\n ) {\n findings.push(\n makeFinding({\n riskScore: 3.5,\n title: `S3 bucket ${name} has no cross-region replication`,\n resourceType: \"AWS::S3::Bucket\",\n resourceId: name,\n resourceArn: arn,\n region,\n description: `Bucket \"${name}\" does not have cross-region replication configured.`,\n impact:\n \"Data is stored in a single region. A regional outage could make the data unavailable.\",\n remediationSteps: [\n \"Enable cross-region replication to a bucket in another region.\",\n \"Ensure versioning is enabled (required for CRR).\",\n \"Consider S3 Replication Time Control for critical data.\",\n ],\n }),\n );\n } else {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(`Bucket ${name} replication check failed: ${msg}`);\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n SecurityHubClient,\n GetFindingsCommand,\n} from \"@aws-sdk/client-securityhub\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\nimport { getSecurityHubSource } from \"../utils/sh-source.js\";\n\nfunction shSeverityToScore(label: string): number | null {\n switch (label) {\n case \"CRITICAL\": return 9.5;\n case \"HIGH\": return 8.0;\n case \"MEDIUM\": return 5.5;\n case \"LOW\": return 3.0;\n case \"INFORMATIONAL\": return null; // skip\n default: return null;\n }\n}\n\nexport class SecurityHubFindingsScanner implements Scanner {\n readonly moduleName = \"security_hub_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n const client = createClient(SecurityHubClient, region, ctx.credentials);\n let nextToken: string | undefined;\n\n do {\n const resp = await client.send(\n new GetFindingsCommand({\n Filters: {\n WorkflowStatus: [\n { Value: \"NEW\", Comparison: \"EQUALS\" },\n { Value: \"NOTIFIED\", Comparison: \"EQUALS\" },\n ],\n RecordState: [{ Value: \"ACTIVE\", Comparison: \"EQUALS\" }],\n },\n MaxResults: 100,\n NextToken: nextToken,\n }),\n );\n\n const shFindings = resp.Findings ?? [];\n resourcesScanned += shFindings.length;\n\n for (const f of shFindings) {\n const severityLabel = f.Severity?.Label ?? \"INFORMATIONAL\";\n const score = shSeverityToScore(severityLabel);\n if (score === null) continue; // skip INFORMATIONAL\n\n const severity = severityFromScore(score);\n const resourceId = f.Resources?.[0]?.Id ?? \"unknown\";\n const resourceType = f.Resources?.[0]?.Type ?? \"AWS::Unknown\";\n const resourceArn = resourceId.startsWith(\"arn:\")\n ? resourceId\n : `arn:${partition}:securityhub:${region}:${accountId}:finding/${f.Id ?? \"unknown\"}`;\n\n const remediationSteps: string[] = [];\n const title = f.Title ?? \"Security Hub Finding\";\n\n // Check if Title is actually informative or just a KB/CVE number\n if (/^KB\\d+$/.test(title)) {\n remediationSteps.push(`Install Windows patch ${title} via WSUS or SSM Patch Manager`);\n remediationSteps.push(`Microsoft KB article: https://support.microsoft.com/help/${title}`);\n } else if (/^CVE-/.test(title)) {\n remediationSteps.push(`Fix vulnerability ${title}: update affected software to patched version`);\n } else {\n remediationSteps.push(title);\n }\n\n // Add documentation URL if available and useful\n if (f.Remediation?.Recommendation?.Url) {\n remediationSteps.push(`Documentation: ${f.Remediation.Recommendation.Url}`);\n }\n\n // Add Recommendation.Text only if it's not generic\n const recText = f.Remediation?.Recommendation?.Text ?? \"\";\n if (recText && ![\"See References\", \"None Provided\", \"\"].includes(recText.trim())) {\n remediationSteps.push(recText);\n }\n\n const finding: Finding = {\n severity,\n title: f.Title ?? \"Security Hub Finding\",\n resourceType,\n resourceId,\n resourceArn,\n region: f.Region ?? region,\n description: f.Description ?? f.Title ?? \"No description\",\n impact: `Source: ${f.ProductName ?? \"Security Hub\"} (${f.GeneratorId ?? \"unknown\"})`,\n riskScore: score,\n remediationSteps,\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId: f.AwsAccountId ?? accountId,\n };\n finding.source = getSecurityHubSource(finding);\n findings.push(finding);\n }\n\n nextToken = resp.NextToken;\n } while (nextToken);\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isNotEnabled =\n (err instanceof Error && err.name === \"InvalidAccessException\") ||\n msg.includes(\"not subscribed\") ||\n msg.includes(\"not enabled\");\n\n if (isNotEnabled) {\n warnings.push(\"Security Hub is not enabled in this region. Enable it to aggregate security findings.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Security Hub findings scan failed: ${msg}`,\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import type { Finding } from \"../types.js\";\n\n/** Extract source sub-category from a Security Hub finding's impact field. */\nexport function getSecurityHubSource(finding: Finding): string {\n const impact = finding.impact ?? \"\";\n const match = impact.match(/^Source:\\s*([^(]+)/);\n if (!match) return \"Other\";\n const product = match[1].trim();\n if (product === \"Security Hub\" || product.includes(\"Foundational\")) return \"FSBP\";\n if (product === \"Inspector\" || product.includes(\"Inspector\")) return \"Inspector\";\n if (product === \"GuardDuty\" || product.includes(\"GuardDuty\")) return \"GuardDuty\";\n if (product === \"Config\" || product.includes(\"Config\")) return \"Config\";\n if (product === \"IAM Access Analyzer\" || product.includes(\"Access Analyzer\")) return \"Access Analyzer\";\n return \"Other\";\n}\n","import {\n GuardDutyClient,\n ListDetectorsCommand,\n} from \"@aws-sdk/client-guardduty\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\n\n/**\n * Detection-only scanner: checks whether GuardDuty is enabled.\n * Actual findings are aggregated via Security Hub.\n */\nexport class GuardDutyFindingsScanner implements Scanner {\n readonly moduleName = \"guardduty_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const warnings: string[] = [];\n\n try {\n const client = createClient(GuardDutyClient, region, ctx.credentials);\n const resp = await client.send(new ListDetectorsCommand({}));\n const detectorIds = resp.DetectorIds ?? [];\n\n if (detectorIds.length === 0) {\n warnings.push(\"GuardDuty is not enabled in this region (no detectors found).\");\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n module: this.moduleName,\n status: \"error\",\n error: `GuardDuty detection check failed: ${msg}`,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n Inspector2Client,\n BatchGetAccountStatusCommand,\n} from \"@aws-sdk/client-inspector2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\n\n/**\n * Detection-only scanner: checks whether Inspector is enabled and which\n * resource scan types (EC2, ECR, Lambda, Lambda Code, Code Repository) are active.\n * Actual findings are aggregated via Security Hub.\n */\nexport class InspectorFindingsScanner implements Scanner {\n readonly moduleName = \"inspector_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const warnings: string[] = [];\n\n try {\n const client = createClient(Inspector2Client, region, ctx.credentials);\n const resp = await client.send(new BatchGetAccountStatusCommand({ accountIds: [] }));\n const account = resp.accounts?.[0];\n\n if (!account || account.state?.status !== \"ENABLED\") {\n warnings.push(\"Inspector is not enabled in this region. Enable it to scan for software vulnerabilities.\");\n } else {\n // Check individual resource scan types\n const rs = account.resourceState;\n const types: Array<{ name: string; status: string | undefined }> = [\n { name: \"EC2\", status: rs?.ec2?.status },\n { name: \"Lambda\", status: rs?.lambda?.status },\n { name: \"ECR\", status: rs?.ecr?.status },\n { name: \"Lambda Code\", status: rs?.lambdaCode?.status },\n { name: \"Code Repository\", status: rs?.codeRepository?.status },\n ];\n const disabled = types.filter((t) => t.status && t.status !== \"ENABLED\");\n if (disabled.length > 0) {\n warnings.push(\n `Inspector scan types not enabled: ${disabled.map((t) => t.name).join(\", \")}. Enable them for full vulnerability coverage.`,\n );\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const errName = err instanceof Error ? err.name : \"\";\n\n const isAccessDenied = errName === \"AccessDeniedException\" || msg.includes(\"AccessDeniedException\");\n if (isAccessDenied) {\n warnings.push(\"Insufficient permissions to access Inspector. Grant inspector2:BatchGetAccountStatus to check enablement.\");\n } else {\n warnings.push(\"Inspector is not enabled in this region. Enable it to scan for software vulnerabilities.\");\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n SupportClient,\n DescribeTrustedAdvisorChecksCommand,\n DescribeTrustedAdvisorCheckResultCommand,\n} from \"@aws-sdk/client-support\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction taStatusToScore(status: string): number | null {\n switch (status) {\n case \"error\": return 8.0; // RED = action required\n case \"warning\": return 5.5; // YELLOW = investigation recommended\n case \"ok\": return null; // GREEN = no issue\n case \"not_available\": return null;\n default: return null;\n }\n}\n\nexport class TrustedAdvisorFindingsScanner implements Scanner {\n readonly moduleName = \"trusted_advisor_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n // Trusted Advisor API endpoint: cn-north-1 for China, us-east-1 for standard\n const supportRegion = region.startsWith(\"cn-\") ? \"cn-north-1\" : \"us-east-1\";\n const clientConfig: any = { region: supportRegion };\n if (ctx.credentials) clientConfig.credentials = ctx.credentials;\n const client = new SupportClient(clientConfig);\n\n // Step 1: List security checks\n const checksResp = await client.send(\n new DescribeTrustedAdvisorChecksCommand({ language: \"en\" }),\n );\n const allChecks = checksResp.checks ?? [];\n const securityChecks = allChecks.filter((c) => c.category === \"security\");\n\n if (securityChecks.length === 0) {\n warnings.push(\"No Trusted Advisor security checks found.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n // Step 2: Get results for each security check\n for (const check of securityChecks) {\n if (!check.id) continue;\n\n try {\n const resultResp = await client.send(\n new DescribeTrustedAdvisorCheckResultCommand({\n checkId: check.id,\n }),\n );\n\n const result = resultResp.result;\n if (!result) continue;\n\n const status = result.status ?? \"not_available\";\n const score = taStatusToScore(status);\n\n resourcesScanned++;\n\n if (score === null) continue; // ok or not_available — skip\n\n // Map flagged resources to findings\n const flaggedResources = result.flaggedResources ?? [];\n\n if (flaggedResources.length === 0) {\n // Check-level finding without specific resources\n const severity = severityFromScore(score);\n findings.push({\n severity,\n title: `[Trusted Advisor] ${check.name ?? \"Security Check\"}`,\n resourceType: \"AWS::TrustedAdvisor::Check\",\n resourceId: check.id,\n resourceArn: `arn:${partition}:trustedadvisor:${region}:${accountId}:check/${check.id}`,\n region,\n description: check.description ?? check.name ?? \"Security check flagged\",\n impact: `Trusted Advisor status: ${status}`,\n riskScore: score,\n remediationSteps: [\n \"Review this Trusted Advisor check in the AWS console.\",\n \"Follow the recommended actions to resolve the flagged issue.\",\n ],\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId,\n });\n continue;\n }\n\n // Create findings for flagged resources (limit to first 25 per check)\n const metadata = check.metadata ?? [];\n for (const fr of flaggedResources.slice(0, 25)) {\n if (fr.isSuppressed) continue;\n\n const severity = severityFromScore(score);\n const resourceMeta = fr.metadata ?? [];\n\n // Try to extract resource ID from metadata\n const resourceIdIdx = metadata.indexOf(\"Resource ID\");\n const regionIdx = metadata.indexOf(\"Region\");\n const flaggedResourceId = resourceIdIdx >= 0 && resourceMeta[resourceIdIdx]\n ? resourceMeta[resourceIdIdx]\n : fr.resourceId ?? \"unknown\";\n const flaggedRegion = regionIdx >= 0 && resourceMeta[regionIdx]\n ? resourceMeta[regionIdx]\n : region;\n\n findings.push({\n severity,\n title: `[Trusted Advisor] ${check.name ?? \"Security Check\"}: ${flaggedResourceId}`,\n resourceType: \"AWS::TrustedAdvisor::FlaggedResource\",\n resourceId: flaggedResourceId,\n resourceArn: `arn:${partition}:trustedadvisor:${flaggedRegion}:${accountId}:check/${check.id}/${fr.resourceId ?? \"unknown\"}`,\n region: flaggedRegion,\n description: `${check.name}: ${resourceMeta.join(\" | \")}`,\n impact: `Trusted Advisor status: ${status} — ${check.name ?? \"security check\"}`,\n riskScore: score,\n remediationSteps: [\n `Review Trusted Advisor check: ${check.name}`,\n \"Follow the recommended actions in the AWS Trusted Advisor console.\",\n ],\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId,\n });\n }\n } catch (checkErr) {\n const checkMsg = checkErr instanceof Error ? checkErr.message : String(checkErr);\n warnings.push(`Trusted Advisor check ${check.name ?? check.id} failed: ${checkMsg}`);\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isSubscriptionRequired =\n msg.includes(\"SubscriptionRequiredException\") ||\n msg.includes(\"subscription\") ||\n msg.includes(\"AWS Premium Support\") ||\n (err instanceof Error && err.name === \"SubscriptionRequiredException\");\n\n if (isSubscriptionRequired) {\n warnings.push(\"Trusted Advisor requires AWS Business or Enterprise Support plan. Skipping.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Trusted Advisor scan failed: ${msg}`,\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n ConfigServiceClient,\n DescribeConfigurationRecordersCommand,\n} from \"@aws-sdk/client-config-service\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\n\n/**\n * Detection-only scanner: checks whether AWS Config is enabled.\n * Actual findings are aggregated via Security Hub.\n */\nexport class ConfigRulesFindingsScanner implements Scanner {\n readonly moduleName = \"config_rules_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const warnings: string[] = [];\n\n try {\n const client = createClient(ConfigServiceClient, region, ctx.credentials);\n const resp = await client.send(new DescribeConfigurationRecordersCommand({}));\n const recorders = resp.ConfigurationRecorders ?? [];\n\n if (recorders.length === 0) {\n warnings.push(\"AWS Config is not enabled in this region.\");\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n\n if (\n msg.includes(\"NoSuchConfigurationRecorder\") ||\n msg.includes(\"InsufficientDeliveryPolicy\") ||\n msg.includes(\"No Configuration Recorder\")\n ) {\n warnings.push(\"AWS Config is not enabled in this region.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Config Rules detection check failed: ${msg}`,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n AccessAnalyzerClient,\n ListAnalyzersCommand,\n} from \"@aws-sdk/client-accessanalyzer\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\n\n/**\n * Detection-only scanner: checks whether IAM Access Analyzer is enabled.\n * Actual findings are aggregated via Security Hub.\n */\nexport class AccessAnalyzerFindingsScanner implements Scanner {\n readonly moduleName = \"access_analyzer_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const warnings: string[] = [];\n\n try {\n const client = createClient(AccessAnalyzerClient, region, ctx.credentials);\n\n let analyzerToken: string | undefined;\n let hasActiveAnalyzer = false;\n\n do {\n const resp = await client.send(\n new ListAnalyzersCommand({ nextToken: analyzerToken }),\n );\n for (const analyzer of resp.analyzers ?? []) {\n if (analyzer.status === \"ACTIVE\") {\n hasActiveAnalyzer = true;\n break;\n }\n }\n if (hasActiveAnalyzer) break;\n analyzerToken = resp.nextToken;\n } while (analyzerToken);\n\n if (!hasActiveAnalyzer) {\n warnings.push(\"No IAM Access Analyzer found. Create an analyzer to detect external access to your resources.\");\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Access Analyzer detection check failed: ${msg}`,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n SSMClient,\n DescribeInstanceInformationCommand,\n DescribeInstancePatchStatesCommand,\n type InstanceInformation,\n type InstancePatchState,\n} from \"@aws-sdk/client-ssm\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nexport class PatchComplianceFindingsScanner implements Scanner {\n readonly moduleName = \"patch_compliance_findings\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n let resourcesScanned = 0;\n\n try {\n const client = createClient(SSMClient, region, ctx.credentials);\n\n // Step 1: Get all managed instances\n let nextToken: string | undefined;\n const instances: InstanceInformation[] = [];\n\n do {\n const resp = await client.send(\n new DescribeInstanceInformationCommand({\n MaxResults: 50,\n NextToken: nextToken,\n }),\n );\n instances.push(...(resp.InstanceInformationList ?? []));\n nextToken = resp.NextToken;\n } while (nextToken);\n\n if (instances.length === 0) {\n warnings.push(\"No SSM-managed instances found in this region.\");\n return {\n module: this.moduleName,\n status: \"success\",\n warnings,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n resourcesScanned = instances.length;\n\n // Step 2: Get patch states in batches\n const instanceIds = instances.map((i) => i.InstanceId).filter(Boolean) as string[];\n const patchStateMap = new Map<string, InstancePatchState>();\n\n // DescribeInstancePatchStates supports up to 50 instances per call\n for (let i = 0; i < instanceIds.length; i += 50) {\n const batch = instanceIds.slice(i, i + 50);\n let patchToken: string | undefined;\n\n do {\n const patchResp = await client.send(\n new DescribeInstancePatchStatesCommand({\n InstanceIds: batch,\n NextToken: patchToken,\n }),\n );\n\n for (const ps of patchResp.InstancePatchStates ?? []) {\n if (ps.InstanceId) {\n patchStateMap.set(ps.InstanceId, ps);\n }\n }\n\n patchToken = patchResp.NextToken;\n } while (patchToken);\n }\n\n // Step 3: Generate findings for instances with missing/failed patches\n for (const instance of instances) {\n const instanceId = instance.InstanceId ?? \"unknown\";\n const platform = instance.PlatformName ?? instance.PlatformType ?? \"unknown\";\n const instanceArn = `arn:${partition}:ec2:${region}:${accountId}:instance/${instanceId}`;\n\n const patchState = patchStateMap.get(instanceId);\n\n if (!patchState) {\n // Instance not managed for patching — INFO-level finding\n const riskScore = 3.0;\n const severity = severityFromScore(riskScore);\n findings.push({\n severity,\n title: `Instance ${instanceId} has no patch compliance data`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instanceId,\n resourceArn: instanceArn,\n region,\n description: `Instance ${instanceId} (${platform}) is managed by SSM but has no patch compliance data. Patch Manager may not be configured for this instance.`,\n impact: \"Patch compliance status is unknown — vulnerabilities may exist.\",\n riskScore,\n remediationSteps: [\n \"Configure AWS Systems Manager Patch Manager for this instance.\",\n \"Create a patch baseline and maintenance window.\",\n \"Run a patch scan to establish compliance status.\",\n ],\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId,\n });\n continue;\n }\n\n const missingCount = patchState.MissingCount ?? 0;\n const failedCount = patchState.FailedCount ?? 0;\n const criticalNonCompliantCount = patchState.CriticalNonCompliantCount ?? 0;\n const securityNonCompliantCount = patchState.SecurityNonCompliantCount ?? 0;\n const otherNonCompliantCount = patchState.OtherNonCompliantCount ?? 0;\n const lastScanTime = patchState.OperationEndTime?.toISOString() ?? \"unknown\";\n\n if (\n missingCount === 0 &&\n failedCount === 0 &&\n criticalNonCompliantCount === 0 &&\n securityNonCompliantCount === 0 &&\n otherNonCompliantCount === 0\n ) {\n continue; // Instance is fully patched\n }\n\n // Determine severity based on patch issues\n let riskScore: number;\n if (criticalNonCompliantCount > 0 || securityNonCompliantCount > 0 || failedCount > 0) {\n riskScore = 7.5; // HIGH — critical/security patches missing or failed\n } else if (otherNonCompliantCount > 0) {\n riskScore = 5.5; // MEDIUM — other non-compliant patches\n } else {\n riskScore = 5.5; // MEDIUM — non-security patches missing\n }\n const severity = severityFromScore(riskScore);\n\n const titleParts: string[] = [];\n if (missingCount > 0) titleParts.push(`${missingCount} missing`);\n if (failedCount > 0) titleParts.push(`${failedCount} failed`);\n if (criticalNonCompliantCount > 0) titleParts.push(`${criticalNonCompliantCount} critical non-compliant`);\n if (securityNonCompliantCount > 0) titleParts.push(`${securityNonCompliantCount} security non-compliant`);\n if (otherNonCompliantCount > 0) titleParts.push(`${otherNonCompliantCount} other non-compliant`);\n\n const descParts = [\n `Instance: ${instanceId}`,\n `Platform: ${platform}`,\n `Missing patches: ${missingCount}`,\n `Failed patches: ${failedCount}`,\n `Critical non-compliant: ${criticalNonCompliantCount}`,\n `Security non-compliant: ${securityNonCompliantCount}`,\n `Other non-compliant: ${otherNonCompliantCount}`,\n `Last scan: ${lastScanTime}`,\n ];\n\n findings.push({\n severity,\n title: `Instance ${instanceId} has ${titleParts.join(\", \")} patches`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instanceId,\n resourceArn: instanceArn,\n region,\n description: descParts.join(\". \"),\n impact: `Instance has ${missingCount} missing and ${failedCount} failed patches — potential security vulnerabilities.`,\n riskScore,\n remediationSteps: [\n `Review patch compliance for instance ${instanceId} in the Systems Manager console.`,\n \"Apply missing patches using a maintenance window or manual patching.\",\n \"Investigate and resolve any failed patch installations.\",\n \"Consider enabling automatic patching through Patch Manager.\",\n ],\n priority: priorityFromSeverity(severity),\n module: this.moduleName,\n accountId,\n });\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n module: this.moduleName,\n status: \"error\",\n error: `Patch compliance scan failed: ${msg}`,\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n EC2Client,\n DescribeInstancesCommand,\n type Instance,\n} from \"@aws-sdk/client-ec2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class Imdsv2EnforcementScanner implements Scanner {\n readonly moduleName = \"imdsv2_enforcement\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region, partition, accountId } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const client = createClient(EC2Client, region, ctx.credentials);\n\n // List all running EC2 instances\n const instances: Instance[] = [];\n let nextToken: string | undefined;\n do {\n const resp = await client.send(\n new DescribeInstancesCommand({\n Filters: [{ Name: \"instance-state-name\", Values: [\"running\"] }],\n NextToken: nextToken,\n }),\n );\n if (resp.Reservations) {\n for (const reservation of resp.Reservations) {\n if (reservation.Instances) {\n instances.push(...reservation.Instances);\n }\n }\n }\n nextToken = resp.NextToken;\n } while (nextToken);\n\n for (const instance of instances) {\n const instanceId = instance.InstanceId ?? \"unknown\";\n const instanceType = instance.InstanceType ?? \"unknown\";\n const state = instance.State?.Name ?? \"unknown\";\n const httpTokens = instance.MetadataOptions?.HttpTokens ?? \"unknown\";\n const hopLimit = instance.MetadataOptions?.HttpPutResponseHopLimit ?? 1;\n const instanceArn = `arn:${partition}:ec2:${region}:${accountId}:instance/${instanceId}`;\n\n if (httpTokens !== \"required\") {\n const description = [\n `EC2 instance ${instanceId} (type: ${instanceType}, state: ${state}) has HttpTokens set to \"${httpTokens}\".`,\n `IMDSv1 is accessible, allowing unauthenticated metadata requests.`,\n ];\n if (hopLimit > 1) {\n description.push(`HttpPutResponseHopLimit is ${hopLimit} (>1), which may allow containers to reach IMDS.`);\n }\n\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `EC2 instance ${instanceId} does not enforce IMDSv2`,\n resourceType: \"AWS::EC2::Instance\",\n resourceId: instanceId,\n resourceArn: instanceArn,\n region,\n description: description.join(\" \"),\n impact: \"IMDSv1 allows attackers to steal IAM role credentials via SSRF attacks\",\n remediationSteps: [\n \"Enforce IMDSv2 by setting HttpTokens to 'required'.\",\n \"Run: aws ec2 modify-instance-metadata-options --instance-id \" + instanceId + \" --http-tokens required --http-endpoint enabled\",\n \"Set HttpPutResponseHopLimit to 1 unless running containers that need metadata access.\",\n \"Update launch templates and Auto Scaling groups to enforce IMDSv2 for new instances.\",\n ],\n }),\n );\n } else if (hopLimit > 1) {\n // IMDSv2 enforced but hop limit is elevated — informational warning\n warnings.push(\n `Instance ${instanceId} enforces IMDSv2 but HttpPutResponseHopLimit is ${hopLimit} (>1). Verify this is intentional for containerized workloads.`,\n );\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: instances.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n return {\n module: this.moduleName,\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import {\n ElasticLoadBalancingV2Client,\n DescribeLoadBalancersCommand,\n type LoadBalancer,\n} from \"@aws-sdk/client-elastic-load-balancing-v2\";\nimport {\n WAFV2Client,\n GetWebACLForResourceCommand,\n} from \"@aws-sdk/client-wafv2\";\nimport { Scanner } from \"./base.js\";\nimport { ScanResult, ScanContext, Finding } from \"../types.js\";\nimport { createClient } from \"../utils/aws-client.js\";\nimport { severityFromScore, priorityFromSeverity } from \"../utils/risk-scoring.js\";\n\nfunction makeFinding(opts: {\n riskScore: number;\n title: string;\n resourceType: string;\n resourceId: string;\n resourceArn: string;\n region: string;\n description: string;\n impact: string;\n remediationSteps: string[];\n}): Finding {\n const severity = severityFromScore(opts.riskScore);\n return { ...opts, severity, priority: priorityFromSeverity(severity) };\n}\n\nexport class WafCoverageScanner implements Scanner {\n readonly moduleName = \"waf_coverage\";\n\n async scan(ctx: ScanContext): Promise<ScanResult> {\n const { region } = ctx;\n const startMs = Date.now();\n const findings: Finding[] = [];\n const warnings: string[] = [];\n\n try {\n const elbClient = createClient(ElasticLoadBalancingV2Client, region, ctx.credentials);\n const wafClient = createClient(WAFV2Client, region, ctx.credentials);\n\n // List all ELBv2 load balancers\n const loadBalancers: LoadBalancer[] = [];\n let marker: string | undefined;\n do {\n const resp = await elbClient.send(\n new DescribeLoadBalancersCommand({ Marker: marker }),\n );\n if (resp.LoadBalancers) {\n loadBalancers.push(...resp.LoadBalancers);\n }\n marker = resp.NextMarker;\n } while (marker);\n\n // Filter to internet-facing only\n const internetFacing = loadBalancers.filter((lb) => lb.Scheme === \"internet-facing\");\n\n for (const lb of internetFacing) {\n const lbName = lb.LoadBalancerName ?? \"unknown\";\n const lbArn = lb.LoadBalancerArn ?? \"unknown\";\n const lbType = lb.Type ?? \"unknown\";\n\n // WAF only applies to ALB (application), not NLB (network) or GLB (gateway)\n if (lbType !== \"application\") {\n warnings.push(\n `Skipping ${lbType} load balancer \"${lbName}\" — WAF Web ACL association is only supported for ALBs.`,\n );\n continue;\n }\n\n try {\n const wafResp = await wafClient.send(\n new GetWebACLForResourceCommand({ ResourceArn: lbArn }),\n );\n\n if (!wafResp.WebACL) {\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `Internet-facing ALB ${lbName} has no WAF protection`,\n resourceType: \"AWS::ElasticLoadBalancingV2::LoadBalancer\",\n resourceId: lbName,\n resourceArn: lbArn,\n region,\n description: `Internet-facing Application Load Balancer \"${lbName}\" does not have a WAF Web ACL associated. Traffic is not inspected for common web exploits.`,\n impact: \"Without WAF, the ALB is exposed to SQL injection, XSS, and other OWASP Top 10 attacks\",\n remediationSteps: [\n \"Create a WAFv2 Web ACL with managed rule groups (e.g., AWSManagedRulesCommonRuleSet).\",\n \"Associate the Web ACL with the ALB using the REGIONAL scope.\",\n \"Enable WAF logging for visibility into blocked requests.\",\n \"Consider adding rate-based rules to mitigate DDoS at the application layer.\",\n ],\n }),\n );\n }\n } catch (wafErr: unknown) {\n const errMsg = wafErr instanceof Error ? wafErr.message : String(wafErr);\n const errName = wafErr instanceof Error ? (wafErr as any).name ?? \"\" : \"\";\n\n // Handle WAFv2 not available or access denied gracefully\n if (errName === \"WAFNonexistentItemException\") {\n // No Web ACL associated — same as null response\n findings.push(\n makeFinding({\n riskScore: 7.5,\n title: `Internet-facing ALB ${lbName} has no WAF protection`,\n resourceType: \"AWS::ElasticLoadBalancingV2::LoadBalancer\",\n resourceId: lbName,\n resourceArn: lbArn,\n region,\n description: `Internet-facing Application Load Balancer \"${lbName}\" does not have a WAF Web ACL associated. Traffic is not inspected for common web exploits.`,\n impact: \"Without WAF, the ALB is exposed to SQL injection, XSS, and other OWASP Top 10 attacks\",\n remediationSteps: [\n \"Create a WAFv2 Web ACL with managed rule groups (e.g., AWSManagedRulesCommonRuleSet).\",\n \"Associate the Web ACL with the ALB using the REGIONAL scope.\",\n \"Enable WAF logging for visibility into blocked requests.\",\n \"Consider adding rate-based rules to mitigate DDoS at the application layer.\",\n ],\n }),\n );\n } else if (errName === \"AccessDeniedException\" || errName === \"WAFInvalidParameterException\") {\n warnings.push(\n `Could not check WAF for ALB \"${lbName}\": ${errMsg}. Ensure wafv2:GetWebACLForResource permission is granted.`,\n );\n } else {\n warnings.push(`Error checking WAF for ALB \"${lbName}\": ${errMsg}`);\n }\n }\n }\n\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: internetFacing.length,\n findingsCount: findings.length,\n scanTimeMs: Date.now() - startMs,\n findings,\n };\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n const errName = err instanceof Error ? (err as any).name ?? \"\" : \"\";\n\n // If WAFv2 or ELBv2 is not available or access denied, return success with warning\n if (errName === \"AccessDeniedException\" || errName === \"UnrecognizedClientException\") {\n return {\n module: this.moduleName,\n status: \"success\",\n warnings: [`WAF coverage check skipped: ${errMsg}`],\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n\n return {\n module: this.moduleName,\n status: \"error\",\n error: errMsg,\n warnings: warnings.length > 0 ? warnings : undefined,\n resourcesScanned: 0,\n findingsCount: 0,\n scanTimeMs: Date.now() - startMs,\n findings: [],\n };\n }\n }\n}\n","import type { I18n } from \"./index.js\";\n\nexport const zhI18n: I18n = {\n // HTML Security Report\n securityReportTitle: \"AWS \\u5b89\\u5168\\u626b\\u63cf\\u62a5\\u544a\",\n securityScore: \"\\u5b89\\u5168\\u8bc4\\u5206\",\n critical: \"\\u4e25\\u91cd\",\n high: \"\\u9ad8\",\n medium: \"\\u4e2d\",\n low: \"\\u4f4e\",\n scanStatistics: \"\\u626b\\u63cf\\u7edf\\u8ba1\",\n module: \"\\u6a21\\u5757\",\n resources: \"\\u8d44\\u6e90\",\n findings: \"\\u53d1\\u73b0\",\n status: \"\\u72b6\\u6001\",\n allFindings: \"\\u6240\\u6709\\u53d1\\u73b0\",\n recommendations: \"\\u5efa\\u8bae\",\n unique: \"\\u53bb\\u91cd\",\n showMore: \"\\u663e\\u793a\\u66f4\\u591a\",\n noIssuesFound: \"\\u672a\\u53d1\\u73b0\\u5b89\\u5168\\u95ee\\u9898\\u3002\",\n allModulesClean: \"\\u6240\\u6709\\u6a21\\u5757\\u6b63\\u5e38\",\n generatedBy: \"\\u7531 AWS Security MCP Server \\u751f\\u6210\",\n informationalOnly: \"\\u672c\\u62a5\\u544a\\u4ec5\\u4f9b\\u53c2\\u8003\\u3002\",\n\n // MLPS Report\n mlpsTitle: \"\\u7b49\\u4fdd\\u4e09\\u7ea7\\u9884\\u68c0\\u62a5\\u544a\",\n mlpsDisclaimer:\n \"\\u672c\\u62a5\\u544a\\u4e3a\\u7b49\\u4fdd\\u4e09\\u7ea7\\u9884\\u68c0\\u53c2\\u8003\\uff0c\\u63d0\\u4f9b\\u4e91\\u5e73\\u53f0\\u914d\\u7f6e\\u68c0\\u67e5\\u6570\\u636e\\u4e0e\\u5efa\\u8bae\\u3002\\u5408\\u89c4\\u5224\\u5b9a\\uff08\\u7b26\\u5408/\\u90e8\\u5206\\u7b26\\u5408/\\u4e0d\\u7b26\\u5408\\uff09\\u9700\\u7531\\u6301\\u8bc1\\u6d4b\\u8bc4\\u673a\\u6784\\u6839\\u636e\\u5b9e\\u9645\\u60c5\\u51b5\\u786e\\u8ba4\\u3002\\uff08GB/T 22239-2019 \\u5b8c\\u6574\\u68c0\\u67e5\\u6e05\\u5355 184 \\u9879\\uff09\",\n checkedItems: \"\\u5df2\\u68c0\\u67e5\\u9879\",\n noIssues: \"\\u672a\\u53d1\\u73b0\\u95ee\\u9898\",\n issuesFound: \"\\u53d1\\u73b0\\u95ee\\u9898\",\n notChecked: \"\\u672a\\u68c0\\u67e5\",\n cloudProvider: \"\\u4e91\\u5e73\\u53f0\\u8d1f\\u8d23\",\n manualReview: \"\\u9700\\u4eba\\u5de5\\u8bc4\\u4f30\",\n notApplicable: \"\\u4e0d\\u9002\\u7528\",\n checkResult: \"\\u68c0\\u67e5\\u7ed3\\u679c\",\n noRelatedIssues: \"\\u68c0\\u67e5\\u7ed3\\u679c\\uff1a\\u672a\\u53d1\\u73b0\\u76f8\\u5173\\u95ee\\u9898\",\n issuesFoundCount: (n: number) =>\n `\\u68c0\\u67e5\\u7ed3\\u679c\\uff1a\\u53d1\\u73b0 ${n} \\u4e2a\\u76f8\\u5173\\u95ee\\u9898`,\n remediation: \"\\u5efa\\u8bae\",\n remediationItems: (n: number) =>\n `\\u5efa\\u8bae\\u6574\\u6539\\u9879\\uff08${n} \\u9879\\u53bb\\u91cd\\uff09`,\n showRemaining: (n: number) => `\\u663e\\u793a\\u5176\\u4f59 ${n} \\u9879`,\n\n // HW Defense Checklist\n hwChecklistTitle:\n \"\\ud83d\\udccb \\u62a4\\u7f51\\u884c\\u52a8\\u8865\\u5145\\u63d0\\u9192\\uff08\\u8d85\\u51fa\\u81ea\\u52a8\\u5316\\u626b\\u63cf\\u8303\\u56f4\\uff09\",\n hwChecklistSubtitle: \"\\u4ee5\\u4e0b\\u4e8b\\u9879\\u9700\\u8981\\u4eba\\u5de5\\u786e\\u8ba4\\u548c\\u6267\\u884c\\uff1a\",\n hwEmergencyIsolation: `\\u26a0\\ufe0f \\u5e94\\u6025\\u9694\\u79bb/\\u6b62\\u8840\\u65b9\\u6848\n \\u25a1 \\u51c6\\u5907\\u4e13\\u7528\\u9694\\u79bb\\u5b89\\u5168\\u7ec4\\uff08\\u65e0 Inbound/Outbound \\u89c4\\u5219\\uff09\n \\u25a1 \\u5236\\u5b9a\\u5b9e\\u4f8b\\u9694\\u79bb SOP\\uff1a\\u544a\\u8b66 \\u2192 \\u6392\\u67e5 \\u2192 \\u5c01\\u9501\\u653b\\u51fbIP \\u2192 \\u7f51\\u7edc\\u9694\\u79bb \\u2192 \\u5b89\\u5168\\u5904\\u7f6e \\u2192 \\u8bb0\\u5f55\\u653b\\u51fb\\u9879\n \\u25a1 \\u660e\\u786e\\u5404\\u7cfb\\u7edf\\uff08\\u751f\\u4ea7\\u6838\\u5fc3/\\u751f\\u4ea7\\u975e\\u6838\\u5fc3/\\u6d4b\\u8bd5/\\u5f00\\u53d1\\uff09\\u7684\\u5e94\\u6025\\u5904\\u7f6e\\u65b9\\u5f0f\n \\u25a1 \\u660e\\u786e\\u5404\\u9879\\u76ee\\u8d26\\u6237\\u53ca\\u8d44\\u6e90\\u7684\\u8d1f\\u8d23\\u4eba\\u4e0e\\u8054\\u7cfb\\u65b9\\u5f0f`,\n hwTestEnvShutdown: `\\u26a0\\ufe0f \\u6d4b\\u8bd5/\\u5f00\\u53d1\\u73af\\u5883\\u5904\\u7f6e\n \\u25a1 \\u975e\\u6838\\u5fc3\\u7cfb\\u7edf\\u5728\\u62a4\\u7f51\\u671f\\u95f4\\u5173\\u95ed\n \\u25a1 \\u6d4b\\u8bd5/\\u5f00\\u53d1\\u73af\\u5883\\u5173\\u95ed\\u6216\\u4e0e\\u751f\\u4ea7\\u4fdd\\u6301\\u540c\\u7b49\\u5b89\\u5168\\u57fa\\u7ebf\n \\u25a1 \\u786e\\u8ba4\\u54ea\\u4e9b\\u73af\\u5883\\u53ef\\u4ee5\\u7d27\\u6025\\u5173\\u505c\\uff0c\\u907f\\u514d\\u653b\\u51fb\\u6269\\u6563`,\n hwDutyTeam: `\\u26a0\\ufe0f \\u503c\\u5b88\\u56e2\\u961f\\u7ec4\\u5efa\n \\u25a1 7\\u00d724 \\u76d1\\u63a7\\u5feb\\u901f\\u54cd\\u5e94\\u56e2\\u961f\n \\u25a1 \\u6280\\u672f\\u4e0e\\u98ce\\u9669\\u5206\\u6790\\u7ec4\n \\u25a1 \\u5b89\\u5168\\u7b56\\u7565\\u4e0b\\u53d1\\u7ec4\n \\u25a1 \\u4e1a\\u52a1\\u54cd\\u5e94\\u7ec4\n \\u25a1 \\u660e\\u786e AWS TAM/Support \\u8054\\u7cfb\\u65b9\\u5f0f\\uff08ES/EOP \\u5ba2\\u6237\\uff09`,\n hwNetworkDiagram: `\\u26a0\\ufe0f \\u51fa\\u5165\\u7ad9\\u8def\\u5f84\\u67b6\\u6784\\u56fe\n \\u25a1 \\u786e\\u4fdd\\u6240\\u6709\\u4e92\\u8054\\u7f51/DX \\u4e13\\u7ebf\\u51fa\\u5165\\u7ad9\\u8def\\u5f84\\u5728\\u67b6\\u6784\\u56fe\\u4e2d\\u6e05\\u6670\\u6807\\u6ce8\n \\u25a1 \\u660e\\u786e\\u5404 ELB/Public EC2/S3/DX \\u7684\\u6570\\u636e\\u6d41\\u5411\n \\u25a1 \\u8bc6\\u522b\\u6240\\u6709\\u9762\\u5411\\u4e92\\u8054\\u7f51\\u7684\\u6570\\u636e\\u4ea4\\u4e92\\u63a5\\u53e3`,\n hwPentest: `\\u26a0\\ufe0f \\u4e3b\\u52a8\\u5f0f\\u6e17\\u900f\\u6d4b\\u8bd5\n \\u25a1 \\u62a4\\u7f51\\u524d\\u8054\\u7cfb\\u5b89\\u5168\\u5382\\u5546\\uff08\\u9752\\u85e4/\\u957f\\u4ead/\\u5fae\\u6b65\\u7b49\\uff09\\u8fdb\\u884c\\u6a21\\u62df\\u653b\\u51fb\\u6f14\\u7ec3\n \\u25a1 \\u57fa\\u4e8e\\u6e17\\u900f\\u6d4b\\u8bd5\\u62a5\\u544a\\u8fdb\\u884c\\u6b63\\u5f0f\\u62a4\\u7f51\\u524d\\u7684\\u5b89\\u5168\\u52a0\\u56fa\n \\u25a1 \\u5173\\u6ce8 AWS \\u5b89\\u5168\\u516c\\u544a\\uff08\\u5df2\\u77e5\\u6f0f\\u6d1e\\u4e0e\\u8865\\u4e01\\uff09`,\n hwWarRoom: `\\u26a0\\ufe0f WAR-ROOM \\u5b9e\\u65f6\\u6c9f\\u901a\n \\u25a1 \\u521b\\u5efa\\u62a4\\u7f51\\u671f\\u95f4\\u4e13\\u7528\\u6c9f\\u901a\\u6e20\\u9053\\uff08\\u4f01\\u5fae/\\u9489\\u9489/\\u98de\\u4e66/Chime\\uff09\n \\u25a1 \\u4e0e AWS TAM \\u5efa\\u7acb WAR-ROOM \\u8054\\u7cfb\\uff08\\u4f01\\u4e1a\\u7ea7\\u652f\\u6301\\u5ba2\\u6237\\uff09\n \\u25a1 \\u7edf\\u4e00\\u6848\\u4f8b\\u6807\\u9898\\u683c\\u5f0f\\uff1a\\u201c\\u3010\\u62a4\\u7f51\\u3011+ \\u95ee\\u9898\\u63cf\\u8ff0\\u201d`,\n hwCredentials: `\\u26a0\\ufe0f \\u5bc6\\u7801\\u4e0e\\u51ed\\u8bc1\\u7ba1\\u7406\n \\u25a1 \\u6240\\u6709 IAM \\u7528\\u6237\\u7ed1\\u5b9a MFA\n \\u25a1 AKSK \\u8f6e\\u8f6c\\u5468\\u671f \\u2264 90 \\u5929\n \\u25a1 \\u907f\\u514d\\u5171\\u4eab\\u8d26\\u6237\\u4f7f\\u7528\n \\u25a1 S3/Lambda/\\u5e94\\u7528\\u4ee3\\u7801\\u4e2d\\u65e0\\u660e\\u6587\\u5bc6\\u7801`,\n hwPostOptimization: `\\u26a0\\ufe0f \\u62a4\\u7f51\\u540e\\u4f18\\u5316\n \\u25a1 \\u9488\\u5bf9\\u653b\\u51fb\\u62a5\\u544a\\u9010\\u9879\\u5e94\\u7b54\\u4e0e\\u4fee\\u590d\n \\u25a1 \\u4e0e\\u5b89\\u5168\\u56e2\\u961f\\u5efa\\u7acb\\u5468\\u671f\\u6027\\u5b89\\u5168\\u7ef4\\u62a4\\u6d41\\u7a0b\n \\u25a1 \\u6301\\u7eed\\u8865\\u5168\\u5b89\\u5168\\u98ce\\u9669`,\n hwReference:\n \"\\u53c2\\u8003\\uff1aAWS \\u62a4\\u7f51\\u884c\\u52a8 Standard Operation Procedure (Compliance IEM)\",\n\n // Service Reminders\n serviceReminderTitle:\n \"\\u26a1 \\u4ee5\\u4e0b\\u5b89\\u5168\\u670d\\u52a1\\u672a\\u542f\\u7528\\uff0c\\u90e8\\u5206\\u68c0\\u67e5\\u65e0\\u6cd5\\u6267\\u884c\\uff1a\",\n serviceReminderFooter:\n \"\\u542f\\u7528\\u4ee5\\u4e0a\\u670d\\u52a1\\u540e\\u91cd\\u65b0\\u626b\\u63cf\\u53ef\\u83b7\\u5f97\\u66f4\\u5b8c\\u6574\\u7684\\u5b89\\u5168\\u8bc4\\u4f30\\u3002\",\n serviceImpact: \"\\u5f71\\u54cd\",\n serviceAction: \"\\u5efa\\u8bae\",\n\n // Common\n account: \"\\u8d26\\u6237\",\n region: \"\\u533a\\u57df\",\n scanTime: \"\\u626b\\u63cf\\u65f6\\u95f4\",\n duration: \"\\u8017\\u65f6\",\n severityDistribution: \"\\u4e25\\u91cd\\u6027\\u5206\\u5e03\",\n findingsByModule: \"\\u6309\\u6a21\\u5757\\u5206\\u7c7b\\u7684\\u53d1\\u73b0\",\n details: \"\\u8be6\\u60c5\",\n\n // Extended — HTML Security Report extras\n topHighestRiskFindings: (n: number) =>\n `\\u524d ${n} \\u9879\\u6700\\u9ad8\\u98ce\\u9669\\u53d1\\u73b0`,\n resource: \"\\u8d44\\u6e90\",\n impact: \"\\u5f71\\u54cd\",\n riskScore: \"\\u98ce\\u9669\\u8bc4\\u5206\",\n showRemainingFindings: (n: number) =>\n `\\u663e\\u793a\\u5269\\u4f59 ${n} \\u9879\\u53d1\\u73b0\\u2026`,\n trendTitle: \"30\\u65e5\\u8d8b\\u52bf\",\n findingsBySeverity: \"\\u6309\\u4e25\\u91cd\\u6027\\u5206\\u7c7b\\u7684\\u53d1\\u73b0\",\n showMoreCount: (n: number) =>\n `\\u663e\\u793a\\u5269\\u4f59 ${n} \\u9879\\u2026`,\n\n // Filter toolbar\n filterSeverity: \"\\u4e25\\u91cd\\u6027\\uff1a\",\n filterModule: \"\\u6a21\\u5757\\uff1a\",\n filterAll: \"\\u5168\\u90e8\",\n filterAllModules: \"\\u5168\\u90e8\\u6a21\\u5757\",\n filterCountTpl: \"\\u663e\\u793a {shown} / {total} \\u4e2a\\u53d1\\u73b0\",\n\n // Extended — MLPS extras\n // Markdown report\n executiveSummary: \"\\u6267\\u884c\\u6458\\u8981\",\n totalFindingsLabel: \"\\u53d1\\u73b0\\u603b\\u6570\",\n description: \"\\u63cf\\u8ff0\",\n priority: \"\\u4f18\\u5148\\u7ea7\",\n noFindingsForSeverity: (severity: string) => `\\u65e0${severity}\\u53d1\\u73b0\\u3002`,\n\n preCheckOverview: \"\\u9884\\u68c0\\u603b\\u89c8\",\n accountInfo: \"\\u8d26\\u6237\\u4fe1\\u606f\",\n checkedCount: (total: number, clean: number, issues: number) =>\n `\\u5df2\\u68c0\\u67e5: ${total} \\u9879\\uff08\\u672a\\u53d1\\u73b0\\u95ee\\u9898: ${clean} \\u9879 | \\u53d1\\u73b0\\u95ee\\u9898: ${issues} \\u9879\\uff09`,\n uncheckedCount: (n: number) =>\n `\\u672a\\u68c0\\u67e5: ${n} \\u9879\\uff08\\u5bf9\\u5e94\\u626b\\u63cf\\u6a21\\u5757\\u672a\\u8fd0\\u884c\\uff09`,\n cloudProviderCount: (n: number) => `\\u4e91\\u5e73\\u53f0\\u8d1f\\u8d23: ${n} \\u9879`,\n manualReviewCount: (n: number) => `\\u9700\\u4eba\\u5de5\\u8bc4\\u4f30: ${n} \\u9879`,\n naCount: (n: number) => `\\u4e0d\\u9002\\u7528: ${n} \\u9879`,\n naNote: (n: number) =>\n `\\u4e0d\\u9002\\u7528\\u9879: ${n} \\u9879\\uff08\\u7269\\u8054\\u7f51/\\u65e0\\u7ebf\\u7f51\\u7edc/\\u79fb\\u52a8\\u7ec8\\u7aef/\\u5de5\\u63a7\\u7cfb\\u7edf/\\u53ef\\u4fe1\\u9a8c\\u8bc1\\u7b49\\uff09`,\n unknownNote: (n: number) =>\n `\\uff08${n} \\u9879\\u672a\\u68c0\\u67e5\\uff0c\\u5bf9\\u5e94\\u626b\\u63cf\\u6a21\\u5757\\u672a\\u8fd0\\u884c\\uff09`,\n cloudItemsNote: (n: number) =>\n `\\u4ee5\\u4e0b ${n} \\u9879\\u7531 AWS \\u4e91\\u5e73\\u53f0\\u8d1f\\u8d23\\uff0c\\u6839\\u636e\\u5b89\\u5168\\u8d23\\u4efb\\u5171\\u62c5\\u6a21\\u578b\\u4e0d\\u5728\\u672c\\u62a5\\u544a\\u68c0\\u67e5\\u8303\\u56f4\\u5185\\u3002`,\n mlpsFooterGenerated: (version: string) =>\n `\\u7531 AWS Security MCP Server v${version} \\u751f\\u6210`,\n mlpsFooterDisclaimer:\n \"\\u672c\\u62a5\\u544a\\u4e3a\\u8bc1\\u636e\\u6536\\u96c6\\u53c2\\u8003\\uff0c\\u4e0d\\u5305\\u542b\\u5408\\u89c4\\u5224\\u5b9a\\u3002\\u5b8c\\u6574\\u7b49\\u4fdd\\u6d4b\\u8bc4\\u9700\\u7531\\u6301\\u8bc1\\u6d4b\\u8bc4\\u673a\\u6784\\u6267\\u884c\\u3002\",\n andMore: (n: number) => `... \\u53ca\\u5176\\u4ed6 ${n} \\u9879`,\n remediationByPriority:\n \"\\u5efa\\u8bae\\u6574\\u6539\\u9879\\uff08\\u6309\\u4f18\\u5148\\u7ea7\\uff09\",\n affectedResources: (n: number) => `\\u6d89\\u53ca ${n} \\u4e2a\\u8d44\\u6e90`,\n installWindowsPatches: (n: number, kbs: string) => `\\u5b89\\u88c5 ${n} \\u4e2a Windows \\u8865\\u4e01 (${kbs})`,\n mlpsCategorySection: {\n \"\\u5b89\\u5168\\u7269\\u7406\\u73af\\u5883\": \"\\u4e00\\u3001\\u5b89\\u5168\\u7269\\u7406\\u73af\\u5883\",\n \"\\u5b89\\u5168\\u901a\\u4fe1\\u7f51\\u7edc\": \"\\u4e8c\\u3001\\u5b89\\u5168\\u901a\\u4fe1\\u7f51\\u7edc\",\n \"\\u5b89\\u5168\\u533a\\u57df\\u8fb9\\u754c\": \"\\u4e09\\u3001\\u5b89\\u5168\\u533a\\u57df\\u8fb9\\u754c\",\n \"\\u5b89\\u5168\\u8ba1\\u7b97\\u73af\\u5883\": \"\\u56db\\u3001\\u5b89\\u5168\\u8ba1\\u7b97\\u73af\\u5883\",\n \"\\u5b89\\u5168\\u7ba1\\u7406\\u4e2d\\u5fc3\": \"\\u4e94\\u3001\\u5b89\\u5168\\u7ba1\\u7406\\u4e2d\\u5fc3\",\n },\n\n // Module display names\n moduleNames: {\n service_detection: \"安全服务检测\",\n secret_exposure: \"密钥暴露\",\n ssl_certificate: \"SSL 证书\",\n dns_dangling: \"悬挂 DNS\",\n network_reachability: \"网络可达性\",\n iam_privilege_escalation: \"IAM 提权分析\",\n public_access_verify: \"公网访问验证\",\n tag_compliance: \"标签合规\",\n idle_resources: \"闲置资源\",\n disaster_recovery: \"灾备评估\",\n security_hub_findings: \"Security Hub\",\n guardduty_findings: \"GuardDuty\",\n inspector_findings: \"Inspector\",\n trusted_advisor_findings: \"Trusted Advisor\",\n config_rules_findings: \"Config Rules\",\n access_analyzer_findings: \"Access Analyzer\",\n patch_compliance_findings: \"补丁合规\",\n imdsv2_enforcement: \"IMDSv2 强制\",\n waf_coverage: \"WAF 覆盖\",\n // Security Hub sub-categories\n \"sh:FSBP\": \"安全最佳实践\",\n \"sh:Inspector\": \"软件漏洞\",\n \"sh:GuardDuty\": \"威胁检测\",\n \"sh:Config\": \"配置合规\",\n \"sh:Access Analyzer\": \"外部访问\",\n \"sh:Other\": \"其他安全发现\",\n },\n\n // Security Hub sub-categories\n securityHubSubCategories: {\n FSBP: { label: \"安全最佳实践\" },\n Inspector: { label: \"软件漏洞\" },\n GuardDuty: { label: \"威胁检测\" },\n Config: { label: \"配置合规\" },\n \"Access Analyzer\": { label: \"外部访问\" },\n Other: { label: \"其他安全发现\" },\n },\n\n // Service Recommendations\n notEnabled: \"\\u672a\\u542f\\u7528\",\n serviceRecommendations: {\n security_hub_findings: {\n icon: \"\\ud83d\\udd34\",\n service: \"Security Hub\",\n impact:\n \"\\u65e0\\u6cd5\\u83b7\\u53d6 300+ \\u9879\\u81ea\\u52a8\\u5316\\u5b89\\u5168\\u68c0\\u67e5\\uff08FSBP/CIS/PCI DSS \\u6807\\u51c6\\uff09\",\n action:\n \"\\u542f\\u7528 Security Hub \\u83b7\\u5f97\\u6700\\u5168\\u9762\\u7684\\u5b89\\u5168\\u6001\\u52bf\\u8bc4\\u4f30\",\n },\n guardduty_findings: {\n icon: \"\\ud83d\\udd34\",\n service: \"GuardDuty\",\n impact:\n \"\\u65e0\\u6cd5\\u68c0\\u6d4b\\u5a01\\u80c1\\u6d3b\\u52a8\\uff08\\u6076\\u610f IP\\u3001\\u5f02\\u5e38 API \\u8c03\\u7528\\u3001\\u52a0\\u5bc6\\u8d27\\u5e01\\u6316\\u77ff\\u7b49\\uff09\",\n action:\n \"\\u542f\\u7528 GuardDuty \\u83b7\\u5f97\\u6301\\u7eed\\u5a01\\u80c1\\u68c0\\u6d4b\\u80fd\\u529b\",\n },\n inspector_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"Inspector\",\n impact:\n \"\\u65e0\\u6cd5\\u626b\\u63cf EC2/Lambda/\\u5bb9\\u5668\\u7684\\u8f6f\\u4ef6\\u6f0f\\u6d1e\\uff08CVE\\uff09\",\n action:\n \"\\u542f\\u7528 Inspector \\u53d1\\u73b0\\u5df2\\u77e5\\u5b89\\u5168\\u6f0f\\u6d1e\",\n },\n trusted_advisor_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"Trusted Advisor\",\n impact:\n \"\\u65e0\\u6cd5\\u83b7\\u53d6 AWS \\u6700\\u4f73\\u5b9e\\u8df5\\u5b89\\u5168\\u68c0\\u67e5\",\n action:\n \"\\u5347\\u7ea7\\u81f3 Business/Enterprise Support \\u8ba1\\u5212\\u4ee5\\u4f7f\\u7528 Trusted Advisor \\u5b89\\u5168\\u68c0\\u67e5\",\n },\n config_rules_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"AWS Config\",\n impact:\n \"\\u65e0\\u6cd5\\u68c0\\u67e5\\u8d44\\u6e90\\u914d\\u7f6e\\u5408\\u89c4\\u72b6\\u6001\",\n action:\n \"\\u542f\\u7528 AWS Config \\u5e76\\u914d\\u7f6e Config Rules\",\n },\n access_analyzer_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"IAM Access Analyzer\",\n impact:\n \"\\u65e0\\u6cd5\\u68c0\\u6d4b\\u8d44\\u6e90\\u662f\\u5426\\u88ab\\u5916\\u90e8\\u8d26\\u53f7\\u6216\\u516c\\u7f51\\u8bbf\\u95ee\",\n action:\n \"\\u521b\\u5efa IAM Access Analyzer\\uff08\\u8d26\\u6237\\u7ea7\\u6216\\u7ec4\\u7ec7\\u7ea7\\uff09\",\n },\n patch_compliance_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"SSM Patch Manager\",\n impact:\n \"\\u65e0\\u6cd5\\u68c0\\u67e5\\u5b9e\\u4f8b\\u8865\\u4e01\\u5408\\u89c4\\u72b6\\u6001\",\n action:\n \"\\u5b89\\u88c5 SSM Agent \\u5e76\\u914d\\u7f6e Patch Manager\",\n },\n },\n\n // HW Defense HTML Report\n hwReportTitle: \"护网蓝队安全评估报告\",\n hwAutoCheck: \"自动化检查\",\n hwManualCheck: \"人工确认事项\",\n hwNoAutoCheck: \"此项无自动化检查\",\n hwClean: \"未发现问题\",\n hwTotalFindings: \"发现总数\",\n hwSectionsChecked: \"检查分类\",\n hwAutoVerified: \"自动验证\",\n hwManualPending: \"人工待确认\",\n hwManualCount: (n: number) => `${n} 项人工确认`,\n hwAffectedResources: (n: number) => `查看受影响资源 (${n})`,\n hwRemediation: \"修复建议\",\n hwSectionNames: {\n attack_surface: { name: \"攻击面收敛\", icon: \"🎯\" },\n vulnerability_patch: { name: \"漏洞与补丁管理\", icon: \"🩹\" },\n identity_credential: { name: \"身份与凭证安全\", icon: \"🔑\" },\n transport_security: { name: \"传输与实例安全\", icon: \"🔒\" },\n security_services: { name: \"安全服务状态\", icon: \"🛡️\" },\n emergency_response: { name: \"应急响应准备\", icon: \"🚨\" },\n environment_control: { name: \"环境处置\", icon: \"🏗️\" },\n post_review: { name: \"护网后优化\", icon: \"📊\" },\n },\n hwManualItems: {\n attack_surface: [\"绘制出入站路径架构图,标注所有互联网/DX专线出入站路径\"],\n vulnerability_patch: [\"联系安全厂商进行模拟攻击演练(渗透测试)\", \"关注 AWS 安全公告(已知漏洞与补丁)\"],\n identity_credential: [\"所有 IAM 用户绑定 MFA\", \"AKSK 轮转周期 ≤ 90 天\", \"避免共享账户使用\", \"S3/Lambda/应用代码中无明文密码\"],\n transport_security: [\"确认所有对外服务使用 TLS 1.2+\", \"检查内部服务间通信是否加密\"],\n security_services: [\"确认 Security Hub 已开启并配置标准\", \"确认 GuardDuty 已在所有区域开启\", \"确认 CloudTrail 多区域日志记录已开启\", \"确认 Config Rules 已配置\"],\n emergency_response: [\"准备专用隔离安全组(无 Inbound/Outbound 规则)\", \"制定实例隔离 SOP:告警 → 排查 → 封锁攻击IP → 网络隔离 → 安全处置 → 记录攻击项\", \"组建 7×24 监控快速响应团队\", \"创建护网期间专用沟通渠道(企微/钉钉/飞书/Chime)\", \"与 AWS TAM 建立 WAR-ROOM 联系(企业级支持客户)\"],\n environment_control: [\"非核心系统在护网期间关闭\", \"测试/开发环境关闭或与生产保持同等安全基线\", \"确认哪些环境可以紧急关停,避免攻击扩散\"],\n post_review: [\"针对攻击报告逐项应答与修复\", \"与安全团队建立周期性安全维护流程\", \"持续补全安全风险\"],\n },\n\n // HW Checklist (full composite)\n hwChecklist: `\n\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\n\\ud83d\\udccb \\u62a4\\u7f51\\u884c\\u52a8\\u8865\\u5145\\u63d0\\u9192\\uff08\\u8d85\\u51fa\\u81ea\\u52a8\\u5316\\u626b\\u63cf\\u8303\\u56f4\\uff09\n\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\n\n\\u4ee5\\u4e0b\\u4e8b\\u9879\\u9700\\u8981\\u4eba\\u5de5\\u786e\\u8ba4\\u548c\\u6267\\u884c\\uff1a\n\n\\u26a0\\ufe0f \\u5e94\\u6025\\u9694\\u79bb/\\u6b62\\u8840\\u65b9\\u6848\n \\u25a1 \\u51c6\\u5907\\u4e13\\u7528\\u9694\\u79bb\\u5b89\\u5168\\u7ec4\\uff08\\u65e0 Inbound/Outbound \\u89c4\\u5219\\uff09\n \\u25a1 \\u5236\\u5b9a\\u5b9e\\u4f8b\\u9694\\u79bb SOP\\uff1a\\u544a\\u8b66 \\u2192 \\u6392\\u67e5 \\u2192 \\u5c01\\u9501\\u653b\\u51fbIP \\u2192 \\u7f51\\u7edc\\u9694\\u79bb \\u2192 \\u5b89\\u5168\\u5904\\u7f6e \\u2192 \\u8bb0\\u5f55\\u653b\\u51fb\\u9879\n \\u25a1 \\u660e\\u786e\\u5404\\u7cfb\\u7edf\\uff08\\u751f\\u4ea7\\u6838\\u5fc3/\\u751f\\u4ea7\\u975e\\u6838\\u5fc3/\\u6d4b\\u8bd5/\\u5f00\\u53d1\\uff09\\u7684\\u5e94\\u6025\\u5904\\u7f6e\\u65b9\\u5f0f\n \\u25a1 \\u660e\\u786e\\u5404\\u9879\\u76ee\\u8d26\\u6237\\u53ca\\u8d44\\u6e90\\u7684\\u8d1f\\u8d23\\u4eba\\u4e0e\\u8054\\u7cfb\\u65b9\\u5f0f\n\n\\u26a0\\ufe0f \\u6d4b\\u8bd5/\\u5f00\\u53d1\\u73af\\u5883\\u5904\\u7f6e\n \\u25a1 \\u975e\\u6838\\u5fc3\\u7cfb\\u7edf\\u5728\\u62a4\\u7f51\\u671f\\u95f4\\u5173\\u95ed\n \\u25a1 \\u6d4b\\u8bd5/\\u5f00\\u53d1\\u73af\\u5883\\u5173\\u95ed\\u6216\\u4e0e\\u751f\\u4ea7\\u4fdd\\u6301\\u540c\\u7b49\\u5b89\\u5168\\u57fa\\u7ebf\n \\u25a1 \\u786e\\u8ba4\\u54ea\\u4e9b\\u73af\\u5883\\u53ef\\u4ee5\\u7d27\\u6025\\u5173\\u505c\\uff0c\\u907f\\u514d\\u653b\\u51fb\\u6269\\u6563\n\n\\u26a0\\ufe0f \\u503c\\u5b88\\u56e2\\u961f\\u7ec4\\u5efa\n \\u25a1 7\\u00d724 \\u76d1\\u63a7\\u5feb\\u901f\\u54cd\\u5e94\\u56e2\\u961f\n \\u25a1 \\u6280\\u672f\\u4e0e\\u98ce\\u9669\\u5206\\u6790\\u7ec4\n \\u25a1 \\u5b89\\u5168\\u7b56\\u7565\\u4e0b\\u53d1\\u7ec4\n \\u25a1 \\u4e1a\\u52a1\\u54cd\\u5e94\\u7ec4\n \\u25a1 \\u660e\\u786e AWS TAM/Support \\u8054\\u7cfb\\u65b9\\u5f0f\\uff08ES/EOP \\u5ba2\\u6237\\uff09\n\n\\u26a0\\ufe0f \\u51fa\\u5165\\u7ad9\\u8def\\u5f84\\u67b6\\u6784\\u56fe\n \\u25a1 \\u786e\\u4fdd\\u6240\\u6709\\u4e92\\u8054\\u7f51/DX \\u4e13\\u7ebf\\u51fa\\u5165\\u7ad9\\u8def\\u5f84\\u5728\\u67b6\\u6784\\u56fe\\u4e2d\\u6e05\\u6670\\u6807\\u6ce8\n \\u25a1 \\u660e\\u786e\\u5404 ELB/Public EC2/S3/DX \\u7684\\u6570\\u636e\\u6d41\\u5411\n \\u25a1 \\u8bc6\\u522b\\u6240\\u6709\\u9762\\u5411\\u4e92\\u8054\\u7f51\\u7684\\u6570\\u636e\\u4ea4\\u4e92\\u63a5\\u53e3\n\n\\u26a0\\ufe0f \\u4e3b\\u52a8\\u5f0f\\u6e17\\u900f\\u6d4b\\u8bd5\n \\u25a1 \\u62a4\\u7f51\\u524d\\u8054\\u7cfb\\u5b89\\u5168\\u5382\\u5546\\uff08\\u9752\\u85e4/\\u957f\\u4ead/\\u5fae\\u6b65\\u7b49\\uff09\\u8fdb\\u884c\\u6a21\\u62df\\u653b\\u51fb\\u6f14\\u7ec3\n \\u25a1 \\u57fa\\u4e8e\\u6e17\\u900f\\u6d4b\\u8bd5\\u62a5\\u544a\\u8fdb\\u884c\\u6b63\\u5f0f\\u62a4\\u7f51\\u524d\\u7684\\u5b89\\u5168\\u52a0\\u56fa\n \\u25a1 \\u5173\\u6ce8 AWS \\u5b89\\u5168\\u516c\\u544a\\uff08\\u5df2\\u77e5\\u6f0f\\u6d1e\\u4e0e\\u8865\\u4e01\\uff09\n\n\\u26a0\\ufe0f WAR-ROOM \\u5b9e\\u65f6\\u6c9f\\u901a\n \\u25a1 \\u521b\\u5efa\\u62a4\\u7f51\\u671f\\u95f4\\u4e13\\u7528\\u6c9f\\u901a\\u6e20\\u9053\\uff08\\u4f01\\u5fae/\\u9489\\u9489/\\u98de\\u4e66/Chime\\uff09\n \\u25a1 \\u4e0e AWS TAM \\u5efa\\u7acb WAR-ROOM \\u8054\\u7cfb\\uff08\\u4f01\\u4e1a\\u7ea7\\u652f\\u6301\\u5ba2\\u6237\\uff09\n \\u25a1 \\u7edf\\u4e00\\u6848\\u4f8b\\u6807\\u9898\\u683c\\u5f0f\\uff1a\\u201c\\u3010\\u62a4\\u7f51\\u3011+ \\u95ee\\u9898\\u63cf\\u8ff0\\u201d\n\n\\u26a0\\ufe0f \\u5bc6\\u7801\\u4e0e\\u51ed\\u8bc1\\u7ba1\\u7406\n \\u25a1 \\u6240\\u6709 IAM \\u7528\\u6237\\u7ed1\\u5b9a MFA\n \\u25a1 AKSK \\u8f6e\\u8f6c\\u5468\\u671f \\u2264 90 \\u5929\n \\u25a1 \\u907f\\u514d\\u5171\\u4eab\\u8d26\\u6237\\u4f7f\\u7528\n \\u25a1 S3/Lambda/\\u5e94\\u7528\\u4ee3\\u7801\\u4e2d\\u65e0\\u660e\\u6587\\u5bc6\\u7801\n\n\\u26a0\\ufe0f \\u62a4\\u7f51\\u540e\\u4f18\\u5316\n \\u25a1 \\u9488\\u5bf9\\u653b\\u51fb\\u62a5\\u544a\\u9010\\u9879\\u5e94\\u7b54\\u4e0e\\u4fee\\u590d\n \\u25a1 \\u4e0e\\u5b89\\u5168\\u56e2\\u961f\\u5efa\\u7acb\\u5468\\u671f\\u6027\\u5b89\\u5168\\u7ef4\\u62a4\\u6d41\\u7a0b\n \\u25a1 \\u6301\\u7eed\\u8865\\u5168\\u5b89\\u5168\\u98ce\\u9669\n\n\\u53c2\\u8003\\uff1aAWS \\u62a4\\u7f51\\u884c\\u52a8 Standard Operation Procedure (Compliance IEM)\n`,\n};\n","import type { I18n } from \"./index.js\";\n\nexport const enI18n: I18n = {\n // HTML Security Report\n securityReportTitle: \"AWS Security Scan Report\",\n securityScore: \"Security Score\",\n critical: \"Critical\",\n high: \"High\",\n medium: \"Medium\",\n low: \"Low\",\n scanStatistics: \"Scan Statistics\",\n module: \"Module\",\n resources: \"Resources\",\n findings: \"Findings\",\n status: \"Status\",\n allFindings: \"All Findings\",\n recommendations: \"Recommendations\",\n unique: \"unique\",\n showMore: \"Show more\",\n noIssuesFound: \"No security issues found.\",\n allModulesClean: \"All modules clean\",\n generatedBy: \"Generated by AWS Security MCP Server\",\n informationalOnly: \"This report is for informational purposes only.\",\n\n // MLPS Report\n mlpsTitle: \"MLPS Level 3 Pre-Check Report\",\n mlpsDisclaimer:\n \"This report is for MLPS Level 3 pre-check reference, providing cloud platform configuration check data and recommendations. Compliance determination (compliant/partially compliant/non-compliant) must be confirmed by a certified assessment institution. (GB/T 22239-2019 full checklist: 184 items)\",\n checkedItems: \"Checked Items\",\n noIssues: \"No Issues Found\",\n issuesFound: \"Issues Found\",\n notChecked: \"Not Checked\",\n cloudProvider: \"Cloud Provider Responsible\",\n manualReview: \"Manual Review Required\",\n notApplicable: \"Not Applicable\",\n checkResult: \"Check Result\",\n noRelatedIssues: \"Check Result: No related issues found\",\n issuesFoundCount: (n: number) =>\n `Check Result: Found ${n} related issue${n === 1 ? \"\" : \"s\"}`,\n remediation: \"Remediation\",\n remediationItems: (n: number) =>\n `Remediation Items (${n} unique)`,\n showRemaining: (n: number) => `Show remaining ${n} items`,\n\n // HW Defense Checklist\n hwChecklistTitle:\n \"\\ud83d\\udccb Cyber Defense Drill Supplementary Reminders (Beyond Automated Scanning)\",\n hwChecklistSubtitle:\n \"The following items require manual verification and execution:\",\n hwEmergencyIsolation: `\\u26a0\\ufe0f Emergency Isolation / Incident Response Plan\n \\u25a1 Prepare dedicated isolation security groups (no Inbound/Outbound rules)\n \\u25a1 Establish instance isolation SOP: Alert \\u2192 Investigate \\u2192 Block attacker IP \\u2192 Network isolation \\u2192 Security response \\u2192 Log attack details\n \\u25a1 Define emergency response procedures for each system (production core/non-core/test/dev)\n \\u25a1 Identify responsible personnel and contacts for each project account and resource`,\n hwTestEnvShutdown: `\\u26a0\\ufe0f Test/Development Environment Handling\n \\u25a1 Shut down non-critical systems during the drill period\n \\u25a1 Shut down test/dev environments or maintain same security baseline as production\n \\u25a1 Confirm which environments can be emergency-stopped to prevent attack propagation`,\n hwDutyTeam: `\\u26a0\\ufe0f On-Duty Team Formation\n \\u25a1 7\\u00d724 monitoring and rapid response team\n \\u25a1 Technical and risk analysis team\n \\u25a1 Security policy deployment team\n \\u25a1 Business response team\n \\u25a1 Confirm AWS TAM/Support contact information (ES/EOP customers)`,\n hwNetworkDiagram: `\\u26a0\\ufe0f Ingress/Egress Path Architecture Diagram\n \\u25a1 Ensure all Internet/DX dedicated line ingress/egress paths are clearly marked in architecture diagrams\n \\u25a1 Clarify data flow for each ELB/Public EC2/S3/DX\n \\u25a1 Identify all internet-facing data interaction interfaces`,\n hwPentest: `\\u26a0\\ufe0f Proactive Penetration Testing\n \\u25a1 Contact security vendors for simulated attack drills before the exercise\n \\u25a1 Conduct security hardening based on penetration test reports\n \\u25a1 Monitor AWS security advisories (known vulnerabilities and patches)`,\n hwWarRoom: `\\u26a0\\ufe0f WAR-ROOM Real-Time Communication\n \\u25a1 Create dedicated communication channels for the drill period (Teams/Slack/Chime)\n \\u25a1 Establish WAR-ROOM connection with AWS TAM (Enterprise Support customers)\n \\u25a1 Standardize case title format: \"[CyberDrill] + Issue Description\"`,\n hwCredentials: `\\u26a0\\ufe0f Password & Credential Management\n \\u25a1 All IAM users must have MFA enabled\n \\u25a1 Access key rotation cycle \\u2264 90 days\n \\u25a1 Avoid shared account usage\n \\u25a1 No plaintext passwords in S3/Lambda/application code`,\n hwPostOptimization: `\\u26a0\\ufe0f Post-Drill Optimization\n \\u25a1 Address and remediate each item from the attack report\n \\u25a1 Establish periodic security maintenance processes with the security team\n \\u25a1 Continuously fill security risk gaps`,\n hwReference:\n \"Reference: AWS Cyber Defense Drill Standard Operation Procedure (Compliance IEM)\",\n\n // Service Reminders\n serviceReminderTitle:\n \"\\u26a1 The following security services are not enabled; some checks cannot be performed:\",\n serviceReminderFooter:\n \"Re-scan after enabling the above services for a more complete security assessment.\",\n serviceImpact: \"Impact\",\n serviceAction: \"Action\",\n\n // Common\n account: \"Account\",\n region: \"Region\",\n scanTime: \"Scan Time\",\n duration: \"Duration\",\n severityDistribution: \"Severity Distribution\",\n findingsByModule: \"Findings by Module\",\n details: \"Details\",\n\n // Extended \\u2014 HTML Security Report extras\n topHighestRiskFindings: (n: number) =>\n `Top ${n} Highest Risk Findings`,\n resource: \"Resource\",\n impact: \"Impact\",\n riskScore: \"Risk Score\",\n showRemainingFindings: (n: number) =>\n `Show remaining ${n} findings\\u2026`,\n trendTitle: \"30-Day Trends\",\n findingsBySeverity: \"Findings by Severity\",\n showMoreCount: (n: number) =>\n `Show ${n} more\\u2026`,\n\n // Filter toolbar\n filterSeverity: \"Severity:\",\n filterModule: \"Module:\",\n filterAll: \"All\",\n filterAllModules: \"All Modules\",\n filterCountTpl: \"Showing {shown} / {total} findings\",\n\n // Extended \\u2014 MLPS extras\n // Markdown report\n executiveSummary: \"Executive Summary\",\n totalFindingsLabel: \"Total Findings\",\n description: \"Description\",\n priority: \"Priority\",\n noFindingsForSeverity: (severity: string) => `No ${severity.toLowerCase()} findings.`,\n\n preCheckOverview: \"Pre-Check Overview\",\n accountInfo: \"Account Information\",\n checkedCount: (total: number, clean: number, issues: number) =>\n `Checked: ${total} items (No issues: ${clean} | Issues found: ${issues})`,\n uncheckedCount: (n: number) =>\n `Not checked: ${n} items (corresponding scan modules not run)`,\n cloudProviderCount: (n: number) =>\n `Cloud provider responsible: ${n} items`,\n manualReviewCount: (n: number) =>\n `Manual review required: ${n} items`,\n naCount: (n: number) => `Not applicable: ${n} items`,\n naNote: (n: number) =>\n `Not applicable: ${n} items (IoT/wireless networks/mobile terminals/ICS/trusted verification, etc.)`,\n unknownNote: (n: number) =>\n `(${n} items not checked \\u2014 corresponding scan modules not run)`,\n cloudItemsNote: (n: number) =>\n `The following ${n} items are the responsibility of the AWS cloud platform and are outside the scope of this report per the shared responsibility model.`,\n mlpsFooterGenerated: (version: string) =>\n `Generated by AWS Security MCP Server v${version}`,\n mlpsFooterDisclaimer:\n \"This report is for evidence collection reference and does not include compliance determination. A complete MLPS assessment must be conducted by a certified assessment institution.\",\n andMore: (n: number) => `\\u2026 and ${n} more`,\n remediationByPriority: \"Remediation Items (by Priority)\",\n affectedResources: (n: number) => `${n} resource${n === 1 ? \"\" : \"s\"} affected`,\n installWindowsPatches: (n: number, kbs: string) => `Install ${n} Windows patch${n === 1 ? \"\" : \"es\"} (${kbs})`,\n mlpsCategorySection: {\n \"\\u5b89\\u5168\\u7269\\u7406\\u73af\\u5883\": \"I. Physical Environment Security\",\n \"\\u5b89\\u5168\\u901a\\u4fe1\\u7f51\\u7edc\": \"II. Communication Network Security\",\n \"\\u5b89\\u5168\\u533a\\u57df\\u8fb9\\u754c\": \"III. Area Boundary Security\",\n \"\\u5b89\\u5168\\u8ba1\\u7b97\\u73af\\u5883\": \"IV. Computing Environment Security\",\n \"\\u5b89\\u5168\\u7ba1\\u7406\\u4e2d\\u5fc3\": \"V. Security Management Center\",\n },\n\n // Module display names\n moduleNames: {\n service_detection: \"Security Service Detection\",\n secret_exposure: \"Secret Exposure\",\n ssl_certificate: \"SSL Certificate\",\n dns_dangling: \"Dangling DNS\",\n network_reachability: \"Network Reachability\",\n iam_privilege_escalation: \"IAM Privilege Escalation\",\n public_access_verify: \"Public Access Verification\",\n tag_compliance: \"Tag Compliance\",\n idle_resources: \"Idle Resources\",\n disaster_recovery: \"Disaster Recovery\",\n security_hub_findings: \"Security Hub\",\n guardduty_findings: \"GuardDuty\",\n inspector_findings: \"Inspector\",\n trusted_advisor_findings: \"Trusted Advisor\",\n config_rules_findings: \"Config Rules\",\n access_analyzer_findings: \"Access Analyzer\",\n patch_compliance_findings: \"Patch Compliance\",\n imdsv2_enforcement: \"IMDSv2 Enforcement\",\n waf_coverage: \"WAF Coverage\",\n // Security Hub sub-categories\n \"sh:FSBP\": \"Security Best Practices\",\n \"sh:Inspector\": \"Software Vulnerabilities\",\n \"sh:GuardDuty\": \"Threat Detection\",\n \"sh:Config\": \"Configuration Compliance\",\n \"sh:Access Analyzer\": \"External Access\",\n \"sh:Other\": \"Other Security Findings\",\n },\n\n // Security Hub sub-categories\n securityHubSubCategories: {\n FSBP: { label: \"Security Best Practices\" },\n Inspector: { label: \"Software Vulnerabilities\" },\n GuardDuty: { label: \"Threat Detection\" },\n Config: { label: \"Configuration Compliance\" },\n \"Access Analyzer\": { label: \"External Access\" },\n Other: { label: \"Other Security Findings\" },\n },\n\n // Service Recommendations\n notEnabled: \"Not Enabled\",\n serviceRecommendations: {\n security_hub_findings: {\n icon: \"\\ud83d\\udd34\",\n service: \"Security Hub\",\n impact:\n \"Cannot obtain 300+ automated security checks (FSBP/CIS/PCI DSS standards)\",\n action:\n \"Enable Security Hub for the most comprehensive security posture assessment\",\n },\n guardduty_findings: {\n icon: \"\\ud83d\\udd34\",\n service: \"GuardDuty\",\n impact:\n \"Cannot detect threat activity (malicious IPs, anomalous API calls, crypto mining, etc.)\",\n action:\n \"Enable GuardDuty for continuous threat detection\",\n },\n inspector_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"Inspector\",\n impact:\n \"Cannot scan EC2/Lambda/container software vulnerabilities (CVEs)\",\n action:\n \"Enable Inspector to discover known security vulnerabilities\",\n },\n trusted_advisor_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"Trusted Advisor\",\n impact:\n \"Cannot obtain AWS best practice security checks\",\n action:\n \"Upgrade to Business/Enterprise Support plan to use Trusted Advisor security checks\",\n },\n config_rules_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"AWS Config\",\n impact:\n \"Cannot check resource configuration compliance status\",\n action:\n \"Enable AWS Config and configure Config Rules\",\n },\n access_analyzer_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"IAM Access Analyzer\",\n impact:\n \"Cannot detect whether resources are accessed by external accounts or public networks\",\n action:\n \"Create IAM Access Analyzer (account-level or organization-level)\",\n },\n patch_compliance_findings: {\n icon: \"\\ud83d\\udfe1\",\n service: \"SSM Patch Manager\",\n impact:\n \"Cannot check instance patch compliance status\",\n action:\n \"Install SSM Agent and configure Patch Manager\",\n },\n },\n\n // HW Defense HTML Report\n hwReportTitle: \"HW Defense Security Assessment Report\",\n hwAutoCheck: \"Automated Checks\",\n hwManualCheck: \"Manual Verification Items\",\n hwNoAutoCheck: \"No automated checks for this section\",\n hwClean: \"No issues found\",\n hwTotalFindings: \"Total Findings\",\n hwSectionsChecked: \"Sections Checked\",\n hwAutoVerified: \"Auto-Verified\",\n hwManualPending: \"Manual Pending\",\n hwManualCount: (n: number) => `${n} manual item${n === 1 ? \"\" : \"s\"}`,\n hwAffectedResources: (n: number) => `View affected resources (${n})`,\n hwRemediation: \"Remediation\",\n hwSectionNames: {\n attack_surface: { name: \"Attack Surface Reduction\", icon: \"🎯\" },\n vulnerability_patch: { name: \"Vulnerability & Patch Management\", icon: \"🩹\" },\n identity_credential: { name: \"Identity & Credential Security\", icon: \"🔑\" },\n transport_security: { name: \"Transport & Instance Security\", icon: \"🔒\" },\n security_services: { name: \"Security Service Status\", icon: \"🛡️\" },\n emergency_response: { name: \"Emergency Response Readiness\", icon: \"🚨\" },\n environment_control: { name: \"Environment Control\", icon: \"🏗️\" },\n post_review: { name: \"Post-Drill Optimization\", icon: \"📊\" },\n },\n hwManualItems: {\n attack_surface: [\"Draw ingress/egress path architecture diagram, mark all Internet/DX dedicated line paths\"],\n vulnerability_patch: [\"Contact security vendors for simulated attack drills (penetration testing)\", \"Monitor AWS security advisories (known vulnerabilities and patches)\"],\n identity_credential: [\"All IAM users must have MFA enabled\", \"Access key rotation cycle ≤ 90 days\", \"Avoid shared account usage\", \"No plaintext passwords in S3/Lambda/application code\"],\n transport_security: [\"Verify all external-facing services use TLS 1.2+\", \"Check internal service-to-service communication encryption\"],\n security_services: [\"Verify Security Hub is enabled with standards configured\", \"Verify GuardDuty is enabled in all regions\", \"Verify CloudTrail multi-region logging is enabled\", \"Verify Config Rules are configured\"],\n emergency_response: [\"Prepare dedicated isolation security groups (no Inbound/Outbound rules)\", \"Establish instance isolation SOP: Alert → Investigate → Block attacker IP → Network isolation → Security response → Log attack details\", \"Form 7×24 monitoring rapid response team\", \"Create dedicated communication channels for the drill period (Teams/Slack/Chime)\", \"Establish WAR-ROOM connection with AWS TAM (Enterprise Support customers)\"],\n environment_control: [\"Shut down non-critical systems during the drill period\", \"Shut down test/dev environments or maintain same security baseline as production\", \"Confirm which environments can be emergency-stopped to prevent attack propagation\"],\n post_review: [\"Address and remediate each item from the attack report\", \"Establish periodic security maintenance processes with the security team\", \"Continuously fill security risk gaps\"],\n },\n\n // HW Checklist (full composite)\n hwChecklist: `\n\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\n\\ud83d\\udccb Cyber Defense Drill Supplementary Reminders (Beyond Automated Scanning)\n\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\n\nThe following items require manual verification and execution:\n\n\\u26a0\\ufe0f Emergency Isolation / Incident Response Plan\n \\u25a1 Prepare dedicated isolation security groups (no Inbound/Outbound rules)\n \\u25a1 Establish instance isolation SOP: Alert \\u2192 Investigate \\u2192 Block attacker IP \\u2192 Network isolation \\u2192 Security response \\u2192 Log attack details\n \\u25a1 Define emergency response procedures for each system (production core/non-core/test/dev)\n \\u25a1 Identify responsible personnel and contacts for each project account and resource\n\n\\u26a0\\ufe0f Test/Development Environment Handling\n \\u25a1 Shut down non-critical systems during the drill period\n \\u25a1 Shut down test/dev environments or maintain same security baseline as production\n \\u25a1 Confirm which environments can be emergency-stopped to prevent attack propagation\n\n\\u26a0\\ufe0f On-Duty Team Formation\n \\u25a1 7\\u00d724 monitoring and rapid response team\n \\u25a1 Technical and risk analysis team\n \\u25a1 Security policy deployment team\n \\u25a1 Business response team\n \\u25a1 Confirm AWS TAM/Support contact information (ES/EOP customers)\n\n\\u26a0\\ufe0f Ingress/Egress Path Architecture Diagram\n \\u25a1 Ensure all Internet/DX dedicated line ingress/egress paths are clearly marked in architecture diagrams\n \\u25a1 Clarify data flow for each ELB/Public EC2/S3/DX\n \\u25a1 Identify all internet-facing data interaction interfaces\n\n\\u26a0\\ufe0f Proactive Penetration Testing\n \\u25a1 Contact security vendors for simulated attack drills before the exercise\n \\u25a1 Conduct security hardening based on penetration test reports\n \\u25a1 Monitor AWS security advisories (known vulnerabilities and patches)\n\n\\u26a0\\ufe0f WAR-ROOM Real-Time Communication\n \\u25a1 Create dedicated communication channels for the drill period (Teams/Slack/Chime)\n \\u25a1 Establish WAR-ROOM connection with AWS TAM (Enterprise Support customers)\n \\u25a1 Standardize case title format: \"[CyberDrill] + Issue Description\"\n\n\\u26a0\\ufe0f Password & Credential Management\n \\u25a1 All IAM users must have MFA enabled\n \\u25a1 Access key rotation cycle \\u2264 90 days\n \\u25a1 Avoid shared account usage\n \\u25a1 No plaintext passwords in S3/Lambda/application code\n\n\\u26a0\\ufe0f Post-Drill Optimization\n \\u25a1 Address and remediate each item from the attack report\n \\u25a1 Establish periodic security maintenance processes with the security team\n \\u25a1 Continuously fill security risk gaps\n\nReference: AWS Cyber Defense Drill Standard Operation Procedure (Compliance IEM)\n`,\n};\n","export type Lang = \"zh\" | \"en\";\n\nexport interface I18n {\n // HTML Security Report\n securityReportTitle: string;\n securityScore: string;\n critical: string;\n high: string;\n medium: string;\n low: string;\n scanStatistics: string;\n module: string;\n resources: string;\n findings: string;\n status: string;\n allFindings: string;\n recommendations: string;\n unique: string;\n showMore: string;\n noIssuesFound: string;\n allModulesClean: string;\n generatedBy: string;\n informationalOnly: string;\n\n // MLPS Report\n mlpsTitle: string;\n mlpsDisclaimer: string;\n checkedItems: string;\n noIssues: string;\n issuesFound: string;\n notChecked: string;\n cloudProvider: string;\n manualReview: string;\n notApplicable: string;\n checkResult: string;\n noRelatedIssues: string;\n issuesFoundCount: (n: number) => string;\n remediation: string;\n remediationItems: (n: number) => string;\n showRemaining: (n: number) => string;\n\n // HW Defense Checklist\n hwChecklistTitle: string;\n hwChecklistSubtitle: string;\n hwEmergencyIsolation: string;\n hwTestEnvShutdown: string;\n hwDutyTeam: string;\n hwNetworkDiagram: string;\n hwPentest: string;\n hwWarRoom: string;\n hwCredentials: string;\n hwPostOptimization: string;\n hwReference: string;\n\n // Service Reminders\n serviceReminderTitle: string;\n serviceReminderFooter: string;\n serviceImpact: string;\n serviceAction: string;\n\n // Common\n account: string;\n region: string;\n scanTime: string;\n duration: string;\n severityDistribution: string;\n findingsByModule: string;\n details: string;\n\n // ---------------------------------------------------------------------------\n // Extended fields (beyond the base interface spec) needed for full coverage\n // ---------------------------------------------------------------------------\n\n // HTML Security Report extras\n topHighestRiskFindings: (n: number) => string;\n resource: string;\n impact: string;\n riskScore: string;\n showRemainingFindings: (n: number) => string;\n trendTitle: string;\n findingsBySeverity: string;\n showMoreCount: (n: number) => string;\n\n // Filter toolbar\n filterSeverity: string;\n filterModule: string;\n filterAll: string;\n filterAllModules: string;\n filterCountTpl: string;\n\n // Markdown report\n executiveSummary: string;\n totalFindingsLabel: string;\n description: string;\n priority: string;\n noFindingsForSeverity: (severity: string) => string;\n\n // MLPS extras\n preCheckOverview: string;\n accountInfo: string;\n checkedCount: (total: number, clean: number, issues: number) => string;\n uncheckedCount: (n: number) => string;\n cloudProviderCount: (n: number) => string;\n manualReviewCount: (n: number) => string;\n naCount: (n: number) => string;\n naNote: (n: number) => string;\n unknownNote: (n: number) => string;\n cloudItemsNote: (n: number) => string;\n mlpsFooterGenerated: (version: string) => string;\n mlpsFooterDisclaimer: string;\n andMore: (n: number) => string;\n remediationByPriority: string;\n affectedResources: (n: number) => string;\n installWindowsPatches: (n: number, kbs: string) => string;\n mlpsCategorySection: Record<string, string>;\n\n // Module display names (unified across all report formats)\n moduleNames: Record<string, string>;\n\n // Security Hub sub-categories\n securityHubSubCategories: Record<string, { label: string }>;\n\n // Service recommendations (per service)\n notEnabled: string;\n serviceRecommendations: Record<\n string,\n { icon: string; service: string; impact: string; action: string }\n >;\n\n // HW Checklist (full composite text)\n hwChecklist: string;\n\n // HW Defense HTML Report\n hwReportTitle: string;\n hwAutoCheck: string;\n hwManualCheck: string;\n hwNoAutoCheck: string;\n hwClean: string;\n hwTotalFindings: string;\n hwSectionsChecked: string;\n hwAutoVerified: string;\n hwManualPending: string;\n hwSectionNames: Record<string, { name: string; icon: string }>;\n hwManualItems: Record<string, string[]>;\n hwManualCount: (n: number) => string;\n hwAffectedResources: (n: number) => string;\n hwRemediation: string;\n}\n\nimport { zhI18n } from \"./zh.js\";\nimport { enI18n } from \"./en.js\";\n\nconst translations: Record<Lang, I18n> = {\n zh: zhI18n,\n en: enI18n,\n};\n\nexport function getI18n(lang: Lang = \"zh\"): I18n {\n return translations[lang] ?? translations.zh;\n}\n","import type { FullScanResult, Finding, Severity } from \"../types.js\";\nimport { getI18n, type Lang } from \"../i18n/index.js\";\n\nconst SEVERITY_ICON: Record<Severity, string> = {\n CRITICAL: \"\\ud83d\\udd34\",\n HIGH: \"\\ud83d\\udfe0\",\n MEDIUM: \"\\ud83d\\udfe1\",\n LOW: \"\\ud83d\\udfe2\",\n};\n\nconst SEVERITY_ORDER: Severity[] = [\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"];\n\nfunction formatDuration(start: string, end: string): string {\n const ms = new Date(end).getTime() - new Date(start).getTime();\n if (ms < 1000) return `${ms}ms`;\n const secs = Math.round(ms / 1000);\n if (secs < 60) return `${secs}s`;\n const mins = Math.floor(secs / 60);\n const remainSecs = secs % 60;\n return `${mins}m ${remainSecs}s`;\n}\n\nexport function generateMarkdownReport(scanResults: FullScanResult, lang?: Lang): string {\n const t = getI18n(lang ?? \"zh\");\n const { summary, modules, accountId, region, scanStart, scanEnd } =\n scanResults;\n const date = scanStart.split(\"T\")[0];\n const duration = formatDuration(scanStart, scanEnd);\n\n const sevLabel: Record<Severity, string> = {\n CRITICAL: t.critical,\n HIGH: t.high,\n MEDIUM: t.medium,\n LOW: t.low,\n };\n\n function renderFinding(f: Finding): string {\n const steps = f.remediationSteps\n .map((s, i) => ` ${i + 1}. ${s}`)\n .join(\"\\n\");\n\n return [\n `#### ${f.title}`,\n `- **${t.resource}:** ${f.resourceId} (\\`${f.resourceArn}\\`)`,\n `- **${t.description}:** ${f.description}`,\n `- **${t.impact}:** ${f.impact}`,\n `- **${t.riskScore}:** ${f.riskScore}/10`,\n `- **${t.remediation}:**`,\n steps,\n `- **${t.priority}:** ${f.priority}`,\n ].join(\"\\n\");\n }\n\n const lines: string[] = [];\n\n lines.push(`# ${t.securityReportTitle} \\u2014 ${date}`);\n lines.push(\"\");\n\n // Executive Summary\n lines.push(`## ${t.executiveSummary}`);\n lines.push(`- **${t.account}:** ${accountId}`);\n lines.push(`- **${t.region}:** ${region}`);\n lines.push(`- **${t.duration}:** ${duration}`);\n lines.push(\n `- **${t.totalFindingsLabel}:** ${summary.totalFindings} (${SEVERITY_ICON.CRITICAL} ${summary.critical} ${t.critical} | ${SEVERITY_ICON.HIGH} ${summary.high} ${t.high} | ${SEVERITY_ICON.MEDIUM} ${summary.medium} ${t.medium} | ${SEVERITY_ICON.LOW} ${summary.low} ${t.low})`,\n );\n lines.push(\"\");\n\n // Edge case: no findings\n if (summary.totalFindings === 0) {\n lines.push(`## ${t.findingsBySeverity}`);\n lines.push(\"\");\n lines.push(`\\u2705 ${t.noIssuesFound}`);\n lines.push(\"\");\n } else {\n // Collect all findings\n const allFindings: Finding[] = modules.flatMap((m) => m.findings);\n\n // Group by severity\n const grouped = new Map<Severity, Finding[]>();\n for (const sev of SEVERITY_ORDER) {\n grouped.set(sev, []);\n }\n for (const f of allFindings) {\n grouped.get(f.severity)!.push(f);\n }\n\n lines.push(`## ${t.findingsBySeverity}`);\n lines.push(\"\");\n\n for (const sev of SEVERITY_ORDER) {\n const findings = grouped.get(sev)!;\n const icon = SEVERITY_ICON[sev];\n lines.push(`### ${icon} ${sevLabel[sev]}`);\n lines.push(\"\");\n\n if (findings.length === 0) {\n lines.push(t.noFindingsForSeverity(sevLabel[sev]));\n lines.push(\"\");\n continue;\n }\n\n // Sort by riskScore descending\n findings.sort((a, b) => b.riskScore - a.riskScore);\n for (const f of findings) {\n lines.push(renderFinding(f));\n lines.push(\"\");\n }\n }\n }\n\n // Scan Statistics\n lines.push(`## ${t.scanStatistics}`);\n lines.push(\n `| ${t.module} | ${t.resources} | ${t.findings} | ${t.status} |`,\n );\n lines.push(\"|--------|------------------|----------|--------|\");\n for (const m of modules) {\n const status = m.status === \"success\" ? \"\\u2705\" : \"\\u274c\";\n lines.push(\n `| ${t.moduleNames[m.module] ?? m.module} | ${m.resourcesScanned} | ${m.findingsCount} | ${status} |`,\n );\n }\n lines.push(\"\");\n\n // Recommendations\n if (summary.totalFindings > 0) {\n const allFindings: Finding[] = modules.flatMap((m) => m.findings);\n allFindings.sort((a, b) => b.riskScore - a.riskScore);\n\n lines.push(`## ${t.recommendations}`);\n for (let i = 0; i < allFindings.length; i++) {\n const f = allFindings[i];\n lines.push(`${i + 1}. [${f.priority}] ${f.title}: ${f.remediationSteps[0] ?? \"Review and remediate.\"}`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n","[\n {\n \"id\": \"L3-PES1-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"物理位置选择\",\n \"controlEn\": \"Physical Location Alteration\",\n \"requirementCn\": \"机房场地应选择在具有防震、防风和防雨等能力的建筑内\",\n \"requirementEn\": \"The computer room should be located in buildings with the ability to be shockproof, windproof and rainproof\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-02\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"物理位置选择\",\n \"controlEn\": \"Physical Location Alteration\",\n \"requirementCn\": \"机房场地应避免设在建筑物的顶层或地下室,否则应加强防水和防潮措施\",\n \"requirementEn\": \"The computer room should avoid being located at the top of the building or the basement, otherwise waterproof and moisture-proof measures should be strengthened.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-03\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"物理访问控制\",\n \"controlEn\": \"Physical Access Control\",\n \"requirementCn\": \"机房出入口应配置电子门禁系统,控制、鉴别和记录进入的人员\",\n \"requirementEn\": \"Entrance and exit of the computer room should be equipped with an electronic access control system to control, identify and record the incoming personnel.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-04\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防盗窃和防破坏\",\n \"controlEn\": \"Anti-theft and Anti-vandalism\",\n \"requirementCn\": \"应将设备或主要部件进行固定,并设置明显的不易除去的标识\",\n \"requirementEn\": \"Device or main components should be fixed and marked with obvious labels that are difficult to remove\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-05\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防盗窃和防破坏\",\n \"controlEn\": \"Anti-theft and Anti-vandalism\",\n \"requirementCn\": \"应将通信线缆铺设在隐蔽安全处\",\n \"requirementEn\": \"The communication cable should be laid in a safe and concealed place\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-06\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防盗窃和防破坏\",\n \"controlEn\": \"Anti-theft and Anti-vandalism\",\n \"requirementCn\": \"应设置机房防盗报警系统或设置有专人值守的视频监控系统\",\n \"requirementEn\": \"A computer room anti-theft alarm system or a video surveillance system with a special person should be set up.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-07\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防雷击\",\n \"controlEn\": \"Lightning Protection\",\n \"requirementCn\": \"应将各类机柜、设施和设备等通过接地系统安全接地\",\n \"requirementEn\": \"All types of cabinets, facilities and equipment should be safely grounded through the grounding system\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-08\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防雷击\",\n \"controlEn\": \"Lightning Protection\",\n \"requirementCn\": \"应采取措施防止感应雷,例如设置防雷保安器或过压保护装置等\",\n \"requirementEn\": \"Measures should be taken to prevent inductive lightning, such as set up lightning protection or overvoltage protection devices.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-09\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防火\",\n \"controlEn\": \"Fire Protection\",\n \"requirementCn\": \"机房应设置火灾自动消防系统,能够自动检测火情、自动报警,并自动灭火\",\n \"requirementEn\": \"Automatic fire protection system which can automatically detect, alarm and extinguish should be set up.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-10\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防火\",\n \"controlEn\": \"Fire Protection\",\n \"requirementCn\": \"机房及相关的工作房间和辅助房应采用具有耐火等级的建筑材料\",\n \"requirementEn\": \"The computer room and related work rooms and auxiliary rooms shall be constructed of fire-resistant building materials\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-11\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防火\",\n \"controlEn\": \"Fire Protection\",\n \"requirementCn\": \"应对机房划分区域进行管理,区域和区域之间设置隔离防火措施\",\n \"requirementEn\": \"The computer room should be managed dividedly, and set fire prevention measures for each region\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-12\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防水和防潮\",\n \"controlEn\": \"Waterproof and Moisture Proof\",\n \"requirementCn\": \"应采取措施防止雨水通过机房窗户、屋顶和墙壁渗透\",\n \"requirementEn\": \"Measures should be taken to avoid rainwater penetrating through the windows, roof and walls of the computer room\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-13\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防水和防潮\",\n \"controlEn\": \"Waterproof and Moisture Proof\",\n \"requirementCn\": \"应采取措施防止机房内水蒸气结露和地下积水的转移与渗透\",\n \"requirementEn\": \"Measures should be taken to prevent water vapor condensation, and to prevent transfer and penetration of underground water in the computer room\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-14\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防水和防潮\",\n \"controlEn\": \"Waterproof and Moisture Proof\",\n \"requirementCn\": \"应安装对水敏感的检测仪表或元件,对机房进行防水检测和报警\",\n \"requirementEn\": \"Water-sensitive detection instruments or components should be installed to conduct waterproof detection and alarm for the computer room.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-15\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防静电\",\n \"controlEn\": \"Anti-static\",\n \"requirementCn\": \"应采用防静电地板或地面并采用必要的接地防静电措施\",\n \"requirementEn\": \"Anti-static floor or ground should be used and necessary grounding anti-static measures should be adopted\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-16\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"防静电\",\n \"controlEn\": \"Anti-static\",\n \"requirementCn\": \"应采取措施防止静电的产生,例如采用静电消除器、佩戴防静电手环等\",\n \"requirementEn\": \"Measures such as use static eliminators and wear anti-static wrist straps should be taken to prevent from generating static electricity.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-17\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"温湿度控制\",\n \"controlEn\": \"Temperature and Humidity Control\",\n \"requirementCn\": \"应设置温湿度自动调节设施,使机房温湿度的变化在设备运行所允许的范围之内\",\n \"requirementEn\": \"Temperature and humidity automatic adjustment facilities should be set up so that the temperature and humidity changes are within the allowable range of equipment operation.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-18\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电力供应\",\n \"controlEn\": \"Electricity Supply\",\n \"requirementCn\": \"应在机房供电线路上配置稳压器和过电压防护设备\",\n \"requirementEn\": \"Voltage stabilizer and overvoltage protection equipment should be configured for the power supply line of the computer room\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-19\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电力供应\",\n \"controlEn\": \"Electricity Supply\",\n \"requirementCn\": \"应提供短期的备用电力供应,至少满足设备在断电情况下的正常运行要求\",\n \"requirementEn\": \"A short-term backup power supply shall be provided to meet the normal operational requirements of the equipment in the event of a power outage\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-20\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电力供应\",\n \"controlEn\": \"Electricity Supply\",\n \"requirementCn\": \"应设置冗余或并行的电力电缆线路为计算机系统供电\",\n \"requirementEn\": \"Equip backup or parallel power cable lines to power the computer system when necessary.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-21\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电磁防护\",\n \"controlEn\": \"Electromagnetic Protection\",\n \"requirementCn\": \"电源线和通信线缆应隔离铺设,避免互相干扰\",\n \"requirementEn\": \"Power cables and communication cables should be laid isolated to avoid mutual interference\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-PES1-22\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"电磁防护\",\n \"controlEn\": \"Electromagnetic Protection\",\n \"requirementCn\": \"应对关键设备实施电磁屏蔽\",\n \"requirementEn\": \"Electromagnetic shielding should be implemented for critical equipment.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的物理环境安全\"\n },\n {\n \"id\": \"L3-CNS1-01\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应保证网络设备的业务处理能力满足业务高峰期需要\",\n \"requirementEn\": \"Service processing capability of network should be guaranteed to meet the peak business needs\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的互联网接入满足业务高峰需求;客户数据中心和亚马逊云之间的连接例如VPN,专线的处理能力需要客户根据业务规划;VPC内部网络服务有自身的限制,开Case提升限制;EC2自身的网络处理能力可以根据业务需求进行选择\"\n },\n {\n \"id\": \"L3-CNS1-02\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应保证网络各个部分的带宽满足业务高峰期需要\",\n \"requirementEn\": \"Ensure that the bandwidth of each part of the network meets the peak business needs\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"亚马逊云科技负责Cloud本身的互联网接入满足业务高峰需求;客户数据中心和亚马逊云之间的连接例如VPN,专线的处理能力需要客户根据业务规划;VPC内部网络服务有自身的限制,开Case提升限制;EC2自身的网络处理能力可以根据业务需求进行选择\"\n },\n {\n \"id\": \"L3-CNS1-03\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应划分不同的网络区域,并按照方便管理和控制的原则为各网络区域分配地址\",\n \"requirementEn\": \"Different network areas should be divided, and addresses should be assigned to each network area in accordance with the principle of convenient management and control\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"利用VPC进行区域和地址划分\"\n },\n {\n \"id\": \"L3-CNS1-04\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应避免将重要网络区域部署在边界处,重要网络区域与其他网络区域之间应采取可靠的技术隔离手段\",\n \"requirementEn\": \"Critical network areas should not be deployed at the network boundaries or without border protection, and reliable technical isolation should be used between important network areas and other network areas\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. AWS侧采用防火墙或者Network ACL(建议确认global region设计)\\n2. On-premise采用防火墙\"\n },\n {\n \"id\": \"L3-CNS1-05\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应提供通信线路、关键网络设备和关键计算设备的硬件冗余,保证系统的可用性\",\n \"requirementEn\": \"The communication lines and hardware of critical network equipment should be adequately backed up to ensure system availability.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"服务确保多可用区部署以及多区域部署;多条专线接入到不同的专线接入点确保高可用\"\n },\n {\n \"id\": \"L3-CNS1-06\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"通信传输\",\n \"controlEn\": \"Communication\",\n \"requirementCn\": \"应采用校验技术或密码技术保证通信过程中数据的完整性\",\n \"requirementEn\": \"Verification techniques or cryptographic techniques should be used to ensure the integrity of the data during communication\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"开启传输加密\"\n },\n {\n \"id\": \"L3-CNS1-07\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"通信传输\",\n \"controlEn\": \"Communication\",\n \"requirementCn\": \"应采用密码技术保证通信过程中数据的保密性\",\n \"requirementEn\": \"Cryptographic techniques should be used to ensure the confidentiality of the data during communication\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"启用SSL/TLS传输加密,利用ACM管理传输加密的密钥\"\n },\n {\n \"id\": \"L3-CNS1-08\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"可信验证\",\n \"controlEn\": \"Trusted Verification\",\n \"requirementCn\": \"可基于可信根对通信设备的系统引导程序、系统程序、重要配置参数和通信应用程序等进行可信验证,并在应用程序的关键执行环节进行动态可信验证,在检测到其可信性受到破坏后进行报警,并将验证结果形成审计记录送至安全管理中心\",\n \"requirementEn\": \"Trusted verification, based on the trusted root, can be applied to system boot program, system program, important configuration parameters, and communication applications of the communication device, and dynamic trusted verification can be used in the key execution of the application, and when detecting the credibility thereof. After being damaged, an alarm is issued, and after detecting that its credibility has been damaged, an alarm should be issued and the verification result should be sent to the Security Management Center.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS1-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应保证跨越边界的访问和数据流通过边界防护设备提供的受控接口进行通信\",\n \"requirementEn\": \"It should be ensured that access and data flows across the boundary are communicated through a controlled interface provided by the border protection device.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应能够对非授权设备私自联到内部网络的行为进行限制或检查\",\n \"requirementEn\": \"It should be able to restrict or check the behavior of unauthorized devices connected to the internal network\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应能够对内部用户非授权联到外部网络的行为进行限制或检查\",\n \"requirementEn\": \"It should be able to restrict or inspect the behavior of internal users who are privately linked to the external network\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 利用NAT 或者 NAT Gateway\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 启用VPC Endpoint 保证通过私有网络访问AWS服务\"\n },\n {\n \"id\": \"L3-ABS1-04\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应限制无线网络的使用,确保无线网络通过受控的边界防护设备接入内部网络\",\n \"requirementEn\": \"The use of the wireless network should be limited to ensure that the wireless network accesses the internal network through controlled border protection equipment.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS1-05\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在网络边界或区域之间根据访问控制策略设置访问控制规则,默认情况下除允许通信外受控接口拒绝所有通信\",\n \"requirementEn\": \"Access control rules should be set between network boundaries or regions based on access control policies, and the controlled interfaces should reject any communication by default except for those that allow communication\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"采用安全组或者Network ACL,按照最小暴露原则设置\"\n },\n {\n \"id\": \"L3-ABS1-06\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应删除多余或无效的访问控制规则,优化访问控制列表,并保证访问控制规则数量最小化\",\n \"requirementEn\": \"Extra or invalid access control rules should be removed to optimize the access control lists, and the number of access control rules should be minimized\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"采用安全组或者Network ACL,按照最小暴露原则设置\"\n },\n {\n \"id\": \"L3-ABS1-07\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应对源地址、目的地址、源端口、目的端口和协议等进行检查,以允许/拒绝数据包进出\",\n \"requirementEn\": \"Check the source address, destination address, source port, destination port, protocol, etc. to allow/deny packets in and out\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 利用VPC Flow log 对进出VPC的通讯进行分析\\n5. 必要时可以启用VPC Traffic Mirror,并利用专业分析软件进行流量分析\"\n },\n {\n \"id\": \"L3-ABS1-08\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应能根据会话状态信息为进出数据流提供明确的允许/拒绝访问的能力\",\n \"requirementEn\": \"Explicit ability to allow/deny access to incoming and outgoing data streams should be provided based on session state information\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-09\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应对进出网络的数据流实现基于应用协议和应用内容的访问控制\",\n \"requirementEn\": \"Access control based on application protocols and application content should be applied to data flows to and from the network.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\\"\"\n },\n {\n \"id\": \"L3-ABS1-10\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应在关键网络节点处检测、防止或限制从外部发起的网络攻击行为\",\n \"requirementEn\": \"Externally initiated cyber attacks should be detected, prevented or restricted at critical network nodes\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-11\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应在关键网络节点处检测、防止或限制从内部发起的网络攻击行为\",\n \"requirementEn\": \"Internally initiated cyber attacks should be detected, prevented or restricted at critical network nodes\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用GuardDuty\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-12\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应采取技术措施对网络行为进行分析,实现对网络攻击特别是新型网络攻击行为的分析\",\n \"requirementEn\": \"Technical measures should be taken to analyze the network behavior, as well as analyze network attacks, especially the new types of attacks.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-ABS1-13\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"当检测到攻击行为时,记录攻击源IP、攻击类型、攻击目的、攻击时间,在发生严重入侵事件时应提供报警\",\n \"requirementEn\": \"When an attack is detected, the attack source IP, attack type, attack purpose, and attack time should be recorded, and alarm when a serious intrusion occurs.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\"\n },\n {\n \"id\": \"L3-ABS1-14\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"恶意代码和垃圾邮件防范\",\n \"controlEn\": \"Malicious Code and Spam Prevention\",\n \"requirementCn\": \"应在关键网络节点处对恶意代码进行检测和清除,并维护恶意代码防护机制的升级和更新\",\n \"requirementEn\": \"Malicious code should be detected and purged at key network nodes, and the upgrade and update of malicious code protection mechanism should be maintained.\",\n \"referenceStatus\": \"不符合 Gap Exist\",\n \"referenceComment\": \"1.使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n2.在操作系统安装第三方安全防护和杀毒软件\"\n },\n {\n \"id\": \"L3-ABS1-15\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"恶意代码和垃圾邮件防范\",\n \"controlEn\": \"Malicious Code and Spam Prevention\",\n \"requirementCn\": \"应在关键网络节点处对垃圾邮件进行检测和防护,并维护垃圾邮件防护机制的升级和更新\",\n \"requirementEn\": \"Spam should be detected and protect at critical network nodes and upgrades and update of spam protection mechanisms should be maintained.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS1-16\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应在网络边界、重要网络节点进行安全审计,审计覆盖到每个用户,对重要的用户行为和重要安全事件进行审计\",\n \"requirementEn\": \"Security audits should be conducted at network borders and important network nodes, and audits should be covered to each user to audit important user behaviors and important security incidents\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. IAM\\n2,堡垒机(session manager或者第三方的堡垒机)\"\n },\n {\n \"id\": \"L3-ABS1-17\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"审计记录应包括事件的日期和时间、用户、事件类型、事件是否成功及其他与审计相关的信息\",\n \"requirementEn\": \"The audit record should include the event date and time, user, event type, success or failure of the event, and other audit-related information\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail\"\n },\n {\n \"id\": \"L3-ABS1-18\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应对审计记录进行保护,定期备份,避免受到未预期的删除、修改或覆盖等\",\n \"requirementEn\": \"Audit records should be protected and backed up regularly to avoid unintended deletions, modifications or overwrites.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail\"\n },\n {\n \"id\": \"L3-ABS1-19\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应能对远程访问的用户行为、访问互联网的用户行为等单独进行行为审计和数据分析\",\n \"requirementEn\": \"It should be possible to conduct separate behavioral audits and data analysis on user behaviors of remote access, user behaviors of accessing the Internet, and so on.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. CloudTraiil\\n2. S3和ALB Access Logs\\n3.使用第三方的下一代防火墙,并结合GLWB进行高可用部署或者上网行为管理产品\"\n },\n {\n \"id\": \"L3-ABS1-20\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"可信验证\",\n \"controlEn\": \"Trusted Verification\",\n \"requirementCn\": \"可基于可信根对边界设备的系统引导程序、系统程序、重要配置参数和边界防护应用程序等进行可信验证,并在应用程序的关键执行环节进行动态可信验证,在检测到其可信性受到破坏后进行报警, 并将验证结果形成审计记录送至安全管理中心\",\n \"requirementEn\": \"Trusted verification, based on the trusted root, can be applied to system boot program, system program, important configuration parameters, and network border protection applications of the network border devices, and dynamic trusted verification can be used in the key execution of the application, and when detecting the credibility thereof. After being damaged, an alarm is issued, and after detecting that its credibility has been damaged, an alarm should be issued and the verification result should be sent to the Security Management Center.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES1-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换\",\n \"requirementEn\": \"The logged-in user should be identified and authenticated. And the identity shall be unique. The identity authentication information should have complexity requirements and be replaced periodically.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-CES1-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"应具有登录失败处理功能,应配置并启用结束会话、限制非法登录次数和当登录连接超时自动退出等相关措施\",\n \"requirementEn\": \"It should have the login failure processing function, and configure and enable the functions of end session, limit the number of illegal logins, and automatically exit when the login connection times out\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 第三方的堡垒机\\n2.AWS平台可考虑基于CLoudTrail日志+Cloudwatch Alarm + Lambda实现\"\n },\n {\n \"id\": \"L3-CES1-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"当进行远程管理时,应采取必要措施防止鉴别信息在网络传输过程中被窃听\",\n \"requirementEn\": \"Necessary measures should be taken to prevent the authentication information from being eavesdropped during network transmission when performing remote management.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 启用传输层加密\\n2. 利用SSH和加密的RDP进行访问EC2\"\n },\n {\n \"id\": \"L3-CES1-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"应采用口令、密码技术、生物技术等两种或两种以上组合的鉴别技术对用户进行身份鉴别, 且其中一种鉴别技术至少应使用密码技术来实现\",\n \"requirementEn\": \"Two or more authentication technologies, e.g. password, cryptography, biotechnology and etc., should be used to identify users, and at least one of them should be implemented by cryptography.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"启用MFA\"\n },\n {\n \"id\": \"L3-CES1-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应对登录的用户分配账号和权限\",\n \"requirementEn\": \"Accounts and permissions should be assigned to the logged in user\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"\\\"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\\\"\"\n },\n {\n \"id\": \"L3-CES1-06\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应重命名或删除默认账户,修改默认账户的默认口令\",\n \"requirementEn\": \"The default account should be renamed or deleted, and the default password of the default account should be changed.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"管理流程\"\n },\n {\n \"id\": \"L3-CES1-07\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应及时删除或停用多余的、过期的账号,避免共享账号的存在\",\n \"requirementEn\": \"The redundant and expired accounts should be deleted or deactivated in time and share accounts is not allowed\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-CES1-08\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应授予管理用户所需的最小权限,实现管理用户的权限分离\",\n \"requirementEn\": \"Administrator access should be reduced to an absolute minimum to achieve separation of administrator privileges\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-CES1-09\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则\",\n \"requirementEn\": \"The access control policy should be configured by the authorized subject, and the access control policy stipulates the access rules of the subject to the object\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"支持基于人员和基于资源的权限分配\"\n },\n {\n \"id\": \"L3-CES1-10\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级\",\n \"requirementEn\": \"The granularity of access control should be at the user level or process level, and the object is at the file and database table level\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-CES1-11\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应对敏感信息资源设置安全标记,并控制主体对有安全标记信息资源的访问\",\n \"requirementEn\": \"Set security tokens for sensitive information resources and control the subject's access to resources with security-tagged information.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"需要应用层面先进行敏感信息的分类,然后利用Tag或者Metadata对数据进行标记,然后利用控制访问策略进行管控\"\n },\n {\n \"id\": \"L3-CES1-12\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应启用安全审计功能,审计覆盖到每个用户,对重要的用户行为和重要安全事件进行审计\",\n \"requirementEn\": \"Security auditing should be enabled, and covers each user, important user behaviors and security incidents\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. CloudTrail \\n2. CloudWatch\\n3. AWS Config 或者 Palo Alto的Prisma Cloud\"\n },\n {\n \"id\": \"L3-CES1-13\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"审计记录应包括事件的日期和时间、用户、事件类型、事件是否成功及其他与审计相关的信息\",\n \"requirementEn\": \"The audit record should include the event date and time, user, event type, success or failure of the event, and other audit-related information\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. CloudTrail \\n2. CloudWatch\\n3. AWS Config 或者 Palo Alto的Prisma Cloud\"\n },\n {\n \"id\": \"L3-CES1-14\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应对审计记录进行保护,定期备份,避免受到未预期的删除、修改或覆盖等\",\n \"requirementEn\": \"Audit records should be protected and backed up regularly to avoid unintended deletions, modifications or overwrites.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. CloudTrail \\n2. CloudWatch\\n3. AWS Config 或者 Palo Alto的Prisma Cloud\"\n },\n {\n \"id\": \"L3-CES1-15\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应对审计进程进行保护,防止未经授权的中断\",\n \"requirementEn\": \"The audit record time shall be synchronized with an accurate time source within the system to ensure the correctness of the audit analysis.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. CloudTrail \\n2. CloudWatch\\n3. AWS Config 或者 Palo Alto的Prisma Cloud\"\n },\n {\n \"id\": \"L3-CES1-17\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应遵循最小安装的原则,仅安装需要的组件和应用程序\",\n \"requirementEn\": \"Follow the principle of minimum installation, and install only the required components and applications.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-CES1-18\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应关闭不需要的系统服务、默认共享和高危端口\",\n \"requirementEn\": \"Unneeded system services, default shares, and high-risk ports should be turned off\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-CES1-19\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应通过设定终端接入方式或网络地址范围对通过网络进行管理的管理终端进行限制\",\n \"requirementEn\": \"The management terminal managed through the network should be restricted by setting the terminal access mode or network address range\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-CES1-20\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应提供数据有效性检验功能,保证通过人机接口输入或通过通信接口输入的内容符合系统设定要求\",\n \"requirementEn\": \"The data validity check function shall be provided to ensure that the content input through the human machine interface or input through the communication interface complies with the system setting requirements\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-CES1-21\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能发现可能存在的漏洞,并在经过充分测试评估后,及时修补漏洞\",\n \"requirementEn\": \"It should be able to identify possible vulnerabilities and fix the vulnerabilities in time after thorough testing and evaluation\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 启用WAF\\n2. 启用GuardDuty\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-CES1-22\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测到对重要节点进行入侵的行为,并在发生严重入侵事件时提供报警\",\n \"requirementEn\": \"It should be able to detect intrusions on important nodes and alert when there is serious intrusion.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 启用WAF\\n2. 启用GuardDuty\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 操作系统层安装第三方安全防护软件\"\n },\n {\n \"id\": \"L3-CES1-23\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"恶意代码防范\",\n \"controlEn\": \"Malicious Code Prevention\",\n \"requirementCn\": \"应采用免受恶意代码攻击的技术措施或主动免疫可信验证机制及时识别入侵和病毒行为,并将其有效阻断\",\n \"requirementEn\": \"Intrusion and virus behavior should be identified and effectively blocked by technical measures against malicious code attacks or active immune trusted authentication mechanisms.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 启用WAF\\n2. 启用GuardDuty\\n3. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n4. 操作系统层安装第三方杀毒产品\"\n },\n {\n \"id\": \"L3-CES1-24\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"可信验证\",\n \"controlEn\": \"Trusted Verification\",\n \"requirementCn\": \"可基于可信根对计算设备的系统引导程序、系统程序、重要配置参数和应用程序等进行可信验证, 并在应用程序的关键执行环节进行动态可信验证,在检测到其可信性受到破坏后进行报警,并将验证 结果形成审计记录送至安全管理中心\",\n \"requirementEn\": \"Trusted verification, based on the trusted root, can be applied to system boot program, system program, important configuration parameters, and applications of the computing devices, and dynamic trusted verification can be used in the key execution of the application, and when detecting the credibility thereof. After being damaged, an alarm is issued, and after detecting that its credibility has been damaged, an alarm should be issued and the verification result should be sent to the Security Management Center.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES1-25\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性\",\n \"controlEn\": \"Data Confidentiality\",\n \"requirementCn\": \"应采用校验技术或密码技术保证重要数据在传输过程中的完整性,包括但不限于鉴别数据、重要业务数据、重要审计数据、重要配置数据、重要视频数据和重要个人信息等\",\n \"requirementEn\": \"Verification techniques or cryptographic techniques should be used to ensure the integrity of important data during transmission, including but not limited to authentication data, important business data, important audit data, important configuration data, important video data and important personal information\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 启用传输加密,并且可以利用Amazon ACM管理密钥\\n2. S3 会验证已上传对象的完整性\\n3. 按照第三方防篡改软件\"\n },\n {\n \"id\": \"L3-CES1-26\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性\",\n \"controlEn\": \"Data Confidentiality\",\n \"requirementCn\": \"应采用校验技术或密码技术保证重要数据在存储过程中的完整性,包括但不限于鉴别数据、重要业务数据、重要审计数据、重要配置数据、重要视频数据和重要个人信息等\",\n \"requirementEn\": \"Verification techniques or cryptographic techniques should be used to ensure the integrity of important data when stored including but not limited to authentication data, important business data, important audit data, important configuration data, important video data and important personal information\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 启用传输加密,并且可以利用Amazon ACM管理密钥\\n2. S3 会验证已上传对象的完整性\\n3. 按照第三方防篡改软件\"\n },\n {\n \"id\": \"L3-CES1-27\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据保密性\",\n \"controlEn\": \"Data Integrity\",\n \"requirementCn\": \"应采用密码技术保证重要数据在传输过程中的保密性,包括但不限于鉴别数据、重要业务数据和重要个人信息等\",\n \"requirementEn\": \"Cryptographic technology should be used to ensure the confidentiality of important data during transmission, including but not limited to authentication data, important business data and important personal information\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"启用KMS\"\n },\n {\n \"id\": \"L3-CES1-28\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据保密性\",\n \"controlEn\": \"Data Integrity\",\n \"requirementCn\": \"应采用密码技术保证重要数据在存储过程中的保密性,包括但不限于鉴别数据、重要业务数据和重要个人信息等\",\n \"requirementEn\": \"Cryptographic technology should be used to ensure the confidentiality of important data when stored, including but not limited to authentication data, important business data and important personal information\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"启用KMS\"\n },\n {\n \"id\": \"L3-CES1-29\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应提供重要数据的本地数据备份与恢复功能\",\n \"requirementEn\": \"Local data backup and recovery functions for important data should be provided\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 存储服务原生支持多副本,客户可以通过快照的方式对数据进行额外备份\\n2. 利用AWS Backup 中心化管理备份的工具。也可以使用AWS各服务中相应的备份功能,单独管理\"\n },\n {\n \"id\": \"L3-CES1-30\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应提供异地实时备份功能,利用通信网络将重要数据实时备份至备份场地\",\n \"requirementEn\": \"Remote real-time backup function should be provided, and use the communication network to back up important data to the backup site in real time\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. 存储服务原生支持多副本,客户可以通过快照的方式对数据进行额外备份\\n2. 利用AWS Backup 中心化管理备份的工具。也可以使用AWS各服务中相应的备份功能,单独管理\\n3. 配置快照和S3跨区域数据复制\"\n },\n {\n \"id\": \"L3-CES1-31\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应提供重要数据处理系统的热冗余,保证系统的高可用性\",\n \"requirementEn\": \"Redundancy of critical data processing systems should be provided to ensure high system availability.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"\\\"1. 存储服务原生支持多副本,客户可以通过快照的方式对数据进行额外备份\\n2. 利用AWS Backup 中心化管理备份的工具。也可以使用AWS各服务中相应的备份功能,单独管理\\\"\"\n },\n {\n \"id\": \"L3-CES1-32\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"剩余信息保护\",\n \"controlEn\": \"Residual Information Protection\",\n \"requirementCn\": \"应保证鉴别信息所在的存储空间被释放或重新分配前得到完全清除\",\n \"requirementEn\": \"Ensure that the storage space where the authentication information is located is completely cleared before being released or redistributed\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. AWS 存储服务的数据清除策略在等保云扩展要求中覆盖\"\n },\n {\n \"id\": \"L3-CES1-33\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"剩余信息保护\",\n \"controlEn\": \"Residual Information Protection\",\n \"requirementCn\": \"应保证存有敏感数据的存储空间被释放或重新分配前得到完全清除\",\n \"requirementEn\": \"Ensure that the storage space containing sensitive data is completely cleared before being released or redistributed.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. AWS 存储服务的数据清除策略在等保云扩展要求中覆盖\"\n },\n {\n \"id\": \"L3-CES1-34\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"个人信息保护\",\n \"controlEn\": \"Personal Information Protection\",\n \"requirementCn\": \"应仅采集和保存业务必需的用户个人信息\",\n \"requirementEn\": \"Only personal information necessary for the business should be collected and stored\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"应用侧行为,AWS不主动采集和保存用户个人信息\"\n },\n {\n \"id\": \"L3-CES1-35\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"个人信息保护\",\n \"controlEn\": \"Personal Information Protection\",\n \"requirementCn\": \"应禁止未授权访问和非法使用用户个人信息\",\n \"requirementEn\": \"Unauthorized access and illegal use of user's personal information should be prohibited.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"应用侧行为,AWS不主动采集和保存用户个人信息\"\n },\n {\n \"id\": \"L3-SMC1-01\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"系统管理\",\n \"controlEn\": \"System Management\",\n \"requirementCn\": \"应对系统管理员进行身份鉴别,只允许其通过特定的命令或操作界面进行系统管理操作,并对这些操作进行审计\",\n \"requirementEn\": \"The system administrator should be authenticated and only allowed to perform system management operations through specific commands or operation interfaces. These operations need to be audited\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-02\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"系统管理\",\n \"controlEn\": \"System Management\",\n \"requirementCn\": \"应通过系统管理员对系统的资源和运行进行配置、控制和管理,包括用户身份、系统资源配置、系统加载和启动、系统运行的异常处理、数据和设备的备份与恢复等\",\n \"requirementEn\": \"The configuration, control, and management of system resources and operations should be performed by system administrators, including user identity, system resource configuration, system loading and startup, system operation exception handling, data and device backup and recovery.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-03\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"审计管理\",\n \"controlEn\": \"Audit Management\",\n \"requirementCn\": \"应对审计管理员进行身份鉴别,只允许其通过特定的命令或操作界面进行安全审计操作,并对这些操作进行审计\",\n \"requirementEn\": \"The audit administrator should be authenticated and only allowed to perform security audit operations through specific commands or operation interfaces. These operations need to be audited\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-04\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"审计管理\",\n \"controlEn\": \"Audit Management\",\n \"requirementCn\": \"应通过审计管理员对审计记录应进行分析,并根据分析结果进行处理,包括根据安全审计策略对审计记录进行存储、管理和查询等\",\n \"requirementEn\": \"The audit administrator should analyze the audit records and dispose them according to the analysis results. The disposals include storage, management and query of the audit records according to the security audit policy.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-05\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"安全管理\",\n \"controlEn\": \"Security Management\",\n \"requirementCn\": \"应对安全管理员进行身份鉴别,只允许其通过特定的命令或操作界面进行安全管理操作,并对这些操作进行审计\",\n \"requirementEn\": \"The security administrator should be authenticated and only allowed to perform security management operations through specific commands or operation interfaces. These operations need to be audited\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-06\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"安全管理\",\n \"controlEn\": \"Security Management\",\n \"requirementCn\": \"应通过安全管理员对系统中的安全策略进行配置,包括安全参数的设置,主体、客体进行统一安全标记,对主体进行授权,配置可信验证策略等\",\n \"requirementEn\": \"The security policy should be configured by the security administrator, including the setting of security parameters, the unified security mark of the subject and the object, the authorization and trusted authentication policy configuration of the subject.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\"\n },\n {\n \"id\": \"L3-SMC1-07\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应划分出特定的管理区域,对分布在网络中的安全设备或安全组件进行管控\",\n \"requirementEn\": \"A specific network management area should be divided to control the security devices or security components distributed in the network\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"利用Firewall Manager可以对WAF进行统一管理\\nGuardDuty可以跨账号统一管理安全发现\\nCloudTrail可以集中对跨账号进行分析\\nSecurityHub可以跨账号统一进行安全发现\"\n },\n {\n \"id\": \"L3-SMC1-08\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应能够建立一条安全的信息传输路径,对网络中的安全设备或安全组件进行管理\",\n \"requirementEn\": \"A secure information transmission channel should be established to manage security devices or security components in the network\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"利用Firewall Manager可以对WAF进行统一管理\\nGuardDuty可以跨账号统一管理安全发现\\nCloudTrail可以集中对跨账号进行分析\\nSecurityHub可以跨账号统一进行安全发现\"\n },\n {\n \"id\": \"L3-SMC1-09\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应对网络链路、安全设备、网络设备和服务器等的运行状况进行集中监测\",\n \"requirementEn\": \"Centralized monitoring of network links, security devices, network devices and servers should be carried out.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudWatch和Splunk进行统一监测\"\n },\n {\n \"id\": \"L3-SMC1-10\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应对分散在各个设备上的审计数据进行收集汇总和集中分析,并保证审计记录的留存时间符合法律法规要求\",\n \"requirementEn\": \"The audit data scattered on various equipment should be collected, summarized and centralized analyzed, and the retention time of audit records should be guaranteed to meet the requirements of laws and regulations.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail\"\n },\n {\n \"id\": \"L3-SMC1-11\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应对安全策略、恶意代码、补丁升级等安全相关事项进行集中管理\",\n \"requirementEn\": \"Security policy, malicious code, patch upgrade and other security related matters should be centrally managed.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"需要第三方防入侵和防病毒支持\"\n },\n {\n \"id\": \"L3-SMC1-12\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应能对网络中发生的各类安全事件进行识别、报警和分析\",\n \"requirementEn\": \"Various types of security incidents occurring in the network can be identified, alerted, and analyzed.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudWatch和Splunk进行统一报警和分析\"\n },\n {\n \"id\": \"L3-PES2-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"基础设施位置\",\n \"controlEn\": \"Location of Infrastructure\",\n \"requirementCn\": \"应保证云计算基础设施位于中国境内\",\n \"requirementEn\": \"Ensure that the cloud computing infrastructure is located in China.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1.参考安全责任共担模型\\n2. AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CNS2-01\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应保证云计算平台不承载高于其安全保护等级的业务应用系统\",\n \"requirementEn\": \"Ensure that the cloud computing platform shall not carry business application systems higher than its security protection level.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1.参考安全责任共担模型\\n2. AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CNS2-02\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应实现不同云服务客户虚拟网络之间的隔离\",\n \"requirementEn\": \"It should implement the independence between different cloud service customer virtual networks.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CNS2-03\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应具有根据云服务客户业务需求提供通信传输、边界防护、入侵防范等安全机制的能力\",\n \"requirementEn\": \"It should have the ability to provide security mechanisms, such as communication transmission, border protection and intrusion prevention, based on the business requirements of cloud service customers.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-CNS2-04\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应具有根据云服务客户业务需求自主设置安全策略的能力,包括定义访问路径、选择安全组件、配置安全策略\",\n \"requirementEn\": \"It should have the ability to independently set security policies based on the business requirements of cloud service customers, including defining access paths, selecting security components and configuring security policies.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CNS2-05\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"应提供开放接口或开放性安全服务,允许云服务客户接入第三方安全产品或在云计算平台选择第三方安全服务\",\n \"requirementEn\": \"It should provide open interfaces or open security services to allow cloud service customers to access third-party security products or select third-party security services on cloud computing platforms.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-ABS2-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在虚拟化网络边界部署访问控制机制,并设置访问控制规则\",\n \"requirementEn\": \"It should deploy access control mechanisms at the boundaries of the virtualized network and set access control rules.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-ABS2-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在不同等级的网络区域边界部署访问控制机制,设置访问控制规则\",\n \"requirementEn\": \"It should deploy access control mechanisms at different levels of network area boundaries and set access control rules.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-ABS2-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测到云服务客户发起的网络攻击行为,并能记录攻击类型、攻击时间、攻击流量等\",\n \"requirementEn\": \"It should be able to detect the network attack behavior initiated by cloud service customers, and record the attack type, attack time, attack traffic, etc.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\"\n },\n {\n \"id\": \"L3-ABS2-04\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测到对虚拟网络节点的网络攻击行为,并能记录攻击类型、攻击时间、攻击流量等\",\n \"requirementEn\": \"It should be able to detect the network attack behavior of virtual network nodes and record the attack type, attack time, attack traffic, etc.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-ABS2-05\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测到虚拟机与宿主机、虚拟机与虚拟机之间的异常流量\",\n \"requirementEn\": \"It should be able to detect abnormal traffic between virtual machines and hosts, and between virtual machines and virtual machines.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-ABS2-06\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应在检测到网络攻击行为、异常流量情况时进行告警\",\n \"requirementEn\": \"It should give an alarm when network attack and abnormal traffic are detected.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"\\\"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范产品\\\"\"\n },\n {\n \"id\": \"L3-ABS2-07\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应对云服务商和云服务客户在远程管理时执行的特权命令进行审计,至少包括虚拟机删除、虚拟机重启\",\n \"requirementEn\": \"Audit the privileged commands executed by the cloud service provider and cloud service customers while remote administration, including at least virtual machine deletion and virtual machine restart.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail and CloudWatch\"\n },\n {\n \"id\": \"L3-ABS2-08\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"安全审计\",\n \"controlEn\": \"Security Audit\",\n \"requirementCn\": \"应保证云服务商对云服务客户系统和数据的操作可被云服务客户审计\",\n \"requirementEn\": \"Ensure that operations of cloud service providers on cloud service customer systems and data can be audited by cloud service customers.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"CloudTrail\"\n },\n {\n \"id\": \"L3-CES2-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"身份鉴别\",\n \"controlEn\": \"Identification and Authentication\",\n \"requirementCn\": \"当远程管理云计算平台中设备时,管理终端和云计算平台之间应建立双向身份验证机制\",\n \"requirementEn\": \"It should establish a mutual authentication mechanism between the management terminal and the cloud computing platform, when remotely managing devices in a cloud computing platform.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\\n3. 利用SSH和加密的RDP进行访问EC2\\n4. 堡垒机\"\n },\n {\n \"id\": \"L3-CES2-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应保证当虚拟机迁移时,访问控制策略随其迁移\",\n \"requirementEn\": \"Ensure that access control policies migrate with the virtual machine as it migrates.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\\n3. 利用SSH和加密的RDP进行访问EC2\\n4. 堡垒机\"\n },\n {\n \"id\": \"L3-CES2-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应允许云服务客户设置不同虚拟机之间的访问控制策略\",\n \"requirementEn\": \"It should allow cloud service customers to set access control policies between different virtual machines.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1. IAM\\n2. 单点登录(Tesla Bounce产品或者AWS SSO 服务将于Q2,2022推出)\\n3. 利用SSH和加密的RDP进行访问EC2\\n4. 堡垒机\"\n },\n {\n \"id\": \"L3-CES2-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测虚拟机之间的资源隔离失效,并进行告警\",\n \"requirementEn\": \"It should be able to detect and alert resource isolation failures between virtual machines.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能检测非授权新建虚拟机或者重新启用虚拟机,并进行告警\",\n \"requirementEn\": \"It should be able to detect and alert unauthorized new or re-enabled virtual machines.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"可通过cloudtrail检测非授权的新建机器行为,并进行告警\"\n },\n {\n \"id\": \"L3-CES2-06\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测恶意代码感染及在虚拟机间蔓延的情况,并进行告警\",\n \"requirementEn\": \"It should be able to detect and alert malicious code infections and spread between virtual machines.\",\n \"referenceStatus\": \"部分符合 Partially\",\n \"referenceComment\": \"1. 按照不同子网设置,采用安全组或者Network ACL,并按照最小化原则机进行配置\\n2. 启用WAF\\n3. 启用GuardDuty\\n4. 使用第三方的下一代防火墙,并结合GLWB进行高可用部署\\n5. 第三方入侵防范和杀毒产品\"\n },\n {\n \"id\": \"L3-CES2-07\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"镜像和快照保护\",\n \"controlEn\": \"Image and Snapshot Protection\",\n \"requirementCn\": \"应针对重要业务系统提供加固的操作系统镜像或操作系统安全加固服务\",\n \"requirementEn\": \"It should provide hardened operating system mirroring or operating system security hardening services for critical business systems.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"若不使用AWS镜像,需要自行加固\"\n },\n {\n \"id\": \"L3-CES2-08\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"镜像和快照保护\",\n \"controlEn\": \"Image and Snapshot Protection\",\n \"requirementCn\": \"应提供虚拟机镜像、快照完整性校验功能,防止虚拟机镜像被恶意篡改\",\n \"requirementEn\": \"It should provide virtual machine image and snapshot integrity check function to prevent malicious tampering of virtual machine image.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"若不使用AWS镜像,需要自行加固\"\n },\n {\n \"id\": \"L3-CES2-09\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"镜像和快照保护\",\n \"controlEn\": \"Image and Snapshot Protection\",\n \"requirementCn\": \"应采取密码技术或其他技术手段防止虚拟机镜像、快照中可能存在的敏感资源被非法访问\",\n \"requirementEn\": \"It should adopt cryptography or other techniques to prevent unauthorized access to sensitive resources that may exist in virtual machine images and snapshots.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"利用KMS对快照进行加密\"\n },\n {\n \"id\": \"L3-CES2-10\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性和保密性\",\n \"controlEn\": \"Data Integrity and Confidentiality\",\n \"requirementCn\": \"应确保云服务客户数据、用户个人信息等存储于中国境内,如需出境应遵循国家相关规定\",\n \"requirementEn\": \"Ensure that cloud service customer data and user personal information are stored in China, and follow relevant national regulations when cross-border transferring.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-11\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性和保密性\",\n \"controlEn\": \"Data Integrity and Confidentiality\",\n \"requirementCn\": \"应确保只有在云服务客户授权下,云服务商或第三方才具有云服务客户数据的管理权限\",\n \"requirementEn\": \"Ensure that the cloud service provider or a third party has the right to manage the cloud service customer data only under the authorization of the cloud service customer.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-12\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性和保密性\",\n \"controlEn\": \"Data Integrity and Confidentiality\",\n \"requirementCn\": \"应使用校验码或密码技术确保虚拟机迁移过程中重要数据的完整性,并在检测到完整性受到破坏时采取必要的恢复措施\",\n \"requirementEn\": \"It should adopt checksum or cryptographic techniques to ensure the integrity of important data during virtual machine migration and take necessary recovery measures when integrity is detected to be compromised.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"传输加密 - ACM\\n存储静态加密 - KMS\\n快照备份服务\"\n },\n {\n \"id\": \"L3-CES2-13\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据完整性和保密性\",\n \"controlEn\": \"Data Integrity and Confidentiality\",\n \"requirementCn\": \"应支持云服务客户部署密钥管理解决方案,保证云服务客户自行实现数据的加解密过程\",\n \"requirementEn\": \"It should support cloud service customers to deploy key management solutions to ensure that cloud service customers can implement the data encryption and decryption process by themselves.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"传输加密 - ACM\\n存储静态加密 - KMS\"\n },\n {\n \"id\": \"L3-CES2-14\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"云服务客户应在本地保存其业务数据的备份\",\n \"requirementEn\": \"Ensure cloud service customers keep a backup of their business data locally.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"请确认是否必须\"\n },\n {\n \"id\": \"L3-CES2-15\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应提供查询云服务客户数据及备份存储位置的能力\",\n \"requirementEn\": \"It should provide the ability to query cloud service customer data and back up storage locations.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-16\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"云服务商的云存储服务应保证云服务客户数据存在若干个可用的副本,各副本之间的内容应保持一致\",\n \"requirementEn\": \"The cloud storage service of the cloud service provider It should ensure that there are several available copies of the customer data of the cloud service, and the contents of each copy It should be consistent.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-CES2-17\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据备份恢复\",\n \"controlEn\": \"Data Backup and Recovery\",\n \"requirementCn\": \"应为云服务客户将业务系统及数据迁移到其他云计算平台和本地系统提供技术手段,并协助完成迁移过程\",\n \"requirementEn\": \"It should provide technical means for cloud service customers to migrate business systems and data to other cloud computing platforms and local systems and assist in the migration process.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"请确认是否必须\"\n },\n {\n \"id\": \"L3-CES2-18\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"剩余信息保护\",\n \"controlEn\": \"Residual Information Protection\",\n \"requirementCn\": \"应保证虚拟机所使用的内存和存储空间回收时得到完全清除\",\n \"requirementEn\": \"Ensure that the memory and storage space used by the virtual machine is completely cleared when reclaimed.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖,不同存储服务均提供数据完全删除或者擦除的方法\"\n },\n {\n \"id\": \"L3-CES2-19\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"剩余信息保护\",\n \"controlEn\": \"Residual Information Protection\",\n \"requirementCn\": \"云服务客户删除业务应用数据时,云计算平台应将云存储中所有副本删除\",\n \"requirementEn\": \"The cloud computing platform It should delete all copies in the cloud storage, when a cloud service customer deletes business application data.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖,不同存储服务均提供数据完全删除或者擦除的方法\"\n },\n {\n \"id\": \"L3-SMC2-01\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应能对物理资源和虚拟资源按照策略做统一管理调度与分配\",\n \"requirementEn\": \"It should be able to uniformly manage and allocate physical resources and virtual resources according to the policy.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-SMC2-02\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应保证云计算平台管理流量与云服务客户业务流量分离\",\n \"requirementEn\": \"Ensure the separation of cloud computing platform management traffic and cloud service customer business traffic.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-SMC2-03\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应根据云服务商和云服务客户的职责划分,收集各自控制部分的审计数据并实现各自的集中审计\",\n \"requirementEn\": \"It should collect the audit data of each control part and implement centralized audit of each control part, according to the responsibilities of cloud service providers and cloud service customers.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1.参考安全责任共担模型\\n2. AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-SMC2-04\",\n \"categoryCn\": \"安全管理中心\",\n \"categoryEn\": \"Security Management Center\",\n \"controlCn\": \"集中管控\",\n \"controlEn\": \"Centralized Management and Control\",\n \"requirementCn\": \"应根据云服务商和云服务客户的职责划分,实现各自控制部分,包括虚拟化网络、虚拟机、虚拟化安全设备等的运行状况的集中监测\",\n \"requirementEn\": \"According to the responsibilities of cloud service providers and cloud service customers, It should realize centralized monitoring of the operation status of their respective control parts, including virtualized networks, virtual machines and virtualized security devices.\",\n \"referenceStatus\": \"符合 No Gap\",\n \"referenceComment\": \"1.参考安全责任共担模型\\n2. AWS自身的等保涵盖\"\n },\n {\n \"id\": \"L3-PES3-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"无线接入点的物理位置\",\n \"controlEn\": \"Location of Wireless Access Point\",\n \"requirementCn\": \"应为无线接入设备的安装选择合理位置,避免过度覆盖和电磁干扰\",\n \"requirementEn\": \"Choose a reasonable location for the installation of wireless access equipment to avoid excessive coverage and electromagnetic interference\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"边界防护\",\n \"controlEn\": \"Border Protection\",\n \"requirementCn\": \"应保证有线网络与无线网络边界之间的访问和数据流通过无线接入网关设备\",\n \"requirementEn\": \"Ensure access and data flow between the wired network and the wireless network boundary pass through the wireless access gateway device\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"无线接入设备应开启接入认证功能,并支持采用认证服务器认证或国家密码管理机构批准的密码模块进行认证\",\n \"requirementEn\": \"Wireless access devices should turn on access authentication function and support to use the authentication server or cryptographic module approved by the State Cryptography Authority of China (SCA).\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测到非授权无线接入设备和非授权移动终端的接入行为\",\n \"requirementEn\": \"Unauthorized wireless access devices and unauthorized mobile terminals should be detected\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-04\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测到针对无线接入设备的网络扫描、DDoS 攻击、密钥破解、中间人攻击和欺骗攻击等行为\",\n \"requirementEn\": \"It should be able to detect network scanning, DDoS attacks, key cracking, man-in-the-middle attacks and deception attacks against wireless access devices.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-05\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够检测到无线接入设备的 SSID 广播、WPS 等高风险功能的开启状态\",\n \"requirementEn\": \"It should be able to detect the use status of high-risk functions such as SSID broadcast and WPS of the wireless access device.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-06\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应禁用无线接入设备和无线接入网关存在风险的功能,如:SSID 广播、WEP 认证等\",\n \"requirementEn\": \"Disable high risk functions of the wireless access device and the wireless access gateway, such as SSID broadcast, WEP authentication, etc.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-07\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应禁止多个 AP 使用同一个认证密钥\",\n \"requirementEn\": \"Multiple APs should be prohibited from using the same authentication key\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS3-08\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够阻断非授权无线接入设备或非授权移动终端\",\n \"requirementEn\": \"It should be able to block the unauthorized wireless access devices or unauthorized mobile terminals\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动终端管控\",\n \"controlEn\": \"Mobile Terminal Control\",\n \"requirementCn\": \"应保证移动终端安装、注册并运行终端管理客户端软件\",\n \"requirementEn\": \"The mobile terminal should be guaranteed to install, register and run the terminal management client software.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动终端管控\",\n \"controlEn\": \"Mobile Terminal Control\",\n \"requirementCn\": \"移动终端应接受移动终端管理服务端的设备生命周期管理、设备远程控制,如:远程锁定、远程擦除等\",\n \"requirementEn\": \"The mobile terminal shall accept the device lifecycle management and remote control from the mobile terminal management server, such as remote locking, remote erasing, etc.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动应用管控\",\n \"controlEn\": \"Mobile Application Control\",\n \"requirementCn\": \"应具有选择应用软件安装、运行的功能\",\n \"requirementEn\": \"It should provide the function which allows to select application software to install and run\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动应用管控\",\n \"controlEn\": \"Mobile Application Control\",\n \"requirementCn\": \"应只允许指定证书签名的应用软件安装和运行\",\n \"requirementEn\": \"Only applications that have specify certificate and signature should be allowed to install and run\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES3-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"移动应用管控\",\n \"controlEn\": \"Mobile Application Control\",\n \"requirementCn\": \"应具有软件白名单功能,应能根据白名单控制应用软件安装、运行\",\n \"requirementEn\": \"It should provide the software whitelist function, and the installation and operation of applications should be controlled according to the whitelist\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES4-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"感知节点设备物理防护\",\n \"controlEn\": \"Physical Protection of Sensor Node\",\n \"requirementCn\": \"感知节点设备所处的物理环境应不对感知节点设备造成物理破坏,如挤压、强振动\",\n \"requirementEn\": \"The physical environment in which the sensor node is located should not cause physical damage to the sensor node, such as extrusion and strong vibration.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES4-02\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"感知节点设备物理防护\",\n \"controlEn\": \"Physical Protection of Sensor Node\",\n \"requirementCn\": \"感知节点设备在工作状态所处物理环境应能正确反映环境状态(如温湿度传感器不能安装在阳光直射区域)\",\n \"requirementEn\": \"The physical environment in which the sensor node is in working status should correctly reflect the environmental state (for example, the temperature and humidity sensor cannot be installed in a direct sunlight area)\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES4-03\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"感知节点设备物理防护\",\n \"controlEn\": \"Physical Protection of Sensor Node\",\n \"requirementCn\": \"感知节点设备在工作状态所处物理环境应不对感知节点设备的正常工作造成影响,如强干扰、阻挡屏蔽等\",\n \"requirementEn\": \"The physical environment in which the sensor node is located should not affect the normal operation of the sensor node, such as strong interference, blocking shielding, etc.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES4-04\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"感知节点设备物理防护\",\n \"controlEn\": \"Physical Protection of Sensor Node\",\n \"requirementCn\": \"关键感知节点设备应具有可供长时间工作的电力供应(关键网关节点设备应具有持久稳定的电力供应能力)\",\n \"requirementEn\": \"Critical sensor nodes should have a power supply for long periods of time (critical gateway node should have a durable and stable power supply capability)\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS4-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"接入控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应保证只有授权的感知节点可以接入\",\n \"requirementEn\": \"Ensured that only authorized sensor nodes can access\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS4-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够限制与感知节点通信的目标地址,以避免对陌生地址的攻击行为\",\n \"requirementEn\": \"The target address to communicate with the sensor node should be restricted, thus avoiding attacks to unfamiliar addresses\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS4-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"入侵防范\",\n \"controlEn\": \"Intrusion Prevention\",\n \"requirementCn\": \"应能够限制与网关节点通信的目标地址,以避免对陌生地址的攻击行为\",\n \"requirementEn\": \"The target address to communicate with the gateway node should be restricted, thus avoiding attacks to unfamiliar addresses\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"感知节点设备安全\",\n \"controlEn\": \"Sensor Node Security\",\n \"requirementCn\": \"应保证只有授权的用户可以对感知节点设备上的软件应用进行配置或变更\",\n \"requirementEn\": \"Ensured that only authorized users can configure or change software applications on the sensor node device.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"感知节点设备安全\",\n \"controlEn\": \"Sensor Node Security\",\n \"requirementCn\": \"应具有对其连接的网关节点设备(包括读卡器)进行身份标识和鉴别的能力\",\n \"requirementEn\": \"It should be able to identify and authenticate the gateway nodes (including card readers) to which they are connected\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"感知节点设备安全\",\n \"controlEn\": \"Sensor Node Security\",\n \"requirementCn\": \"应具有对其连接的其他感知节点设备(包括路由节点)进行身份标识和鉴别的能力\",\n \"requirementEn\": \"It should be able to identify and authenticate other connected node (including routing nodes) to which they are connected\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"应设置最大并发连接数\",\n \"requirementEn\": \"The maximum number of concurrent connections of the gateway node should be set.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"应具备对合法连接设备(包括终端节点、路由节点、数据处理中心)进行标识和鉴别的能力\",\n \"requirementEn\": \"Ability to identify and authenticate legitimate connected devices (including endpoints, routing nodes, data processing centers)\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-06\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"应具备过滤非法节点和伪造节点所发送的数据的能力\",\n \"requirementEn\": \"It should be able to filter data sent by illegal and forged nodes\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-07\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"授权用户应能够在设备使用过程中对关键密钥进行在线更新\",\n \"requirementEn\": \"Authorized users should be able to update critical keys online during device use\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-08\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"网关节点设备安全\",\n \"controlEn\": \"Gateway Node Security\",\n \"requirementCn\": \"授权用户应能够在设备使用过程中对关键配置参数进行在线更新\",\n \"requirementEn\": \"Authorized users should be able to update critical configuration parameters online while the device is in use\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-09\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"抗数据重放\",\n \"controlEn\": \"Anti-data Playback\",\n \"requirementCn\": \"应能够鉴别数据的新鲜性,避免历史数据的重放攻击\",\n \"requirementEn\": \"Identify the freshness of data and avoid replay attacks of historical data\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-10\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"抗数据重放\",\n \"controlEn\": \"Anti-data Playback\",\n \"requirementCn\": \"应能够鉴别历史数据的非法修改,避免数据的修改重放攻击\",\n \"requirementEn\": \"Identifies illegal modification of historical data to avoid data modification and replay attacks\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES4-11\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"数据融合处理\",\n \"controlEn\": \"Data Aggregation Processing\",\n \"requirementCn\": \"应对来自传感网的数据进行数据融合处理,使不同种类的数据可以在同一个平台被使用\",\n \"requirementEn\": \"Data from the sensor network should be aggregated to make different types of data be used on the same platform\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES5-01\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"室外控制设备物理防护\",\n \"controlEn\": \"Physical Protection of Outdoor Control Equipment\",\n \"requirementCn\": \"室外控制设备应放置于采用铁板或其他防火材料制作的箱体或装置中并紧固箱体或装置具有透风、散热、防盗、防雨和防火能力等\",\n \"requirementEn\": \"The outdoor control equipment shall be placed in a box or device made of iron plates or other fireproof materials and fastened to the cabinet or device to have ventilation, heat dissipation, anti-theft, rainproof and fireproof capabilities, etc.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-PES5-02\",\n \"categoryCn\": \"安全物理环境\",\n \"categoryEn\": \"Physical Environment Security\",\n \"controlCn\": \"室外控制设备物理防护\",\n \"controlEn\": \"Physical Protection of Outdoor Control Equipment\",\n \"requirementCn\": \"室外控制设备放置应远离强电磁干扰、强热源等环境,如无法避免应及时做好应急处置及检修, 保证设备正常运行\",\n \"requirementEn\": \"The outdoor control equipment should be placed away from strong electromagnetic interference, strong heat source and other extreme environments. If it is unavoidable, emergency treatment and maintenance should be done in time to ensure the normal operation of the equipment.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CNS5-01\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"工业控制系统与企业其他系统之间应划分为两个区域,区域间应采用单向的技术隔离手段\",\n \"requirementEn\": \"The industrial control system and other systems of the enterprise should be divided into two areas, and one-way technical isolation should be adopted between the areas.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CNS5-02\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"工业控制系统内部应根据业务特点划分为不同的安全域,安全域之间应采用技术隔离手段\",\n \"requirementEn\": \"The industrial control system should be intenally divided into different security domains according to the business feature. Technical isolation should be adopted between different security domains.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CNS5-03\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"网络架构\",\n \"controlEn\": \"Network Architecture\",\n \"requirementCn\": \"涉及实时控制和数据传输的工业控制系统,应使用独立的网络设备组网,在物理层面上实现与其它数据网及外部公共信息网的安全隔离\",\n \"requirementEn\": \"Industrial control systems involving real-time control and data transmission should use independent network equipment to set up a network to achieve secure isolation from other data networks and external public information networks at physical level.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CNS5-04\",\n \"categoryCn\": \"安全通信网络\",\n \"categoryEn\": \"Communication Network Security\",\n \"controlCn\": \"通信传输\",\n \"controlEn\": \"Communication Transmission\",\n \"requirementCn\": \"在工业控制系统内使用广域网进行控制指令或相关数据交换的应采用加密认证技术手段实现身份认证、访问控制和数据加密传输\",\n \"requirementEn\": \"If WAN is used in industrial control system to control instructions or exchange related data, encryption and authentication technology should be adopted to realize identity authentication, access control and data encryption transmission\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-01\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在工业控制系统与企业其他系统之间部署访问控制设备,配置访问控制策略,禁止任何穿越区域边界的 E-Mail、Web、Telnet、Rlogin、FTP 等通用网络服务\",\n \"requirementEn\": \"The access control device should be deployed between the industrial control system and other enterprise systems, and the access control policy should be configured to prohibit any common network services such as E-Mail, Web, Telnet, Rlogin, and FTP that traverse the boundary of the area.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-02\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"访问控制\",\n \"controlEn\": \"Access Control\",\n \"requirementCn\": \"应在工业控制系统内安全域和安全域之间的边界防护机制失效时,及时进行报警\",\n \"requirementEn\": \"The alarm should be promptly issued when the boundary protection mechanism between different security domains fails in the industrial control system.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-03\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"拨号使用控制\",\n \"controlEn\": \"Dail-up Use Control\",\n \"requirementCn\": \"工业控制系统确需使用拨号访问服务的,应限制具有拨号访问权限的用户数量,并采取用户身份鉴别和访问控制等措施\",\n \"requirementEn\": \"If the industrial control system needs to use the dial-up access service, it should limit the number of users with dial-up access rights, and take measures such as user identity authentication and access control.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-04\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"拨号使用控制\",\n \"controlEn\": \"Dail-up Use Control\",\n \"requirementCn\": \"拨号服务器和客户端均应使用经安全加固的操作系统,并采取数字证书认证、传输加密和访问控制等措施\",\n \"requirementEn\": \"Both the dial-up server and the client should use a security-hardened operating system and take measures such as digital certificate authentication, transport encryption, and access control.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-05\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"无线使用控制\",\n \"controlEn\": \"Wireless Use Control\",\n \"requirementCn\": \"应对所有参与无线通信的用户(人员、软件进程或者设备)提供唯一性标识和鉴别\",\n \"requirementEn\": \"Provide unique identification and authentication to all users (personnel, software processes or devices) involved in wireless communications\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-06\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"无线使用控制\",\n \"controlEn\": \"Wireless Use Control\",\n \"requirementCn\": \"应对所有参与无线通信的用户(人员、软件进程或者设备)进行授权以及执行使用进行限制\",\n \"requirementEn\": \"Restrictions on the authorization and execution of all users (personnel, software processes or devices) involved in wireless communication\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-07\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"无线使用控制\",\n \"controlEn\": \"Wireless Use Control\",\n \"requirementCn\": \"应对无线通信采取传输加密的安全措施,实现传输报文的机密性保护\",\n \"requirementEn\": \"Security measures for transmission encryption should be adopted for wireless communication to achieve confidentiality protection of transmitted messages.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-ABS5-08\",\n \"categoryCn\": \"安全区域边界\",\n \"categoryEn\": \"Area Boundary Security\",\n \"controlCn\": \"无线使用控制\",\n \"controlEn\": \"Wireless Use Control\",\n \"requirementCn\": \"对采用无线通信技术进行控制的工业控制系统,应能识别其物理环境中发射的未经授权的无线设备,报告未经授权试图接入或干扰控制系统的行为\",\n \"requirementEn\": \"Industrial control systems that use wireless communication technology should be able to identify unauthorized wireless devices transmitted in their physical environment and report unauthorized attempts to access or interfere with control systems.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-01\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"控制设备自身应实现相应级别安全通用要求提出的身份鉴别、访问控制和安全审计等安全要求,如受条件限制控制设备无法实现上述要求,应由其上位控制或管理设备实现同等功能或通过管理手段控制\",\n \"requirementEn\": \"The control device itself shall implement the security requirements such as identity authentication, access control and security audit proposed by the corresponding level of security general requirements. If the above requirements cannot be implemented by restricted conditions, the equivalent function should be implemented by its upper class control or controlled by management means\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-02\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"应在经过充分测试评估后,在不影响系统安全稳定运行的情况下对控制设备进行补丁更新、固件更新等工作\",\n \"requirementEn\": \"After sufficient testing and evaluation, patches and firmware update can be applied to the control equipment which should not affect the safe and stable operation of the system.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-03\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"应关闭或拆除控制设备的软盘驱动、光盘驱动、USB 接口、串行口或多余网口等,确需保留的必须通过相关的技术措施实施严格的监控管理\",\n \"requirementEn\": \"The floppy disk drive, CD-ROM drive, USB interface, serial port or redundant network port of the control device should be turned off or removed. It should be strictly monitored and managed through relevant technical measures if any of them are indeed to retain.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-04\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"应使用专用设备和专用软件对控制设备进行更新\",\n \"requirementEn\": \"Control equipment should be updated with dedicated equipment and software\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n },\n {\n \"id\": \"L3-CES5-05\",\n \"categoryCn\": \"安全计算环境\",\n \"categoryEn\": \"Computing Environment Security\",\n \"controlCn\": \"控制设备安全\",\n \"controlEn\": \"Control Equipment Security\",\n \"requirementCn\": \"应保证控制设备在上线前经过安全性检测,避免控制设备固件中存在恶意代码程序\",\n \"requirementEn\": \"It should be ensured that the control device is tested for security before going online, and there is no malicious code program in the control device firmware.\",\n \"referenceStatus\": \"不适用 N/A\",\n \"referenceComment\": \"\"\n }\n]","/**\n * MLPS Level 3 (等保三级) GB/T 22239-2019 full checklist mapping.\n *\n * Each of the 184 checks is classified into one of four types:\n * auto — scanner modules can evaluate pass/fail automatically\n * cloud_provider — AWS (cloud platform) is responsible; compliant by default\n * manual — requires manual verification or third-party tools\n * not_applicable — N/A for cloud-only environments (IoT, ICS, wireless, mobile, trusted verification)\n */\n\nimport checklistJson from \"./mlps3-full-checklist.json\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface MlpsChecklistItem {\n id: string;\n categoryCn: string;\n categoryEn: string;\n controlCn: string;\n controlEn: string;\n requirementCn: string;\n requirementEn: string;\n referenceStatus: string;\n referenceComment: string;\n}\n\nexport interface MlpsCheckMapping {\n id: string;\n type: \"auto\" | \"cloud_provider\" | \"manual\" | \"not_applicable\";\n /** For auto: which scanner modules to check */\n modules?: string[];\n /** For auto: specific Security Hub control IDs to match (e.g. \"EC2.2\", \"IAM.7\") */\n securityHubControlIds?: string[];\n /** For auto: keywords to match in finding title/description (use securityHubControlIds when possible) */\n findingPatterns?: string[];\n /** For manual: guidance text */\n guidance?: string;\n /** For cloud_provider: brief note */\n note?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Full checklist data (imported from JSON, bundled by tsup/esbuild)\n// ---------------------------------------------------------------------------\n\nexport const MLPS3_FULL_CHECKLIST: MlpsChecklistItem[] =\n checklistJson as MlpsChecklistItem[];\n\n// ---------------------------------------------------------------------------\n// Category ordering for the report\n// ---------------------------------------------------------------------------\n\nexport const MLPS3_CATEGORY_ORDER = [\n \"安全物理环境\",\n \"安全通信网络\",\n \"安全区域边界\",\n \"安全计算环境\",\n \"安全管理中心\",\n] as const;\n\nexport const MLPS3_CATEGORY_SECTION: Record<string, string> = {\n \"安全物理环境\": \"一、安全物理环境\",\n \"安全通信网络\": \"二、安全通信网络\",\n \"安全区域边界\": \"三、安全区域边界\",\n \"安全计算环境\": \"四、安全计算环境\",\n \"安全管理中心\": \"五、安全管理中心\",\n};\n\n// ---------------------------------------------------------------------------\n// Mapping: 184 checks → type + modules/patterns/guidance\n// ---------------------------------------------------------------------------\n\nexport const MLPS3_CHECK_MAPPING: MlpsCheckMapping[] = [\n // =========================================================================\n // 安全物理环境 — L3-PES1-* (22 items) → cloud_provider\n // =========================================================================\n { id: \"L3-PES1-01\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-02\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-03\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-04\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-05\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-06\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-07\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-08\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-09\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-10\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-11\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-12\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-13\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-14\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-15\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-16\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-17\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-18\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-19\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-20\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-21\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n { id: \"L3-PES1-22\", type: \"cloud_provider\", note: \"AWS 负责机房物理安全\" },\n\n // L3-PES2-01 (Cloud extension — physical infra in China)\n { id: \"L3-PES2-01\", type: \"cloud_provider\", note: \"AWS 中国区基础设施位于中国境内\" },\n\n // L3-PES3-01 (Wireless — N/A)\n { id: \"L3-PES3-01\", type: \"not_applicable\" },\n\n // L3-PES4-* (IoT sensor — N/A)\n { id: \"L3-PES4-01\", type: \"not_applicable\" },\n { id: \"L3-PES4-02\", type: \"not_applicable\" },\n { id: \"L3-PES4-03\", type: \"not_applicable\" },\n { id: \"L3-PES4-04\", type: \"not_applicable\" },\n\n // L3-PES5-* (Industrial control outdoor — N/A)\n { id: \"L3-PES5-01\", type: \"not_applicable\" },\n { id: \"L3-PES5-02\", type: \"not_applicable\" },\n\n // =========================================================================\n // 安全通信网络 — L3-CNS1-* (8 items)\n // =========================================================================\n { id: \"L3-CNS1-01\", type: \"cloud_provider\", note: \"AWS 负责网络设备处理能力\" },\n { id: \"L3-CNS1-02\", type: \"cloud_provider\", note: \"AWS 负责网络带宽\" },\n {\n id: \"L3-CNS1-03\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.2\"],\n },\n {\n id: \"L3-CNS1-04\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.2\", \"EC2.18\", \"EC2.19\"],\n },\n { id: \"L3-CNS1-05\", type: \"cloud_provider\", note: \"AWS 多可用区/多区域冗余\" },\n {\n id: \"L3-CNS1-06\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-CNS1-07\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n { id: \"L3-CNS1-08\", type: \"not_applicable\" },\n\n // L3-CNS2-* (Cloud extension communication — 5 items)\n { id: \"L3-CNS2-01\", type: \"cloud_provider\", note: \"AWS 等保涵盖\" },\n { id: \"L3-CNS2-02\", type: \"cloud_provider\", note: \"VPC 实现虚拟网络隔离\" },\n {\n id: \"L3-CNS2-03\",\n type: \"auto\",\n modules: [\"network_reachability\", \"waf_coverage\", \"guardduty_findings\"],\n },\n { id: \"L3-CNS2-04\", type: \"cloud_provider\", note: \"AWS 支持自主安全策略配置\" },\n { id: \"L3-CNS2-05\", type: \"cloud_provider\", note: \"AWS Marketplace 支持第三方产品\" },\n\n // L3-CNS5-* (Industrial control communication — N/A)\n { id: \"L3-CNS5-01\", type: \"not_applicable\" },\n { id: \"L3-CNS5-02\", type: \"not_applicable\" },\n { id: \"L3-CNS5-03\", type: \"not_applicable\" },\n { id: \"L3-CNS5-04\", type: \"not_applicable\" },\n\n // =========================================================================\n // 安全区域边界 — L3-ABS1-* (20 items)\n // =========================================================================\n {\n id: \"L3-ABS1-01\",\n type: \"auto\",\n modules: [\"network_reachability\", \"waf_coverage\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-02\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-03\",\n type: \"manual\",\n guidance: \"需确认 NAT Gateway、VPC Endpoint 配置,限制内部用户非授权外联\",\n },\n { id: \"L3-ABS1-04\", type: \"not_applicable\" },\n {\n id: \"L3-ABS1-05\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-06\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-07\",\n type: \"auto\",\n modules: [\"network_reachability\", \"waf_coverage\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS1-08\",\n type: \"manual\",\n guidance: \"需启用 WAF 或部署第三方下一代防火墙实现基于会话状态的访问控制\",\n },\n {\n id: \"L3-ABS1-09\",\n type: \"manual\",\n guidance: \"需启用 WAF 或部署第三方下一代防火墙实现基于应用协议的访问控制\",\n },\n {\n id: \"L3-ABS1-10\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\", \"inspector_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"GuardDuty.1\"],\n },\n {\n id: \"L3-ABS1-11\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\", \"inspector_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"GuardDuty.1\"],\n },\n {\n id: \"L3-ABS1-12\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\", \"inspector_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"GuardDuty.1\"],\n },\n {\n id: \"L3-ABS1-13\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-ABS1-14\",\n type: \"manual\",\n guidance: \"需在操作系统安装第三方杀毒软件,或部署下一代防火墙进行恶意代码检测\",\n },\n { id: \"L3-ABS1-15\", type: \"not_applicable\" },\n {\n id: \"L3-ABS1-16\",\n type: \"auto\",\n modules: [\"service_detection\", \"config_rules_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-ABS1-17\",\n type: \"auto\",\n modules: [\"service_detection\", \"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-ABS1-18\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.4\", \"CloudTrail.5\", \"CloudTrail.6\", \"CloudTrail.7\"],\n },\n {\n id: \"L3-ABS1-19\",\n type: \"manual\",\n guidance: \"需配置 S3 Access Log、ALB Access Log,或部署上网行为管理产品进行远程访问行为审计\",\n },\n { id: \"L3-ABS1-20\", type: \"not_applicable\" },\n\n // L3-ABS2-* (Cloud extension boundary — 8 items)\n {\n id: \"L3-ABS2-01\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS2-02\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-ABS2-03\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-ABS2-04\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-ABS2-05\",\n type: \"auto\",\n modules: [\"guardduty_findings\"],\n },\n {\n id: \"L3-ABS2-06\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-ABS2-07\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-ABS2-08\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n\n // L3-ABS3-* (Wireless boundary — N/A)\n { id: \"L3-ABS3-01\", type: \"not_applicable\" },\n { id: \"L3-ABS3-02\", type: \"not_applicable\" },\n { id: \"L3-ABS3-03\", type: \"not_applicable\" },\n { id: \"L3-ABS3-04\", type: \"not_applicable\" },\n { id: \"L3-ABS3-05\", type: \"not_applicable\" },\n { id: \"L3-ABS3-06\", type: \"not_applicable\" },\n { id: \"L3-ABS3-07\", type: \"not_applicable\" },\n { id: \"L3-ABS3-08\", type: \"not_applicable\" },\n\n // L3-ABS4-* (IoT boundary — N/A)\n { id: \"L3-ABS4-01\", type: \"not_applicable\" },\n { id: \"L3-ABS4-02\", type: \"not_applicable\" },\n { id: \"L3-ABS4-03\", type: \"not_applicable\" },\n\n // L3-ABS5-* (Industrial control boundary — N/A)\n { id: \"L3-ABS5-01\", type: \"not_applicable\" },\n { id: \"L3-ABS5-02\", type: \"not_applicable\" },\n { id: \"L3-ABS5-03\", type: \"not_applicable\" },\n { id: \"L3-ABS5-04\", type: \"not_applicable\" },\n { id: \"L3-ABS5-05\", type: \"not_applicable\" },\n { id: \"L3-ABS5-06\", type: \"not_applicable\" },\n { id: \"L3-ABS5-07\", type: \"not_applicable\" },\n { id: \"L3-ABS5-08\", type: \"not_applicable\" },\n\n // =========================================================================\n // 安全计算环境 — L3-CES1-* (34 items, no CES1-16)\n // =========================================================================\n {\n id: \"L3-CES1-01\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"access_analyzer_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.7\", \"IAM.10\", \"IAM.11\"],\n },\n {\n id: \"L3-CES1-02\",\n type: \"manual\",\n guidance: \"需配置堡垒机或通过 CloudTrail + CloudWatch Alarm + Lambda 实现登录失败处理\",\n },\n {\n id: \"L3-CES1-03\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-CES1-04\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"IAM.5\", \"IAM.6\"],\n },\n {\n id: \"L3-CES1-05\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"access_analyzer_findings\"],\n },\n {\n id: \"L3-CES1-06\",\n type: \"manual\",\n guidance: \"需确认已重命名或删除默认账户(如 root 直接登录),修改默认口令\",\n },\n {\n id: \"L3-CES1-07\",\n type: \"auto\",\n modules: [\"security_hub_findings\", \"access_analyzer_findings\"],\n securityHubControlIds: [\"IAM.3\", \"IAM.4\", \"IAM.22\"],\n },\n {\n id: \"L3-CES1-08\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.1\", \"IAM.21\"],\n },\n {\n id: \"L3-CES1-09\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"access_analyzer_findings\"],\n },\n {\n id: \"L3-CES1-10\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.1\", \"IAM.21\"],\n },\n {\n id: \"L3-CES1-11\",\n type: \"manual\",\n guidance: \"需在应用层对敏感信息进行分类,利用 Tag 或 Metadata 标记数据,配合访问控制策略管控\",\n },\n {\n id: \"L3-CES1-12\",\n type: \"auto\",\n modules: [\"service_detection\", \"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-CES1-13\",\n type: \"auto\",\n modules: [\"service_detection\", \"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-CES1-14\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.4\", \"CloudTrail.5\", \"CloudTrail.6\", \"CloudTrail.7\"],\n },\n {\n id: \"L3-CES1-15\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.4\", \"CloudTrail.5\"],\n },\n // Note: L3-CES1-16 does not exist in the standard\n {\n id: \"L3-CES1-17\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-CES1-18\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-CES1-19\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n {\n id: \"L3-CES1-20\",\n type: \"manual\",\n guidance: \"需启用 WAF 规则进行输入验证,或在应用层实现数据有效性检验\",\n },\n {\n id: \"L3-CES1-21\",\n type: \"auto\",\n modules: [\"inspector_findings\", \"patch_compliance_findings\"],\n },\n {\n id: \"L3-CES1-22\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"waf_coverage\"],\n },\n {\n id: \"L3-CES1-23\",\n type: \"manual\",\n guidance: \"需在操作系统层安装第三方杀毒产品;可结合 GuardDuty 检测恶意行为\",\n },\n { id: \"L3-CES1-24\", type: \"not_applicable\" },\n {\n id: \"L3-CES1-25\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-CES1-26\",\n type: \"manual\",\n guidance: \"需安装第三方防篡改软件;S3 可利用对象校验确保完整性\",\n },\n {\n id: \"L3-CES1-27\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-CES1-28\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"S3.4\", \"EC2.7\", \"RDS.3\"],\n },\n {\n id: \"L3-CES1-29\",\n type: \"auto\",\n modules: [\"disaster_recovery\"],\n },\n {\n id: \"L3-CES1-30\",\n type: \"auto\",\n modules: [\"disaster_recovery\"],\n },\n {\n id: \"L3-CES1-31\",\n type: \"auto\",\n modules: [\"disaster_recovery\"],\n },\n { id: \"L3-CES1-32\", type: \"cloud_provider\", note: \"AWS 存储服务数据清除策略覆盖\" },\n { id: \"L3-CES1-33\", type: \"cloud_provider\", note: \"AWS 存储服务数据清除策略覆盖\" },\n {\n id: \"L3-CES1-34\",\n type: \"manual\",\n guidance: \"应用侧行为 — 需确认仅采集和保存业务必需的用户个人信息\",\n },\n {\n id: \"L3-CES1-35\",\n type: \"manual\",\n guidance: \"应用侧行为 — 需确认禁止未授权访问和非法使用用户个人信息\",\n },\n\n // L3-CES2-* (Cloud extension computing — 19 items)\n {\n id: \"L3-CES2-01\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"IAM.5\", \"IAM.6\"],\n },\n { id: \"L3-CES2-02\", type: \"cloud_provider\", note: \"AWS 确保 VM 迁移时访问控制随迁\" },\n {\n id: \"L3-CES2-03\",\n type: \"auto\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n securityHubControlIds: [\"EC2.18\", \"EC2.19\"],\n },\n { id: \"L3-CES2-04\", type: \"cloud_provider\", note: \"AWS 负责虚拟化资源隔离\" },\n {\n id: \"L3-CES2-05\",\n type: \"auto\",\n modules: [\"guardduty_findings\"],\n },\n {\n id: \"L3-CES2-06\",\n type: \"manual\",\n guidance: \"需部署第三方入侵防范和杀毒产品检测虚拟机间恶意代码蔓延\",\n },\n {\n id: \"L3-CES2-07\",\n type: \"manual\",\n guidance: \"若不使用 AWS 官方镜像,需自行加固操作系统\",\n },\n {\n id: \"L3-CES2-08\",\n type: \"manual\",\n guidance: \"若不使用 AWS 官方镜像,需自行校验镜像和快照完整性\",\n },\n {\n id: \"L3-CES2-09\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"EC2.7\"],\n },\n { id: \"L3-CES2-10\", type: \"cloud_provider\", note: \"AWS 中国区数据存储于中国境内\" },\n { id: \"L3-CES2-11\", type: \"cloud_provider\", note: \"AWS 仅在客户授权下管理数据\" },\n { id: \"L3-CES2-12\", type: \"cloud_provider\", note: \"AWS 确保 VM 迁移数据完整性\" },\n {\n id: \"L3-CES2-13\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"KMS.4\"],\n },\n { id: \"L3-CES2-14\", type: \"not_applicable\" },\n { id: \"L3-CES2-15\", type: \"cloud_provider\", note: \"AWS 支持查询数据及备份存储位置\" },\n { id: \"L3-CES2-16\", type: \"cloud_provider\", note: \"AWS 存储服务保证多副本一致\" },\n { id: \"L3-CES2-17\", type: \"not_applicable\" },\n { id: \"L3-CES2-18\", type: \"cloud_provider\", note: \"AWS 确保 VM 内存和存储空间回收时完全清除\" },\n { id: \"L3-CES2-19\", type: \"cloud_provider\", note: \"AWS 确保删除数据时清除所有副本\" },\n\n // L3-CES3-* (Mobile — N/A)\n { id: \"L3-CES3-01\", type: \"not_applicable\" },\n { id: \"L3-CES3-02\", type: \"not_applicable\" },\n { id: \"L3-CES3-03\", type: \"not_applicable\" },\n { id: \"L3-CES3-04\", type: \"not_applicable\" },\n { id: \"L3-CES3-05\", type: \"not_applicable\" },\n\n // L3-CES4-* (IoT sensor/gateway — N/A)\n { id: \"L3-CES4-01\", type: \"not_applicable\" },\n { id: \"L3-CES4-02\", type: \"not_applicable\" },\n { id: \"L3-CES4-03\", type: \"not_applicable\" },\n { id: \"L3-CES4-04\", type: \"not_applicable\" },\n { id: \"L3-CES4-05\", type: \"not_applicable\" },\n { id: \"L3-CES4-06\", type: \"not_applicable\" },\n { id: \"L3-CES4-07\", type: \"not_applicable\" },\n { id: \"L3-CES4-08\", type: \"not_applicable\" },\n { id: \"L3-CES4-09\", type: \"not_applicable\" },\n { id: \"L3-CES4-10\", type: \"not_applicable\" },\n { id: \"L3-CES4-11\", type: \"not_applicable\" },\n\n // L3-CES5-* (Industrial control — N/A)\n { id: \"L3-CES5-01\", type: \"not_applicable\" },\n { id: \"L3-CES5-02\", type: \"not_applicable\" },\n { id: \"L3-CES5-03\", type: \"not_applicable\" },\n { id: \"L3-CES5-04\", type: \"not_applicable\" },\n { id: \"L3-CES5-05\", type: \"not_applicable\" },\n\n // =========================================================================\n // 安全管理中心 — L3-SMC1-* (12 items)\n // =========================================================================\n {\n id: \"L3-SMC1-01\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.4\", \"IAM.6\"],\n },\n {\n id: \"L3-SMC1-02\",\n type: \"auto\",\n modules: [\"security_hub_findings\", \"config_rules_findings\"],\n securityHubControlIds: [\"Config.1\"],\n },\n {\n id: \"L3-SMC1-03\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.4\", \"IAM.6\"],\n },\n {\n id: \"L3-SMC1-04\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-SMC1-05\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.4\", \"IAM.6\"],\n },\n {\n id: \"L3-SMC1-06\",\n type: \"auto\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n securityHubControlIds: [\"IAM.1\", \"IAM.21\"],\n },\n {\n id: \"L3-SMC1-07\",\n type: \"auto\",\n modules: [\"service_detection\"],\n findingPatterns: [\"Security Hub\"],\n },\n {\n id: \"L3-SMC1-08\",\n type: \"auto\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n securityHubControlIds: [\"ELB.1\"],\n },\n {\n id: \"L3-SMC1-09\",\n type: \"manual\",\n guidance: \"需配置 CloudWatch 集中监控平台,结合 SNS 进行告警通知\",\n },\n {\n id: \"L3-SMC1-10\",\n type: \"auto\",\n modules: [\"security_hub_findings\"],\n securityHubControlIds: [\"CloudTrail.1\"],\n },\n {\n id: \"L3-SMC1-11\",\n type: \"manual\",\n guidance: \"需部署第三方防入侵和防病毒产品进行安全策略、恶意代码、补丁升级集中管理\",\n },\n {\n id: \"L3-SMC1-12\",\n type: \"auto\",\n modules: [\"guardduty_findings\", \"security_hub_findings\"],\n securityHubControlIds: [\"GuardDuty.1\"],\n },\n\n // L3-SMC2-* (Cloud extension management center — 4 items)\n { id: \"L3-SMC2-01\", type: \"cloud_provider\", note: \"AWS 负责统一管理调度和分配\" },\n { id: \"L3-SMC2-02\", type: \"cloud_provider\", note: \"AWS 确保管理流量与业务流量分离\" },\n { id: \"L3-SMC2-03\", type: \"cloud_provider\", note: \"AWS 基于责任共担模型实现集中审计\" },\n { id: \"L3-SMC2-04\", type: \"cloud_provider\", note: \"AWS 基于责任共担模型实现集中监测\" },\n];\n\n// ---------------------------------------------------------------------------\n// Lookup helper — build an index for fast access\n// ---------------------------------------------------------------------------\n\nconst _mappingIndex = new Map<string, MlpsCheckMapping>();\nfor (const m of MLPS3_CHECK_MAPPING) {\n _mappingIndex.set(m.id, m);\n}\n\nexport function getMappingById(id: string): MlpsCheckMapping | undefined {\n return _mappingIndex.get(id);\n}\n","import type { FullScanResult, Finding } from \"../types.js\";\nimport {\n MLPS3_FULL_CHECKLIST,\n MLPS3_CATEGORY_ORDER,\n getMappingById,\n type MlpsChecklistItem,\n type MlpsCheckMapping,\n} from \"../data/mlps3-check-mapping.js\";\nimport { getI18n, type Lang } from \"../i18n/index.js\";\n\n// Re-export for use by html-report and tests\nexport {\n MLPS3_FULL_CHECKLIST,\n MLPS3_CHECK_MAPPING,\n MLPS3_CATEGORY_ORDER,\n MLPS3_CATEGORY_SECTION,\n getMappingById,\n type MlpsChecklistItem,\n type MlpsCheckMapping,\n} from \"../data/mlps3-check-mapping.js\";\n\n// ---------------------------------------------------------------------------\n// Full-checklist evaluation result\n// ---------------------------------------------------------------------------\n\nexport type FullCheckStatus = \"clean\" | \"issues\" | \"unknown\" | \"cloud_provider\" | \"manual\" | \"not_applicable\";\n\nexport interface FullCheckResult {\n item: MlpsChecklistItem;\n mapping: MlpsCheckMapping;\n status: FullCheckStatus;\n relatedFindings: Finding[];\n}\n\n/**\n * Evaluate a single checklist item against scan results.\n */\nexport function evaluateFullCheck(\n item: MlpsChecklistItem,\n mapping: MlpsCheckMapping,\n allFindings: Finding[],\n scanModules: Array<{ module: string; status: string }>,\n): FullCheckResult {\n if (mapping.type === \"cloud_provider\") {\n return { item, mapping, status: \"cloud_provider\", relatedFindings: [] };\n }\n if (mapping.type === \"not_applicable\") {\n return { item, mapping, status: \"not_applicable\", relatedFindings: [] };\n }\n if (mapping.type === \"manual\") {\n return { item, mapping, status: \"manual\", relatedFindings: [] };\n }\n\n // Type \"auto\" — check modules present and evaluate findings\n const mods = mapping.modules ?? [];\n\n const allModulesPresent = mods.every((mod) =>\n scanModules.some((m) => m.module === mod && m.status === \"success\"),\n );\n\n if (!allModulesPresent) {\n return { item, mapping, status: \"unknown\", relatedFindings: [] };\n }\n\n let relatedFindings: Finding[];\n\n if (mapping.securityHubControlIds?.length) {\n // Hybrid: security_hub_findings filtered by specific control IDs,\n // other scanner modules matched at module level (all findings count)\n relatedFindings = allFindings.filter((f) => {\n if (!mods.includes(f.module ?? \"\")) return false;\n if (f.module === \"security_hub_findings\") {\n return mapping.securityHubControlIds!.some((id) => f.title.includes(id));\n }\n return true;\n });\n } else if (mapping.findingPatterns?.length) {\n // Pattern-based matching (for service_detection or other special cases)\n const patterns = mapping.findingPatterns;\n relatedFindings = allFindings.filter((f) => {\n if (!mods.includes(f.module ?? \"\")) return false;\n const text = `${f.title} ${f.description}`.toLowerCase();\n return patterns.some((pattern) => text.includes(pattern.toLowerCase()));\n });\n } else {\n // Module-level: any findings from mapped modules = fail\n relatedFindings = allFindings.filter((f) => mods.includes(f.module ?? \"\"));\n }\n\n // Evidence collection: clean (0 findings) or issues (1+ findings)\n const status: FullCheckStatus = relatedFindings.length === 0 ? \"clean\" : \"issues\";\n\n return { item, mapping, status, relatedFindings };\n}\n\n/**\n * Evaluate all 184 checks from the full GB/T 22239-2019 checklist.\n */\nexport function evaluateAllFullChecks(\n scanResults: FullScanResult,\n): FullCheckResult[] {\n const allFindings: Finding[] = scanResults.modules.flatMap((m) =>\n m.findings.map((f) => ({ ...f, module: f.module ?? m.module })),\n );\n const scanModules = scanResults.modules.map((m) => ({\n module: m.module,\n status: m.status,\n }));\n\n return MLPS3_FULL_CHECKLIST.map((item) => {\n const mapping = getMappingById(item.id);\n if (!mapping) {\n // Unmapped check — treat as manual\n return {\n item,\n mapping: { id: item.id, type: \"manual\" as const, guidance: \"未映射的检查项\" },\n status: \"manual\" as FullCheckStatus,\n relatedFindings: [],\n };\n }\n return evaluateFullCheck(item, mapping, allFindings, scanModules);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Legacy types and exports (kept for backward compatibility)\n// ---------------------------------------------------------------------------\n\nexport interface MlpsCheck {\n id: string;\n category: string;\n name: string;\n modules: string[];\n findingPatterns: string[];\n}\n\nexport const MLPS_CHECKS: MlpsCheck[] = [\n // 一、身份鉴别\n {\n id: \"8.1.4.1a\",\n category: \"身份鉴别\",\n name: \"密码策略\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"password policy\", \"password length\", \"complexity\", \"password expiry\", \"reuse prevention\", \"IAM.7\", \"IAM.10\"],\n },\n {\n id: \"8.1.4.1a\",\n category: \"身份鉴别\",\n name: \"密钥轮换\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"access key older\", \"access key rotated\", \"IAM.3\", \"IAM.4\"],\n },\n {\n id: \"8.1.4.1d\",\n category: \"身份鉴别\",\n name: \"双因素认证\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"MFA\", \"IAM.5\", \"IAM.6\"],\n },\n // 二、访问控制\n {\n id: \"8.1.4.2c\",\n category: \"访问控制\",\n name: \"最小权限\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\"],\n findingPatterns: [\n \"AdministratorAccess\", \"PowerUserAccess\", \"IAMFullAccess\",\n \"over-permissive\", \"privilege escalation\",\n \"self-grant\", \"iam:*\", \"create admin\", \"Lambda role passing\",\n \"CreateAccessKey\", \"AssumeRole\",\n ],\n },\n {\n id: \"8.1.4.2\",\n category: \"访问控制\",\n name: \"安全组\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n findingPatterns: [\"allows all ports\", \"allows SSH\", \"allows RDP\", \"MySQL\", \"PostgreSQL\", \"MongoDB\", \"Redis\", \"high-risk port\", \"security group\", \"EC2.18\", \"EC2.19\"],\n },\n // 三、安全审计\n {\n id: \"8.1.4.3a\",\n category: \"安全审计\",\n name: \"审计功能\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"CloudTrail\", \"not enabled\", \"multi-region\", \"not logging\", \"CloudTrail.1\"],\n },\n {\n id: \"8.1.4.3b\",\n category: \"安全审计\",\n name: \"审计完整性\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"log file validation\", \"log integrity\", \"log validation\", \"CloudTrail.4\", \"CloudTrail.5\"],\n },\n {\n id: \"8.1.4.3c\",\n category: \"安全审计\",\n name: \"审计保护\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"CloudTrail\", \"S3 bucket\", \"encryption\", \"versioning\", \"Block Public Access\", \"CloudTrail.6\", \"CloudTrail.7\"],\n },\n // 四、入侵防范\n {\n id: \"8.1.4.4a\",\n category: \"入侵防范\",\n name: \"GuardDuty 威胁检测\",\n modules: [\"service_detection\", \"guardduty_findings\"],\n findingPatterns: [\"GuardDuty\"],\n },\n {\n id: \"8.1.4.4a\",\n category: \"入侵防范\",\n name: \"Inspector 漏洞扫描\",\n modules: [\"service_detection\", \"inspector_findings\"],\n findingPatterns: [\"Inspector\", \"CVE-\"],\n },\n // 五、数据安全\n {\n id: \"8.1.4.5a\",\n category: \"数据安全\",\n name: \"传输加密\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n findingPatterns: [\"HTTPS\", \"TLS\", \"HTTP listener\", \"certificate\", \"ELB.1\"],\n },\n {\n id: \"8.1.4.5b\",\n category: \"数据安全\",\n name: \"S3 存储加密\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"no default encryption\", \"not encrypted\", \"S3.4\"],\n },\n {\n id: \"8.1.4.5b\",\n category: \"数据安全\",\n name: \"EBS 默认加密\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"EBS default encryption\", \"EC2.7\"],\n },\n {\n id: \"8.1.4.5b\",\n category: \"数据安全\",\n name: \"RDS 存储加密\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"storage is not encrypted\", \"RDS.3\"],\n },\n // 六、网络安全\n {\n id: \"8.1.3.1a\",\n category: \"网络安全\",\n name: \"网络架构\",\n modules: [\"security_hub_findings\"],\n findingPatterns: [\"default VPC\", \"EC2.2\"],\n },\n {\n id: \"8.1.3.2a\",\n category: \"网络安全\",\n name: \"边界防护\",\n modules: [\"network_reachability\", \"security_hub_findings\"],\n findingPatterns: [\"allows all ports\", \"allows SSH\", \"allows RDP\", \"security group\", \"EC2.18\", \"EC2.19\"],\n },\n];\n\nexport const CATEGORY_ORDER = [\n \"身份鉴别\",\n \"访问控制\",\n \"安全审计\",\n \"入侵防范\",\n \"数据安全\",\n \"网络安全\",\n];\n\nexport const CATEGORY_SECTION: Record<string, string> = {\n \"身份鉴别\": \"一、身份鉴别\",\n \"访问控制\": \"二、访问控制\",\n \"安全审计\": \"三、安全审计\",\n \"入侵防范\": \"四、入侵防范\",\n \"数据安全\": \"五、数据安全\",\n \"网络安全\": \"六、网络安全\",\n};\n\nexport interface CheckResult {\n check: MlpsCheck;\n status: \"clean\" | \"issues\" | \"unknown\";\n relatedFindings: Finding[];\n}\n\nexport function evaluateCheck(\n check: MlpsCheck,\n allFindings: Finding[],\n scanModules: Array<{ module: string; status: string }>,\n): CheckResult {\n // Verify all required modules ran successfully\n const allModulesPresent = check.modules.every((mod) =>\n scanModules.some((m) => m.module === mod && m.status === \"success\"),\n );\n\n if (!allModulesPresent) {\n return { check, status: \"unknown\", relatedFindings: [] };\n }\n\n // Find findings from the relevant modules that match any of the patterns\n const relatedFindings = allFindings.filter((f) => {\n const moduleMatch = check.modules.some((mod) => f.module === mod);\n if (!moduleMatch) return false;\n\n const text = `${f.title} ${f.description}`.toLowerCase();\n return check.findingPatterns.some((pattern) =>\n text.includes(pattern.toLowerCase()),\n );\n });\n\n return {\n check,\n status: relatedFindings.length === 0 ? \"clean\" : \"issues\",\n relatedFindings,\n };\n}\n\nexport function generateMlps3Report(scanResults: FullScanResult, lang?: Lang): string {\n const t = getI18n(lang ?? \"zh\");\n const isEn = (lang ?? \"zh\") === \"en\";\n const { accountId, region, scanStart } = scanResults;\n const scanTime = scanStart.replace(\"T\", \" \").replace(/\\.\\d+Z$/, \" UTC\");\n\n // Evaluate all 184 checks from the full GB/T 22239-2019 checklist\n const results = evaluateAllFullChecks(scanResults);\n\n // Summary counts by type\n const autoResults = results.filter((r) => r.mapping.type === \"auto\");\n const autoClean = autoResults.filter((r) => r.status === \"clean\").length;\n const autoIssues = autoResults.filter((r) => r.status === \"issues\").length;\n const autoUnknown = autoResults.filter((r) => r.status === \"unknown\").length;\n const checkedTotal = autoClean + autoIssues;\n const cloudCount = results.filter((r) => r.status === \"cloud_provider\").length;\n const manualCount = results.filter((r) => r.status === \"manual\").length;\n const naCount = results.filter((r) => r.status === \"not_applicable\").length;\n\n // Helpers for language-aware item text\n const itemControl = (r: FullCheckResult) => isEn ? r.item.controlEn : r.item.controlCn;\n const itemReq = (r: FullCheckResult) => isEn ? r.item.requirementEn : r.item.requirementCn;\n\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${t.mlpsTitle}`);\n lines.push(`> **${t.mlpsDisclaimer}**`);\n lines.push(\"\");\n\n // Account info\n lines.push(`## ${t.accountInfo}`);\n lines.push(`- ${t.account}: ${accountId} | ${t.region}: ${region} | ${t.scanTime}: ${scanTime}`);\n lines.push(\"\");\n\n // Summary\n lines.push(`## ${t.preCheckOverview}`);\n lines.push(`- ${t.checkedCount(checkedTotal, autoClean, autoIssues)}`);\n if (autoUnknown > 0) {\n lines.push(`- ${t.uncheckedCount(autoUnknown)}`);\n }\n lines.push(`- ${t.cloudProviderCount(cloudCount)}`);\n lines.push(`- ${t.manualReviewCount(manualCount)}`);\n if (naCount > 0) {\n lines.push(`- ${t.naCount(naCount)}`);\n }\n lines.push(\"\");\n\n // Group results by categoryCn (skip N/A items)\n for (const category of MLPS3_CATEGORY_ORDER) {\n const sectionTitle = t.mlpsCategorySection[category] ?? category;\n const catResults = results.filter(\n (r) => r.item.categoryCn === category && r.status !== \"not_applicable\",\n );\n if (catResults.length === 0) continue;\n\n lines.push(`## ${sectionTitle}`);\n lines.push(\"\");\n\n // Group by control within category\n const controlMap = new Map<string, FullCheckResult[]>();\n for (const r of catResults) {\n const key = r.item.controlCn;\n if (!controlMap.has(key)) controlMap.set(key, []);\n controlMap.get(key)!.push(r);\n }\n\n for (const [_controlKey, controlResults] of controlMap) {\n const controlName = itemControl(controlResults[0]);\n lines.push(`### ${controlName}`);\n for (const r of controlResults) {\n const icon = r.status === \"clean\" ? \"\\u2705\"\n : r.status === \"issues\" ? \"\\u274c\"\n : r.status === \"unknown\" ? \"\\u26a0\\ufe0f\"\n : r.status === \"manual\" ? \"\\ud83d\\udccb\"\n : \"\\ud83c\\udfe2\";\n const suffix = r.status === \"unknown\" ? ` \\u2014 ${t.notChecked}`\n : r.status === \"manual\" ? ` \\u2014 ${r.mapping.guidance ?? t.manualReview}`\n : r.status === \"cloud_provider\" ? ` \\u2014 ${r.mapping.note ?? t.cloudProvider}`\n : r.status === \"clean\" ? ` ${t.noIssues}`\n : ` ${t.issuesFound}`;\n\n const reqText = itemReq(r);\n lines.push(`- [${icon}] ${r.item.id} ${reqText.slice(0, 60)}${reqText.length > 60 ? \"\\u2026\" : \"\"}${suffix}`);\n if (r.status === \"issues\" && r.relatedFindings.length > 0) {\n for (const f of r.relatedFindings.slice(0, 3)) {\n lines.push(` - ${f.severity}: ${f.title}`);\n }\n if (r.relatedFindings.length > 3) {\n lines.push(` - ${t.andMore(r.relatedFindings.length - 3)}`);\n }\n }\n }\n lines.push(\"\");\n }\n }\n\n // Remediation recommendations sorted by priority\n const failedResults = results.filter((r) => r.status === \"issues\");\n if (failedResults.length > 0) {\n lines.push(`## ${t.remediationByPriority}`);\n lines.push(\"\");\n\n // Collect all related findings from failed checks, deduplicate, sort by riskScore\n const allFailedFindings = new Map<string, Finding>();\n for (const r of failedResults) {\n for (const f of r.relatedFindings) {\n const key = `${f.resourceId}:${f.title}`;\n if (!allFailedFindings.has(key)) {\n allFailedFindings.set(key, f);\n }\n }\n }\n\n const sorted = [...allFailedFindings.values()].sort(\n (a, b) => b.riskScore - a.riskScore,\n );\n\n for (let i = 0; i < sorted.length; i++) {\n const f = sorted[i];\n const priority = f.riskScore >= 9.0 ? \"P0\" : f.riskScore >= 7.0 ? \"P1\" : f.riskScore >= 4.0 ? \"P2\" : \"P3\";\n const remediation = f.remediationSteps[0] ?? \"Review and remediate.\";\n lines.push(`${i + 1}. [${priority}] ${f.title} — ${remediation}`);\n }\n lines.push(\"\");\n }\n\n // N/A note\n if (naCount > 0) {\n lines.push(`> ${t.naNote(naCount)}`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n","import type { FullScanResult, Finding, Severity, DashboardHistoryEntry, ScanResult } from \"../types.js\";\nimport {\n evaluateAllFullChecks,\n MLPS3_CATEGORY_ORDER,\n type FullCheckResult,\n} from \"./mlps-report.js\";\nimport { VERSION } from \"../version.js\";\nimport { getI18n, type Lang } from \"../i18n/index.js\";\nimport { getSecurityHubSource } from \"../utils/sh-source.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction esc(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/** Only allow http/https URLs — reject javascript:, data:, vbscript:, etc. */\nfunction safeUrl(url: string): string | null {\n try {\n const u = new URL(url);\n if (u.protocol === \"https:\" || u.protocol === \"http:\") return url;\n return null;\n } catch {\n return null;\n }\n}\n\n/** Escape HTML but render URLs as clickable links */\nfunction escWithLinks(s: string): string {\n const parts = s.split(/(https?:\\/\\/\\S+)/);\n return parts.map((part, i) => {\n if (i % 2 === 1) {\n const safe = safeUrl(part);\n if (safe) {\n return `<a href=\"${esc(safe)}\" style=\"color:#60a5fa\" target=\"_blank\" rel=\"noopener\">${esc(part)}</a>`;\n }\n return esc(part);\n }\n return esc(part);\n }).join(\"\");\n}\n\nfunction calcScore(summary: FullScanResult[\"summary\"]): number {\n const raw =\n 100 -\n summary.critical * 15 -\n summary.high * 5 -\n summary.medium * 2 -\n summary.low * 0.5;\n return Math.max(0, Math.min(100, Math.round(raw)));\n}\n\nfunction formatDuration(start: string, end: string): string {\n const ms = new Date(end).getTime() - new Date(start).getTime();\n if (ms < 1000) return `${ms}ms`;\n const secs = Math.round(ms / 1000);\n if (secs < 60) return `${secs}s`;\n return `${Math.floor(secs / 60)}m ${secs % 60}s`;\n}\n\nconst SEV_COLOR: Record<Severity, string> = {\n CRITICAL: \"#ef4444\",\n HIGH: \"#f97316\",\n MEDIUM: \"#eab308\",\n LOW: \"#22c55e\",\n};\n\nconst SEVERITY_ORDER: Severity[] = [\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"];\n\n/** Normalize a recommendation by replacing resource-specific identifiers with placeholders. */\nfunction getRecommendationTemplate(rem: string): string {\n return rem\n .replace(/\\b(i-[0-9a-f]+)\\b/g, '{instance}')\n .replace(/\\b(vol-[0-9a-f]+)\\b/g, '{volume}')\n .replace(/\\b(sg-[0-9a-f]+)\\b/g, '{sg}')\n .replace(/\\b(eipalloc-[0-9a-f]+)\\b/g, '{eip}')\n .replace(/\\b(arn:aws[-\\w]*:[^\"\\s]+)\\b/g, '{arn}')\n .replace(/\"[^\"]+\"/g, '{name}')\n .replace(/bucket \\S+/g, 'bucket {name}')\n .replace(/instance \\S+/g, 'instance {id}')\n .replace(/volume \\S+/g, 'volume {id}')\n .replace(/rule \\S+/g, 'rule {name}');\n}\n\nconst SECURITY_HUB_SUB_CAT_ORDER = [\"FSBP\", \"Inspector\", \"GuardDuty\", \"Config\", \"Access Analyzer\", \"Other\"];\n\nfunction scoreColor(score: number): string {\n if (score >= 80) return \"#22c55e\";\n if (score >= 50) return \"#eab308\";\n return \"#ef4444\";\n}\n\n// ---------------------------------------------------------------------------\n// Service Dependency Reminder\n// ---------------------------------------------------------------------------\n\n// SERVICE_RECOMMENDATIONS are now in the i18n module (t.serviceRecommendations)\n\nconst SERVICE_NOT_ENABLED_PATTERNS = [\n \"not enabled\",\n \"not found\",\n \"No IAM Access Analyzer\",\n \"No SSM-managed instances\",\n \"requires AWS Business or Enterprise Support\",\n \"not available\",\n \"is not enabled\",\n];\n\nfunction getDisabledServices(modules: ScanResult[], lang?: Lang): Array<{ icon: string; service: string; impact: string; action: string }> {\n const t = getI18n(lang ?? \"zh\");\n const disabled: Array<{ icon: string; service: string; impact: string; action: string }> = [];\n for (const mod of modules) {\n const rec = t.serviceRecommendations[mod.module];\n if (!rec) continue;\n if (!mod.warnings?.length) continue;\n const hasNotEnabled = mod.warnings.some((w) =>\n SERVICE_NOT_ENABLED_PATTERNS.some((p) => w.includes(p)),\n );\n if (hasNotEnabled) {\n disabled.push(rec);\n }\n }\n return disabled;\n}\n\nfunction buildServiceReminderHtml(modules: ScanResult[], lang?: Lang): string {\n const t = getI18n(lang ?? \"zh\");\n const disabled = getDisabledServices(modules, lang);\n if (disabled.length === 0) return \"\";\n\n const items = disabled.map((svc) => `\n <div style=\"margin-bottom:12px\">\n <div style=\"font-weight:600;font-size:15px\">${esc(svc.icon)} ${esc(svc.service)} ${esc(t.notEnabled)}</div>\n <div style=\"margin-left:28px;color:#cbd5e1;font-size:13px\">${esc(t.serviceImpact)}\\uff1a${esc(svc.impact)}</div>\n <div style=\"margin-left:28px;color:#cbd5e1;font-size:13px\">${esc(t.serviceAction)}\\uff1a${esc(svc.action)}</div>\n </div>`).join(\"\\n\");\n\n return `\n <section>\n <div style=\"background:#2d1f00;border:1px solid #b45309;border-radius:8px;padding:20px;margin-bottom:32px\">\n <div style=\"font-size:17px;font-weight:700;margin-bottom:12px\">${esc(t.serviceReminderTitle)}</div>\n ${items}\n <div style=\"margin-top:12px;font-size:13px;color:#fbbf24;font-weight:500\">${esc(t.serviceReminderFooter)}</div>\n </div>\n </section>`;\n}\n\n// ---------------------------------------------------------------------------\n// CSS\n// ---------------------------------------------------------------------------\n\nfunction sharedCss(): string {\n return `\n *{margin:0;padding:0;box-sizing:border-box}\n body{background:#0f172a;color:#f8fafc;font-family:Inter,system-ui,-apple-system,sans-serif;line-height:1.6;font-size:14px}\n .container{max-width:900px;margin:0 auto;padding:40px 24px}\n header{text-align:center;margin-bottom:40px;border-bottom:1px solid #334155;padding-bottom:24px}\n header h1{font-size:28px;font-weight:700;margin-bottom:8px;letter-spacing:-0.5px}\n .meta{color:#94a3b8;font-size:13px}\n .disclaimer{color:#94a3b8;font-size:12px;font-style:italic;margin-top:8px;max-width:640px;margin-left:auto;margin-right:auto}\n h2{font-size:20px;font-weight:600;margin:32px 0 16px;padding-bottom:8px;border-bottom:1px solid #334155}\n h3{font-size:16px;font-weight:600;margin:16px 0 8px}\n h4{font-size:14px;font-weight:600;margin:12px 0 4px}\n .card{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:20px;margin-bottom:16px}\n .summary{display:flex;gap:24px;margin-bottom:32px;flex-wrap:wrap}\n .score-card{background:#1e293b;border:1px solid #334155;border-radius:12px;padding:24px 32px;text-align:center;flex:0 0 auto}\n .score-value{font-size:48px;font-weight:700}\n .score-label{color:#94a3b8;font-size:13px;margin-top:4px}\n .severity-stats{display:flex;gap:12px;flex-wrap:wrap;flex:1;align-items:center;justify-content:center}\n .stat-card{border-radius:8px;padding:16px 20px;text-align:center;min-width:100px;border:1px solid #334155;background:#1e293b}\n .stat-count{font-size:28px;font-weight:700}\n .stat-label{font-size:12px;color:#94a3b8;margin-top:2px}\n .stat-critical .stat-count{color:#ef4444}\n .stat-high .stat-count{color:#f97316}\n .stat-medium .stat-count{color:#eab308}\n .stat-low .stat-count{color:#22c55e}\n .charts{display:flex;gap:24px;margin-bottom:32px;flex-wrap:wrap;justify-content:center}\n .chart-box{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:20px;flex:1;min-width:280px}\n .chart-title{font-size:14px;font-weight:600;margin-bottom:12px;text-align:center;color:#cbd5e1}\n .sev-critical{border-left-color:#ef4444}\n .sev-high{border-left-color:#f97316}\n .sev-medium{border-left-color:#eab308}\n .sev-low{border-left-color:#22c55e}\n .badge{display:inline-block;padding:2px 10px;border-radius:4px;font-size:11px;font-weight:700;letter-spacing:0.5px;color:#fff}\n .badge-critical{background:#ef4444}\n .badge-high{background:#f97316}\n .badge-medium{background:#eab308;color:#1e293b}\n .badge-low{background:#22c55e;color:#1e293b}\n .finding-title{font-size:15px;font-weight:600;margin-bottom:8px}\n .finding-detail{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n .finding-detail strong{color:#f8fafc}\n .remediation-steps{margin-top:8px;padding-left:20px}\n .remediation-steps li{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n table{width:100%;border-collapse:collapse;margin-bottom:16px}\n th{background:#334155;color:#f8fafc;padding:10px 12px;text-align:left;font-size:13px;font-weight:600}\n td{padding:8px 12px;border-bottom:1px solid #334155;font-size:13px;color:#cbd5e1}\n tr:hover td{background:rgba(51,65,85,0.3)}\n .recommendations ol{padding-left:24px}\n .recommendations li{margin-bottom:8px;color:#cbd5e1;font-size:13px}\n .priority-p0{color:#ef4444;font-weight:700}\n .priority-p1{color:#f97316;font-weight:700}\n .priority-p2{color:#eab308;font-weight:700}\n .priority-p3{color:#22c55e;font-weight:700}\n footer{margin-top:48px;padding-top:24px;border-top:1px solid #334155;text-align:center}\n footer p{color:#64748b;font-size:12px;margin-bottom:4px}\n .check-item{display:flex;align-items:flex-start;gap:8px;padding:8px 12px;border-radius:6px;margin-bottom:4px;font-size:14px}\n .check-pass{background:rgba(34,197,94,0.1)}\n .check-fail{background:rgba(239,68,68,0.1)}\n .check-unknown{background:rgba(148,163,184,0.1)}\n .check-icon{font-size:16px;flex-shrink:0}\n .check-name{font-weight:500}\n .check-findings{margin-left:28px;margin-top:4px}\n .check-findings li{color:#94a3b8;font-size:12px;margin-bottom:2px;list-style:none}\n .no-findings{text-align:center;padding:40px;color:#22c55e;font-size:18px;font-weight:600}\n .finding-fold{background:#1e293b;border:1px solid #334155;border-radius:8px;margin-bottom:12px;border-left:4px solid;overflow:hidden}\n .finding-fold>summary{cursor:pointer;padding:12px 20px;display:flex;align-items:center;gap:12px;list-style:none;user-select:none}\n .finding-fold>summary::-webkit-details-marker{display:none}\n .finding-fold>summary::marker{content:\"\"}\n .finding-fold>summary .badge{margin-bottom:0}\n .finding-fold>summary::after{content:\"\\\\25B6\";font-size:10px;color:#64748b;flex-shrink:0;transition:transform 0.2s}\n .finding-fold[open]>summary::after{transform:rotate(90deg)}\n .finding-fold[open]>summary{border-bottom:1px solid #334155}\n .finding-body{padding:12px 20px 16px}\n .finding-summary-title{font-weight:600;font-size:14px;flex:1}\n .finding-summary-score{color:#94a3b8;font-size:13px;font-weight:600;white-space:nowrap}\n .top5-card{display:flex;gap:16px;background:#1e293b;border:1px solid #334155;border-radius:12px;padding:24px;margin-bottom:16px;border-left:4px solid}\n .top5-card .badge{margin-bottom:0}\n .top5-rank{font-size:28px;font-weight:800;color:#475569;min-width:44px;display:flex;align-items:flex-start;justify-content:center}\n .top5-content{flex:1}\n .top5-title{font-size:17px;font-weight:700;margin:8px 0}\n .top5-detail{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n .top5-detail strong{color:#f8fafc}\n .top5-remediation{margin-top:8px;padding-left:20px}\n .top5-remediation li{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n .trend-section{margin-bottom:32px}\n .trend-chart{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:20px;margin-bottom:16px}\n .trend-title{font-size:14px;font-weight:600;margin-bottom:12px;text-align:center;color:#cbd5e1}\n .category-fold{background:#1e293b;border:1px solid #334155;border-radius:8px;margin-bottom:16px;overflow:hidden}\n .category-fold>summary{cursor:pointer;padding:16px 20px;display:flex;align-items:center;gap:12px;list-style:none;font-size:18px;font-weight:600;user-select:none}\n .category-fold>summary::-webkit-details-marker{display:none}\n .category-fold>summary::marker{content:\"\"}\n .category-fold>summary::after{content:\"\\\\25B6\";font-size:12px;color:#64748b;flex-shrink:0;transition:transform 0.2s}\n .category-fold[open]>summary::after{transform:rotate(90deg)}\n .category-fold[open]>summary{border-bottom:1px solid #334155}\n .category-body{padding:12px 20px 16px}\n .category-title{flex:1}\n .category-stats{display:inline-flex;gap:12px;font-size:13px}\n .category-stat-pass{color:#22c55e}\n .category-stat-fail{color:#ef4444}\n .category-stat-unknown{color:#94a3b8}\n .module-fold{background:#1e293b;border:1px solid #334155;border-radius:8px;margin-bottom:16px;overflow:hidden}\n .module-fold>summary{cursor:pointer;padding:16px 20px;display:flex;align-items:center;gap:12px;list-style:none;user-select:none;flex-wrap:wrap}\n .module-fold>summary::-webkit-details-marker{display:none}\n .module-fold>summary::marker{content:\"\"}\n .module-fold>summary h3{margin:0;font-size:16px}\n .module-fold>summary::after{content:\"\\\\25B6\";font-size:12px;color:#64748b;flex-shrink:0;transition:transform 0.2s;margin-left:auto}\n .module-fold[open]>summary::after{transform:rotate(90deg)}\n .module-fold[open]>summary{border-bottom:1px solid #334155}\n .module-body{padding:12px 20px 16px}\n .module-badges{display:inline-flex;gap:6px;flex-wrap:wrap}\n .severity-group{margin-bottom:16px}\n .severity-group-fold{margin-bottom:16px}\n .severity-group-fold>summary{cursor:pointer;padding:4px 0;list-style:none;user-select:none}\n .severity-group-fold>summary::-webkit-details-marker{display:none}\n .severity-group-fold>summary::marker{content:\"\"}\n .severity-group-fold>summary h4{margin:0;display:inline}\n .finding-card{display:flex;align-items:center;gap:8px;padding:8px 12px;margin-bottom:4px;border-radius:6px;border-left:4px solid #334155;background:rgba(30,41,59,0.5);flex-wrap:wrap}\n .finding-title-text{font-weight:600;font-size:13px;flex:1;min-width:200px}\n .finding-resource{color:#94a3b8;font-size:12px;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n .finding-card>details{width:100%;margin-top:4px}\n .finding-card>details>summary{cursor:pointer;font-size:12px;color:#60a5fa;user-select:none}\n .finding-card-body{padding:8px 0}\n .finding-card-body p{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n .finding-card-body ol{padding-left:20px}\n .finding-card-body li{color:#cbd5e1;font-size:13px;margin-bottom:2px}\n .rec-fold{background:#1e293b;border:1px solid #334155;border-radius:8px;margin-bottom:16px;overflow:hidden}\n .rec-fold>summary{cursor:pointer;padding:16px 20px;display:flex;align-items:center;gap:12px;list-style:none;user-select:none}\n .rec-fold>summary::-webkit-details-marker{display:none}\n .rec-fold>summary::marker{content:\"\"}\n .rec-fold>summary::after{content:\"\\\\25B6\";font-size:12px;color:#64748b;flex-shrink:0;transition:transform 0.2s;margin-left:auto}\n .rec-fold[open]>summary::after{transform:rotate(90deg)}\n .rec-fold[open]>summary{border-bottom:1px solid #334155}\n .rec-body{padding:12px 20px 16px}\n .rec-body ol{padding-left:24px}\n .rec-body li{margin-bottom:8px;color:#cbd5e1;font-size:13px}\n .rec-body .badge{margin-right:6px;vertical-align:middle}\n .filter-toolbar{display:flex;flex-wrap:wrap;gap:16px;align-items:center;margin-bottom:20px;padding:12px 16px;background:#1e293b;border:1px solid #334155;border-radius:8px}\n .filter-group{display:flex;align-items:center;gap:8px}\n .filter-label{color:#94a3b8;font-size:13px}\n .filter-btn{padding:4px 12px;border-radius:4px;border:1px solid #475569;background:transparent;color:#cbd5e1;cursor:pointer;font-size:13px}\n .filter-btn:hover{background:#334155}\n .filter-btn.active{background:#3b82f6;border-color:#3b82f6;color:#fff}\n .filter-select{padding:4px 8px;border-radius:4px;border:1px solid #475569;background:#0f172a;color:#cbd5e1;font-size:13px}\n .filter-count{color:#64748b;font-size:13px;margin-left:auto}\n @media print{\n .filter-toolbar{display:none !important}\n .finding-card,.module-fold{display:block !important}\n body{background:#fff;color:#1e293b;-webkit-print-color-adjust:exact;print-color-adjust:exact}\n .container{max-width:100%;padding:20px}\n .card,.score-card,.stat-card,.chart-box,.finding-fold,.top5-card,.trend-chart,.category-fold,.module-fold,.finding-card,.rec-fold{background:#fff;border:1px solid #e2e8f0}\n .badge{border:1px solid}\n header{border-bottom-color:#e2e8f0}\n h2{border-bottom-color:#e2e8f0}\n th{background:#f1f5f9;color:#1e293b}\n td{border-bottom-color:#e2e8f0;color:#475569}\n footer{border-top-color:#e2e8f0}\n .meta,.disclaimer{color:#64748b}\n .finding-detail,.top5-detail{color:#475569}\n .finding-detail strong,.top5-detail strong{color:#1e293b}\n .stat-label,.score-label{color:#64748b}\n .chart-title,.trend-title{color:#475569}\n .remediation-steps li,.top5-remediation li{color:#475569}\n .recommendations li{color:#475569}\n .finding-card-body p,.finding-card-body li{color:#475569}\n .finding-title-text{color:#1e293b}\n .finding-resource{color:#64748b}\n .check-findings li{color:#64748b}\n .finding-fold,.top5-card,.category-fold,.module-fold,.finding-card,.rec-fold{break-inside:avoid}\n .check-item{break-inside:avoid}\n svg text{fill:#1e293b !important}\n .finding-fold[open]>summary,.category-fold[open]>summary,.module-fold[open]>summary,.rec-fold[open]>summary{border-bottom-color:#e2e8f0}\n details{display:block}\n details>summary{display:block}\n details>:not(summary){display:block !important}\n }\n `;\n}\n\n// ---------------------------------------------------------------------------\n// SVG Charts\n// ---------------------------------------------------------------------------\n\nfunction donutChart(summary: FullScanResult[\"summary\"]): string {\n const total = summary.totalFindings;\n const r = 80;\n const circ = 2 * Math.PI * r; // ~502.65\n\n if (total === 0) {\n return [\n '<svg viewBox=\"0 0 200 200\" width=\"200\" height=\"200\">',\n ' <circle cx=\"100\" cy=\"100\" r=\"80\" fill=\"none\" stroke=\"#334155\" stroke-width=\"20\"/>',\n ' <text x=\"100\" y=\"105\" text-anchor=\"middle\" fill=\"#22c55e\" font-size=\"24\" font-weight=\"700\">0</text>',\n \"</svg>\",\n ].join(\"\\n\");\n }\n\n const segments: Array<{ count: number; color: string }> = [\n { count: summary.critical, color: SEV_COLOR.CRITICAL },\n { count: summary.high, color: SEV_COLOR.HIGH },\n { count: summary.medium, color: SEV_COLOR.MEDIUM },\n { count: summary.low, color: SEV_COLOR.LOW },\n ].filter((s) => s.count > 0);\n\n let offset = 0;\n const circles = segments.map((s) => {\n const arc = (s.count / total) * circ;\n const el = `<circle cx=\"100\" cy=\"100\" r=\"80\" fill=\"none\" stroke=\"${s.color}\" stroke-width=\"20\" stroke-dasharray=\"${arc.toFixed(2)} ${(circ - arc).toFixed(2)}\" stroke-dashoffset=\"${(-offset).toFixed(2)}\" transform=\"rotate(-90 100 100)\"/>`;\n offset += arc;\n return el;\n });\n\n return [\n '<svg viewBox=\"0 0 200 200\" width=\"200\" height=\"200\">',\n ...circles.map((c) => ` ${c}`),\n ` <text x=\"100\" y=\"105\" text-anchor=\"middle\" fill=\"#f8fafc\" font-size=\"28\" font-weight=\"700\">${total}</text>`,\n \"</svg>\",\n ].join(\"\\n\");\n}\n\nfunction barChart(modules: FullScanResult[\"modules\"], allCleanLabel = \"All modules clean\"): string {\n const withFindings = modules\n .filter((m) => m.findingsCount > 0)\n .sort((a, b) => b.findingsCount - a.findingsCount)\n .slice(0, 12);\n\n if (withFindings.length === 0) {\n return [\n '<svg viewBox=\"0 0 400 50\" width=\"100%\">',\n ` <text x=\"200\" y=\"30\" text-anchor=\"middle\" fill=\"#22c55e\" font-size=\"14\" font-weight=\"600\">${esc(allCleanLabel)}</text>`,\n \"</svg>\",\n ].join(\"\\n\");\n }\n\n const maxCount = withFindings[0].findingsCount;\n const barH = 22;\n const gap = 6;\n const labelW = 160;\n const maxBarW = 190;\n const height = withFindings.length * (barH + gap);\n\n const bars = withFindings.map((m, i) => {\n const y = i * (barH + gap);\n const w = Math.max(4, (m.findingsCount / maxCount) * maxBarW);\n const worstSev = m.findings.reduce<Severity>((worst, f) => {\n const idx = SEVERITY_ORDER.indexOf(f.severity);\n return idx < SEVERITY_ORDER.indexOf(worst) ? f.severity : worst;\n }, \"LOW\");\n const color = SEV_COLOR[worstSev];\n return [\n `<text x=\"${labelW - 8}\" y=\"${y + barH / 2 + 4}\" text-anchor=\"end\" fill=\"#94a3b8\" font-size=\"11\">${esc(m.module)}</text>`,\n `<rect x=\"${labelW}\" y=\"${y}\" width=\"${w.toFixed(1)}\" height=\"${barH}\" rx=\"3\" fill=\"${color}\" opacity=\"0.85\"/>`,\n `<text x=\"${labelW + w + 6}\" y=\"${y + barH / 2 + 4}\" fill=\"#f8fafc\" font-size=\"11\">${m.findingsCount}</text>`,\n ].join(\"\\n\");\n });\n\n return [\n `<svg viewBox=\"0 0 400 ${height}\" width=\"100%\">`,\n ...bars,\n \"</svg>\",\n ].join(\"\\n\");\n}\n\nfunction findingsTrendChart(history: DashboardHistoryEntry[]): string {\n const entries = history.slice(-30);\n if (entries.length < 2) return \"\";\n\n const W = 800;\n const H = 260;\n const pad = { top: 30, right: 20, bottom: 50, left: 50 };\n const plotW = W - pad.left - pad.right;\n const plotH = H - pad.top - pad.bottom;\n\n const maxVal = Math.max(\n 1,\n ...entries.flatMap((e) => [e.critical, e.high, e.medium, e.low]),\n );\n\n const xPos = (i: number) =>\n pad.left + (i / Math.max(1, entries.length - 1)) * plotW;\n const yPos = (v: number) => pad.top + plotH - (v / maxVal) * plotH;\n\n const lines: Array<{\n key: \"critical\" | \"high\" | \"medium\" | \"low\";\n color: string;\n label: string;\n }> = [\n { key: \"critical\", color: \"#ef4444\", label: \"Critical\" },\n { key: \"high\", color: \"#f97316\", label: \"High\" },\n { key: \"medium\", color: \"#eab308\", label: \"Medium\" },\n { key: \"low\", color: \"#22c55e\", label: \"Low\" },\n ];\n\n const polylines = lines\n .map((line) => {\n const pts = entries\n .map(\n (e, i) =>\n `${xPos(i).toFixed(1)},${yPos(e[line.key]).toFixed(1)}`,\n )\n .join(\" \");\n return `<polyline points=\"${pts}\" fill=\"none\" stroke=\"${line.color}\" stroke-width=\"2\" stroke-linejoin=\"round\"/>`;\n })\n .join(\"\\n \");\n\n const xLabels = entries\n .map((e, i) => {\n if (i % 5 !== 0 && i !== entries.length - 1) return \"\";\n return `<text x=\"${xPos(i).toFixed(1)}\" y=\"${H - 8}\" text-anchor=\"middle\" fill=\"#94a3b8\" font-size=\"10\">${e.date.slice(5)}</text>`;\n })\n .filter(Boolean)\n .join(\"\\n \");\n\n const ySteps = 5;\n const yLabels = Array.from({ length: ySteps + 1 }, (_, i) => {\n const val = Math.round((maxVal / ySteps) * i);\n return [\n `<text x=\"${pad.left - 8}\" y=\"${yPos(val).toFixed(1)}\" text-anchor=\"end\" fill=\"#94a3b8\" font-size=\"10\" dominant-baseline=\"middle\">${val}</text>`,\n `<line x1=\"${pad.left}\" y1=\"${yPos(val).toFixed(1)}\" x2=\"${W - pad.right}\" y2=\"${yPos(val).toFixed(1)}\" stroke=\"#334155\" stroke-width=\"0.5\"/>`,\n ].join(\"\\n \");\n }).join(\"\\n \");\n\n const legend = lines\n .map((line, i) => {\n const lx = pad.left + i * 110;\n return `<rect x=\"${lx}\" y=\"8\" width=\"14\" height=\"3\" rx=\"1\" fill=\"${line.color}\"/><text x=\"${lx + 18}\" y=\"12\" fill=\"#94a3b8\" font-size=\"10\">${line.label}</text>`;\n })\n .join(\"\\n \");\n\n return [\n `<svg viewBox=\"0 0 ${W} ${H}\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">`,\n ` ${legend}`,\n ` ${yLabels}`,\n ` ${polylines}`,\n ` ${xLabels}`,\n \"</svg>\",\n ].join(\"\\n\");\n}\n\nfunction scoreTrendChart(history: DashboardHistoryEntry[]): string {\n const entries = history.slice(-30);\n if (entries.length < 2) return \"\";\n\n const W = 800;\n const H = 220;\n const pad = { top: 20, right: 20, bottom: 50, left: 50 };\n const plotW = W - pad.left - pad.right;\n const plotH = H - pad.top - pad.bottom;\n\n const xPos = (i: number) =>\n pad.left + (i / Math.max(1, entries.length - 1)) * plotW;\n const yPos = (v: number) => pad.top + plotH - (v / 100) * plotH;\n\n const pts = entries\n .map((e, i) => `${xPos(i).toFixed(1)},${yPos(e.score).toFixed(1)}`)\n .join(\" \");\n\n const zones = [\n `<rect x=\"${pad.left}\" y=\"${yPos(100).toFixed(1)}\" width=\"${plotW}\" height=\"${(yPos(80) - yPos(100)).toFixed(1)}\" fill=\"#22c55e\" opacity=\"0.06\"/>`,\n `<rect x=\"${pad.left}\" y=\"${yPos(80).toFixed(1)}\" width=\"${plotW}\" height=\"${(yPos(50) - yPos(80)).toFixed(1)}\" fill=\"#eab308\" opacity=\"0.06\"/>`,\n `<rect x=\"${pad.left}\" y=\"${yPos(50).toFixed(1)}\" width=\"${plotW}\" height=\"${(yPos(0) - yPos(50)).toFixed(1)}\" fill=\"#ef4444\" opacity=\"0.06\"/>`,\n ].join(\"\\n \");\n\n const xLabels = entries\n .map((e, i) => {\n if (i % 5 !== 0 && i !== entries.length - 1) return \"\";\n return `<text x=\"${xPos(i).toFixed(1)}\" y=\"${H - 8}\" text-anchor=\"middle\" fill=\"#94a3b8\" font-size=\"10\">${e.date.slice(5)}</text>`;\n })\n .filter(Boolean)\n .join(\"\\n \");\n\n const yVals = [0, 25, 50, 75, 100];\n const yLabels = yVals\n .map(\n (val) =>\n `<text x=\"${pad.left - 8}\" y=\"${yPos(val).toFixed(1)}\" text-anchor=\"end\" fill=\"#94a3b8\" font-size=\"10\" dominant-baseline=\"middle\">${val}</text>\\n <line x1=\"${pad.left}\" y1=\"${yPos(val).toFixed(1)}\" x2=\"${W - pad.right}\" y2=\"${yPos(val).toFixed(1)}\" stroke=\"#334155\" stroke-width=\"0.5\"/>`,\n )\n .join(\"\\n \");\n\n return [\n `<svg viewBox=\"0 0 ${W} ${H}\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">`,\n ` ${zones}`,\n ` ${yLabels}`,\n ` <polyline points=\"${pts}\" fill=\"none\" stroke=\"#60a5fa\" stroke-width=\"2.5\" stroke-linejoin=\"round\"/>`,\n ` ${xLabels}`,\n \"</svg>\",\n ].join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// General HTML Report\n// ---------------------------------------------------------------------------\n\nexport function generateHtmlReport(\n scanResults: FullScanResult,\n history?: DashboardHistoryEntry[],\n lang?: Lang,\n): string {\n const t = getI18n(lang ?? \"zh\");\n const htmlLang = (lang ?? \"zh\") === \"zh\" ? \"zh-CN\" : \"en\";\n const { summary, modules, accountId, region, scanStart, scanEnd } =\n scanResults;\n const date = scanStart.split(\"T\")[0];\n const duration = formatDuration(scanStart, scanEnd);\n const score = calcScore(summary);\n\n const allFindings: Finding[] = modules.flatMap((m) =>\n m.findings.map((f) => ({ ...f, module: f.module ?? m.module })),\n );\n\n // Pre-compute Security Hub sub-categories for bar chart and stats table\n const shModule = modules.find(m => m.module === \"security_hub_findings\");\n const shSubCats: Array<{ key: string; label: string; count: number; findings: Finding[] }> = [];\n if (shModule && shModule.findingsCount > 0) {\n const catMap: Record<string, Finding[]> = {};\n for (const f of shModule.findings) {\n const cat = getSecurityHubSource(f);\n if (!catMap[cat]) catMap[cat] = [];\n catMap[cat].push(f);\n }\n for (const cat of SECURITY_HUB_SUB_CAT_ORDER) {\n const catFindings = catMap[cat];\n if (catFindings && catFindings.length > 0) {\n const meta = t.securityHubSubCategories[cat];\n const shLabel = t.moduleNames[`sh:${cat}`] ?? meta?.label ?? cat;\n shSubCats.push({\n key: cat,\n label: shLabel,\n count: catFindings.length,\n findings: catFindings,\n });\n }\n }\n }\n\n // Detection-only modules — their findings come via Security Hub sub-categories\n const DETECTION_ONLY_MODULES = new Set([\n \"guardduty_findings\",\n \"inspector_findings\",\n \"config_rules_findings\",\n \"access_analyzer_findings\",\n ]);\n\n // Expand SH module into sub-categories for bar chart, hide detection-only scanners\n const barChartModules: ScanResult[] = modules.flatMap(m => {\n if (DETECTION_ONLY_MODULES.has(m.module)) return [];\n if (m.module === \"security_hub_findings\" && shSubCats.length > 0) {\n return shSubCats.map(sc => ({\n ...m,\n module: t.moduleNames[`sh:${sc.key}`] ?? sc.key,\n findingsCount: sc.count,\n findings: sc.findings,\n }));\n }\n return [{ ...m, module: t.moduleNames[m.module] ?? m.module }];\n });\n\n // --- Top 5 Findings ---\n let top5Html = \"\";\n if (allFindings.length > 0) {\n const top5 = [...allFindings]\n .sort((a, b) => b.riskScore - a.riskScore)\n .slice(0, 5);\n const cards = top5\n .map(\n (f, i) => `\n <div class=\"top5-card sev-${esc(f.severity.toLowerCase())}\">\n <div class=\"top5-rank\">#${i + 1}</div>\n <div class=\"top5-content\">\n <span class=\"badge badge-${esc(f.severity.toLowerCase())}\">${esc(f.severity)}</span>\n <div class=\"top5-title\">${esc(f.title)}</div>\n <div class=\"top5-detail\"><strong>${t.resource}:</strong> ${esc(f.resourceId)}</div>\n <div class=\"top5-detail\"><strong>${t.impact}:</strong> ${esc(f.impact)}</div>\n <div class=\"top5-detail\"><strong>${t.riskScore}:</strong> ${f.riskScore}/10</div>\n <h4>${t.remediation}</h4>\n <ol class=\"top5-remediation\">${f.remediationSteps.map((s) => `<li>${escWithLinks(s)}</li>`).join(\"\")}</ol>\n </div>\n </div>`,\n )\n .join(\"\\n\");\n top5Html = `\n <section>\n <h2>${esc(t.topHighestRiskFindings(top5.length))}</h2>\n ${cards}\n </section>`;\n }\n\n // --- Findings HTML (grouped by module, then severity) ---\n let findingsHtml: string;\n let filterToolbarHtml = \"\";\n if (summary.totalFindings === 0) {\n findingsHtml = `<div class=\"no-findings\">${esc(t.noIssuesFound)}</div>`;\n } else {\n const FOLD_THRESHOLD = 20;\n\n const renderCard = (f: Finding, moduleKey: string): string => {\n const sev = f.severity.toLowerCase();\n return `<div class=\"finding-card sev-${esc(sev)}\" data-severity=\"${esc(f.severity)}\" data-module=\"${esc(moduleKey)}\">\n <span class=\"badge badge-${esc(sev)}\">${esc(f.severity)}</span>\n <span class=\"finding-title-text\">${esc(f.title)}</span>\n <span class=\"finding-resource\">${esc(f.resourceArn || f.resourceId)}</span>\n <details><summary>${t.details}</summary><div class=\"finding-card-body\">\n <p>${esc(f.description)}</p>\n <p><strong>${t.remediation}:</strong></p>\n <ol>${f.remediationSteps.map((s) => `<li>${escWithLinks(s)}</li>`).join(\"\")}</ol>\n </div></details>\n </div>`;\n };\n\n const renderCards = (findings: Finding[], moduleKey: string): string => {\n if (findings.length <= FOLD_THRESHOLD) {\n return findings.map(f => renderCard(f, moduleKey)).join(\"\\n\");\n }\n const first = findings.slice(0, FOLD_THRESHOLD).map(f => renderCard(f, moduleKey)).join(\"\\n\");\n const rest = findings.slice(FOLD_THRESHOLD).map(f => renderCard(f, moduleKey)).join(\"\\n\");\n return `${first}\\n<details><summary>${t.showRemainingFindings(findings.length - FOLD_THRESHOLD)}</summary>\\n${rest}\\n</details>`;\n };\n\n const SEV_EMOJI: Record<string, string> = {\n CRITICAL: \"🔴\",\n HIGH: \"🟠\",\n MEDIUM: \"🟡\",\n LOW: \"🔵\",\n };\n\n // Group findings by module\n const moduleMap = new Map<string, Finding[]>();\n for (const f of allFindings) {\n const mod = f.module ?? \"unknown\";\n if (!moduleMap.has(mod)) moduleMap.set(mod, []);\n moduleMap.get(mod)!.push(f);\n }\n\n // Expand security_hub_findings into per-sub-category entries, filter detection-only scanners\n const expandedEntries: Array<[string, Finding[], string | null]> = []; // [key, findings, subCatLabel]\n for (const [mod, findings] of moduleMap.entries()) {\n if (DETECTION_ONLY_MODULES.has(mod)) continue;\n if (mod === \"security_hub_findings\" && shSubCats.length > 0) {\n for (const sc of shSubCats) {\n expandedEntries.push([sc.key, sc.findings, sc.label]);\n }\n } else {\n expandedEntries.push([mod, findings, null]);\n }\n }\n\n // Sort modules: those with critical/high first, then by count\n const moduleEntries = expandedEntries.sort((a, b) => {\n const aHasCritHigh = a[1].some((f) => f.severity === \"CRITICAL\" || f.severity === \"HIGH\");\n const bHasCritHigh = b[1].some((f) => f.severity === \"CRITICAL\" || f.severity === \"HIGH\");\n if (aHasCritHigh !== bHasCritHigh) return aHasCritHigh ? -1 : 1;\n return b[1].length - a[1].length;\n });\n\n const renderSeverityGroups = (findings: Finding[], moduleKey: string): string => {\n return SEVERITY_ORDER.map((sev) => {\n const sevFindings = findings.filter((f) => f.severity === sev);\n if (sevFindings.length === 0) return \"\";\n sevFindings.sort((a, b) => b.riskScore - a.riskScore);\n\n const emoji = SEV_EMOJI[sev] ?? \"\";\n const label = sev.charAt(0) + sev.slice(1).toLowerCase();\n\n return `<details class=\"severity-group-fold\">\n <summary><h4>${emoji} ${label} (${sevFindings.length})</h4></summary>\n ${renderCards(sevFindings, moduleKey)}\n </details>`;\n }).filter(Boolean).join(\"\\n\");\n };\n\n const renderModuleBadges = (findings: Finding[]): string => {\n const sevCounts: Record<string, number> = { CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0 };\n for (const f of findings) sevCounts[f.severity]++;\n return SEVERITY_ORDER\n .filter((sev) => sevCounts[sev] > 0)\n .map((sev) => `<span class=\"badge badge-${sev.toLowerCase()}\">${sevCounts[sev]} ${sev.charAt(0) + sev.slice(1).toLowerCase()}</span>`)\n .join(\" \");\n };\n\n findingsHtml = moduleEntries.map(([modName, modFindings, subCatLabel]) => {\n const badges = renderModuleBadges(modFindings);\n const displayName = subCatLabel ?? (t.moduleNames[modName] ?? modName);\n\n return `<details class=\"module-fold\" data-module=\"${esc(modName)}\">\n <summary>\n <h3>🔒 ${esc(displayName)} (${modFindings.length})</h3>\n <span class=\"module-badges\">${badges}</span>\n </summary>\n <div class=\"module-body\">\n ${renderSeverityGroups(modFindings, modName)}\n </div>\n </details>`;\n }).join(\"\\n\");\n\n // --- Filter toolbar (module options from actual findings) ---\n const moduleOptions = moduleEntries.map(([modKey, , subCatLabel]) => {\n const label = subCatLabel ?? (t.moduleNames[modKey] ?? modKey);\n return `<option value=\"${esc(modKey)}\">${esc(label)}</option>`;\n }).join(\"\\n \");\n\n filterToolbarHtml = `<div class=\"filter-toolbar\" id=\"filterBar\">\n <div class=\"filter-group\">\n <span class=\"filter-label\">${esc(t.filterSeverity)}</span>\n <button class=\"filter-btn active\" data-severity=\"ALL\">${esc(t.filterAll)}</button>\n <button class=\"filter-btn\" data-severity=\"CRITICAL\">Critical</button>\n <button class=\"filter-btn\" data-severity=\"HIGH\">High</button>\n <button class=\"filter-btn\" data-severity=\"MEDIUM\">Medium</button>\n <button class=\"filter-btn\" data-severity=\"LOW\">Low</button>\n </div>\n <div class=\"filter-group\">\n <span class=\"filter-label\">${esc(t.filterModule)}</span>\n <select class=\"filter-select\" id=\"moduleFilter\">\n <option value=\"ALL\">${esc(t.filterAllModules)}</option>\n ${moduleOptions}\n </select>\n </div>\n <div class=\"filter-count\" id=\"filterCount\" data-tpl=\"${esc(t.filterCountTpl)}\"></div>\n </div>`;\n }\n\n // --- Trend Charts ---\n let trendHtml = \"\";\n if (history && history.length >= 2) {\n trendHtml = `\n <section class=\"trend-section\">\n <h2>${esc(t.trendTitle)}</h2>\n <div class=\"trend-chart\">\n <div class=\"trend-title\">${esc(t.findingsBySeverity)}</div>\n ${findingsTrendChart(history)}\n </div>\n <div class=\"trend-chart\">\n <div class=\"trend-title\">${esc(t.securityScore)}</div>\n ${scoreTrendChart(history)}\n </div>\n </section>`;\n }\n\n // --- Statistics table ---\n const isModuleDisabled = (m: ScanResult): string | undefined => {\n if (!m.warnings?.length) return undefined;\n const w = m.warnings.find((w) =>\n SERVICE_NOT_ENABLED_PATTERNS.some((p) => w.includes(p)),\n );\n return w;\n };\n\n const statsRows = modules\n .flatMap(\n (m) => {\n // Hide detection-only scanners — their data is in SH sub-categories\n if (DETECTION_ONLY_MODULES.has(m.module)) return [];\n // Replace security_hub_findings parent row with flat sub-category rows\n if (m.module === \"security_hub_findings\" && shSubCats.length > 0) {\n return shSubCats.map(sc =>\n `<tr><td>${esc(sc.label)}</td><td>${m.resourcesScanned}</td><td>${sc.count}</td><td>✓</td></tr>`,\n );\n }\n // Show N/A for disabled services\n const disabledWarning = isModuleDisabled(m);\n if (disabledWarning) {\n const rec = t.serviceRecommendations[m.module];\n const reason = rec ? rec.action : disabledWarning;\n return [`<tr><td>${esc(t.moduleNames[m.module] ?? m.module)}</td><td>-</td><td>-</td><td style=\"color:#eab308\">⚠ ${esc(reason)}</td></tr>`];\n }\n return [`<tr><td>${esc(t.moduleNames[m.module] ?? m.module)}</td><td>${m.resourcesScanned}</td><td>${m.findingsCount}</td><td>${m.status === \"success\" ? \"✓\" : \"✗\"}</td></tr>`];\n },\n )\n .join(\"\\n\");\n\n // --- Recommendations (deduplicated) ---\n let recsHtml = \"\";\n if (summary.totalFindings > 0) {\n const recMap = new Map<string, { text: string; severity: Severity; count: number; url?: string }>();\n const kbPatches: string[] = [];\n let kbSeverity: Severity = \"LOW\";\n let kbUrl: string | undefined;\n const cveList: string[] = [];\n let cveSeverity: Severity = \"LOW\";\n let cveUrl: string | undefined;\n const genericPatterns = [\"See References\", \"None Provided\", \"Review the finding\", \"Review and remediate.\"];\n\n for (const f of allFindings) {\n const rem = f.remediationSteps[0] ?? \"Review and remediate.\";\n const url = f.remediationSteps.find((s) => s.startsWith(\"Documentation:\"))?.replace(\"Documentation: \", \"\");\n\n // Skip generic remediation\n if (genericPatterns.some(p => rem.startsWith(p))) continue;\n\n // Group KB patches together\n const kbMatch = f.title.match(/KB\\d+/);\n if (kbMatch && (f.module === \"security_hub_findings\" || f.module === \"inspector_findings\")) {\n kbPatches.push(kbMatch[0]);\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(kbSeverity)) kbSeverity = f.severity;\n if (!kbUrl && url) kbUrl = url;\n continue;\n }\n\n // Group CVE vulnerabilities together\n const cveMatch = f.title.match(/CVE-[\\d-]+/);\n if (cveMatch && (f.module === \"security_hub_findings\" || f.module === \"inspector_findings\")) {\n cveList.push(cveMatch[0]);\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(cveSeverity)) cveSeverity = f.severity;\n if (!cveUrl && url) cveUrl = url;\n continue;\n }\n\n // Group Security Hub findings by control ID\n if (f.module === \"security_hub_findings\") {\n const controlMatch = f.title.match(/^([A-Z][A-Za-z0-9]*\\.\\d+)\\s/);\n if (controlMatch) {\n const controlId = controlMatch[1];\n const key = `ctrl:${controlId}`;\n const existing = recMap.get(key);\n if (existing) {\n existing.count++;\n if (!existing.url && url) existing.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existing.severity)) existing.severity = f.severity;\n } else {\n recMap.set(key, { text: `[${controlId}] ${rem}`, severity: f.severity, count: 1, url });\n }\n continue;\n }\n }\n\n // Template-based grouping for own scanner findings (not Security Hub/Inspector)\n if (f.module !== \"security_hub_findings\" && f.module !== \"inspector_findings\") {\n const template = getRecommendationTemplate(rem);\n if (template !== rem) {\n const templateKey = `tmpl:${f.module}:${template}`;\n const existingTmpl = recMap.get(templateKey);\n if (existingTmpl) {\n existingTmpl.count++;\n if (!existingTmpl.url && url) existingTmpl.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existingTmpl.severity)) {\n existingTmpl.severity = f.severity;\n }\n continue;\n }\n recMap.set(templateKey, { text: rem, severity: f.severity, count: 1, url });\n continue;\n }\n }\n\n // Default grouping by remediation text\n const existing = recMap.get(rem);\n if (existing) {\n existing.count++;\n if (!existing.url && url) existing.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existing.severity)) {\n existing.severity = f.severity;\n }\n } else {\n recMap.set(rem, { text: rem, severity: f.severity, count: 1, url });\n }\n }\n\n // Add grouped KB patches as a single entry\n if (kbPatches.length > 0) {\n const unique = [...new Set(kbPatches)];\n const kbList = unique.slice(0, 5).join(\", \") + (unique.length > 5 ? \", \\u2026\" : \"\");\n recMap.set(\"__kb__\", { text: t.installWindowsPatches(unique.length, kbList), severity: kbSeverity, count: 1, url: kbUrl });\n }\n\n // Add grouped CVE vulnerabilities as a single entry\n if (cveList.length > 0) {\n const unique = [...new Set(cveList)];\n const cveDisplay = unique.slice(0, 5).join(\", \") + (unique.length > 5 ? \", \\u2026\" : \"\");\n const cveText = (lang ?? \"zh\") === \"zh\"\n ? `\\u4fee\\u590d ${unique.length} \\u4e2a\\u8f6f\\u4ef6\\u6f0f\\u6d1e (${cveDisplay})\\uff0c\\u66f4\\u65b0\\u53d7\\u5f71\\u54cd\\u7684\\u8f6f\\u4ef6\\u5305\\u5230\\u6700\\u65b0\\u7248\\u672c`\n : `Fix ${unique.length} software vulnerabilities (${cveDisplay}) — update affected packages to latest patched versions`;\n recMap.set(\"__cve__\", { text: cveText, severity: cveSeverity, count: 1, url: cveUrl });\n }\n\n // Post-process: embed resource count for control-ID and template groups\n for (const [key, rec] of recMap) {\n if ((key.startsWith(\"ctrl:\") || key.startsWith(\"tmpl:\")) && rec.count > 1) {\n rec.text += ` \\u2014 ${t.affectedResources(rec.count)}`;\n rec.count = 1;\n }\n }\n\n const uniqueRecs = [...recMap.values()].sort((a, b) => {\n const sevDiff = SEVERITY_ORDER.indexOf(a.severity) - SEVERITY_ORDER.indexOf(b.severity);\n if (sevDiff !== 0) return sevDiff;\n return b.count - a.count;\n });\n\n const renderRec = (r: { text: string; severity: Severity; count: number; url?: string }): string => {\n const sev = r.severity.toLowerCase();\n const countLabel = r.count > 1 ? ` (× ${r.count})` : \"\";\n const safeLink = r.url ? safeUrl(r.url) : null;\n const linkHtml = safeLink ? ` <a href=\"${esc(safeLink)}\" style=\"color:#60a5fa\" target=\"_blank\" rel=\"noopener\">📖</a>` : \"\";\n return `<li><span class=\"badge badge-${esc(sev)}\">${esc(r.severity)}</span> ${esc(r.text)}${countLabel}${linkHtml}</li>`;\n };\n\n const TOP_N = 10;\n const topItems = uniqueRecs.slice(0, TOP_N).map(renderRec).join(\"\\n\");\n const remaining = uniqueRecs.slice(TOP_N);\n const moreHtml = remaining.length > 0\n ? `\\n<details><summary>${t.showMoreCount(remaining.length)}</summary>\\n${remaining.map(renderRec).join(\"\\n\")}\\n</details>`\n : \"\";\n\n recsHtml = `\n <details class=\"rec-fold\">\n <summary><h2 style=\"margin:0;border:0;display:inline\">${esc(t.recommendations)} (${uniqueRecs.length} ${esc(t.unique)})</h2></summary>\n <div class=\"rec-body\">\n <ol>${topItems}${moreHtml}</ol>\n </div>\n </details>`;\n }\n\n // --- Filter script (client-side JS) ---\n const filterScript = summary.totalFindings > 0 ? `<script>\n(function(){\n var activeSev='ALL',activeMod='ALL';\n var countEl=document.getElementById('filterCount');\n var tpl=countEl?countEl.getAttribute('data-tpl'):'';\n function apply(){\n var cards=document.querySelectorAll('.finding-card[data-severity]');\n var shown=0,total=cards.length;\n cards.forEach(function(c){\n var sevOk=activeSev==='ALL'||c.getAttribute('data-severity')===activeSev;\n var modOk=activeMod==='ALL'||c.getAttribute('data-module')===activeMod;\n c.style.display=(sevOk&&modOk)?'':'none';\n if(sevOk&&modOk)shown++;\n });\n if(countEl)countEl.textContent=tpl.replace('{shown}',shown).replace('{total}',total);\n document.querySelectorAll('.module-fold').forEach(function(f){\n var mod=f.getAttribute('data-module');\n if(activeMod!=='ALL'&&mod!==activeMod){f.style.display='none';return;}\n var hasVisible=f.querySelectorAll('.finding-card:not([style*=\"display: none\"])').length>0;\n f.style.display=hasVisible?'':'none';\n });\n document.querySelectorAll('.severity-group-fold').forEach(function(g){\n g.style.display=g.querySelectorAll('.finding-card:not([style*=\"display: none\"])').length?'':'none';\n });\n }\n document.querySelectorAll('.filter-btn[data-severity]').forEach(function(b){\n b.addEventListener('click',function(){\n document.querySelectorAll('.filter-btn[data-severity]').forEach(function(x){x.classList.remove('active')});\n b.classList.add('active');\n activeSev=b.getAttribute('data-severity');\n apply();\n });\n });\n var sel=document.getElementById('moduleFilter');\n if(sel)sel.addEventListener('change',function(){activeMod=sel.value;apply();});\n apply();\n})();\n<\\/script>` : \"\";\n\n return `<!DOCTYPE html>\n<html lang=\"${htmlLang}\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${esc(t.securityReportTitle)} — ${esc(date)}</title>\n<style>${sharedCss()}</style>\n</head>\n<body>\n<div class=\"container\">\n\n<header>\n <h1>🛡️ ${esc(t.securityReportTitle)}</h1>\n <div class=\"meta\">${esc(t.account)}: ${esc(accountId)} | ${esc(t.region)}: ${esc(region)} | ${esc(date)} | ${esc(t.duration)}: ${esc(duration)}</div>\n</header>\n\n<section class=\"summary\">\n <div class=\"score-card\">\n <div class=\"score-value\" style=\"color:${scoreColor(score)}\">${score}</div>\n <div class=\"score-label\">${esc(t.securityScore)}</div>\n </div>\n <div class=\"severity-stats\">\n <div class=\"stat-card stat-critical\"><div class=\"stat-count\">${summary.critical}</div><div class=\"stat-label\">${esc(t.critical)}</div></div>\n <div class=\"stat-card stat-high\"><div class=\"stat-count\">${summary.high}</div><div class=\"stat-label\">${esc(t.high)}</div></div>\n <div class=\"stat-card stat-medium\"><div class=\"stat-count\">${summary.medium}</div><div class=\"stat-label\">${esc(t.medium)}</div></div>\n <div class=\"stat-card stat-low\"><div class=\"stat-count\">${summary.low}</div><div class=\"stat-label\">${esc(t.low)}</div></div>\n </div>\n</section>\n\n<section class=\"charts\">\n <div class=\"chart-box\">\n <div class=\"chart-title\">${esc(t.severityDistribution)}</div>\n <div style=\"text-align:center\">${donutChart(summary)}</div>\n </div>\n <div class=\"chart-box\">\n <div class=\"chart-title\">${esc(t.findingsByModule)}</div>\n ${barChart(barChartModules, t.allModulesClean)}\n </div>\n</section>\n\n${trendHtml}\n\n${top5Html}\n\n${buildServiceReminderHtml(modules, lang)}\n\n<section>\n <h2>${esc(t.scanStatistics)}</h2>\n <table>\n <thead><tr><th>${esc(t.module)}</th><th>${esc(t.resources)}</th><th>${esc(t.findings)}</th><th>${esc(t.status)}</th></tr></thead>\n <tbody>${statsRows}</tbody>\n </table>\n</section>\n\n<section>\n <h2>${esc(t.allFindings)}</h2>\n ${filterToolbarHtml}\n ${findingsHtml}\n</section>\n\n${recsHtml}\n\n<footer>\n <p>${esc(t.generatedBy)} v${VERSION}</p>\n <p>${esc(t.informationalOnly)}</p>\n</footer>\n\n</div>\n${filterScript}\n</body>\n</html>`;\n}\n\n// ---------------------------------------------------------------------------\n// MLPS Level 3 HTML Report (等保三级) — Full GB/T 22239-2019 (184 items)\n// ---------------------------------------------------------------------------\n\nexport function generateMlps3HtmlReport(\n scanResults: FullScanResult,\n history?: DashboardHistoryEntry[],\n lang?: Lang,\n): string {\n const t = getI18n(lang ?? \"zh\");\n const htmlLang = (lang ?? \"zh\") === \"zh\" ? \"zh-CN\" : \"en\";\n const { accountId, region, scanStart } = scanResults;\n const date = scanStart.split(\"T\")[0];\n const scanTime = scanStart.replace(\"T\", \" \").replace(/\\.\\d+Z$/, \" UTC\");\n\n // Evaluate all 184 checks\n const results = evaluateAllFullChecks(scanResults);\n\n // Summary counts by type\n const autoResults = results.filter((r) => r.mapping.type === \"auto\");\n const autoClean = autoResults.filter((r) => r.status === \"clean\").length;\n const autoIssues = autoResults.filter((r) => r.status === \"issues\").length;\n const autoUnknown = autoResults.filter((r) => r.status === \"unknown\").length;\n const checkedTotal = autoClean + autoIssues;\n const cloudCount = results.filter((r) => r.status === \"cloud_provider\").length;\n const manualCount = results.filter((r) => r.status === \"manual\").length;\n const naCount = results.filter((r) => r.status === \"not_applicable\").length;\n\n // --- Trend Charts ---\n let trendHtml = \"\";\n if (history && history.length >= 2) {\n trendHtml = `\n <section class=\"trend-section\">\n <h2>${esc(t.trendTitle)}</h2>\n <div class=\"trend-chart\">\n <div class=\"trend-title\">${esc(t.findingsBySeverity)}</div>\n ${findingsTrendChart(history)}\n </div>\n <div class=\"trend-chart\">\n <div class=\"trend-title\">${esc(t.securityScore)}</div>\n ${scoreTrendChart(history)}\n </div>\n </section>`;\n }\n\n // Helper to pick item text by lang\n const isEn = (lang ?? \"zh\") === \"en\";\n const itemControl = (r: FullCheckResult) => isEn ? r.item.controlEn : r.item.controlCn;\n const itemReq = (r: FullCheckResult) => isEn ? r.item.requirementEn : r.item.requirementCn;\n\n // --- Group results by categoryCn (key is always categoryCn for ordering) ---\n const categoryMap = new Map<string, FullCheckResult[]>();\n for (const r of results) {\n if (r.status === \"not_applicable\") continue; // N/A items excluded from domain sections\n const cat = r.item.categoryCn;\n if (!categoryMap.has(cat)) categoryMap.set(cat, []);\n categoryMap.get(cat)!.push(r);\n }\n\n // --- Build domain sections ---\n const categorySections = MLPS3_CATEGORY_ORDER\n .map((category) => {\n const sectionTitle = t.mlpsCategorySection[category] ?? category;\n const catResults = categoryMap.get(category);\n if (!catResults || catResults.length === 0) return \"\";\n\n // Check if ALL results in this category are cloud_provider\n const allCloud = catResults.every((r) => r.status === \"cloud_provider\");\n if (allCloud) {\n return `<details class=\"category-fold mlps-cloud-section\">\n <summary>\n <span class=\"category-title\">${esc(sectionTitle)}</span>\n <span class=\"category-stats\"><span class=\"category-stat-cloud\">\\ud83c\\udfe2 ${catResults.length} ${esc(t.cloudProvider)}</span></span>\n </summary>\n <div class=\"category-body\">\n <div class=\"mlps-cloud-note\">${esc(t.cloudItemsNote(catResults.length))}</div>\n ${catResults.map((r) => `<div class=\"check-item check-cloud\"><span class=\"check-icon\">\\ud83c\\udfe2</span><span class=\"check-name\">${esc(r.item.id)} ${esc(itemControl(r))}</span><span class=\"check-note\">${esc(r.mapping.note ?? \"\")}</span></div>`).join(\"\\n\")}\n </div>\n</details>`;\n }\n\n // Mixed category — compute stats\n const catClean = catResults.filter((r) => r.status === \"clean\").length;\n const catIssues = catResults.filter((r) => r.status === \"issues\").length;\n const catUnknown = catResults.filter((r) => r.status === \"unknown\").length;\n const catCloud = catResults.filter((r) => r.status === \"cloud_provider\").length;\n const catManual = catResults.filter((r) => r.status === \"manual\").length;\n\n const statsHtml = [\n catClean > 0 ? `<span class=\"category-stat-clean\">\\ud83d\\udfe2 ${catClean}</span>` : \"\",\n catIssues > 0 ? `<span class=\"category-stat-issues\">\\ud83d\\udd34 ${catIssues}</span>` : \"\",\n catUnknown > 0 ? `<span class=\"category-stat-unknown\">? ${catUnknown}</span>` : \"\",\n catCloud > 0 ? `<span class=\"category-stat-cloud\">\\ud83c\\udfe2 ${catCloud}</span>` : \"\",\n catManual > 0 ? `<span class=\"category-stat-manual\">\\ud83d\\udccb ${catManual}</span>` : \"\",\n ].filter(Boolean).join(\"\");\n\n // Group by control within category (key by controlCn for grouping stability)\n const controlMap = new Map<string, FullCheckResult[]>();\n for (const r of catResults) {\n const key = r.item.controlCn;\n if (!controlMap.has(key)) controlMap.set(key, []);\n controlMap.get(key)!.push(r);\n }\n\n const controlGroups = [...controlMap.entries()]\n .map(([_controlKey, controlResults]) => {\n const controlName = itemControl(controlResults[0]);\n // Cloud provider items in this control\n const cloudItems = controlResults.filter((r) => r.status === \"cloud_provider\");\n const nonCloudItems = controlResults.filter((r) => r.status !== \"cloud_provider\");\n\n let itemsHtml = \"\";\n\n // Render non-cloud items\n for (const r of nonCloudItems) {\n const icon = r.status === \"clean\" ? \"\\ud83d\\udfe2\"\n : r.status === \"issues\" ? \"\\ud83d\\udd34\"\n : r.status === \"unknown\" ? \"\\u2b1c\"\n : r.status === \"manual\" ? \"\\ud83d\\udccb\"\n : \"\\ud83c\\udfe2\";\n const cls = `check-${r.status === \"cloud_provider\" ? \"cloud\" : r.status}`;\n const suffix = r.status === \"unknown\" ? ` \\u2014 ${esc(t.notChecked)}`\n : r.status === \"manual\" ? ` \\u2014 ${esc(r.mapping.guidance ?? t.manualReview)}`\n : \"\";\n\n let findingsDetail = \"\";\n if (r.status === \"clean\") {\n findingsDetail = `<div class=\"check-detail\">${esc(t.noRelatedIssues)}</div>`;\n } else if (r.status === \"issues\" && r.relatedFindings.length > 0) {\n const fItems = r.relatedFindings\n .slice(0, 5)\n .map((f) => `<li>${esc(f.severity)}: ${esc(f.title)}</li>`);\n if (r.relatedFindings.length > 5) {\n fItems.push(`<li>${esc(t.andMore(r.relatedFindings.length - 5))}</li>`);\n }\n const remediationHint = r.relatedFindings[0]?.remediationSteps?.[0]\n ? `<p style=\"color:#fbbf24;font-size:12px;margin-top:4px\">${esc(t.remediation)}\\uff1a${escWithLinks(r.relatedFindings[0].remediationSteps[0])}</p>`\n : \"\";\n findingsDetail = `<div class=\"check-findings-wrap\"><details><summary>${esc(t.issuesFoundCount(r.relatedFindings.length))}</summary><ul class=\"check-findings\">${fItems.join(\"\")}</ul>${remediationHint}</details></div>`;\n }\n\n const reqText = itemReq(r);\n itemsHtml += `<div class=\"check-item ${cls}\"><span class=\"check-icon\">${icon}</span><span class=\"check-name\">${esc(r.item.id)} ${esc(reqText.slice(0, 60))}${reqText.length > 60 ? \"\\u2026\" : \"\"}${suffix}</span></div>\\n${findingsDetail}`;\n }\n\n // Render cloud items compactly\n if (cloudItems.length > 0) {\n for (const r of cloudItems) {\n const reqText = itemReq(r);\n itemsHtml += `<div class=\"check-item check-cloud\"><span class=\"check-icon\">\\ud83c\\udfe2</span><span class=\"check-name\">${esc(r.item.id)} ${esc(reqText.slice(0, 50))}${reqText.length > 50 ? \"\\u2026\" : \"\"}</span><span class=\"check-note\">${esc(t.cloudProvider)}</span></div>\\n`;\n }\n }\n\n const grpClean = controlResults.filter((r) => r.status === \"clean\").length;\n const grpIssues = controlResults.filter((r) => r.status === \"issues\").length;\n const grpUnknown = controlResults.filter((r) => r.status === \"unknown\").length;\n const grpCloud = controlResults.filter((r) => r.status === \"cloud_provider\").length;\n const grpManual = controlResults.filter((r) => r.status === \"manual\").length;\n\n const grpStats = [\n grpClean > 0 ? `<span class=\"category-stat-clean\">\\ud83d\\udfe2 ${grpClean}</span>` : \"\",\n grpIssues > 0 ? `<span class=\"category-stat-issues\">\\ud83d\\udd34 ${grpIssues}</span>` : \"\",\n grpUnknown > 0 ? `<span class=\"category-stat-unknown\">? ${grpUnknown}</span>` : \"\",\n grpCloud > 0 ? `<span class=\"category-stat-cloud\">\\ud83c\\udfe2 ${grpCloud}</span>` : \"\",\n grpManual > 0 ? `<span class=\"category-stat-manual\">\\ud83d\\udccb ${grpManual}</span>` : \"\",\n ].filter(Boolean).join(\" \");\n\n // Items with issues expanded by default, others collapsed\n const hasFailures = grpIssues > 0;\n return `<details class=\"severity-group-fold\"${hasFailures ? \" open\" : \"\"}><summary><h4>${esc(controlName)} <span class=\"category-stats\">${grpStats}</span></h4></summary>\\n${itemsHtml}\\n</details>`;\n })\n .join(\"\\n\");\n\n return `<details class=\"category-fold\">\n <summary>\n <span class=\"category-title\">${esc(sectionTitle)}</span>\n <span class=\"category-stats\">${statsHtml}</span>\n </summary>\n <div class=\"category-body\">${controlGroups}</div>\n</details>`;\n })\n .filter(Boolean)\n .join(\"\\n\");\n\n // --- Remediation for failed auto checks (deduplicated) ---\n const failedResults = results.filter((r) => r.status === \"issues\");\n let remediationHtml = \"\";\n if (failedResults.length > 0) {\n const mlpsRecMap = new Map<string, { text: string; severity: Severity; count: number; url?: string }>();\n const mlpsKbPatches: string[] = [];\n let mlpsKbSeverity: Severity = \"LOW\";\n let mlpsKbUrl: string | undefined;\n const mlpsCveList: string[] = [];\n let mlpsCveSeverity: Severity = \"LOW\";\n let mlpsCveUrl: string | undefined;\n const mlpsGenericPatterns = [\"See References\", \"None Provided\", \"Review the finding\", \"Review and remediate.\"];\n\n for (const r of failedResults) {\n for (const f of r.relatedFindings) {\n const rem = f.remediationSteps[0] ?? \"Review and remediate.\";\n const url = f.remediationSteps.find((s) => s.startsWith(\"Documentation:\"))?.replace(\"Documentation: \", \"\");\n\n // Skip generic remediation\n if (mlpsGenericPatterns.some(p => rem.startsWith(p))) continue;\n\n // Group KB patches\n const kbMatch = f.title.match(/KB\\d+/);\n if (kbMatch && (f.module === \"security_hub_findings\" || f.module === \"inspector_findings\")) {\n mlpsKbPatches.push(kbMatch[0]);\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(mlpsKbSeverity)) mlpsKbSeverity = f.severity;\n if (!mlpsKbUrl && url) mlpsKbUrl = url;\n continue;\n }\n\n // Group CVE vulnerabilities\n const cveMatch = f.title.match(/CVE-[\\d-]+/);\n if (cveMatch) {\n mlpsCveList.push(cveMatch[0]);\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(mlpsCveSeverity)) mlpsCveSeverity = f.severity;\n if (!mlpsCveUrl && url) mlpsCveUrl = url;\n continue;\n }\n\n // Group by control ID for Security Hub\n if (f.module === \"security_hub_findings\") {\n const controlMatch = f.title.match(/^([A-Z][A-Za-z0-9]*\\.\\d+)\\s/);\n if (controlMatch) {\n const controlId = controlMatch[1];\n const key = `ctrl:${controlId}`;\n const existing = mlpsRecMap.get(key);\n if (existing) {\n existing.count++;\n if (!existing.url && url) existing.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existing.severity)) existing.severity = f.severity;\n } else {\n mlpsRecMap.set(key, { text: `[${controlId}] ${rem}`, severity: f.severity, count: 1, url });\n }\n continue;\n }\n }\n\n // Template-based grouping for own scanner findings (not Security Hub/Inspector)\n if (f.module !== \"security_hub_findings\" && f.module !== \"inspector_findings\") {\n const template = getRecommendationTemplate(rem);\n if (template !== rem) {\n const templateKey = `tmpl:${f.module}:${template}`;\n const existingTmpl = mlpsRecMap.get(templateKey);\n if (existingTmpl) {\n existingTmpl.count++;\n if (!existingTmpl.url && url) existingTmpl.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existingTmpl.severity)) {\n existingTmpl.severity = f.severity;\n }\n continue;\n }\n mlpsRecMap.set(templateKey, { text: rem, severity: f.severity, count: 1, url });\n continue;\n }\n }\n\n const existing = mlpsRecMap.get(rem);\n if (existing) {\n existing.count++;\n if (!existing.url && url) existing.url = url;\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(existing.severity)) {\n existing.severity = f.severity;\n }\n } else {\n mlpsRecMap.set(rem, { text: rem, severity: f.severity, count: 1, url });\n }\n }\n }\n\n // Add grouped KB patches\n if (mlpsKbPatches.length > 0) {\n const unique = [...new Set(mlpsKbPatches)];\n const kbList = unique.slice(0, 5).join(\", \") + (unique.length > 5 ? \", \\u2026\" : \"\");\n mlpsRecMap.set(\"__kb__\", { text: t.installWindowsPatches(unique.length, kbList), severity: mlpsKbSeverity, count: 1, url: mlpsKbUrl });\n }\n\n if (mlpsCveList.length > 0) {\n const unique = [...new Set(mlpsCveList)];\n const cveDisplay = unique.slice(0, 5).join(\", \") + (unique.length > 5 ? \", \\u2026\" : \"\");\n const cveText = (lang ?? \"zh\") === \"zh\"\n ? `\\u4fee\\u590d ${unique.length} \\u4e2a\\u8f6f\\u4ef6\\u6f0f\\u6d1e (${cveDisplay})\\uff0c\\u66f4\\u65b0\\u53d7\\u5f71\\u54cd\\u7684\\u8f6f\\u4ef6\\u5305\\u5230\\u6700\\u65b0\\u7248\\u672c`\n : `Fix ${unique.length} software vulnerabilities (${cveDisplay}) \\u2014 update affected packages to latest patched versions`;\n mlpsRecMap.set(\"__cve__\", { text: cveText, severity: mlpsCveSeverity, count: 1, url: mlpsCveUrl });\n }\n\n // Post-process: embed resource count for control-ID and template groups\n for (const [key, rec] of mlpsRecMap) {\n if ((key.startsWith(\"ctrl:\") || key.startsWith(\"tmpl:\")) && rec.count > 1) {\n rec.text += ` \\u2014 ${t.affectedResources(rec.count)}`;\n rec.count = 1;\n }\n }\n\n const mlpsUniqueRecs = [...mlpsRecMap.values()].sort((a, b) => {\n const sevDiff = SEVERITY_ORDER.indexOf(a.severity) - SEVERITY_ORDER.indexOf(b.severity);\n if (sevDiff !== 0) return sevDiff;\n return b.count - a.count;\n });\n\n if (mlpsUniqueRecs.length > 0) {\n const renderMlpsRec = (r: { text: string; severity: Severity; count: number; url?: string }): string => {\n const sev = r.severity.toLowerCase();\n const countLabel = r.count > 1 ? ` (× ${r.count})` : \"\";\n const safeLink = r.url ? safeUrl(r.url) : null;\n const linkHtml = safeLink ? ` <a href=\"${esc(safeLink)}\" style=\"color:#60a5fa\" target=\"_blank\" rel=\"noopener\">📖</a>` : \"\";\n return `<li><span class=\"badge badge-${esc(sev)}\">${esc(r.severity)}</span> ${esc(r.text)}${countLabel}${linkHtml}</li>`;\n };\n\n const MLPS_TOP_N = 10;\n const mlpsTopItems = mlpsUniqueRecs.slice(0, MLPS_TOP_N).map(renderMlpsRec).join(\"\\n\");\n const mlpsRemaining = mlpsUniqueRecs.slice(MLPS_TOP_N);\n const mlpsMoreHtml = mlpsRemaining.length > 0\n ? `\\n<details><summary>${esc(t.showRemaining(mlpsRemaining.length))}…</summary>\\n${mlpsRemaining.map(renderMlpsRec).join(\"\\n\")}\\n</details>`\n : \"\";\n\n remediationHtml = `\n <details class=\"rec-fold\" open>\n <summary><h2 style=\"margin:0;border:0;display:inline\">${esc(t.remediationItems(mlpsUniqueRecs.length))}</h2></summary>\n <div class=\"rec-body\">\n <ol>${mlpsTopItems}${mlpsMoreHtml}</ol>\n </div>\n </details>`;\n }\n }\n\n // --- N/A count at bottom ---\n const naNote = naCount > 0\n ? `<p style=\"color:#64748b;font-size:13px;margin-top:24px\">${esc(t.naNote(naCount))}</p>`\n : \"\";\n\n const unknownNote =\n autoUnknown > 0\n ? `<div style=\"color:#94a3b8;font-size:12px;margin-top:8px\">${esc(t.unknownNote(autoUnknown))}</div>`\n : \"\";\n\n const mlpsCss = `\n .mlps-cloud-section>summary{color:#94a3b8}\n .mlps-cloud-note{color:#94a3b8;font-size:13px;margin-bottom:12px;font-style:italic}\n .check-cloud{background:rgba(148,163,184,0.08)}\n .check-cloud .check-note{color:#64748b;font-size:12px;margin-left:auto;white-space:nowrap}\n .check-manual{background:rgba(148,163,184,0.06)}\n .check-clean{background:rgba(34,197,94,0.1);border-left:3px solid #22c55e}\n .check-issues{background:rgba(239,68,68,0.1);border-left:3px solid #ef4444}\n .check-unknown{background:rgba(148,163,184,0.1);border-left:3px solid #94a3b8}\n .check-findings-wrap{margin-left:28px;margin-bottom:4px}\n .check-detail{color:#94a3b8;font-size:13px;margin-left:28px;margin-top:2px}\n .category-stat-clean{color:#22c55e}\n .category-stat-issues{color:#ef4444}\n .category-stat-cloud{color:#94a3b8}\n .category-stat-manual{color:#94a3b8}\n .mlps-summary-cards{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:32px}\n .mlps-summary-card{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:16px 20px;text-align:center;min-width:100px;flex:1}\n .mlps-summary-card .stat-count{font-size:28px;font-weight:700}\n .mlps-summary-card .stat-label{font-size:12px;color:#94a3b8;margin-top:2px}\n `;\n\n return `<!DOCTYPE html>\n<html lang=\"${htmlLang}\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${esc(t.mlpsTitle)} — ${esc(date)}</title>\n<style>${sharedCss()}${mlpsCss}</style>\n</head>\n<body>\n<div class=\"container\">\n\n<header>\n <h1>🛡️ ${esc(t.mlpsTitle)}</h1>\n <div class=\"disclaimer\">${esc(t.mlpsDisclaimer)}</div>\n <div class=\"meta\">${esc(t.account)}: ${esc(accountId)} | ${esc(t.region)}: ${esc(region)} | ${esc(t.scanTime)}: ${esc(scanTime)}</div>\n</header>\n\n<section class=\"summary\" style=\"display:block;text-align:center\">\n <div style=\"font-size:36px;font-weight:700;margin-bottom:12px\">\n <span style=\"color:#22c55e\">${autoClean}</span> <span style=\"color:#94a3b8;font-size:18px\">${esc(t.noIssues)}</span>\n <span style=\"color:#475569;margin:0 16px\">/</span>\n <span style=\"color:#ef4444\">${autoIssues}</span> <span style=\"color:#94a3b8;font-size:18px\">${esc(t.issuesFound)}</span>\n </div>\n <div class=\"mlps-summary-cards\" style=\"justify-content:center\">\n <div class=\"mlps-summary-card\"><div class=\"stat-count\" style=\"color:#60a5fa\">${checkedTotal}</div><div class=\"stat-label\">${esc(t.checkedItems)}</div></div>\n <div class=\"mlps-summary-card\"><div class=\"stat-count\" style=\"color:#94a3b8\">${cloudCount}</div><div class=\"stat-label\">\\ud83c\\udfe2 ${esc(t.cloudProvider)}</div></div>\n <div class=\"mlps-summary-card\"><div class=\"stat-count\" style=\"color:#eab308\">${manualCount}</div><div class=\"stat-label\">\\ud83d\\udccb ${esc(t.manualReview)}</div></div>\n ${naCount > 0 ? `<div class=\"mlps-summary-card\"><div class=\"stat-count\" style=\"color:#64748b\">${naCount}</div><div class=\"stat-label\">\\u2796 ${esc(t.notApplicable)}</div></div>` : \"\"}\n </div>\n</section>\n${unknownNote}\n\n${trendHtml}\n\n${buildServiceReminderHtml(scanResults.modules, lang)}\n\n${categorySections}\n\n${remediationHtml}\n\n${naNote}\n\n<footer>\n <p>${esc(t.mlpsFooterGenerated(VERSION))}</p>\n <p>${esc(t.mlpsFooterDisclaimer)}</p>\n</footer>\n\n</div>\n</body>\n</html>`;\n}\n","import type { FullScanResult, Finding, Severity } from \"../types.js\";\nimport { VERSION } from \"../version.js\";\nimport { getI18n, type Lang } from \"../i18n/index.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers (same XSS-safe helpers as html-report.ts)\n// ---------------------------------------------------------------------------\n\nfunction esc(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction safeUrl(url: string): string | null {\n try {\n const u = new URL(url);\n if (u.protocol === \"https:\" || u.protocol === \"http:\") return url;\n return null;\n } catch {\n return null;\n }\n}\n\nfunction escWithLinks(s: string): string {\n const parts = s.split(/(https?:\\/\\/\\S+)/);\n return parts\n .map((part, i) => {\n if (i % 2 === 1) {\n const safe = safeUrl(part);\n if (safe) {\n return `<a href=\"${esc(safe)}\" style=\"color:#60a5fa\" target=\"_blank\" rel=\"noopener\">${esc(part)}</a>`;\n }\n return esc(part);\n }\n return esc(part);\n })\n .join(\"\");\n}\n\nconst SEVERITY_ORDER: Severity[] = [\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"];\n\n// ---------------------------------------------------------------------------\n// HW Defense SOP section definitions\n// ---------------------------------------------------------------------------\n\ninterface HwSection {\n id: string;\n autoModules: string[];\n shKeywords: string[];\n}\n\nconst HW_SECTIONS: HwSection[] = [\n {\n id: \"attack_surface\",\n autoModules: [\"network_reachability\", \"dns_dangling\", \"public_access_verify\", \"waf_coverage\"],\n shKeywords: [\"network\", \"public\", \"exposure\", \"port\", \"waf\", \"firewall\", \"vpc\", \"securitygroup\"],\n },\n {\n id: \"vulnerability_patch\",\n autoModules: [\"patch_compliance_findings\"],\n shKeywords: [\"vulnerability\", \"patch\", \"cve\", \"inspector\", \"software\"],\n },\n {\n id: \"identity_credential\",\n autoModules: [\"iam_privilege_escalation\", \"secret_exposure\"],\n shKeywords: [\"iam\", \"access\", \"privilege\", \"credential\", \"password\", \"mfa\", \"key rotation\"],\n },\n {\n id: \"transport_security\",\n autoModules: [\"ssl_certificate\", \"imdsv2_enforcement\"],\n shKeywords: [\"ssl\", \"tls\", \"certificate\", \"imds\", \"metadata\"],\n },\n {\n id: \"security_services\",\n autoModules: [\"service_detection\"],\n shKeywords: [],\n },\n {\n id: \"emergency_response\",\n autoModules: [],\n shKeywords: [],\n },\n {\n id: \"environment_control\",\n autoModules: [],\n shKeywords: [],\n },\n {\n id: \"post_review\",\n autoModules: [],\n shKeywords: [],\n },\n];\n\n// ---------------------------------------------------------------------------\n// CSS (dark theme, same base as html-report.ts with HW-specific additions)\n// ---------------------------------------------------------------------------\n\nfunction hwCss(): string {\n return `\n *{margin:0;padding:0;box-sizing:border-box}\n body{background:#0f172a;color:#f8fafc;font-family:Inter,system-ui,-apple-system,sans-serif;line-height:1.6;font-size:14px}\n .container{max-width:900px;margin:0 auto;padding:40px 24px}\n header{text-align:center;margin-bottom:40px;border-bottom:1px solid #334155;padding-bottom:24px}\n header h1{font-size:28px;font-weight:700;margin-bottom:8px;letter-spacing:-0.5px}\n .meta{color:#94a3b8;font-size:13px}\n h2{font-size:20px;font-weight:600;margin:32px 0 16px;padding-bottom:8px;border-bottom:1px solid #334155}\n h3{font-size:16px;font-weight:600;margin:16px 0 8px}\n h4{font-size:14px;font-weight:600;margin:12px 0 4px}\n .summary-cards{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:32px;justify-content:center}\n .summary-card{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:16px 20px;text-align:center;min-width:100px;flex:1}\n .summary-card .stat-count{font-size:28px;font-weight:700}\n .summary-card .stat-label{font-size:12px;color:#94a3b8;margin-top:2px}\n .badge{display:inline-block;padding:2px 10px;border-radius:4px;font-size:11px;font-weight:700;letter-spacing:0.5px;color:#fff}\n .badge-critical{background:#ef4444}\n .badge-high{background:#f97316}\n .badge-medium{background:#eab308;color:#1e293b}\n .badge-low{background:#22c55e;color:#1e293b}\n .hw-section{background:#1e293b;border:1px solid #334155;border-radius:8px;margin-bottom:16px;overflow:hidden}\n .hw-section>summary{cursor:pointer;padding:16px 20px;display:flex;align-items:center;gap:12px;list-style:none;font-size:16px;font-weight:600;user-select:none;flex-wrap:wrap}\n .hw-section>summary::-webkit-details-marker{display:none}\n .hw-section>summary::marker{content:\"\"}\n .hw-section>summary::after{content:\"\\\\25B6\";font-size:12px;color:#64748b;flex-shrink:0;transition:transform 0.2s;margin-left:auto}\n .hw-section[open]>summary::after{transform:rotate(90deg)}\n .hw-section[open]>summary{border-bottom:1px solid #334155}\n .hw-section-body{padding:16px 20px}\n .hw-section-icon{font-size:20px}\n .hw-section-title{flex:1}\n .hw-section-stats{display:inline-flex;gap:8px;font-size:12px;flex-wrap:wrap}\n .hw-section-stats .badge{font-size:10px;padding:1px 8px}\n .hw-auto-section{margin-bottom:16px}\n .hw-auto-section h4{color:#60a5fa;margin-bottom:8px}\n .hw-manual-section h4{color:#fbbf24;margin-bottom:8px}\n .hw-clean{color:#22c55e;font-size:14px;padding:8px 12px;background:rgba(34,197,94,0.1);border-radius:6px}\n .hw-no-auto{color:#94a3b8;font-size:14px;padding:8px 12px;background:rgba(148,163,184,0.08);border-radius:6px}\n .hw-manual-item{display:flex;align-items:flex-start;gap:8px;padding:6px 12px;margin-bottom:4px;font-size:14px;color:#cbd5e1;border-radius:4px;background:rgba(148,163,184,0.06)}\n .hw-manual-checkbox{color:#fbbf24;font-size:16px;flex-shrink:0}\n .finding-card{display:flex;align-items:center;gap:8px;padding:8px 12px;margin-bottom:4px;border-radius:6px;border-left:4px solid #334155;background:rgba(30,41,59,0.5);flex-wrap:wrap}\n .sev-critical{border-left-color:#ef4444}\n .sev-high{border-left-color:#f97316}\n .sev-medium{border-left-color:#eab308}\n .sev-low{border-left-color:#22c55e}\n .finding-title-text{font-weight:600;font-size:13px;flex:1;min-width:200px}\n .finding-resource{color:#94a3b8;font-size:12px;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n .finding-card>details{width:100%;margin-top:4px}\n .finding-card>details>summary{cursor:pointer;font-size:12px;color:#60a5fa;user-select:none}\n .finding-card-body{padding:8px 0}\n .finding-card-body p{color:#cbd5e1;font-size:13px;margin-bottom:4px}\n .finding-card-body ol{padding-left:20px}\n .finding-card-body li{color:#cbd5e1;font-size:13px;margin-bottom:2px}\n .hw-finding-group{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:12px 16px;margin-bottom:8px}\n .hw-finding-header{display:flex;align-items:center;gap:8px}\n .hw-finding-title{color:#e2e8f0;font-size:14px;flex:1}\n .hw-finding-count{color:#94a3b8;font-size:13px;font-weight:600;background:#334155;padding:2px 8px;border-radius:4px}\n .hw-finding-resources{padding:8px 0}\n .hw-resource-item{font-size:12px;color:#94a3b8;padding:2px 0;font-family:monospace}\n .hw-finding-remediation{border-top:1px solid #334155;margin-top:8px;padding-top:8px}\n .hw-finding-remediation ol{margin:4px 0;padding-left:20px;font-size:13px;color:#cbd5e1}\n footer{margin-top:48px;padding-top:24px;border-top:1px solid #334155;text-align:center}\n footer p{color:#64748b;font-size:12px;margin-bottom:4px}\n @media print{\n body{background:#fff;color:#1e293b;-webkit-print-color-adjust:exact;print-color-adjust:exact}\n .container{max-width:100%;padding:20px}\n .hw-section,.summary-card,.finding-card{background:#fff;border:1px solid #e2e8f0}\n .badge{border:1px solid}\n header{border-bottom-color:#e2e8f0}\n h2{border-bottom-color:#e2e8f0}\n footer{border-top-color:#e2e8f0}\n .summary-card .stat-label{color:#64748b}\n .finding-title-text{color:#1e293b}\n .finding-resource{color:#64748b}\n .finding-card-body p,.finding-card-body li{color:#475569}\n .hw-section[open]>summary{border-bottom-color:#e2e8f0}\n .hw-manual-item{color:#475569}\n details{display:block}\n details>summary{display:block}\n details>:not(summary){display:block !important}\n }\n `;\n}\n\n// ---------------------------------------------------------------------------\n// Main report generator\n// ---------------------------------------------------------------------------\n\nexport function generateHwDefenseHtmlReport(\n scanResults: FullScanResult,\n lang?: Lang,\n): string {\n const t = getI18n(lang ?? \"zh\");\n const htmlLang = (lang ?? \"zh\") === \"zh\" ? \"zh-CN\" : \"en\";\n const { accountId, region, scanStart } = scanResults;\n const date = scanStart.split(\"T\")[0];\n const scanTime = scanStart.replace(\"T\", \" \").replace(/\\.\\d+Z$/, \" UTC\");\n\n // Build module findings map\n const moduleMap = new Map<string, Finding[]>();\n for (const mod of scanResults.modules) {\n const findings = mod.findings.map((f) => ({ ...f, module: f.module ?? mod.module }));\n moduleMap.set(mod.module, findings);\n }\n\n // Track SH findings already assigned (dedup — first match wins)\n const assignedShFindings = new Set<string>();\n\n function shFindingKey(f: Finding): string {\n return `${f.title}|${f.resourceId}|${f.resourceArn}`;\n }\n\n // Process each section\n interface SectionResult {\n id: string;\n findings: Finding[];\n manualItems: string[];\n hasAutoModules: boolean;\n hasAutoResults: boolean;\n }\n\n const sectionResults: SectionResult[] = [];\n\n for (const section of HW_SECTIONS) {\n const findings: Finding[] = [];\n\n // Collect findings from auto modules (non-SH)\n for (const mod of section.autoModules) {\n if (mod === \"security_hub_findings\") continue;\n const modFindings = moduleMap.get(mod) ?? [];\n findings.push(...modFindings);\n }\n\n // Collect SH findings by keyword match (dedup across sections)\n if (section.shKeywords.length > 0) {\n const shFindings = moduleMap.get(\"security_hub_findings\") ?? [];\n for (const f of shFindings) {\n const key = shFindingKey(f);\n if (assignedShFindings.has(key)) continue;\n const searchText = `${f.title} ${f.description} ${f.impact}`.toLowerCase();\n if (section.shKeywords.some((kw) => searchText.includes(kw))) {\n findings.push(f);\n assignedShFindings.add(key);\n }\n }\n }\n\n // Check if this section has any auto modules defined\n const hasAutoModules = section.autoModules.length > 0 || section.shKeywords.length > 0;\n\n // Check if we actually have scanner results for any of the auto modules\n const hasAutoResults = hasAutoModules && (\n section.autoModules.some((m) => moduleMap.has(m)) ||\n (section.shKeywords.length > 0 && moduleMap.has(\"security_hub_findings\"))\n );\n\n // Manual items from i18n\n const manualItems = t.hwManualItems[section.id] ?? [];\n\n sectionResults.push({\n id: section.id,\n findings,\n manualItems,\n hasAutoModules,\n hasAutoResults,\n });\n }\n\n // Summary stats\n const totalFindings = sectionResults.reduce((sum, s) => sum + s.findings.length, 0);\n const sectionsChecked = sectionResults.filter((s) => s.hasAutoResults || s.manualItems.length > 0).length;\n const autoVerified = sectionResults.filter((s) => s.hasAutoResults).length;\n const totalManualItems = sectionResults.reduce((sum, s) => sum + s.manualItems.length, 0);\n\n // Group findings by CVE, control ID, or exact title\n interface FindingGroup {\n title: string;\n findings: Finding[];\n highestSeverity: Severity;\n }\n\n function groupFindings(findings: Finding[]): FindingGroup[] {\n const groups = new Map<string, Finding[]>();\n const groupTitles = new Map<string, string>();\n\n for (const f of findings) {\n const cveMatch = f.title.match(/CVE-\\d{4}-\\d+/i);\n if (cveMatch) {\n const key = `cve:${cveMatch[0].toUpperCase()}`;\n if (!groups.has(key)) {\n groups.set(key, []);\n groupTitles.set(key, f.title);\n }\n groups.get(key)!.push(f);\n continue;\n }\n const controlMatch = f.title.match(/[A-Z]+\\.\\d+/);\n if (controlMatch) {\n const key = `ctrl:${controlMatch[0]}`;\n if (!groups.has(key)) {\n groups.set(key, []);\n groupTitles.set(key, f.title);\n }\n groups.get(key)!.push(f);\n continue;\n }\n const key = `title:${f.title}`;\n if (!groups.has(key)) {\n groups.set(key, []);\n groupTitles.set(key, f.title);\n }\n groups.get(key)!.push(f);\n }\n\n const result: FindingGroup[] = [];\n for (const [key, gFindings] of groups) {\n let highestSeverity: Severity = \"LOW\";\n for (const f of gFindings) {\n if (SEVERITY_ORDER.indexOf(f.severity) < SEVERITY_ORDER.indexOf(highestSeverity)) {\n highestSeverity = f.severity;\n }\n }\n result.push({ title: groupTitles.get(key)!, findings: gFindings, highestSeverity });\n }\n return result;\n }\n\n // Render grouped finding card\n const renderGroup = (group: FindingGroup): string => {\n const sev = group.highestSeverity.toLowerCase();\n const count = group.findings.length;\n const first = group.findings[0];\n const resourceItems = group.findings\n .map((f) => `<div class=\"hw-resource-item\">${esc(f.resourceId)} — ${esc(f.resourceArn)}</div>`)\n .join(\"\\n\");\n const remediationSteps = first.remediationSteps\n .map((s) => `<li>${escWithLinks(s)}</li>`)\n .join(\"\");\n return `<div class=\"hw-finding-group\">\n <div class=\"hw-finding-header\">\n <span class=\"badge badge-${esc(sev)}\">${esc(group.highestSeverity)}</span>\n <span class=\"hw-finding-title\">${esc(group.title)}</span>\n <span class=\"hw-finding-count\">×${count}</span>\n </div>\n <details>\n <summary>${t.hwAffectedResources(count)}</summary>\n <div class=\"hw-finding-resources\">\n ${resourceItems}\n </div>\n <div class=\"hw-finding-remediation\">\n <strong>${esc(t.hwRemediation)}:</strong>\n <ol>${remediationSteps}</ol>\n </div>\n </details>\n</div>`;\n };\n\n // Render sections\n const sectionsHtml = sectionResults\n .map((section) => {\n const meta = t.hwSectionNames[section.id];\n if (!meta) return \"\";\n const sectionName = meta.name;\n const sectionIcon = meta.icon ?? \"\";\n\n // Stats badges for summary line\n const statBadges: string[] = [];\n if (section.findings.length > 0) {\n // Count by severity\n const sevCounts: Record<string, number> = {};\n for (const f of section.findings) {\n sevCounts[f.severity] = (sevCounts[f.severity] ?? 0) + 1;\n }\n for (const sev of SEVERITY_ORDER) {\n if (sevCounts[sev]) {\n statBadges.push(\n `<span class=\"badge badge-${sev.toLowerCase()}\">${sevCounts[sev]} ${sev}</span>`,\n );\n }\n }\n } else if (section.hasAutoResults) {\n statBadges.push(`<span style=\"color:#22c55e;font-size:12px\">✓ ${esc(t.hwClean)}</span>`);\n }\n if (section.manualItems.length > 0) {\n statBadges.push(`<span style=\"color:#fbbf24;font-size:12px\">☐ ${esc(t.hwManualCount(section.manualItems.length))}</span>`);\n }\n\n // Auto-check section\n let autoHtml: string;\n if (!section.hasAutoModules) {\n autoHtml = `<div class=\"hw-no-auto\">⚪ ${esc(t.hwNoAutoCheck)}</div>`;\n } else if (!section.hasAutoResults) {\n autoHtml = `<div class=\"hw-no-auto\">⚪ ${esc(t.hwNoAutoCheck)}</div>`;\n } else if (section.findings.length === 0) {\n autoHtml = `<div class=\"hw-clean\">✔ ${esc(t.hwClean)}</div>`;\n } else {\n // Sort findings: critical first, then by riskScore\n const sorted = [...section.findings].sort((a, b) => {\n const sevDiff = SEVERITY_ORDER.indexOf(a.severity) - SEVERITY_ORDER.indexOf(b.severity);\n if (sevDiff !== 0) return sevDiff;\n return b.riskScore - a.riskScore;\n });\n const groups = groupFindings(sorted);\n autoHtml = groups.map(renderGroup).join(\"\\n\");\n }\n\n // Manual checklist section\n let manualHtml = \"\";\n if (section.manualItems.length > 0) {\n const items = section.manualItems\n .map((item) => `<div class=\"hw-manual-item\"><span class=\"hw-manual-checkbox\">□</span>${esc(item)}</div>`)\n .join(\"\\n\");\n manualHtml = `\n <div class=\"hw-manual-section\">\n <h4>📋 ${esc(t.hwManualCheck)}</h4>\n ${items}\n </div>`;\n }\n\n return `<details class=\"hw-section\">\n <summary>\n <span class=\"hw-section-icon\">${esc(sectionIcon)}</span>\n <span class=\"hw-section-title\">${esc(sectionName)}</span>\n <span class=\"hw-section-stats\">${statBadges.join(\" \")}</span>\n </summary>\n <div class=\"hw-section-body\">\n <div class=\"hw-auto-section\">\n <h4>🤖 ${esc(t.hwAutoCheck)}</h4>\n ${autoHtml}\n </div>\n ${manualHtml}\n </div>\n</details>`;\n })\n .filter(Boolean)\n .join(\"\\n\");\n\n // Determine finding color for summary\n const findingsColor = totalFindings === 0 ? \"#22c55e\" : totalFindings <= 5 ? \"#eab308\" : \"#ef4444\";\n\n return `<!DOCTYPE html>\n<html lang=\"${htmlLang}\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${esc(t.hwReportTitle)} — ${esc(date)}</title>\n<style>${hwCss()}</style>\n</head>\n<body>\n<div class=\"container\">\n\n<header>\n <h1>🛡️ ${esc(t.hwReportTitle)}</h1>\n <div class=\"meta\">${esc(t.account)}: ${esc(accountId)} | ${esc(t.region)}: ${esc(region)} | ${esc(t.scanTime)}: ${esc(scanTime)}</div>\n</header>\n\n<section class=\"summary-cards\">\n <div class=\"summary-card\"><div class=\"stat-count\" style=\"color:${findingsColor}\">${totalFindings}</div><div class=\"stat-label\">${esc(t.hwTotalFindings)}</div></div>\n <div class=\"summary-card\"><div class=\"stat-count\" style=\"color:#60a5fa\">${sectionsChecked}</div><div class=\"stat-label\">${esc(t.hwSectionsChecked)}</div></div>\n <div class=\"summary-card\"><div class=\"stat-count\" style=\"color:#22c55e\">${autoVerified}</div><div class=\"stat-label\">${esc(t.hwAutoVerified)}</div></div>\n <div class=\"summary-card\"><div class=\"stat-count\" style=\"color:#fbbf24\">${totalManualItems}</div><div class=\"stat-label\">${esc(t.hwManualPending)}</div></div>\n</section>\n\n${sectionsHtml}\n\n<footer>\n <p>${esc(t.generatedBy)} v${VERSION}</p>\n\n</footer>\n\n</div>\n</body>\n</html>`;\n}\n","import { writeFileSync, readFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nimport type {\n FullScanResult,\n DashboardData,\n DashboardHistoryEntry,\n} from \"../types.js\";\n\nexport function calculateScore(summary: FullScanResult[\"summary\"]): number {\n const raw =\n 100 -\n summary.critical * 15 -\n summary.high * 5 -\n summary.medium * 2 -\n summary.low * 0.5;\n return Math.max(0, Math.min(100, raw));\n}\n\nexport function saveResults(\n scanResults: FullScanResult,\n outputDir?: string,\n): string {\n const baseDir = outputDir ?? join(homedir(), \".aws-security\");\n const today = scanResults.scanStart.slice(0, 10); // YYYY-MM-DD\n\n // Create directories\n const scanDir = join(baseDir, \"scans\", today);\n const dashboardDir = join(baseDir, \"dashboard\");\n mkdirSync(scanDir, { recursive: true });\n mkdirSync(dashboardDir, { recursive: true });\n\n // Write raw scan\n writeFileSync(join(scanDir, \"scan.json\"), JSON.stringify(scanResults, null, 2));\n\n // Read existing dashboard data\n const dataPath = join(dashboardDir, \"data.json\");\n let existing: DashboardData | null = null;\n if (existsSync(dataPath)) {\n try {\n existing = JSON.parse(readFileSync(dataPath, \"utf-8\")) as DashboardData;\n } catch {\n // Corrupt or invalid JSON — start fresh\n existing = null;\n }\n }\n\n // Build history entry for today\n const historyEntry: DashboardHistoryEntry = {\n date: today,\n score: calculateScore(scanResults.summary),\n critical: scanResults.summary.critical,\n high: scanResults.summary.high,\n medium: scanResults.summary.medium,\n low: scanResults.summary.low,\n totalFindings: scanResults.summary.totalFindings,\n };\n\n // Merge history: replace same-date entry or append\n let history = existing?.history ?? [];\n const idx = history.findIndex((h) => h.date === today);\n if (idx >= 0) {\n history[idx] = historyEntry;\n } else {\n history.push(historyEntry);\n }\n // Keep only last 30 entries\n history = history.slice(-30);\n\n // Build dashboard data\n const dashboardData: DashboardData = {\n lastScan: {\n scanStart: scanResults.scanStart,\n scanEnd: scanResults.scanEnd,\n region: scanResults.region,\n accountId: scanResults.accountId,\n summary: scanResults.summary,\n modules: scanResults.modules.map((m) => ({\n module: m.module,\n findingsCount: m.findingsCount,\n status: m.status,\n })),\n findings: scanResults.modules.flatMap((m) =>\n m.findings.map((f) => ({ ...f, module: m.module })),\n ),\n },\n history,\n meta: {\n generatedAt: new Date().toISOString(),\n version: \"1.0.0\",\n dataRetentionDays: 30,\n },\n };\n\n writeFileSync(dataPath, JSON.stringify(dashboardData, null, 2));\n return dataPath;\n}\n","export interface FindingsFilter {\n /** Filter Security Hub findings by category keywords (case-insensitive match on title/description/impact) */\n securityHubCategories?: string[];\n /** Filter GuardDuty findings by type prefix (matched against impact field) */\n guardDutyTypes?: string[];\n /** Filter Inspector findings by type (matched against impact field) */\n inspectorTypes?: string[];\n /** Filter by minimum severity */\n minSeverity?: string;\n}\n\nconst SEVERITY_ORDER: Record<string, number> = {\n LOW: 0,\n MEDIUM: 1,\n HIGH: 2,\n CRITICAL: 3,\n};\n\nexport function applyFindingsFilter(\n moduleName: string,\n findings: import(\"../types.js\").Finding[],\n filter: FindingsFilter,\n): import(\"../types.js\").Finding[] {\n let result = findings;\n\n // Apply severity filter\n if (filter.minSeverity) {\n const minLevel = SEVERITY_ORDER[filter.minSeverity.toUpperCase()] ?? 0;\n result = result.filter((f) => (SEVERITY_ORDER[f.severity] ?? 0) >= minLevel);\n }\n\n // Apply module-specific category filters\n if (moduleName === \"security_hub_findings\" && filter.securityHubCategories?.length) {\n const keywords = filter.securityHubCategories;\n result = result.filter((f) =>\n keywords.some((kw) => {\n const lower = kw.toLowerCase();\n return (\n f.title.toLowerCase().includes(lower) ||\n f.description.toLowerCase().includes(lower) ||\n f.impact.toLowerCase().includes(lower)\n );\n }),\n );\n }\n\n if (moduleName === \"guardduty_findings\" && filter.guardDutyTypes?.length) {\n const prefixes = filter.guardDutyTypes;\n result = result.filter((f) =>\n prefixes.some((prefix) => f.impact.includes(prefix)),\n );\n }\n\n if (moduleName === \"inspector_findings\" && filter.inspectorTypes?.length) {\n const types = filter.inspectorTypes;\n result = result.filter((f) =>\n types.some((t) => f.impact.includes(t)),\n );\n }\n\n return result;\n}\n\nexport const SCAN_GROUPS: Record<string, {\n name: string;\n description: string;\n modules: string[];\n reportType?: string;\n findingsFilter?: FindingsFilter;\n}> = {\n mlps3_precheck: {\n name: \"等保三级预检\",\n description: \"GB/T 22239-2019 等保三级 AWS 云租户层配置检查\",\n modules: [\"service_detection\", \"secret_exposure\", \"ssl_certificate\", \"dns_dangling\", \"network_reachability\", \"iam_privilege_escalation\", \"tag_compliance\", \"disaster_recovery\", \"security_hub_findings\", \"guardduty_findings\", \"inspector_findings\", \"trusted_advisor_findings\", \"config_rules_findings\", \"access_analyzer_findings\", \"patch_compliance_findings\", \"imdsv2_enforcement\", \"waf_coverage\"],\n reportType: \"mlps3\",\n },\n hw_defense: {\n name: \"护网蓝队加固\",\n description: \"护网前安全自查 — 攻击者视角的攻击面+弱点评估\",\n modules: [\"service_detection\", \"network_reachability\", \"dns_dangling\", \"public_access_verify\", \"ssl_certificate\", \"waf_coverage\", \"imdsv2_enforcement\", \"secret_exposure\", \"iam_privilege_escalation\", \"patch_compliance_findings\", \"security_hub_findings\"],\n findingsFilter: {\n securityHubCategories: [\"network\", \"public\", \"exposure\", \"port\", \"WAF\", \"vulnerability\", \"patch\", \"IAM\", \"iam\", \"access\", \"privilege\", \"secret\", \"credential\", \"password\", \"IMDS\", \"firewall\", \"VPC\", \"vpc\", \"SecurityGroup\", \"securitygroup\", \"CVE\", \"cve\", \"Inspector\", \"inspector\", \"software\", \"MFA\", \"mfa\", \"key rotation\", \"SSL\", \"ssl\", \"TLS\", \"tls\", \"certificate\", \"metadata\", \"CloudTrail\", \"cloudtrail\", \"logging\", \"audit\", \"encryption\"],\n minSeverity: \"MEDIUM\",\n },\n },\n exposure: {\n name: \"公网暴露面评估\",\n description: \"评估公网可达的资源和端口\",\n modules: [\"network_reachability\", \"dns_dangling\", \"public_access_verify\", \"ssl_certificate\", \"security_hub_findings\", \"access_analyzer_findings\", \"imdsv2_enforcement\", \"waf_coverage\"],\n findingsFilter: {\n securityHubCategories: [\"network\", \"public\", \"exposure\", \"port\"],\n },\n },\n data_encryption: {\n name: \"数据加密审计\",\n description: \"全面检查存储和传输加密状态\",\n modules: [\"ssl_certificate\", \"security_hub_findings\"],\n findingsFilter: {\n securityHubCategories: [\"encryption\", \"Encryption\"],\n },\n },\n least_privilege: {\n name: \"最小权限审计\",\n description: \"IAM 权限最小化评估\",\n modules: [\"iam_privilege_escalation\", \"security_hub_findings\", \"access_analyzer_findings\"],\n findingsFilter: {\n securityHubCategories: [\"IAM\", \"iam\", \"access\", \"privilege\"],\n },\n },\n log_integrity: {\n name: \"日志完整性审计\",\n description: \"审计日志完整性和保护\",\n modules: [\"service_detection\", \"security_hub_findings\"],\n findingsFilter: {\n securityHubCategories: [\"logging\", \"CloudTrail\", \"audit\"],\n },\n },\n disaster_recovery: {\n name: \"灾备评估\",\n description: \"备份和灾备能力评估\",\n modules: [\"disaster_recovery\", \"security_hub_findings\"],\n },\n idle_resources: {\n name: \"闲置资源清理\",\n description: \"发现未使用的资源\",\n modules: [\"idle_resources\", \"trusted_advisor_findings\"],\n },\n tag_compliance: {\n name: \"资源标签合规\",\n description: \"检查必需标签\",\n modules: [\"tag_compliance\"],\n },\n new_account_baseline: {\n name: \"新账户基线检查\",\n description: \"新 AWS 账户安全基线\",\n modules: [\"service_detection\", \"secret_exposure\", \"iam_privilege_escalation\", \"security_hub_findings\", \"guardduty_findings\", \"access_analyzer_findings\", \"imdsv2_enforcement\"],\n },\n aggregation: {\n name: \"安全服务聚合\",\n description: \"从 Security Hub / GuardDuty / Inspector / Trusted Advisor / Config Rules / Access Analyzer / Patch Compliance 聚合所有安全发现\",\n modules: [\"security_hub_findings\", \"guardduty_findings\", \"inspector_findings\", \"trusted_advisor_findings\", \"config_rules_findings\", \"access_analyzer_findings\", \"patch_compliance_findings\"],\n },\n};\n","export const SECURITY_RULES_CONTENT = `# AWS Security Scan Modules & Rules (19 modules)\n\n## 1. Service Detection (service_detection)\nDetects which AWS security services are enabled and assesses overall security maturity.\n- **Security Hub not enabled** — Risk 7.5: Provides 300+ automated security checks.\n- **GuardDuty not enabled** — Risk 7.5: Provides continuous threat detection.\n- **Inspector not enabled** — Risk 6.0: Scans for software vulnerabilities.\n- **AWS Config not enabled** — Risk 6.0: Tracks configuration changes.\n- CloudTrail detection is included for coverage metrics.\n\n### Maturity Levels\n| Enabled Services | Level |\n|------------------|-------|\n| 0–1 | Basic |\n| 2–3 | Intermediate |\n| 4 | Advanced |\n| 5 | Comprehensive |\n\n## 2. Security Hub Findings (security_hub_findings)\nAggregates active findings from AWS Security Hub. Replaces individual config scanners (SG, S3, IAM, CloudTrail, RDS, EBS, VPC, etc.) with centralized compliance checks from FSBP, CIS, and PCI DSS standards.\n- Findings are filtered to ACTIVE + NEW/NOTIFIED workflow status.\n- Severity mapped: CRITICAL → 9.5, HIGH → 8.0, MEDIUM → 5.5, LOW → 3.0.\n- INFORMATIONAL findings are skipped.\n\n## 3. GuardDuty Findings (guardduty_findings)\nDetection-only: checks if GuardDuty is enabled in the region.\n- GuardDuty findings are aggregated via Security Hub (security_hub_findings module).\n- Reports whether GuardDuty detectors are active.\n\n## 4. Inspector Findings (inspector_findings)\nDetection-only: checks if Inspector is enabled in the region.\n- Inspector findings are aggregated via Security Hub (security_hub_findings module).\n- Reports whether Inspector scanning (EC2/Lambda) is active.\n\n## 5. Trusted Advisor Findings (trusted_advisor_findings)\nAggregates security checks from AWS Trusted Advisor.\n- Requires AWS Business or Enterprise Support plan.\n- In China regions, uses cn-north-1 as the Support API endpoint.\n- Status mapped: error (RED) → 8.0, warning (YELLOW) → 5.5, ok (GREEN) → skip.\n\n## 6. Secret Exposure (secret_exposure)\nChecks Lambda env vars and EC2 userData for exposed secrets (AWS keys, private keys, passwords).\n\n## 7. SSL Certificate (ssl_certificate)\nChecks ACM certificates for expiry, failed status, and upcoming renewals.\n\n## 8. Dangling DNS (dns_dangling)\nChecks Route53 CNAME records for dangling DNS (subdomain takeover risk).\n\n## 9. Network Reachability (network_reachability)\nAnalyzes true network reachability by combining Security Group + NACL rules for public EC2 instances.\n\n## 10. IAM Privilege Escalation (iam_privilege_escalation)\nDetects IAM privilege escalation paths — users/roles that can escalate to admin via policy manipulation, role creation, or service abuse.\n\n## 11. Public Access Verify (public_access_verify)\nVerifies actual public accessibility of resources marked as public (S3 HTTP check, RDS DNS resolution).\n\n## 12. Tag Compliance (tag_compliance)\nChecks EC2, RDS, and S3 resources for required tags (Environment, Project, Owner).\n\n## 13. Idle Resources (idle_resources)\nFinds unused/idle AWS resources (unattached EBS volumes, unused EIPs, stopped instances, unused security groups).\n\n## 14. Disaster Recovery (disaster_recovery)\nAssesses disaster recovery readiness — RDS Multi-AZ & backups, EBS snapshot coverage, S3 versioning & cross-region replication.\n\n## 15. Config Rules Findings (config_rules_findings)\nDetection-only: checks if AWS Config Rules are configured.\n- Config Rule compliance findings are aggregated via Security Hub (security_hub_findings module).\n- Reports whether Config is enabled and counts active rules.\n- Gracefully handles regions where AWS Config is not enabled.\n\n## 16. IAM Access Analyzer Findings (access_analyzer_findings)\nDetection-only: checks if IAM Access Analyzer is configured.\n- Access Analyzer findings are aggregated via Security Hub (security_hub_findings module).\n- Reports whether active analyzers exist.\n- Returns warning if no analyzer is configured.\n\n## 17. SSM Patch Compliance (patch_compliance_findings)\nChecks patch compliance status for SSM-managed instances.\n- Lists all managed instances via SSM.\n- Retrieves patch compliance state for each instance.\n- Missing security patches or failed patches → HIGH (7.5).\n- Missing non-security patches → MEDIUM (5.5).\n- Instances without patch data flagged as LOW (3.0) for visibility.\n- Includes platform info, missing/failed counts, and last scan time.\n\n## 18. IMDSv2 Enforcement (imdsv2_enforcement)\nChecks if EC2 instances enforce IMDSv2 (Instance Metadata Service v2).\n- Lists all running EC2 instances and checks MetadataOptions.HttpTokens.\n- **HttpTokens != \"required\"** — Risk 7.5: IMDSv1 allows credential theft via SSRF attacks.\n- Also checks HttpPutResponseHopLimit — values >1 on containerized workloads noted as warning.\n- Remediation: Set HttpTokens to \"required\" via modify-instance-metadata-options.\n\n## 19. WAF Coverage (waf_coverage)\nChecks if internet-facing ALBs have WAF Web ACL associated for protection.\n- Lists all ELBv2 load balancers, filters to internet-facing only.\n- For each internet-facing ALB, checks WAFv2 Web ACL association.\n- **No WAF Web ACL** — Risk 7.5: ALB exposed to SQL injection, XSS, and OWASP Top 10 attacks.\n- NLBs (L4) are skipped as WAF does not apply — noted in warnings.\n- Gracefully handles WAFv2 access denied or unavailable regions.\n`;\n\nexport const RISK_SCORING_CONTENT = `# Risk Scoring Model\n\n## Score Ranges\nEach finding is assigned a risk score from 0.0 to 10.0 based on potential impact and exploitability.\n\n| Score Range | Severity | Priority | Description |\n|-------------|----------|----------|-------------|\n| 9.0 – 10.0 | CRITICAL | P0 | Immediate action required. Active exploitation risk. |\n| 7.0 – 8.9 | HIGH | P1 | Address within 24-48 hours. Significant exposure. |\n| 4.0 – 6.9 | MEDIUM | P2 | Address within 1-2 weeks. Moderate risk. |\n| 0.0 – 3.9 | LOW | P3 | Address in next maintenance cycle. Minor risk. |\n\n## Severity Mapping\n\\`\\`\\`\nscore >= 9.0 → CRITICAL\nscore >= 7.0 → HIGH\nscore >= 4.0 → MEDIUM\nscore < 4.0 → LOW\n\\`\\`\\`\n\n## Priority Mapping\n\\`\\`\\`\nCRITICAL → P0 (Immediate)\nHIGH → P1 (Urgent)\nMEDIUM → P2 (Normal)\nLOW → P3 (Low)\n\\`\\`\\`\n\n## Scoring Factors\n- **Exploitability**: How easily can this misconfiguration be exploited?\n- **Blast radius**: What data or systems are at risk?\n- **Public exposure**: Is the resource internet-facing?\n- **Compliance**: Does this violate common compliance frameworks (CIS, SOC2)?\n- **Data sensitivity**: Could sensitive data be exposed or lost?\n\n## Examples\n- Root account without MFA → 10.0 (total account compromise risk)\n- Public S3 ACL → 9.5 (data breach via public access)\n- Missing encryption at rest → 6.0 (data exposure if storage is compromised)\n- Versioning disabled → 3.0 (data loss risk, low exploitability)\n`;\n","#!/usr/bin/env node\n\nimport { startServer } from \"../src/index.js\";\nimport { VERSION } from \"../src/version.js\";\n\nconst args = process.argv.slice(2);\nconst subcommand = args[0];\n\nconst HELP = `Usage: aws-security-mcp [command] [options]\n\nCommands:\n (default) Start MCP server (stdio, for Kiro/Claude Code)\n dashboard Start local HTTP server serving the security dashboard\n deploy-dashboard Deploy dashboard to an S3 bucket as a static website\n\nOptions:\n --region <region> AWS region (default: AWS_REGION env or us-east-1)\n --version Print version and exit\n --help, -h Show this help message\n\nDashboard options:\n --port <port> Port for local dashboard server (default: 3000)\n\nDeploy options:\n --bucket <name> S3 bucket name (required)\n --region <region> AWS region for the S3 bucket\n\nEnvironment variables:\n AWS_REGION Default AWS region\n AWS_DEFAULT_REGION Fallback default region\n\nThe MCP server communicates over stdio using the MCP protocol.`;\n\nif (args.includes(\"--help\") || args.includes(\"-h\")) {\n console.log(HELP);\n process.exit(0);\n}\n\nif (args.includes(\"--version\")) {\n console.log(`aws-security-mcp ${VERSION}`);\n process.exit(0);\n}\n\nfunction getArg(name: string): string | undefined {\n const idx = args.indexOf(name);\n if (idx !== -1 && args[idx + 1]) return args[idx + 1];\n return undefined;\n}\n\nfunction getRegion(): string {\n return (\n getArg(\"--region\") ??\n process.env.AWS_REGION ??\n process.env.AWS_DEFAULT_REGION ??\n \"us-east-1\"\n );\n}\n\nif (subcommand === \"dashboard\") {\n const port = Number(getArg(\"--port\")) || 3000;\n import(\"../src/commands/dashboard.js\").then(({ startDashboard }) => {\n startDashboard(port);\n });\n} else if (subcommand === \"deploy-dashboard\") {\n const bucket = getArg(\"--bucket\");\n if (!bucket) {\n console.error(\"Error: --bucket <name> is required for deploy-dashboard\");\n process.exit(1);\n }\n const region = getRegion();\n import(\"../src/commands/deploy-dashboard.js\").then(({ deployDashboard }) => {\n deployDashboard(bucket, region).catch((err) => {\n console.error(\"Deploy failed:\", err.message || err);\n process.exit(1);\n });\n });\n} else if (subcommand && !subcommand.startsWith(\"--\")) {\n console.error(`Unknown command: ${subcommand}`);\n console.error('Run \"aws-security-mcp --help\" for usage.');\n process.exit(1);\n} else {\n // Default: start MCP server\n const region = getRegion();\n startServer(region).catch((err) => {\n console.error(\"Fatal:\", err);\n process.exit(1);\n });\n}\n"],"mappings":";;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,gBAAAA,qBAAoB;AAC7B,SAAS,gBAAgB;AACzB,SAAS,QAAAC,OAAM,SAAS,eAAe;AACvC,SAAS,cAAAC,aAAY,oBAAoB;AACzC,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,YAAY;AAiBd,SAAS,eAAe,OAAO,KAAY;AAEhD,QAAM,eAAeF,MAAK,WAAW,sBAAsB;AAE3D,MAAI,CAACC,YAAW,YAAY,GAAG;AAC7B,YAAQ;AAAA,MACN;AAAA,YACe,YAAY;AAAA,IAC7B;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,aAAaD;AAAA,IACjB,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,IAC/C;AAAA,EACF;AACA,QAAM,WAAWA,MAAK,cAAc,WAAW;AAC/C,MAAIC,YAAW,UAAU,GAAG;AAC1B,iBAAa,YAAY,QAAQ;AACjC,YAAQ,IAAI,yBAAyB,UAAU,EAAE;AAAA,EACnD,OAAO;AACL,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,QAAQ,YAAY;AAEzC,QAAM,SAASF,cAAa,OAAO,KAAK,QAAQ;AAC9C,UAAM,MAAM,IAAI,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK;AACtC,QAAI,WAAW;AAAA,MACbC,MAAK,cAAc,QAAQ,MAAM,eAAe,GAAG;AAAA,IACrD;AAGA,QAAI,CAAC,SAAS,WAAW,eAAe,GAAG,KAAK,aAAa,cAAc;AACzE,UAAI,UAAU,GAAG;AACjB,UAAI,IAAI,WAAW;AACnB;AAAA,IACF;AAGA,QAAI,CAACC,YAAW,QAAQ,GAAG;AACzB,iBAAWD,MAAK,cAAc,YAAY;AAAA,IAC5C;AAEA,QAAI;AACF,YAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,YAAM,MAAM,QAAQ,QAAQ;AAC5B,UAAI,UAAU,KAAK;AAAA,QACjB,gBAAgB,WAAW,GAAG,KAAK;AAAA,MACrC,CAAC;AACD,UAAI,IAAI,OAAO;AAAA,IACjB,QAAQ;AACN,UAAI,UAAU,GAAG;AACjB,UAAI,IAAI,WAAW;AAAA,IACrB;AAAA,EACF,CAAC;AAED,SAAO,OAAO,MAAM,MAAM;AACxB,UAAM,MAAM,oBAAoB,IAAI;AACpC,YAAQ,IAAI;AAAA,0BAA6B,GAAG;AAAA,CAAI;AAChD,YAAQ,IAAI,yBAAyB;AAGrC,UAAM,MACJ,QAAQ,aAAa,WACjB,SACA,QAAQ,aAAa,UACnB,UACA;AACR,SAAK,GAAG,GAAG,IAAI,GAAG,IAAI,MAAM;AAAA,IAE5B,CAAC;AAAA,EACH,CAAC;AAED,SAAO,GAAG,SAAS,CAAC,QAA+B;AACjD,QAAI,IAAI,SAAS,cAAc;AAC7B,cAAQ,MAAM,QAAQ,IAAI,wCAAwC;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,UAAM;AAAA,EACR,CAAC;AACH;AA1GA,IAOM,YACA,WAEA;AAVN;AAAA;AAAA;AAOA,IAAM,aAAaE,eAAc,YAAY,GAAG;AAChD,IAAM,YAAYF,MAAK,YAAY,IAAI;AAEvC,IAAM,aAAqC;AAAA,MACzC,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,UAAU;AAAA,IACZ;AAAA;AAAA;;;ACpBA;AAAA;AAAA;AAAA;AAAA,SAAS,aAAa,gBAAAG,eAAc,cAAAC,aAAY,gBAAAC,qBAAoB;AACpE,SAAS,QAAAC,OAAM,WAAAC,UAAS,gBAAgB;AACxC,SAAS,iBAAAC,sBAAqB;AAC9B;AAAA,EACE,YAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAiBP,SAAS,aAAa,KAAuB;AAC3C,QAAM,QAAkB,CAAC;AACzB,aAAW,SAAS,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC,GAAG;AAC7D,UAAM,OAAOH,MAAK,KAAK,MAAM,IAAI;AACjC,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,KAAK,GAAG,aAAa,IAAI,CAAC;AAAA,IAClC,OAAO;AACL,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,gBACpB,QACA,QACe;AACf,QAAM,eAAeA,MAAKI,YAAW,sBAAsB;AAE3D,MAAI,CAACN,YAAW,YAAY,GAAG;AAC7B,YAAQ;AAAA,MACN;AAAA,YACe,YAAY;AAAA,IAC7B;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,aAAaE;AAAA,IACjB,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,IAC/C;AAAA,EACF;AACA,QAAM,WAAWA,MAAK,cAAc,WAAW;AAC/C,MAAIF,YAAW,UAAU,GAAG;AAC1B,IAAAC,cAAa,YAAY,QAAQ;AACjC,YAAQ,IAAI,yBAAyB,UAAU,EAAE;AAAA,EACnD,OAAO;AACL,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK,IAAII,UAAS,EAAE,OAAO,CAAC;AAGlC,UAAQ,IAAI,oBAAoB,MAAM,gCAAgC;AACtE,QAAM,GAAG;AAAA,IACP,IAAI,wBAAwB;AAAA,MAC1B,QAAQ;AAAA,MACR,sBAAsB;AAAA,QACpB,eAAe,EAAE,QAAQ,aAAa;AAAA,QACtC,eAAe,EAAE,KAAK,aAAa;AAAA;AAAA,MACrC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,YAAY,OAAO,WAAW,KAAK,IAAI,WAAW;AACxD,UAAQ,IAAI,6CAA6C,MAAM,KAAK;AACpE,QAAM,GAAG;AAAA,IACP,IAAI,uBAAuB;AAAA,MACzB,QAAQ;AAAA,MACR,QAAQ,KAAK,UAAU;AAAA,QACrB,SAAS;AAAA,QACT,WAAW;AAAA,UACT;AAAA,YACE,KAAK;AAAA,YACL,QAAQ;AAAA,YACR,WAAW;AAAA,YACX,QAAQ;AAAA,YACR,UAAU,OAAO,SAAS,SAAS,MAAM;AAAA,UAC3C;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAGA,QAAM,QAAQ,aAAa,YAAY;AACvC,UAAQ,IAAI,aAAa,MAAM,MAAM,kBAAkB,MAAM,KAAK;AAElE,aAAW,YAAY,OAAO;AAC5B,UAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,UAAM,MAAMF,SAAQ,QAAQ;AAC5B,UAAM,cAAc,cAAc,GAAG,KAAK;AAC1C,UAAM,OAAOJ,cAAa,QAAQ;AAElC,UAAM,GAAG;AAAA,MACP,IAAI,iBAAiB;AAAA,QACnB,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,MAAM;AAAA,QACN,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AACA,YAAQ,IAAI,KAAK,GAAG,EAAE;AAAA,EACxB;AAEA,QAAM,SAAS,OAAO,WAAW,KAAK,IAAI,qBAAqB;AAC/D,QAAM,aAAa,UAAU,MAAM,eAAe,MAAM,IAAI,MAAM;AAClE,UAAQ,IAAI;AAAA,iCAAoC;AAChD,UAAQ,IAAI,gBAAgB,UAAU,EAAE;AACxC,UAAQ;AAAA,IACN;AAAA,EACF;AACF;AAlIA,IAUMQ,aACAD,YAEA;AAbN;AAAA;AAAA;AAUA,IAAMC,cAAaH,eAAc,YAAY,GAAG;AAChD,IAAME,aAAYJ,MAAKK,aAAY,IAAI;AAEvC,IAAM,gBAAwC;AAAA,MAC5C,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,UAAU;AAAA,IACZ;AAAA;AAAA;;;ACvBA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,SAAS;;;ACFX,IAAM,UAAU;;;ACAvB,SAAS,WAAW,gCAAgC;AAEpD,IAAI;AAEG,SAAS,aAAa,QAAwB;AACnD,MAAI,OAAO,WAAW,KAAK,EAAG,QAAO;AACrC,MAAI,OAAO,WAAW,SAAS,EAAG,QAAO;AACzC,SAAO;AACT;AAEO,SAAS,aAAa,QAAwB;AAEnD,MAAI,OAAO,WAAW,KAAK,EAAG,QAAO;AACrC,SAAO;AACT;AAEA,eAAsB,aAAa,QAAkC;AACnE,MAAI,gBAAiB,QAAO;AAE5B,QAAM,YAAY,UAAU;AAC5B,QAAM,MAAM,IAAI,UAAU,EAAE,QAAQ,UAAU,CAAC;AAC/C,QAAM,WAAW,MAAM,IAAI,KAAK,IAAI,yBAAyB,CAAC,CAAC,CAAC;AAChE,oBAAkB,SAAS,WAAW;AACtC,SAAO;AACT;AAEO,SAAS,aACd,aACA,QACA,aACG;AACH,QAAM,SAAc,EAAE,QAAQ,UAAU,YAAY;AACpD,MAAI,YAAa,QAAO,cAAc;AACtC,SAAO,IAAI,YAAY,MAAM;AAC/B;;;AClCA,SAAS,aAAAC,YAAW,mBAAmB,4BAAAC,iCAAgC;AAQhE,IAAM,sBAAsB;AAEnC,eAAsB,WAAW,SAAiB,QAAgB,SAO/D;AACD,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,aAAa,SAAS,cAAc;AAC1C,QAAM,MAAM,IAAIC,WAAU,EAAE,OAAO,CAAC;AACpC,QAAM,SAAS,MAAM,IAAI,KAAK,IAAI,kBAAkB;AAAA,IAClD,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,iBAAiB;AAAA,EACnB,CAAC,CAAC;AACF,SAAO;AAAA,IACL,aAAa,OAAO,YAAa;AAAA,IACjC,iBAAiB,OAAO,YAAa;AAAA,IACrC,cAAc,OAAO,YAAa;AAAA,EACpC;AACF;AAEO,SAAS,aAAa,WAAmB,UAAkB,YAAY,OAAe;AAC3F,SAAO,OAAO,SAAS,SAAS,SAAS,SAAS,QAAQ;AAC5D;;;ACpCA,SAAS,qBAAqB,2BAA2B;AASzD,eAAsB,gBAAgB,QAAuC;AAG3E,QAAM,YAAY,OAAO,WAAW,KAAK,IAAI,mBAAmB;AAChE,QAAM,SAAS,IAAI,oBAAoB,EAAE,QAAQ,UAAU,CAAC;AAC5D,QAAM,WAAyB,CAAC;AAChC,MAAI;AAEJ,KAAG;AACD,UAAM,SAAS,MAAM,OAAO,KAAK,IAAI,oBAAoB,EAAE,WAAW,UAAU,CAAC,CAAC;AAClF,eAAW,QAAQ,OAAO,YAAY,CAAC,GAAG;AACxC,UAAI,KAAK,WAAW,UAAU;AAC5B,iBAAS,KAAK;AAAA,UACZ,IAAI,KAAK;AAAA,UACT,MAAM,KAAK,QAAQ;AAAA,UACnB,OAAO,KAAK,SAAS;AAAA,UACrB,QAAQ,KAAK;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AACA,gBAAY,OAAO;AAAA,EACrB,SAAS;AAET,SAAO;AACT;;;AC1BA,IAAM,sBAAsB,oBAAI,IAAI;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,aAAa,SAAuB;AAC3C,MAAI,WAAW;AACf,MAAI,OAAO;AACX,MAAI,SAAS;AACb,MAAI,MAAM;AACV,MAAI,iBAAiB;AACrB,MAAI,eAAe;AAEnB,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,WAAW,WAAW;AAC1B;AAAA,IACF,OAAO;AACL;AAAA,IACF;AACA,eAAW,KAAK,EAAE,UAAU;AAC1B,cAAQ,EAAE,UAAU;AAAA,QAClB,KAAK;AAAY;AAAY;AAAA,QAC7B,KAAK;AAAQ;AAAQ;AAAA,QACrB,KAAK;AAAU;AAAU;AAAA,QACzB,KAAK;AAAO;AAAO;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,eAAe,WAAW,OAAO,SAAS;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,uBACb,UACA,KACuB;AACvB,QAAM,UAAU,MAAM,QAAQ,WAAW,SAAS,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC;AAEzE,SAAO,QAAQ,IAAI,CAAC,QAAQ,MAAM;AAChC,QAAI,OAAO,WAAW,aAAa;AAEjC,iBAAW,KAAK,OAAO,MAAM,UAAU;AACrC,YAAI,CAAC,EAAE,UAAW,GAAE,YAAY,IAAI;AACpC,YAAI,CAAC,EAAE,gBAAgB,IAAI,aAAc,GAAE,eAAe,IAAI;AAAA,MAChE;AACA,aAAO,OAAO;AAAA,IAChB;AACA,WAAO;AAAA,MACL,QAAQ,SAAS,CAAC,EAAE;AAAA,MACpB,QAAQ;AAAA,MACR,OAAO,OAAO,kBAAkB,QAAQ,OAAO,OAAO,UAAU,OAAO,OAAO,MAAM;AAAA,MACpF,kBAAkB;AAAA,MAClB,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,UAAU,CAAC;AAAA,IACb;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,eACpB,UACA,QACyB;AACzB,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AAGzC,MAAI;AACJ,MAAI;AACF,gBAAY,MAAM,aAAa,MAAM;AAAA,EACvC,QAAQ;AACN,gBAAY;AAAA,EACd;AAEA,QAAM,YAAY,aAAa,MAAM;AACrC,QAAM,MAAmB,EAAE,QAAQ,WAAW,UAAU;AAExD,QAAM,UAAU,MAAM,uBAAuB,UAAU,GAAG;AAE1D,QAAM,WAAU,oBAAI,KAAK,GAAE,YAAY;AAEvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,aAAa,OAAO;AAAA,EAC/B;AACF;AAQA,eAAsB,wBACpB,UACA,QACA,MACyB;AACzB,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAM,YAAY,aAAa,MAAM;AAGrC,MAAI;AACJ,MAAI;AACF,qBAAiB,MAAM,aAAa,MAAM;AAAA,EAC5C,QAAQ;AACN,qBAAiB;AAAA,EACnB;AAGA,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,gBAAgB,MAAM;AAAA,EACzC,SAAS,KAAK;AACZ,UAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAE9D,UAAM,SAAS,MAAM,eAAe,UAAU,MAAM;AACpD,QAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,UAAI,CAAC,OAAO,QAAQ,CAAC,EAAE,SAAU,QAAO,QAAQ,CAAC,EAAE,WAAW,CAAC;AAC/D,aAAO,QAAQ,CAAC,EAAE,SAAS,QAAQ,sDAAsD,MAAM,kCAAkC;AAAA,IACnI;AACA,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,YAAY,QAAQ;AAC3B,UAAM,QAAQ,IAAI,IAAI,KAAK,UAAU;AACrC,eAAW,SAAS,OAAO,CAAC,MAAM,MAAM,IAAI,EAAE,EAAE,CAAC;AAAA,EACnD;AAGA,QAAM,sBAAsB,SAAS,OAAO,CAAC,MAAM,oBAAoB,IAAI,EAAE,UAAU,CAAC;AACxF,QAAM,qBAAqB,SAAS,OAAO,CAAC,MAAM,CAAC,oBAAoB,IAAI,EAAE,UAAU,CAAC;AAExF,QAAM,aAA2B,CAAC;AAGlC,MAAI,oBAAoB,SAAS,GAAG;AAClC,UAAM,WAAwB,EAAE,QAAQ,WAAW,WAAW,eAAe;AAC7E,UAAM,aAAa,MAAM,uBAAuB,qBAAqB,QAAQ;AAC7E,eAAW,KAAK,GAAG,UAAU;AAAA,EAC/B;AAGA,aAAW,WAAW,UAAU;AAC9B,QAAI;AACJ,QAAI,eAAe,QAAQ;AAG3B,QAAI,QAAQ,OAAO,gBAAgB;AACjC,UAAI;AACF,cAAM,UAAU,aAAa,QAAQ,IAAI,KAAK,UAAU,SAAS;AACjE,sBAAc,MAAM,WAAW,SAAS,MAAM;AAAA,MAChD,SAAS,KAAK;AAEZ,mBAAW,KAAK;AAAA,UACd,QAAQ,eAAe,QAAQ,EAAE;AAAA,UACjC,QAAQ;AAAA,UACR,OAAO,oCAAoC,QAAQ,EAAE,KAAK,QAAQ,IAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAC5H,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf,YAAY;AAAA,UACZ,UAAU,CAAC;AAAA,QACb,CAAC;AACD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAmB;AAAA,MACvB;AAAA,MACA;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,IACF;AAEA,UAAM,iBAAiB,MAAM,uBAAuB,oBAAoB,GAAG;AAC3E,eAAW,KAAK,GAAG,cAAc;AAAA,EACnC;AAEA,QAAM,WAAU,oBAAI,KAAK,GAAE,YAAY;AAGvC,MAAI,KAAK,YAAY,QAAQ;AAC3B,UAAM,QAAQ,IAAI,IAAI,KAAK,UAAU;AACrC,eAAW,OAAO,YAAY;AAC5B,UAAI,oBAAoB,IAAI,IAAI,MAAM,GAAG;AACvC,YAAI,WAAW,IAAI,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,aAAa,MAAM,IAAI,EAAE,SAAS,CAAC;AAChF,YAAI,gBAAgB,IAAI,SAAS;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,IACT,SAAS,aAAa,UAAU;AAAA,EAClC;AACF;;;AC9NA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;;;ACjBA,SAAS,kBAAkB,OAAyB;AACzD,MAAI,SAAS,EAAK,QAAO;AACzB,MAAI,SAAS,EAAK,QAAO;AACzB,MAAI,SAAS,EAAK,QAAO;AACzB,SAAO;AACT;AAEO,SAAS,qBAAqB,UAA8B;AACjE,UAAQ,UAAU;AAAA,IAChB,KAAK;AAAY,aAAO;AAAA,IACxB,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAU,aAAO;AAAA,IACtB,KAAK;AAAO,aAAO;AAAA,EACrB;AACF;;;ADuBA,SAAS,YAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEA,SAAS,eAAe,KAAuB;AAC7C,MAAI,EAAE,eAAe,OAAQ,QAAO;AACpC,QAAM,OAAQ,IAAkC,QAAQ;AACxD,QAAM,OAAQ,IAAkC,QAAQ;AACxD,SACE,SAAS,2BACT,SAAS,wBACT,SAAS,kBACT,SAAS,2BACT,SAAS,kBACT,SAAS;AAAA,GAER,IAAI,SAAS,SAAS,8BAA8B,KAAK,WACzD,IAAI,SAAS,SAAS,eAAe,KAAK;AAE/C;AAEA,SAAS,aAAa,KAAuB;AAC3C,MAAI,EAAE,eAAe,OAAQ,QAAO;AACpC,SACE,IAAI,SAAS;AAAA,EACb,IAAI,SAAS,uBACb,IAAI,QAAQ,SAAS,aAAa,KAClC,IAAI,QAAQ,SAAS,gBAAgB;AAEzC;AAEA,SAAS,qBACP,cACyD;AACzD,MAAI,gBAAgB,EAAG,QAAO;AAC9B,MAAI,gBAAgB,EAAG,QAAO;AAC9B,MAAI,gBAAgB,EAAG,QAAO;AAC9B,SAAO;AACT;AAEO,IAAM,0BAAN,MAAiD;AAAA,EAC7C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAC5B,UAAM,WAA4B,CAAC;AAGnC,QAAI;AACF,YAAM,KAAK,aAAa,kBAAkB,QAAQ,IAAI,WAAW;AACjE,YAAM,OAAO,MAAM,GAAG,KAAK,IAAI,sBAAsB,CAAC,CAAC,CAAC;AACxD,YAAM,SAAS,KAAK,aAAa,CAAC;AAClC,UAAI,OAAO,SAAS,GAAG;AACrB,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS,GAAG,OAAO,MAAM;AAAA,QAC3B,CAAC;AAAA,MACH,OAAO;AACL,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,QAClB,CAAC;AAAA,MAEH;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,GAAG,GAAG;AACvB,iBAAS,KAAK,sDAAsD;AACpE,iBAAS,KAAK,EAAE,MAAM,cAAc,SAAS,MAAM,SAAS,gBAAgB,CAAC;AAAA,MAC/E,WAAW,aAAa,GAAG,GAAG;AAC5B,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,QAClB,CAAC;AAAA,MAEH,OAAO;AACL,iBAAS,KAAK,gCAAgC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAChG,iBAAS,KAAK,EAAE,MAAM,cAAc,SAAS,MAAM,SAAS,kBAAkB,CAAC;AAAA,MACjF;AAAA,IACF;AAGA,QAAI;AACF,YAAM,KAAK,aAAa,mBAAmB,QAAQ,IAAI,WAAW;AAClE,YAAM,GAAG,KAAK,IAAI,mBAAmB,CAAC,CAAC,CAAC;AACxC,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,eAAe,GAAG,GAAG;AACvB,iBAAS,KAAK,wDAAwD;AACtE,iBAAS,KAAK,EAAE,MAAM,gBAAgB,SAAS,MAAM,SAAS,gBAAgB,CAAC;AAAA,MACjF,WAAW,aAAa,GAAG,GAAG;AAC5B,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,oBAAoB;AAAA,QACtB,CAAC;AACD,iBAAS;AAAA,UACP,YAAY;AAAA,YACV,WAAW;AAAA,YACX,OAAO;AAAA,YACP,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,aAAa,OAAO,SAAS,gBAAgB,MAAM,IAAI,SAAS;AAAA,YAChE;AAAA,YACA,aACE;AAAA,YACF,QACE;AAAA,YACF,kBAAkB;AAAA,cAChB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,iBAAS,KAAK,kCAAkC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAClG,iBAAS,KAAK,EAAE,MAAM,gBAAgB,SAAS,MAAM,SAAS,kBAAkB,CAAC;AAAA,MACnF;AAAA,IACF;AAGA,QAAI;AACF,YAAM,KAAK,aAAa,iBAAiB,QAAQ,IAAI,WAAW;AAChE,YAAM,OAAO,MAAM,GAAG,KAAK,IAAI,qBAAqB,CAAC,CAAC,CAAC;AACvD,YAAM,YAAY,KAAK,eAAe,CAAC;AACvC,UAAI,UAAU,SAAS,GAAG;AACxB,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS,GAAG,UAAU,MAAM;AAAA,QAC9B,CAAC;AAAA,MACH,OAAO;AACL,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,oBAAoB;AAAA,QACtB,CAAC;AACD,iBAAS;AAAA,UACP,YAAY;AAAA,YACV,WAAW;AAAA,YACX,OAAO;AAAA,YACP,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,aAAa,OAAO,SAAS,cAAc,MAAM,IAAI,SAAS;AAAA,YAC9D;AAAA,YACA,aACE;AAAA,YACF,QACE;AAAA,YACF,kBAAkB;AAAA,cAChB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,GAAG,GAAG;AACvB,iBAAS,KAAK,qDAAqD;AACnE,iBAAS,KAAK,EAAE,MAAM,aAAa,SAAS,MAAM,SAAS,gBAAgB,CAAC;AAAA,MAC9E,WAAW,aAAa,GAAG,GAAG;AAC5B,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,oBAAoB;AAAA,QACtB,CAAC;AACD,iBAAS;AAAA,UACP,YAAY;AAAA,YACV,WAAW;AAAA,YACX,OAAO;AAAA,YACP,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,aAAa,OAAO,SAAS,cAAc,MAAM,IAAI,SAAS;AAAA,YAC9D;AAAA,YACA,aACE;AAAA,YACF,QACE;AAAA,YACF,kBAAkB;AAAA,cAChB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,iBAAS,KAAK,+BAA+B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAC/F,iBAAS,KAAK,EAAE,MAAM,aAAa,SAAS,MAAM,SAAS,kBAAkB,CAAC;AAAA,MAChF;AAAA,IACF;AAGA,QAAI;AACF,YAAM,OAAO,aAAa,kBAAkB,QAAQ,IAAI,WAAW;AACnE,YAAM,OAAO,MAAM,KAAK,KAAK,IAAI,6BAA6B,EAAE,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;AAC1F,YAAM,WAAW,KAAK,YAAY,CAAC;AACnC,YAAM,SAAS,SAAS,KAAK,CAAC,MAAM;AAClC,cAAM,IAAI,EAAE,OAAO;AACnB,YAAI,MAAM,aAAa,MAAM,WAAY,QAAO;AAEhD,cAAM,KAAK,EAAE;AACb,YAAI,CAAC,GAAI,QAAO;AAChB,eAAO,CAAC,OAAO,OAAO,UAAU,cAAc,gBAAgB,EAAE;AAAA,UAC9D,CAAC,MAAM,GAAG,CAAC,GAAG,WAAW;AAAA,QAC3B;AAAA,MACF,CAAC;AACD,UAAI,QAAQ;AACV,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,QACX,CAAC;AAAA,MACH,OAAO;AACL,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,oBAAoB;AAAA,QACtB,CAAC;AACD,iBAAS;AAAA,UACP,YAAY;AAAA,YACV,WAAW;AAAA,YACX,OAAO;AAAA,YACP,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,aAAa,OAAO,SAAS,eAAe,MAAM,IAAI,SAAS;AAAA,YAC/D;AAAA,YACA,aACE;AAAA,YACF,QACE;AAAA,YACF,kBAAkB;AAAA,cAChB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,GAAG,GAAG;AACvB,iBAAS,KAAK,qDAAqD;AACnE,iBAAS,KAAK,EAAE,MAAM,aAAa,SAAS,MAAM,SAAS,gBAAgB,CAAC;AAAA,MAC9E,WAAW,aAAa,GAAG,GAAG;AAC5B,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,oBAAoB;AAAA,QACtB,CAAC;AACD,iBAAS;AAAA,UACP,YAAY;AAAA,YACV,WAAW;AAAA,YACX,OAAO;AAAA,YACP,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,aAAa,OAAO,SAAS,eAAe,MAAM,IAAI,SAAS;AAAA,YAC/D;AAAA,YACA,aACE;AAAA,YACF,QACE;AAAA,YACF,kBAAkB;AAAA,cAChB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,iBAAS,KAAK,+BAA+B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAC/F,iBAAS,KAAK,EAAE,MAAM,aAAa,SAAS,MAAM,SAAS,kBAAkB,CAAC;AAAA,MAChF;AAAA,IACF;AAGA,QAAI;AACF,YAAM,MAAM,aAAa,qBAAqB,QAAQ,IAAI,WAAW;AACrE,YAAM,OAAO,MAAM,IAAI,KAAK,IAAI,sCAAsC,CAAC,CAAC,CAAC;AACzE,YAAM,YAAY,KAAK,0BAA0B,CAAC;AAClD,UAAI,UAAU,SAAS,GAAG;AACxB,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS,GAAG,UAAU,MAAM;AAAA,QAC9B,CAAC;AAAA,MACH,OAAO;AACL,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,QAClB,CAAC;AACD,iBAAS;AAAA,UACP,YAAY;AAAA,YACV,WAAW;AAAA,YACX,OAAO;AAAA,YACP,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,aAAa,OAAO,SAAS,WAAW,MAAM,IAAI,SAAS;AAAA,YAC3D;AAAA,YACA,aACE;AAAA,YACF,QACE;AAAA,YACF,kBAAkB;AAAA,cAChB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,GAAG,GAAG;AACvB,iBAAS,KAAK,sDAAsD;AACpE,iBAAS,KAAK,EAAE,MAAM,cAAc,SAAS,MAAM,SAAS,gBAAgB,CAAC;AAAA,MAC/E,WAAW,aAAa,GAAG,GAAG;AAC5B,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,QAClB,CAAC;AACD,iBAAS;AAAA,UACP,YAAY;AAAA,YACV,WAAW;AAAA,YACX,OAAO;AAAA,YACP,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,aAAa,OAAO,SAAS,WAAW,MAAM,IAAI,SAAS;AAAA,YAC3D;AAAA,YACA,aACE;AAAA,YACF,QACE;AAAA,YACF,kBAAkB;AAAA,cAChB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,iBAAS,KAAK,gCAAgC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAChG,iBAAS,KAAK,EAAE,MAAM,cAAc,SAAS,MAAM,SAAS,kBAAkB,CAAC;AAAA,MACjF;AAAA,IACF;AAGA,UAAM,gBAAgB,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI;AAC/D,UAAM,eAAe,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI,EAAE;AAChE,UAAM,kBAAkB,cAAc,SAAS,IAAI,KAAK,MAAO,eAAe,cAAc,SAAU,GAAG,IAAI;AAC7G,UAAM,gBAAgB,qBAAqB,YAAY;AAEvD,UAAM,kBAA0C;AAAA,MAC9C;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,QAAQ;AAAA,MACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,MAC3C,kBAAkB,SAAS;AAAA,MAC3B,eAAe,SAAS;AAAA,MACxB,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB;AAAA;AAAA,MAEA,GAAI,EAAE,kBAAkB,gBAAgB;AAAA,IAC1C;AAAA,EACF;AACF;;;AE1bA;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAMP,IAAM,kBAAyF;AAAA,EAC7F,EAAE,MAAM,kBAAkB,SAAS,oBAAoB,WAAW,QAAQ;AAAA,EAC1E,EAAE,MAAM,eAAe,SAAS,gCAAgC,WAAW,QAAQ;AAAA,EACnF,EAAE,MAAM,uBAAuB,SAAS,2EAA2E,WAAW,OAAO;AACvI;AAEA,SAASC,aAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEO,IAAM,wBAAN,MAA+C;AAAA,EAC3C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAC5B,QAAI,mBAAmB;AAEvB,QAAI;AAEF,UAAI;AACF,cAAM,SAAS,aAAa,cAAc,QAAQ,IAAI,WAAW;AACjE,cAAM,YAAqC,CAAC;AAC5C,YAAI;AACJ,WAAG;AACD,gBAAM,OAAO,MAAM,OAAO;AAAA,YACxB,IAAI,qBAAqB,EAAE,QAAQ,OAAO,CAAC;AAAA,UAC7C;AACA,cAAI,KAAK,UAAW,WAAU,KAAK,GAAG,KAAK,SAAS;AACpD,mBAAS,KAAK;AAAA,QAChB,SAAS;AAET,4BAAoB,UAAU;AAE9B,mBAAW,MAAM,WAAW;AAC1B,gBAAM,SAAS,GAAG,gBAAgB;AAClC,gBAAM,QACJ,GAAG,eACH,OAAO,SAAS,WAAW,MAAM,IAAI,SAAS,aAAa,MAAM;AACnE,gBAAM,UAAU,GAAG,aAAa,aAAa,CAAC;AAE9C,qBAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,OAAO,GAAG;AACzD,uBAAW,MAAM,iBAAiB;AAChC,kBAAI,GAAG,cAAc,QAAQ;AAC3B,oBAAI,GAAG,QAAQ,KAAK,OAAO,GAAG;AAC5B,2BAAS;AAAA,oBACPA,aAAY;AAAA,sBACV,WAAW;AAAA,sBACX,OAAO,UAAU,MAAM,4BAA4B,OAAO;AAAA,sBAC1D,cAAc;AAAA,sBACd,YAAY;AAAA,sBACZ,aAAa;AAAA,sBACb;AAAA,sBACA,aAAa,oBAAoB,MAAM,wCAAwC,OAAO;AAAA,sBACtF,QACE;AAAA,sBACF,kBAAkB;AAAA,wBAChB;AAAA,wBACA;AAAA,wBACA;AAAA,sBACF;AAAA,oBACF,CAAC;AAAA,kBACH;AAAA,gBACF;AAAA,cACF,OAAO;AAEL,oBAAI,GAAG,QAAQ,KAAK,QAAQ,GAAG;AAC7B,wBAAM,YAAY,GAAG,SAAS,mBAAmB,MAAM;AACvD,2BAAS;AAAA,oBACPA,aAAY;AAAA,sBACV;AAAA,sBACA,OAAO,UAAU,MAAM,qBAAqB,GAAG,IAAI;AAAA,sBACnD,cAAc;AAAA,sBACd,YAAY;AAAA,sBACZ,aAAa;AAAA,sBACb;AAAA,sBACA,aAAa,oBAAoB,MAAM,8CAA8C,GAAG,IAAI;AAAA,sBAC5F,QACE;AAAA,sBACF,kBAAkB;AAAA,wBAChB;AAAA,wBACA;AAAA,wBACA;AAAA,wBACA;AAAA,sBACF;AAAA,oBACF,CAAC;AAAA,kBACH;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,GAAY;AACnB,iBAAS,KAAK,sBAAsB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,MAClF;AAGA,UAAI;AACF,cAAM,MAAM,aAAa,WAAW,QAAQ,IAAI,WAAW;AAC3D,cAAM,YAAwB,CAAC;AAC/B,YAAI;AACJ,WAAG;AACD,gBAAM,OAAO,MAAM,IAAI;AAAA,YACrB,IAAI,yBAAyB,EAAE,WAAW,UAAU,CAAC;AAAA,UACvD;AACA,qBAAW,OAAO,KAAK,gBAAgB,CAAC,GAAG;AACzC,gBAAI,IAAI,UAAW,WAAU,KAAK,GAAG,IAAI,SAAS;AAAA,UACpD;AACA,sBAAY,KAAK;AAAA,QACnB,SAAS;AAET,4BAAoB,UAAU;AAE9B,mBAAW,QAAQ,WAAW;AAC5B,gBAAM,SAAS,KAAK,cAAc;AAClC,gBAAM,UAAU,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,aAAa,MAAM;AAE9E,cAAI;AACJ,cAAI;AACF,kBAAM,WAAW,MAAM,IAAI;AAAA,cACzB,IAAI,iCAAiC;AAAA,gBACnC,YAAY;AAAA,gBACZ,WAAW;AAAA,cACb,CAAC;AAAA,YACH;AACA,kBAAM,MAAM,SAAS,UAAU;AAC/B,gBAAI,KAAK;AACP,yBAAW,OAAO,KAAK,KAAK,QAAQ,EAAE,SAAS,OAAO;AAAA,YACxD;AAAA,UACF,SAAS,GAAY;AACnB,qBAAS,KAAK,+BAA+B,MAAM,KAAK,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AACpG;AAAA,UACF;AAEA,cAAI,CAAC,SAAU;AAEf,qBAAW,MAAM,iBAAiB;AAChC,gBAAI,GAAG,cAAc,OAAQ;AAC7B,gBAAI,GAAG,QAAQ,KAAK,QAAQ,GAAG;AAC7B,oBAAM,YAAY,GAAG,SAAS,mBAAmB,MAAM;AACvD,uBAAS;AAAA,gBACPA,aAAY;AAAA,kBACV;AAAA,kBACA,OAAO,OAAO,MAAM,sBAAsB,GAAG,IAAI;AAAA,kBACjD,cAAc;AAAA,kBACd,YAAY;AAAA,kBACZ,aAAa;AAAA,kBACb;AAAA,kBACA,aAAa,iBAAiB,MAAM,gCAAgC,GAAG,IAAI;AAAA,kBAC3E,QACE;AAAA,kBACF,kBAAkB;AAAA,oBAChB;AAAA,oBACA;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,GAAY;AACnB,iBAAS,KAAK,4BAA4B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,MACxF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;ACzNA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAMP,SAASC,aAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEO,IAAM,wBAAN,MAA+C;AAAA,EAC3C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,YAAM,SAAS,aAAa,WAAW,QAAQ,IAAI,WAAW;AAG9D,YAAM,QAA8B,CAAC;AACrC,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,OAAO;AAAA,UACxB,IAAI,wBAAwB,EAAE,WAAW,UAAU,CAAC;AAAA,QACtD;AACA,YAAI,KAAK,wBAAwB;AAC/B,gBAAM,KAAK,GAAG,KAAK,sBAAsB;AAAA,QAC3C;AACA,oBAAY,KAAK;AAAA,MACnB,SAAS;AAET,iBAAW,QAAQ,OAAO;AACxB,cAAM,UAAU,KAAK,kBAAkB;AACvC,cAAM,aAAa,KAAK,cAAc;AAEtC,YAAI;AACJ,YAAI;AACF,gBAAM,WAAW,MAAM,OAAO;AAAA,YAC5B,IAAI,2BAA2B,EAAE,gBAAgB,QAAQ,CAAC;AAAA,UAC5D;AACA,mBAAS,SAAS;AAAA,QACpB,SAAS,GAAY;AACnB,mBAAS,KAAK,kCAAkC,OAAO,KAAK,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AACxG;AAAA,QACF;AAEA,YAAI,CAAC,OAAQ;AAEb,cAAM,SAAS,OAAO,UAAU;AAChC,cAAM,UAAU,OAAO,WAAW,CAAC;AACnC,cAAM,WAAW,QAAQ,SAAS,IAAI,cAAc,QAAQ,MAAM,kBAAkB;AAGpF,YAAI,WAAW,UAAU;AACvB,mBAAS;AAAA,YACPA,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,mBAAmB,UAAU;AAAA,cACpC,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb;AAAA,cACA,aAAa,wBAAwB,UAAU,uBAAuB,QAAQ;AAAA,cAC9E,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAGA,YAAI,WAAW,YAAY,OAAO,UAAU;AAC1C,gBAAM,MAAM,oBAAI,KAAK;AACrB,gBAAM,aAAa,IAAI,KAAK,OAAO,QAAQ;AAC3C,gBAAM,kBAAkB,KAAK;AAAA,aAC1B,WAAW,QAAQ,IAAI,IAAI,QAAQ,MAAM,MAAO,KAAK,KAAK;AAAA,UAC7D;AAEA,cAAI,kBAAkB,GAAG;AACvB,qBAAS;AAAA,cACPA,aAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,mBAAmB,UAAU;AAAA,gBACpC,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,wBAAwB,UAAU,aAAa,KAAK,IAAI,eAAe,CAAC,aAAa,QAAQ;AAAA,gBAC1G,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF,WAAW,kBAAkB,IAAI;AAC/B,qBAAS;AAAA,cACPA,aAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,mBAAmB,UAAU,eAAe,eAAe;AAAA,gBAClE,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,wBAAwB,UAAU,gBAAgB,eAAe,UAAU,WAAW,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,QAAQ;AAAA,gBAC3I,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF,WAAW,kBAAkB,IAAI;AAC/B,qBAAS;AAAA,cACPA,aAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,mBAAmB,UAAU,eAAe,eAAe;AAAA,gBAClE,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,wBAAwB,UAAU,gBAAgB,eAAe,UAAU,WAAW,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,QAAQ;AAAA,gBAC3I,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB,MAAM;AAAA,QACxB,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AC1LA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAY,WAAW;AAMhC,SAASC,aAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEA,SAAS,oBAAoB,QAA+B;AAG1D,QAAM,YAAY;AAClB,QAAM,IAAI,OAAO,MAAM,SAAS;AAChC,SAAO,IAAI,EAAE,CAAC,IAAI;AACpB;AAEA,SAAS,eAAe,QAAoD;AAC1E,MAAI,2CAA2C,KAAK,MAAM,EAAG,QAAO;AACpE,MAAI,mCAAmC,KAAK,MAAM,EAAG,QAAO;AAC5D,MAAI,wBAAwB,KAAK,MAAM,EAAG,QAAO;AACjD,SAAO;AACT;AAEA,eAAe,YAAY,UAAoC;AAC7D,MAAI;AAEF,UAAM,IAAI,SAAS,SAAS,GAAG,IAAI,SAAS,MAAM,GAAG,EAAE,IAAI;AAC3D,UAAM,IAAI,QAAQ,CAAC;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,qBAAN,MAA4C;AAAA,EACxC,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAC5B,QAAI,mBAAmB;AAEvB,QAAI;AACF,YAAM,UAAU,aAAa,eAAe,QAAQ,IAAI,WAAW;AAGnE,YAAM,QAAsB,CAAC;AAC7B,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,QAAQ;AAAA,UACzB,IAAI,uBAAuB,EAAE,QAAQ,OAAO,CAAC;AAAA,QAC/C;AACA,YAAI,KAAK,YAAa,OAAM,KAAK,GAAG,KAAK,WAAW;AACpD,iBAAS,KAAK,cAAc,KAAK,aAAa;AAAA,MAChD,SAAS;AAET,iBAAW,QAAQ,OAAO;AACxB,cAAM,SAAS,KAAK,MAAM;AAC1B,cAAM,WAAW,KAAK,QAAQ;AAC9B,cAAM,cAAc,OAAO,QAAQ,gBAAgB,EAAE;AAGrD,cAAM,UAA+B,CAAC;AACtC,YAAI;AACJ,YAAI;AACJ,WAAG;AACD,gBAAM,OAAO,MAAM,QAAQ;AAAA,YACzB,IAAI,8BAA8B;AAAA,cAChC,cAAc;AAAA,cACd,iBAAiB;AAAA,cACjB,iBAAiB;AAAA,YACnB,CAAC;AAAA,UACH;AACA,cAAI,KAAK,mBAAoB,SAAQ,KAAK,GAAG,KAAK,kBAAkB;AACpE,cAAI,KAAK,aAAa;AACpB,uBAAW,KAAK;AAChB,uBAAW,KAAK;AAAA,UAClB,OAAO;AACL,uBAAW;AACX,uBAAW;AAAA,UACb;AAAA,QACF,SAAS;AAGT,cAAM,eAAe,QAAQ;AAAA,UAC3B,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,mBAAmB,EAAE,gBAAgB,SAAS;AAAA,QAC/E;AAEA,4BAAoB,aAAa;AAEjC,mBAAW,UAAU,cAAc;AACjC,gBAAM,aAAa,OAAO,QAAQ;AAClC,gBAAM,SAAS,OAAO,gBAAiB,CAAC,EAAE,SAAS;AACnD,gBAAM,YAAY,OAAO,SAAS,yBAAyB,WAAW;AACtE,gBAAM,aAAa,eAAe,MAAM;AAExC,cAAI,eAAe,MAAM;AAEvB,kBAAM,aAAa,oBAAoB,MAAM;AAC7C,gBAAI,YAAY;AACd,kBAAI,eAAe;AACnB,kBAAI;AACF,sBAAM,KAAK,aAAa,UAAU,QAAQ,IAAI,WAAW;AACzD,sBAAM,GAAG,KAAK,IAAI,kBAAkB,EAAE,QAAQ,WAAW,CAAC,CAAC;AAC3D,+BAAe;AAAA,cACjB,SAAS,GAAY;AACnB,sBAAM,UAAW,EAAwB,QAAQ;AAEjD,oBAAI,YAAY,eAAe,YAAY,kBAAkB,YAAY,OAAO;AAC9E,iCAAe;AAAA,gBACjB;AAAA,cACF;AAEA,kBAAI,CAAC,cAAc;AACjB,yBAAS;AAAA,kBACPA,aAAY;AAAA,oBACV,WAAW;AAAA,oBACX,OAAO,SAAS,UAAU,sCAAsC,UAAU;AAAA,oBAC1E,cAAc;AAAA,oBACd,YAAY;AAAA,oBACZ,aAAa;AAAA,oBACb;AAAA,oBACA,aAAa,eAAe,UAAU,cAAc,QAAQ,+BAA+B,UAAU;AAAA,oBACrG,QACE;AAAA,oBACF,kBAAkB;AAAA,sBAChB;AAAA,sBACA;AAAA,sBACA;AAAA,oBACF;AAAA,kBACF,CAAC;AAAA,gBACH;AAAA,cACF;AAAA,YACF;AAAA,UACF,WAAW,eAAe,OAAO;AAC/B,kBAAM,WAAW,MAAM,YAAY,MAAM;AACzC,gBAAI,CAAC,UAAU;AACb,uBAAS;AAAA,gBACPA,aAAY;AAAA,kBACV,WAAW;AAAA,kBACX,OAAO,SAAS,UAAU;AAAA,kBAC1B,cAAc;AAAA,kBACd,YAAY;AAAA,kBACZ,aAAa;AAAA,kBACb;AAAA,kBACA,aAAa,eAAe,UAAU,cAAc,QAAQ,yBAAyB,MAAM;AAAA,kBAC3F,QACE;AAAA,kBACF,kBAAkB;AAAA,oBAChB;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,WAAW,eAAe,cAAc;AACtC,kBAAM,WAAW,MAAM,YAAY,MAAM;AACzC,gBAAI,CAAC,UAAU;AACb,uBAAS;AAAA,gBACPA,aAAY;AAAA,kBACV,WAAW;AAAA,kBACX,OAAO,SAAS,UAAU;AAAA,kBAC1B,cAAc;AAAA,kBACd,YAAY;AAAA,kBACZ,aAAa;AAAA,kBACb;AAAA,kBACA,aAAa,eAAe,UAAU,cAAc,QAAQ,gCAAgC,MAAM;AAAA,kBAClG,QACE;AAAA,kBACF,kBAAkB;AAAA,oBAChB;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,WAAW,eAAe,MAAM;AAE9B,kBAAM,WAAW,MAAM,YAAY,MAAM;AACzC,gBAAI,CAAC,UAAU;AACb,uBAAS;AAAA,gBACPA,aAAY;AAAA,kBACV,WAAW;AAAA,kBACX,OAAO,SAAS,UAAU;AAAA,kBAC1B,cAAc;AAAA,kBACd,YAAY;AAAA,kBACZ,aAAa;AAAA,kBACb;AAAA,kBACA,aAAa,eAAe,UAAU,cAAc,QAAQ,qBAAqB,MAAM;AAAA,kBACvF,QACE;AAAA,kBACF,kBAAkB;AAAA,oBAChB;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AC7PA;AAAA,EACE,aAAAC;AAAA,EACA,4BAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AAMP,IAAM,kBAA0C;AAAA,EAC9C,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AAEA,SAASC,aAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEA,SAAS,aAAa,KAAsB,MAAuB;AACjE,aAAW,MAAM,KAAK;AACpB,eAAW,QAAQ,GAAG,iBAAiB,CAAC,GAAG;AACzC,UAAI,0BAA0B,MAAM,IAAI,EAAG,QAAO;AAAA,IACpD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,KAA+B;AACvD,aAAW,MAAM,KAAK;AACpB,eAAW,QAAQ,GAAG,iBAAiB,CAAC,GAAG;AACzC,UAAI,WAAW,IAAI,KAAK,aAAa,IAAI,EAAG,QAAO;AAAA,IACrD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,0BAA0B,MAAoB,MAAuB;AAC5E,MAAI,CAAC,aAAa,IAAI,EAAG,QAAO;AAChC,QAAM,OAAO,KAAK,YAAY;AAC9B,QAAM,KAAK,KAAK,UAAU;AAC1B,MAAI,SAAS,MAAM,OAAO,GAAI,QAAO;AACrC,SAAO,QAAQ,QAAQ,QAAQ;AACjC;AAEA,SAAS,aAAa,MAA6B;AACjD,QAAM,WAAW,KAAK,YAAY,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW;AAC1E,QAAM,WAAW,KAAK,cAAc,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,aAAa,MAAM;AACzE,SAAO,WAAW;AACpB;AAEA,SAAS,WAAW,MAA6B;AAC/C,QAAM,OAAO,KAAK,YAAY;AAC9B,QAAM,KAAK,KAAK,UAAU;AAC1B,SAAQ,SAAS,MAAM,OAAO,MAAQ,SAAS,KAAK,OAAO;AAC7D;AAEA,SAAS,eAAe,MAAkB,MAAuB;AAG/D,QAAM,gBAAgB,KAAK,WAAW,CAAC,GACpC,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,EAChC,KAAK,CAAC,GAAG,OAAO,EAAE,cAAc,MAAM,EAAE,cAAc,EAAE;AAE3D,aAAW,QAAQ,cAAc;AAC/B,QAAI,oBAAoB,MAAM,IAAI,KAAK,yBAAyB,IAAI,GAAG;AAErE,aAAO,KAAK,eAAe;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,MAAuB,MAAuB;AAEzE,MAAI,KAAK,aAAa,KAAM,QAAO;AAEnC,MAAI,KAAK,aAAa,OAAO,KAAK,aAAa,KAAM,QAAO;AAC5D,QAAM,OAAO,KAAK,WAAW,QAAQ;AACrC,QAAM,KAAK,KAAK,WAAW,MAAM;AACjC,SAAO,QAAQ,QAAQ,QAAQ;AACjC;AAEA,SAAS,yBAAyB,MAAgC;AAChE,SAAO,KAAK,cAAc,eAAe,KAAK,kBAAkB;AAClE;AAEO,IAAM,6BAAN,MAAoD;AAAA,EAChD,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,YAAM,SAAS,aAAaC,YAAW,QAAQ,IAAI,WAAW;AAG9D,YAAM,SAAS,oBAAI,IAAoB;AACvC,UAAI;AACF,cAAM,UAAU,MAAM,OAAO,KAAK,IAAI,yBAAyB,CAAC,CAAC,CAAC;AAClE,mBAAW,QAAQ,QAAQ,aAAa,CAAC,GAAG;AAC1C,cAAI,KAAK,cAAc,KAAK,UAAU;AACpC,mBAAO,IAAI,KAAK,YAAY,KAAK,QAAQ;AAAA,UAC3C;AAAA,QACF;AAAA,MACF,SAAS,GAAY;AACnB,iBAAS,KAAK,+BAA+B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,MAC3F;AAGA,YAAM,YAAwB,CAAC;AAC/B,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,OAAO;AAAA,UACxB,IAAIC,0BAAyB,EAAE,WAAW,UAAU,CAAC;AAAA,QACvD;AACA,mBAAW,OAAO,KAAK,gBAAgB,CAAC,GAAG;AACzC,cAAI,IAAI,UAAW,WAAU,KAAK,GAAG,IAAI,SAAS;AAAA,QACpD;AACA,oBAAY,KAAK;AAAA,MACnB,SAAS;AAGT,YAAM,kBAAkB,UAAU,OAAO,CAAC,SAAS;AACjD,cAAM,SAAS,KAAK,cAAc;AAClC,eAAO,KAAK,mBAAmB,OAAO,IAAI,MAAM;AAAA,MAClD,CAAC;AAGD,YAAM,QAAQ,oBAAI,IAAY;AAC9B,YAAM,YAAY,oBAAI,IAAY;AAClC,iBAAW,QAAQ,iBAAiB;AAClC,mBAAW,MAAM,KAAK,kBAAkB,CAAC,GAAG;AAC1C,cAAI,GAAG,QAAS,OAAM,IAAI,GAAG,OAAO;AAAA,QACtC;AACA,YAAI,KAAK,SAAU,WAAU,IAAI,KAAK,QAAQ;AAAA,MAChD;AAGA,YAAM,QAAQ,oBAAI,IAA2B;AAC7C,UAAI,MAAM,OAAO,GAAG;AAClB,cAAM,SAAS,MAAM,OAAO;AAAA,UAC1B,IAAI,8BAA8B;AAAA,YAChC,UAAU,CAAC,GAAG,KAAK;AAAA,UACrB,CAAC;AAAA,QACH;AACA,mBAAW,MAAM,OAAO,kBAAkB,CAAC,GAAG;AAC5C,cAAI,GAAG,QAAS,OAAM,IAAI,GAAG,SAAS,EAAE;AAAA,QAC1C;AAAA,MACF;AAGA,YAAM,gBAAgB,oBAAI,IAAwB;AAClD,UAAI,UAAU,OAAO,GAAG;AACtB,YAAI;AACJ,cAAM,WAAyB,CAAC;AAChC,WAAG;AACD,gBAAM,WAAW,MAAM,OAAO;AAAA,YAC5B,IAAI,2BAA2B;AAAA,cAC7B,SAAS,CAAC,EAAE,MAAM,yBAAyB,QAAQ,CAAC,GAAG,SAAS,EAAE,CAAC;AAAA,cACnE,WAAW;AAAA,YACb,CAAC;AAAA,UACH;AACA,cAAI,SAAS,YAAa,UAAS,KAAK,GAAG,SAAS,WAAW;AAC/D,sBAAY,SAAS;AAAA,QACvB,SAAS;AAET,mBAAW,QAAQ,UAAU;AAC3B,qBAAW,SAAS,KAAK,gBAAgB,CAAC,GAAG;AAC3C,gBAAI,MAAM,UAAU;AAClB,4BAAc,IAAI,MAAM,UAAU,IAAI;AAAA,YACxC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,iBAAW,QAAQ,iBAAiB;AAClC,cAAM,SAAS,KAAK,cAAc;AAClC,cAAM,UAAU,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,aAAa,MAAM;AAC9E,cAAM,WAAW,KAAK,mBAAmB,OAAO,IAAI,MAAM,KAAK;AAC/D,cAAM,WAAW,KAAK,YAAY;AAGlC,cAAM,UAA2B,CAAC;AAClC,mBAAW,MAAM,KAAK,kBAAkB,CAAC,GAAG;AAC1C,cAAI,GAAG,SAAS;AACd,kBAAM,SAAS,MAAM,IAAI,GAAG,OAAO;AACnC,gBAAI,OAAQ,SAAQ,KAAK,MAAM;AAAA,UACjC;AAAA,QACF;AAEA,cAAM,OAAO,cAAc,IAAI,QAAQ;AAGvC,mBAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,eAAe,GAAG;AACjE,gBAAM,OAAO,OAAO,OAAO;AAC3B,gBAAM,WAAW,aAAa,SAAS,IAAI;AAC3C,gBAAM,aAAa,OAAO,eAAe,MAAM,IAAI,IAAI;AAEvD,cAAI,YAAY,YAAY;AAC1B,qBAAS;AAAA,cACPF,aAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,OAAO,MAAM,KAAK,QAAQ,MAAM,QAAQ,KAAK,IAAI;AAAA,gBACxD,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,iBAAiB,MAAM,mBAAmB,QAAQ,iEAAiE,QAAQ,UAAU,IAAI;AAAA,gBACtJ,QACE,GAAG,QAAQ;AAAA,gBACb,kBAAkB;AAAA,kBAChB,kDAAkD,IAAI;AAAA,kBACtD;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF,WAAW,YAAY,CAAC,YAAY;AAClC,qBAAS;AAAA,cACPA,aAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,OAAO,MAAM,KAAK,QAAQ,KAAK,IAAI;AAAA,gBAC1C,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,iBAAiB,MAAM,MAAM,QAAQ,uCAAuC,QAAQ,UAAU,IAAI;AAAA,gBAC/G,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB,6CAA6C,IAAI;AAAA,kBACjD;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAGA,YAAI,iBAAiB,OAAO,GAAG;AAE7B,gBAAM,WAAW,OAAO,eAAe,MAAM,EAAE,IAAI;AACnD,cAAI,UAAU;AACZ,qBAAS;AAAA,cACPA,aAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,OAAO,MAAM,KAAK,QAAQ;AAAA,gBACjC,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,iBAAiB,MAAM,mBAAmB,QAAQ;AAAA,gBAC/D,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB,gBAAgB;AAAA,QAClC,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AC/TA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAMP,SAASG,aAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAQA,SAAS,eAAe,KAAwB;AAC9C,QAAM,UAAoB,CAAC;AAC3B,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,SAAS;AACf,QAAM,QAAQ,MAAM,QAAQ,OAAO,SAAS,IACxC,OAAO,YACP,OAAO,YACL,CAAC,OAAO,SAAS,IACjB,CAAC;AAEP,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,QAAS;AAC7B,UAAM,OAAO,MAAM,QAAQ,KAAK,MAAM,IAClC,KAAK,SACL,KAAK,SACH,CAAC,KAAK,MAAM,IACZ,CAAC;AACP,YAAQ,KAAK,GAAG,IAAI;AAAA,EACtB;AACA,SAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAC3C;AAEA,SAAS,UAAU,SAAmB,SAA0B;AAC9D,QAAM,MAAM,QAAQ,YAAY;AAChC,SAAO,QAAQ,KAAK,CAAC,MAAM;AACzB,QAAI,MAAM,IAAK,QAAO;AACtB,QAAI,MAAM,IAAK,QAAO;AAEtB,QAAI,EAAE,SAAS,GAAG,GAAG;AACnB,YAAM,SAAS,EAAE,MAAM,GAAG,EAAE;AAC5B,UAAI,IAAI,WAAW,MAAM,EAAG,QAAO;AAAA,IACrC;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAEO,IAAM,gCAAN,MAAuD;AAAA,EACnD,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAC5B,UAAM,YAAY,aAAa,MAAM;AAErC,aAAS;AAAA,MACP;AAAA,IACF;AAEA,QAAI;AACF,YAAM,SAAS,aAAa,WAAW,WAAW,IAAI,WAAW;AAGjE,YAAM,QAAgB,CAAC;AACvB,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,OAAO;AAAA,UACxB,IAAI,iBAAiB,EAAE,QAAQ,OAAO,CAAC;AAAA,QACzC;AACA,YAAI,KAAK,MAAO,OAAM,KAAK,GAAG,KAAK,KAAK;AACxC,iBAAS,KAAK,cAAc,KAAK,SAAS;AAAA,MAC5C,SAAS;AAET,iBAAW,QAAQ,OAAO;AACxB,cAAM,WAAW,KAAK,YAAY;AAClC,cAAM,UACJ,KAAK,OACL,OAAO,SAAS,SAAS,SAAS,SAAS,QAAQ;AAGrD,cAAM,aAAuB,CAAC;AAG9B,YAAI;AACF,gBAAM,eAAe,MAAM,OAAO;AAAA,YAChC,IAAI,gCAAgC,EAAE,UAAU,SAAS,CAAC;AAAA,UAC5D;AACA,qBAAW,UAAU,aAAa,oBAAoB,CAAC,GAAG;AACxD,kBAAM,YAAY,OAAO;AACzB,gBAAI,CAAC,UAAW;AAChB,gBAAI;AACF,oBAAM,aAAa,MAAM,OAAO;AAAA,gBAC9B,IAAI,iBAAiB,EAAE,WAAW,UAAU,CAAC;AAAA,cAC/C;AACA,oBAAM,YACJ,WAAW,QAAQ,oBAAoB;AACzC,oBAAM,cAAc,MAAM,OAAO;AAAA,gBAC/B,IAAI,wBAAwB;AAAA,kBAC1B,WAAW;AAAA,kBACX,WAAW;AAAA,gBACb,CAAC;AAAA,cACH;AACA,oBAAM,MAAM,YAAY,eAAe;AACvC,kBAAI,KAAK;AACP,sBAAM,SAAS,KAAK,MAAM,mBAAmB,GAAG,CAAC;AACjD,2BAAW,KAAK,GAAG,eAAe,MAAM,CAAC;AAAA,cAC3C;AAAA,YACF,SAAS,GAAY;AACnB,oBAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,uBAAS;AAAA,gBACP,yBAAyB,SAAS,aAAa,QAAQ,KAAK,GAAG;AAAA,cACjE;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,GAAY;AACnB,gBAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,mBAAS;AAAA,YACP,6CAA6C,QAAQ,KAAK,GAAG;AAAA,UAC/D;AAAA,QACF;AAGA,YAAI;AACF,gBAAM,aAAa,MAAM,OAAO;AAAA,YAC9B,IAAI,wBAAwB,EAAE,UAAU,SAAS,CAAC;AAAA,UACpD;AACA,qBAAW,cAAc,WAAW,eAAe,CAAC,GAAG;AACrD,gBAAI;AACF,oBAAM,mBAAmB,MAAM,OAAO;AAAA,gBACpC,IAAI,qBAAqB;AAAA,kBACvB,UAAU;AAAA,kBACV,YAAY;AAAA,gBACd,CAAC;AAAA,cACH;AACA,oBAAM,MAAM,iBAAiB;AAC7B,kBAAI,KAAK;AACP,sBAAM,SAAS,KAAK,MAAM,mBAAmB,GAAG,CAAC;AACjD,2BAAW,KAAK,GAAG,eAAe,MAAM,CAAC;AAAA,cAC3C;AAAA,YACF,SAAS,GAAY;AACnB,oBAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,uBAAS;AAAA,gBACP,gCAAgC,UAAU,aAAa,QAAQ,KAAK,GAAG;AAAA,cACzE;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,GAAY;AACnB,gBAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,mBAAS;AAAA,YACP,2CAA2C,QAAQ,KAAK,GAAG;AAAA,UAC7D;AAAA,QACF;AAEA,YAAI,WAAW,WAAW,EAAG;AAG7B,YACE,UAAU,YAAY,OAAO,KAC7B,WAAW,SAAS,GAAG,GACvB;AACA,mBAAS;AAAA,YACPA,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,YAAY,QAAQ;AAAA,cAC3B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb,QAAQ;AAAA,cACR,aAAa,SAAS,QAAQ;AAAA,cAC9B,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB,8CAA8C,QAAQ;AAAA,gBACtD;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAEA;AAAA,QACF;AAGA,YACE,UAAU,YAAY,mBAAmB,KACzC,UAAU,YAAY,sBAAsB,GAC5C;AACA,mBAAS;AAAA,YACPA,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,YAAY,QAAQ;AAAA,cAC3B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb,QAAQ;AAAA,cACR,aAAa,SAAS,QAAQ;AAAA,cAC9B,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB,gEAAgE,QAAQ;AAAA,gBACxE;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAGA,YACE,UAAU,YAAY,gBAAgB,KACtC,UAAU,YAAY,sBAAsB,GAC5C;AACA,mBAAS;AAAA,YACPA,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,YAAY,QAAQ;AAAA,cAC3B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb,QAAQ;AAAA,cACR,aAAa,SAAS,QAAQ;AAAA,cAC9B,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB,uFAAuF,QAAQ;AAAA,gBAC/F;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAGA,YACE,UAAU,YAAY,cAAc,KACpC,UAAU,YAAY,uBAAuB,GAC7C;AACA,mBAAS;AAAA,YACPA,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,YAAY,QAAQ;AAAA,cAC3B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb,QAAQ;AAAA,cACR,aAAa,SAAS,QAAQ;AAAA,cAC9B,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB,yDAAyD,QAAQ;AAAA,gBACjE;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAGA,YAAI,UAAU,YAAY,qBAAqB,GAAG;AAChD,mBAAS;AAAA,YACPA,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,YAAY,QAAQ;AAAA,cAC3B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb,QAAQ;AAAA,cACR,aAAa,SAAS,QAAQ;AAAA,cAC9B,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAGA,YAAI,UAAU,YAAY,gBAAgB,GAAG;AAC3C,mBAAS;AAAA,YACPA,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,YAAY,QAAQ;AAAA,cAC3B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb,QAAQ;AAAA,cACR,aAAa,SAAS,QAAQ;AAAA,cAC9B,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB,2DAA2D,QAAQ;AAAA,gBACnE;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB,MAAM;AAAA,QACxB,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AC/VA;AAAA,EACE,YAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,OAAOC,UAAS;AAMhB,SAASC,aAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEA,SAAS,WAAW,QAAgB,QAAwB;AAC1D,QAAM,SAAS,OAAO,WAAW,KAAK,IAClC,qBACA;AACJ,SAAO,WAAW,MAAM,OAAO,MAAM,IAAI,MAAM;AACjD;AAEA,eAAe,gBACb,QACA,YACA,eACA,UACiB;AACjB,MAAI;AACF,UAAM,OAAO,MAAM,OAAO;AAAA,MACxB,IAAI,yBAAyB,EAAE,QAAQ,WAAW,CAAC;AAAA,IACrD;AACA,UAAM,MAAM,OAAO,KAAK,sBAAsB,EAAE,KAAK;AACrD,WAAO;AAAA,EACT,SAAS,GAAY;AACnB,UAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,aAAS,KAAK,sCAAsC,UAAU,WAAW,aAAa,KAAK,GAAG,EAAE;AAChG,WAAO;AAAA,EACT;AACF;AAEA,eAAe,qBACb,QACA,YACA,UAC2B;AAE3B,MAAI,YAAY;AAChB,MAAI;AACF,UAAM,MAAM,MAAM,OAAO;AAAA,MACvB,IAAI,4BAA4B,EAAE,QAAQ,WAAW,CAAC;AAAA,IACxD;AACA,UAAM,MAAM,IAAI;AAChB,gBAAY,CAAC,EACX,KAAK,mBACL,KAAK,oBACL,KAAK,qBACL,KAAK;AAAA,EAET,SAAS,GAAY;AACnB,QACE,aAAa,SACb,EAAE,SAAS,wCACX;AACA,kBAAY;AAAA,IACd,OAAO;AACL,YAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,eAAS,KAAK,4CAA4C,UAAU,KAAK,GAAG,EAAE;AAC9E,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,UAAW,QAAO;AAGtB,MAAI;AACF,UAAM,MAAM,MAAM,OAAO;AAAA,MACvB,IAAI,oBAAoB,EAAE,QAAQ,WAAW,CAAC;AAAA,IAChD;AACA,eAAW,SAAS,IAAI,UAAU,CAAC,GAAG;AACpC,YAAM,MAAM,MAAM,SAAS,OAAO;AAClC,UAAI,IAAI,SAAS,UAAU,KAAK,IAAI,SAAS,oBAAoB,GAAG;AAClE,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,SAAS,GAAY;AACnB,UAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,aAAS,KAAK,kCAAkC,UAAU,KAAK,GAAG,EAAE;AAAA,EACtE;AAGA,MAAI;AACF,UAAM,eAAe,MAAM,OAAO;AAAA,MAChC,IAAI,6BAA6B,EAAE,QAAQ,WAAW,CAAC;AAAA,IACzD;AACA,QAAI,aAAa,cAAc,SAAU,QAAO;AAAA,EAClD,SAAS,GAAY;AAEnB,QAAI,aAAa,SAAS,CAAC,EAAE,KAAK,SAAS,oBAAoB,GAAG;AAChE,YAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,eAAS,KAAK,4CAA4C,UAAU,KAAK,GAAG,EAAE;AAAA,IAChF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,IAAqB;AACxC,MAAI,GAAG,WAAW,KAAK,EAAG,QAAO;AACjC,MAAI,GAAG,WAAW,UAAU,EAAG,QAAO;AACtC,MAAI,GAAG,WAAW,MAAM,GAAG;AACzB,UAAM,SAAS,SAAS,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE;AAC5C,WAAO,UAAU,MAAM,UAAU;AAAA,EACnC;AACA,MAAI,GAAG,WAAW,MAAM,EAAG,QAAO;AAClC,SAAO;AACT;AAEO,IAAM,4BAAN,MAAmD;AAAA,EAC/C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAC5B,QAAI,mBAAmB;AAEvB,QAAI;AAEF,UAAI;AACF,cAAM,WAAW,aAAaC,WAAU,QAAQ,IAAI,WAAW;AAC/D,cAAM,WAAW,MAAM,SAAS,KAAK,IAAI,mBAAmB,CAAC,CAAC,CAAC;AAC/D,cAAM,UAAU,SAAS,WAAW,CAAC;AAErC,mBAAW,UAAU,SAAS;AAC5B,gBAAM,OAAO,OAAO,QAAQ;AAC5B,gBAAM,MAAM,OAAO,SAAS,SAAS,IAAI;AAEzC,gBAAM,eAAe,MAAM,gBAAgB,UAAU,MAAM,QAAQ,QAAQ;AAC3E,gBAAM,eACJ,iBAAiB,SACb,WACA,aAAaA,WAAU,cAAc,IAAI,WAAW;AAE1D,gBAAM,eAAe,MAAM,qBAAqB,cAAc,MAAM,QAAQ;AAC5E,cAAI,iBAAiB,UAAU,CAAC,aAAc;AAE9C;AACA,gBAAM,MAAM,WAAW,MAAM,YAAY;AAEzC,cAAI;AACF,kBAAM,OAAO,MAAM,MAAM,KAAK;AAAA,cAC5B,QAAQ;AAAA,cACR,QAAQ,YAAY,QAAQ,GAAI;AAAA,YAClC,CAAC;AAED,gBAAI,KAAK,MAAM,KAAK,WAAW,KAAK;AAClC,uBAAS;AAAA,gBACPD,aAAY;AAAA,kBACV,WAAW;AAAA,kBACX,OAAO,aAAa,IAAI;AAAA,kBACxB,cAAc;AAAA,kBACd,YAAY;AAAA,kBACZ,aAAa;AAAA,kBACb,QAAQ;AAAA,kBACR,aAAa,gBAAgB,GAAG,oBAAoB,KAAK,MAAM;AAAA,kBAC/D,QACE;AAAA,kBACF,kBAAkB;AAAA,oBAChB;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF,WAAW,KAAK,WAAW,KAAK;AAC9B,uBAAS;AAAA,gBACPA,aAAY;AAAA,kBACV,WAAW;AAAA,kBACX,OAAO,aAAa,IAAI;AAAA,kBACxB,cAAc;AAAA,kBACd,YAAY;AAAA,kBACZ,aAAa;AAAA,kBACb,QAAQ;AAAA,kBACR,aAAa,WAAW,IAAI;AAAA,kBAC5B,QACE;AAAA,kBACF,kBAAkB;AAAA,oBAChB;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,SAAS,GAAY;AACnB,kBAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,qBAAS,KAAK,yBAAyB,IAAI,YAAY,GAAG,EAAE;AAAA,UAC9D;AAAA,QACF;AAAA,MACF,SAAS,GAAY;AACnB,cAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,iBAAS,KAAK,yCAAyC,GAAG,EAAE;AAAA,MAC9D;AAGA,UAAI;AACF,cAAM,YAAY,aAAa,WAAW,QAAQ,IAAI,WAAW;AACjE,cAAM,YAA0B,CAAC;AACjC,YAAI;AACJ,WAAG;AACD,gBAAM,OAAO,MAAM,UAAU;AAAA,YAC3B,IAAI,2BAA2B,EAAE,QAAQ,OAAO,CAAC;AAAA,UACnD;AACA,cAAI,KAAK,YAAa,WAAU,KAAK,GAAG,KAAK,WAAW;AACxD,mBAAS,KAAK;AAAA,QAChB,SAAS;AAET,mBAAW,MAAM,WAAW;AAC1B,cAAI,CAAC,GAAG,mBAAoB;AAE5B,gBAAM,OAAO,GAAG,wBAAwB;AACxC,gBAAM,QACJ,GAAG,iBACH,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,OAAO,IAAI;AACxD,gBAAM,WAAW,GAAG,UAAU;AAC9B,cAAI,CAAC,SAAU;AAEf;AAEA,cAAI;AACF,kBAAM,YAAY,MAAME,KAAI,SAAS,SAAS,QAAQ;AACtD,kBAAM,cAAc,UAAU,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;AAE3D,gBAAI,aAAa;AACf,uBAAS;AAAA,gBACPF,aAAY;AAAA,kBACV,WAAW;AAAA,kBACX,OAAO,gBAAgB,IAAI;AAAA,kBAC3B,cAAc;AAAA,kBACd,YAAY;AAAA,kBACZ,aAAa;AAAA,kBACb;AAAA,kBACA,aAAa,gBAAgB,QAAQ,8BAA8B,UAAU,KAAK,IAAI,CAAC;AAAA,kBACvF,QACE;AAAA,kBACF,kBAAkB;AAAA,oBAChB;AAAA,oBACA;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,SAAS,GAAY;AACnB,kBAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,qBAAS,KAAK,0BAA0B,IAAI,KAAK,QAAQ,aAAa,GAAG,EAAE;AAAA,UAC7E;AAAA,QACF;AAAA,MACF,SAAS,GAAY;AACnB,cAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,iBAAS,KAAK,0CAA0C,GAAG,EAAE;AAAA,MAC/D;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AClTA;AAAA,EACE,aAAAG;AAAA,EACA,4BAAAC;AAAA,OAEK;AACP;AAAA,EACE,aAAAC;AAAA,EACA,8BAAAC;AAAA,OAEK;AACP;AAAA,EACE,YAAAC;AAAA,EACA,sBAAAC;AAAA,EACA;AAAA,OACK;AAMP,IAAM,wBAAwB,CAAC,eAAe,WAAW,OAAO;AAEhE,SAASC,aAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEA,SAAS,eACP,MACA,cACU;AACV,QAAM,UAAU,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AACpD,SAAO,aAAa,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;AACrD;AAEO,IAAM,uBAAN,MAA8C;AAAA,EAC1C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAC5B,QAAI,mBAAmB;AACvB,UAAM,eAAe;AAErB,QAAI;AAEF,UAAI;AACF,cAAM,YAAY,aAAaC,YAAW,QAAQ,IAAI,WAAW;AACjE,cAAM,YAAwB,CAAC;AAC/B,YAAI;AACJ,WAAG;AACD,gBAAM,OAAO,MAAM,UAAU;AAAA,YAC3B,IAAIC,0BAAyB,EAAE,WAAW,UAAU,CAAC;AAAA,UACvD;AACA,qBAAW,OAAO,KAAK,gBAAgB,CAAC,GAAG;AACzC,gBAAI,IAAI,UAAW,WAAU,KAAK,GAAG,IAAI,SAAS;AAAA,UACpD;AACA,sBAAY,KAAK;AAAA,QACnB,SAAS;AAET,4BAAoB,UAAU;AAE9B,mBAAW,YAAY,WAAW;AAChC,gBAAM,KAAK,SAAS,cAAc;AAClC,gBAAM,MAAM,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,aAAa,EAAE;AACtE,gBAAM,OAAO,SAAS,QAAQ,CAAC;AAC/B,gBAAM,UAAU,eAAe,MAAM,YAAY;AAEjD,cAAI,QAAQ,SAAS,GAAG;AACtB,qBAAS;AAAA,cACPF,aAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,gBAAgB,EAAE,2BAA2B,QAAQ,KAAK,IAAI,CAAC;AAAA,gBACtE,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,iBAAiB,EAAE,6CAA6C,QAAQ,KAAK,IAAI,CAAC;AAAA,gBAC/F,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB,yBAAyB,QAAQ,KAAK,IAAI,CAAC,iBAAiB,EAAE;AAAA,kBAC9D;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,GAAY;AACnB,cAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,iBAAS,KAAK,oCAAoC,GAAG,EAAE;AAAA,MACzD;AAGA,UAAI;AACF,cAAM,YAAY,aAAaG,YAAW,QAAQ,IAAI,WAAW;AACjE,cAAM,cAA4B,CAAC;AACnC,YAAI;AACJ,WAAG;AACD,gBAAM,OAAO,MAAM,UAAU;AAAA,YAC3B,IAAIC,4BAA2B,EAAE,QAAQ,OAAO,CAAC;AAAA,UACnD;AACA,cAAI,KAAK,YAAa,aAAY,KAAK,GAAG,KAAK,WAAW;AAC1D,mBAAS,KAAK;AAAA,QAChB,SAAS;AAET,4BAAoB,YAAY;AAEhC,mBAAW,MAAM,aAAa;AAC5B,gBAAM,OAAO,GAAG,wBAAwB;AACxC,gBAAM,QACJ,GAAG,iBACH,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,OAAO,IAAI;AACxD,gBAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,YAC1C,KAAK,EAAE;AAAA,YACP,OAAO,EAAE;AAAA,UACX,EAAE;AACF,gBAAM,UAAU,eAAe,MAAM,YAAY;AAEjD,cAAI,QAAQ,SAAS,GAAG;AACtB,qBAAS;AAAA,cACPJ,aAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,gBAAgB,IAAI,2BAA2B,QAAQ,KAAK,IAAI,CAAC;AAAA,gBACxE,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,iBAAiB,IAAI,6CAA6C,QAAQ,KAAK,IAAI,CAAC;AAAA,gBACjG,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB,yBAAyB,QAAQ,KAAK,IAAI,CAAC,qBAAqB,IAAI;AAAA,kBACpE;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,GAAY;AACnB,cAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,iBAAS,KAAK,oCAAoC,GAAG,EAAE;AAAA,MACzD;AAGA,UAAI;AACF,cAAM,WAAW,aAAaK,WAAU,QAAQ,IAAI,WAAW;AAC/D,cAAM,WAAW,MAAM,SAAS,KAAK,IAAIC,oBAAmB,CAAC,CAAC,CAAC;AAC/D,cAAM,UAAU,SAAS,WAAW,CAAC;AACrC,4BAAoB,QAAQ;AAE5B,mBAAW,UAAU,SAAS;AAC5B,gBAAM,OAAO,OAAO,QAAQ;AAC5B,gBAAM,MAAM,OAAO,SAAS,SAAS,IAAI;AAEzC,cAAI;AACF,kBAAM,cAAc,MAAM,SAAS;AAAA,cACjC,IAAI,wBAAwB,EAAE,QAAQ,KAAK,CAAC;AAAA,YAC9C;AACA,kBAAM,QAAQ,YAAY,UAAU,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,cAClD,KAAK,EAAE;AAAA,cACP,OAAO,EAAE;AAAA,YACX,EAAE;AACF,kBAAM,UAAU,eAAe,MAAM,YAAY;AAEjD,gBAAI,QAAQ,SAAS,GAAG;AACtB,uBAAS;AAAA,gBACPN,aAAY;AAAA,kBACV,WAAW;AAAA,kBACX,OAAO,aAAa,IAAI,2BAA2B,QAAQ,KAAK,IAAI,CAAC;AAAA,kBACrE,cAAc;AAAA,kBACd,YAAY;AAAA,kBACZ,aAAa;AAAA,kBACb,QAAQ;AAAA,kBACR,aAAa,cAAc,IAAI,6CAA6C,QAAQ,KAAK,IAAI,CAAC;AAAA,kBAC9F,QACE;AAAA,kBACF,kBAAkB;AAAA,oBAChB,yBAAyB,QAAQ,KAAK,IAAI,CAAC,eAAe,IAAI;AAAA,oBAC9D;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,SAAS,GAAY;AACnB,gBACE,aAAa,SACb,EAAE,SAAS,gBACX;AAEA,uBAAS;AAAA,gBACPA,aAAY;AAAA,kBACV,WAAW;AAAA,kBACX,OAAO,aAAa,IAAI,2BAA2B,aAAa,KAAK,IAAI,CAAC;AAAA,kBAC1E,cAAc;AAAA,kBACd,YAAY;AAAA,kBACZ,aAAa;AAAA,kBACb,QAAQ;AAAA,kBACR,aAAa,cAAc,IAAI,wDAAwD,aAAa,KAAK,IAAI,CAAC;AAAA,kBAC9G,QACE;AAAA,kBACF,kBAAkB;AAAA,oBAChB,0BAA0B,aAAa,KAAK,IAAI,CAAC,eAAe,IAAI;AAAA,oBACpE;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF,OAAO;AACL,oBAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,uBAAS,KAAK,oBAAoB,IAAI,YAAY,GAAG,EAAE;AAAA,YACzD;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,GAAY;AACnB,cAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,iBAAS,KAAK,mCAAmC,GAAG,EAAE;AAAA,MACxD;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AChQA;AAAA,EACE,aAAAO;AAAA,EACA;AAAA,EACA,4BAAAC;AAAA,EACA,4BAAAC;AAAA,EACA;AAAA,EACA,iCAAAC;AAAA,OAKK;AAMP,SAASC,aAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEO,IAAM,uBAAN,MAA8C;AAAA,EAC1C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,YAAM,SAAS,aAAaC,YAAW,QAAQ,IAAI,WAAW;AAC9D,UAAI,mBAAmB;AAGvB,YAAM,UAAoB,CAAC;AAC3B,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,OAAO;AAAA,UACxB,IAAI,uBAAuB,EAAE,WAAW,SAAS,CAAC;AAAA,QACpD;AACA,YAAI,KAAK,QAAS,SAAQ,KAAK,GAAG,KAAK,OAAO;AAC9C,mBAAW,KAAK;AAAA,MAClB,SAAS;AAET,0BAAoB,QAAQ;AAE5B,iBAAW,OAAO,SAAS;AACzB,YAAI,IAAI,UAAU,aAAa;AAC7B,gBAAM,QAAQ,IAAI,YAAY;AAC9B,mBAAS;AAAA,YACPD,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,cAAc,KAAK;AAAA,cAC1B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,WAAW,KAAK;AAAA,cACxE;AAAA,cACA,aAAa,eAAe,KAAK,MAAM,IAAI,QAAQ,GAAG,OAAO,IAAI,cAAc,SAAS;AAAA,cACxF,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAGA,UAAI,YAAuB,CAAC;AAC5B,UAAI;AACF,cAAM,WAAW,MAAM,OAAO,KAAK,IAAIE,0BAAyB,CAAC,CAAC,CAAC;AACnE,oBAAY,SAAS,aAAa,CAAC;AAAA,MACrC,SAAS,GAAY;AACnB,cAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,iBAAS,KAAK,4BAA4B,GAAG,EAAE;AAAA,MACjD;AAEA,0BAAoB,UAAU;AAE9B,iBAAW,QAAQ,WAAW;AAC5B,YAAI,CAAC,KAAK,eAAe;AACvB,gBAAM,UAAU,KAAK,gBAAgB;AACrC,gBAAM,WAAW,KAAK,YAAY;AAClC,mBAAS;AAAA,YACPF,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,cAAc,QAAQ;AAAA,cAC7B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,eAAe,OAAO;AAAA,cAC9E;AAAA,cACA,aAAa,cAAc,QAAQ,KAAK,OAAO;AAAA,cAC/C,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAGA,YAAM,YAAwB,CAAC;AAC/B,UAAI;AACJ,SAAG;AACD,cAAM,WAAW,MAAM,OAAO;AAAA,UAC5B,IAAIG,0BAAyB,EAAE,WAAW,UAAU,CAAC;AAAA,QACvD;AACA,mBAAW,OAAO,SAAS,gBAAgB,CAAC,GAAG;AAC7C,cAAI,IAAI,UAAW,WAAU,KAAK,GAAG,IAAI,SAAS;AAAA,QACpD;AACA,oBAAY,SAAS;AAAA,MACvB,SAAS;AAET,0BAAoB,UAAU;AAC9B,YAAM,MAAM,KAAK,IAAI;AAErB,iBAAW,QAAQ,WAAW;AAC5B,YAAI,KAAK,OAAO,SAAS,WAAW;AAClC,gBAAM,SAAS,KAAK,cAAc;AAClC,gBAAM,SAAS,KAAK,yBAAyB;AAC7C,gBAAM,cAAc,SAAS,cAAc,MAAM,IAAI;AAErD,cAAI,CAAC,aAAa;AAChB,qBAAS;AAAA,cACP,8CAA8C,MAAM,4BAA4B,MAAM;AAAA,YACxF;AACA;AAAA,UACF;AAEA,gBAAM,cAAc,KAAK;AAAA,aACtB,MAAM,gBAAgB,KAAK,KAAK,KAAK;AAAA,UACxC;AAEA,cAAI,cAAc,IAAI;AACpB,qBAAS;AAAA,cACPH,aAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,gBAAgB,MAAM,yBAAyB,WAAW;AAAA,gBACjE,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,aAAa,MAAM;AAAA,gBAC3E;AAAA,gBACA,aAAa,iBAAiB,MAAM,MAAM,KAAK,gBAAgB,SAAS,6BAA6B,WAAW;AAAA,gBAChH,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,YAAM,iBAAkC,CAAC;AACzC,UAAI;AACJ,SAAG;AACD,cAAM,SAAS,MAAM,OAAO;AAAA,UAC1B,IAAII,+BAA8B,EAAE,WAAW,QAAQ,CAAC;AAAA,QAC1D;AACA,YAAI,OAAO,eAAgB,gBAAe,KAAK,GAAG,OAAO,cAAc;AACvE,kBAAU,OAAO;AAAA,MACnB,SAAS;AAGT,YAAM,YAAY,oBAAI,IAAY;AAClC,UAAI;AACJ,SAAG;AACD,cAAM,UAAU,MAAM,OAAO;AAAA,UAC3B,IAAI,iCAAiC,EAAE,WAAW,SAAS,CAAC;AAAA,QAC9D;AACA,mBAAW,OAAO,QAAQ,qBAAqB,CAAC,GAAG;AACjD,qBAAW,SAAS,IAAI,UAAU,CAAC,GAAG;AACpC,gBAAI,MAAM,QAAS,WAAU,IAAI,MAAM,OAAO;AAAA,UAChD;AAAA,QACF;AACA,mBAAW,QAAQ;AAAA,MACrB,SAAS;AAET,0BAAoB,eAAe;AAEnC,iBAAW,MAAM,gBAAgB;AAC/B,cAAM,OAAO,GAAG,WAAW;AAE3B,YAAI,GAAG,cAAc,UAAW;AAEhC,YAAI,CAAC,UAAU,IAAI,IAAI,GAAG;AACxB,mBAAS;AAAA,YACPJ,aAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,kBAAkB,IAAI;AAAA,cAC7B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa,OAAO,SAAS,QAAQ,MAAM,IAAI,GAAG,WAAW,SAAS,mBAAmB,IAAI;AAAA,cAC7F;AAAA,cACA,aAAa,mBAAmB,GAAG,SAAS,MAAM,IAAI;AAAA,cACtD,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,cAAc,QAA+B;AACpD,QAAM,QAAQ,OAAO,MAAM,iDAAiD;AAC5E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,KAAK,MAAM,MAAM,CAAC,CAAC;AAClC,SAAO,MAAM,MAAM,IAAI,OAAO;AAChC;;;ACrQA;AAAA,EACE,aAAAK;AAAA,EACA,8BAAAC;AAAA,OAEK;AACP;AAAA,EACE,aAAAC;AAAA,EACA,0BAAAC;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE,YAAAC;AAAA,EACA,sBAAAC;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAMP,IAAM,gBAAgB,IAAI,KAAK,KAAK,KAAK;AAEzC,SAASC,cAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEO,IAAM,0BAAN,MAAiD;AAAA,EAC7C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,UAAI,mBAAmB;AAGvB,YAAM,YAAY,aAAaC,YAAW,QAAQ,IAAI,WAAW;AACjE,YAAM,YAA0B,CAAC;AACjC,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,UAAU;AAAA,UAC3B,IAAIC,4BAA2B,EAAE,QAAQ,OAAO,CAAC;AAAA,QACnD;AACA,YAAI,KAAK,YAAa,WAAU,KAAK,GAAG,KAAK,WAAW;AACxD,iBAAS,KAAK;AAAA,MAChB,SAAS;AAET,0BAAoB,UAAU;AAE9B,iBAAW,MAAM,WAAW;AAC1B,cAAM,OAAO,GAAG,wBAAwB;AACxC,cAAM,QACJ,GAAG,iBACH,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,OAAO,IAAI;AACxD,cAAM,SAAS,GAAG,UAAU;AAG5B,YAAI,CAAC,GAAG,SAAS;AACf,mBAAS;AAAA,YACPF,cAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,gBAAgB,IAAI;AAAA,cAC3B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb;AAAA,cACA,aAAa,iBAAiB,IAAI,MAAM,MAAM;AAAA,cAC9C,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAGA,cAAM,YAAY,GAAG,yBAAyB;AAC9C,YAAI,cAAc,GAAG;AACnB,mBAAS;AAAA,YACPA,cAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,gBAAgB,IAAI;AAAA,cAC3B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb;AAAA,cACA,aAAa,iBAAiB,IAAI,MAAM,MAAM;AAAA,cAC9C,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,WAAW,YAAY,GAAG;AACxB,mBAAS;AAAA,YACPA,cAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,gBAAgB,IAAI,6BAA6B,SAAS;AAAA,cACjE,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb;AAAA,cACA,aAAa,iBAAiB,IAAI,MAAM,MAAM,oCAAoC,SAAS;AAAA,cAC3F,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAGA,YAAM,YAAY,aAAaG,YAAW,QAAQ,IAAI,WAAW;AAEjE,YAAM,UAAoB,CAAC;AAC3B,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,UAAU;AAAA,UAC3B,IAAIC,wBAAuB,EAAE,WAAW,SAAS,CAAC;AAAA,QACpD;AACA,YAAI,KAAK,QAAS,SAAQ,KAAK,GAAG,KAAK,OAAO;AAC9C,mBAAW,KAAK;AAAA,MAClB,SAAS;AAGT,YAAM,YAAwB,CAAC;AAC/B,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,UAAU;AAAA,UAC3B,IAAI,yBAAyB;AAAA,YAC3B,UAAU,CAAC,MAAM;AAAA,YACjB,WAAW;AAAA,UACb,CAAC;AAAA,QACH;AACA,YAAI,KAAK,UAAW,WAAU,KAAK,GAAG,KAAK,SAAS;AACpD,oBAAY,KAAK;AAAA,MACnB,SAAS;AAGT,YAAM,yBAAyB,oBAAI,IAAoB;AACvD,iBAAW,QAAQ,WAAW;AAC5B,YAAI,CAAC,KAAK,YAAY,KAAK,UAAU,YAAa;AAClD,cAAM,WAAW,KAAK,WAAW,QAAQ,KAAK;AAC9C,cAAM,WAAW,uBAAuB,IAAI,KAAK,QAAQ,KAAK;AAC9D,YAAI,WAAW,UAAU;AACvB,iCAAuB,IAAI,KAAK,UAAU,QAAQ;AAAA,QACpD;AAAA,MACF;AAGA,YAAM,eAAe,QAAQ,OAAO,CAAC,MAAM,EAAE,UAAU,QAAQ;AAC/D,0BAAoB,aAAa;AACjC,YAAM,MAAM,KAAK,IAAI;AAErB,iBAAW,OAAO,cAAc;AAC9B,cAAM,QAAQ,IAAI,YAAY;AAC9B,cAAM,SAAS,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,WAAW,KAAK;AAC1E,cAAM,aAAa,uBAAuB,IAAI,KAAK;AAEnD,YAAI,eAAe,QAAW;AAE5B,mBAAS;AAAA,YACPJ,cAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,cAAc,KAAK;AAAA,cAC1B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb;AAAA,cACA,aAAa,eAAe,KAAK,MAAM,IAAI,QAAQ,GAAG,OAAO,IAAI,cAAc,SAAS;AAAA,cACxF,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,WAAW,MAAM,aAAa,eAAe;AAC3C,gBAAM,YAAY,KAAK,OAAO,MAAM,eAAe,KAAK,KAAK,KAAK,IAAK;AACvE,mBAAS;AAAA,YACPA,cAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,cAAc,KAAK,4BAA4B,SAAS;AAAA,cAC/D,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb;AAAA,cACA,aAAa,eAAe,KAAK,MAAM,IAAI,QAAQ,GAAG,+BAA+B,SAAS;AAAA,cAC9F,QACE;AAAA,cACF,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAGA,YAAM,WAAW,aAAaK,WAAU,QAAQ,IAAI,WAAW;AAE/D,UAAI,cAAwB,CAAC;AAC7B,UAAI;AACF,cAAM,WAAW,MAAM,SAAS,KAAK,IAAIC,oBAAmB,CAAC,CAAC,CAAC;AAC/D,uBAAe,SAAS,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAmB,CAAC,CAAC,CAAC;AAAA,MAC1F,SAAS,GAAY;AACnB,cAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,iBAAS,KAAK,0BAA0B,GAAG,EAAE;AAAA,MAC/C;AAEA,0BAAoB,YAAY;AAEhC,iBAAW,QAAQ,aAAa;AAC9B,cAAM,MAAM,OAAO,SAAS,SAAS,IAAI;AAGzC,YAAI;AACF,gBAAM,MAAM,MAAM,SAAS;AAAA,YACzB,IAAI,2BAA2B,EAAE,QAAQ,KAAK,CAAC;AAAA,UACjD;AACA,cAAI,IAAI,WAAW,WAAW;AAC5B,qBAAS;AAAA,cACPN,cAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,aAAa,IAAI;AAAA,gBACxB,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,WAAW,IAAI,mBAAmB,IAAI,UAAU,SAAS;AAAA,gBACtE,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF,SAAS,GAAY;AACnB,gBAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,mBAAS,KAAK,UAAU,IAAI,6BAA6B,GAAG,EAAE;AAAA,QAChE;AAGA,YAAI;AACF,gBAAM,SAAS;AAAA,YACb,IAAI,4BAA4B,EAAE,QAAQ,KAAK,CAAC;AAAA,UAClD;AAAA,QAEF,SAAS,GAAY;AACnB,cACE,aAAa,SACb,EAAE,SAAS,yCACX;AACA,qBAAS;AAAA,cACPA,cAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,aAAa,IAAI;AAAA,gBACxB,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,WAAW,IAAI;AAAA,gBAC5B,QACE;AAAA,gBACF,kBAAkB;AAAA,kBAChB;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF,OAAO;AACL,kBAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,qBAAS,KAAK,UAAU,IAAI,8BAA8B,GAAG,EAAE;AAAA,UACjE;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;ACxUA;AAAA,EACE,qBAAAO;AAAA,EACA;AAAA,OACK;;;ACAA,SAAS,qBAAqB,SAA0B;AAC7D,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,QAAQ,OAAO,MAAM,oBAAoB;AAC/C,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAU,MAAM,CAAC,EAAE,KAAK;AAC9B,MAAI,YAAY,kBAAkB,QAAQ,SAAS,cAAc,EAAG,QAAO;AAC3E,MAAI,YAAY,eAAe,QAAQ,SAAS,WAAW,EAAG,QAAO;AACrE,MAAI,YAAY,eAAe,QAAQ,SAAS,WAAW,EAAG,QAAO;AACrE,MAAI,YAAY,YAAY,QAAQ,SAAS,QAAQ,EAAG,QAAO;AAC/D,MAAI,YAAY,yBAAyB,QAAQ,SAAS,iBAAiB,EAAG,QAAO;AACrF,SAAO;AACT;;;ADJA,SAAS,kBAAkB,OAA8B;AACvD,UAAQ,OAAO;AAAA,IACb,KAAK;AAAY,aAAO;AAAA,IACxB,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAU,aAAO;AAAA,IACtB,KAAK;AAAO,aAAO;AAAA,IACnB,KAAK;AAAiB,aAAO;AAAA;AAAA,IAC7B;AAAS,aAAO;AAAA,EAClB;AACF;AAEO,IAAM,6BAAN,MAAoD;AAAA,EAChD,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAC5B,QAAI,mBAAmB;AAEvB,QAAI;AACF,YAAM,SAAS,aAAaC,oBAAmB,QAAQ,IAAI,WAAW;AACtE,UAAI;AAEJ,SAAG;AACD,cAAM,OAAO,MAAM,OAAO;AAAA,UACxB,IAAI,mBAAmB;AAAA,YACrB,SAAS;AAAA,cACP,gBAAgB;AAAA,gBACd,EAAE,OAAO,OAAO,YAAY,SAAS;AAAA,gBACrC,EAAE,OAAO,YAAY,YAAY,SAAS;AAAA,cAC5C;AAAA,cACA,aAAa,CAAC,EAAE,OAAO,UAAU,YAAY,SAAS,CAAC;AAAA,YACzD;AAAA,YACA,YAAY;AAAA,YACZ,WAAW;AAAA,UACb,CAAC;AAAA,QACH;AAEA,cAAM,aAAa,KAAK,YAAY,CAAC;AACrC,4BAAoB,WAAW;AAE/B,mBAAW,KAAK,YAAY;AAC1B,gBAAM,gBAAgB,EAAE,UAAU,SAAS;AAC3C,gBAAM,QAAQ,kBAAkB,aAAa;AAC7C,cAAI,UAAU,KAAM;AAEpB,gBAAM,WAAW,kBAAkB,KAAK;AACxC,gBAAM,aAAa,EAAE,YAAY,CAAC,GAAG,MAAM;AAC3C,gBAAM,eAAe,EAAE,YAAY,CAAC,GAAG,QAAQ;AAC/C,gBAAM,cAAc,WAAW,WAAW,MAAM,IAC5C,aACA,OAAO,SAAS,gBAAgB,MAAM,IAAI,SAAS,YAAY,EAAE,MAAM,SAAS;AAEpF,gBAAM,mBAA6B,CAAC;AACpC,gBAAM,QAAQ,EAAE,SAAS;AAGzB,cAAI,UAAU,KAAK,KAAK,GAAG;AACzB,6BAAiB,KAAK,yBAAyB,KAAK,gCAAgC;AACpF,6BAAiB,KAAK,4DAA4D,KAAK,EAAE;AAAA,UAC3F,WAAW,QAAQ,KAAK,KAAK,GAAG;AAC9B,6BAAiB,KAAK,qBAAqB,KAAK,+CAA+C;AAAA,UACjG,OAAO;AACL,6BAAiB,KAAK,KAAK;AAAA,UAC7B;AAGA,cAAI,EAAE,aAAa,gBAAgB,KAAK;AACtC,6BAAiB,KAAK,kBAAkB,EAAE,YAAY,eAAe,GAAG,EAAE;AAAA,UAC5E;AAGA,gBAAM,UAAU,EAAE,aAAa,gBAAgB,QAAQ;AACvD,cAAI,WAAW,CAAC,CAAC,kBAAkB,iBAAiB,EAAE,EAAE,SAAS,QAAQ,KAAK,CAAC,GAAG;AAChF,6BAAiB,KAAK,OAAO;AAAA,UAC/B;AAEA,gBAAM,UAAmB;AAAA,YACvB;AAAA,YACA,OAAO,EAAE,SAAS;AAAA,YAClB;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ,EAAE,UAAU;AAAA,YACpB,aAAa,EAAE,eAAe,EAAE,SAAS;AAAA,YACzC,QAAQ,WAAW,EAAE,eAAe,cAAc,KAAK,EAAE,eAAe,SAAS;AAAA,YACjF,WAAW;AAAA,YACX;AAAA,YACA,UAAU,qBAAqB,QAAQ;AAAA,YACvC,QAAQ,KAAK;AAAA,YACb,WAAW,EAAE,gBAAgB;AAAA,UAC/B;AACA,kBAAQ,SAAS,qBAAqB,OAAO;AAC7C,mBAAS,KAAK,OAAO;AAAA,QACvB;AAEA,oBAAY,KAAK;AAAA,MACnB,SAAS;AAET,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAMC,gBACH,eAAe,SAAS,IAAI,SAAS,4BACtC,IAAI,SAAS,gBAAgB,KAC7B,IAAI,SAAS,aAAa;AAE5B,UAAIA,eAAc;AAChB,iBAAS,KAAK,uFAAuF;AACrG,eAAO;AAAA,UACL,QAAQ,KAAK;AAAA,UACb,QAAQ;AAAA,UACR;AAAA,UACA,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU,CAAC;AAAA,QACb;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,sCAAsC,GAAG;AAAA,QAChD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AExJA;AAAA,EACE,mBAAAC;AAAA,EACA,wBAAAC;AAAA,OACK;AASA,IAAM,2BAAN,MAAkD;AAAA,EAC9C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,YAAM,SAAS,aAAaC,kBAAiB,QAAQ,IAAI,WAAW;AACpE,YAAM,OAAO,MAAM,OAAO,KAAK,IAAIC,sBAAqB,CAAC,CAAC,CAAC;AAC3D,YAAM,cAAc,KAAK,eAAe,CAAC;AAEzC,UAAI,YAAY,WAAW,GAAG;AAC5B,iBAAS,KAAK,+DAA+D;AAAA,MAC/E;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,qCAAqC,GAAG;AAAA,QAC/C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;ACnDA;AAAA,EACE,oBAAAC;AAAA,EACA,gCAAAC;AAAA,OACK;AAUA,IAAM,2BAAN,MAAkD;AAAA,EAC9C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,YAAM,SAAS,aAAaC,mBAAkB,QAAQ,IAAI,WAAW;AACrE,YAAM,OAAO,MAAM,OAAO,KAAK,IAAIC,8BAA6B,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;AACnF,YAAM,UAAU,KAAK,WAAW,CAAC;AAEjC,UAAI,CAAC,WAAW,QAAQ,OAAO,WAAW,WAAW;AACnD,iBAAS,KAAK,0FAA0F;AAAA,MAC1G,OAAO;AAEL,cAAM,KAAK,QAAQ;AACnB,cAAM,QAA6D;AAAA,UACjE,EAAE,MAAM,OAAO,QAAQ,IAAI,KAAK,OAAO;AAAA,UACvC,EAAE,MAAM,UAAU,QAAQ,IAAI,QAAQ,OAAO;AAAA,UAC7C,EAAE,MAAM,OAAO,QAAQ,IAAI,KAAK,OAAO;AAAA,UACvC,EAAE,MAAM,eAAe,QAAQ,IAAI,YAAY,OAAO;AAAA,UACtD,EAAE,MAAM,mBAAmB,QAAQ,IAAI,gBAAgB,OAAO;AAAA,QAChE;AACA,cAAM,WAAW,MAAM,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,SAAS;AACvE,YAAI,SAAS,SAAS,GAAG;AACvB,mBAAS;AAAA,YACP,qCAAqC,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,UAC7E;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAM,UAAU,eAAe,QAAQ,IAAI,OAAO;AAElD,YAAMC,kBAAiB,YAAY,2BAA2B,IAAI,SAAS,uBAAuB;AAClG,UAAIA,iBAAgB;AAClB,iBAAS,KAAK,2GAA2G;AAAA,MAC3H,OAAO;AACL,iBAAS,KAAK,0FAA0F;AAAA,MAC1G;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR;AAAA,QACA,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AC7EA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAKP,SAAS,gBAAgB,QAA+B;AACtD,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAS,aAAO;AAAA;AAAA,IACrB,KAAK;AAAW,aAAO;AAAA;AAAA,IACvB,KAAK;AAAM,aAAO;AAAA;AAAA,IAClB,KAAK;AAAiB,aAAO;AAAA,IAC7B;AAAS,aAAO;AAAA,EAClB;AACF;AAEO,IAAM,gCAAN,MAAuD;AAAA,EACnD,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAC5B,QAAI,mBAAmB;AAEvB,QAAI;AAEF,YAAM,gBAAgB,OAAO,WAAW,KAAK,IAAI,eAAe;AAChE,YAAM,eAAoB,EAAE,QAAQ,cAAc;AAClD,UAAI,IAAI,YAAa,cAAa,cAAc,IAAI;AACpD,YAAM,SAAS,IAAI,cAAc,YAAY;AAG7C,YAAM,aAAa,MAAM,OAAO;AAAA,QAC9B,IAAI,oCAAoC,EAAE,UAAU,KAAK,CAAC;AAAA,MAC5D;AACA,YAAM,YAAY,WAAW,UAAU,CAAC;AACxC,YAAM,iBAAiB,UAAU,OAAO,CAAC,MAAM,EAAE,aAAa,UAAU;AAExE,UAAI,eAAe,WAAW,GAAG;AAC/B,iBAAS,KAAK,2CAA2C;AACzD,eAAO;AAAA,UACL,QAAQ,KAAK;AAAA,UACb,QAAQ;AAAA,UACR;AAAA,UACA,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU,CAAC;AAAA,QACb;AAAA,MACF;AAGA,iBAAW,SAAS,gBAAgB;AAClC,YAAI,CAAC,MAAM,GAAI;AAEf,YAAI;AACF,gBAAM,aAAa,MAAM,OAAO;AAAA,YAC9B,IAAI,yCAAyC;AAAA,cAC3C,SAAS,MAAM;AAAA,YACjB,CAAC;AAAA,UACH;AAEA,gBAAM,SAAS,WAAW;AAC1B,cAAI,CAAC,OAAQ;AAEb,gBAAM,SAAS,OAAO,UAAU;AAChC,gBAAM,QAAQ,gBAAgB,MAAM;AAEpC;AAEA,cAAI,UAAU,KAAM;AAGpB,gBAAM,mBAAmB,OAAO,oBAAoB,CAAC;AAErD,cAAI,iBAAiB,WAAW,GAAG;AAEjC,kBAAM,WAAW,kBAAkB,KAAK;AACxC,qBAAS,KAAK;AAAA,cACZ;AAAA,cACA,OAAO,qBAAqB,MAAM,QAAQ,gBAAgB;AAAA,cAC1D,cAAc;AAAA,cACd,YAAY,MAAM;AAAA,cAClB,aAAa,OAAO,SAAS,mBAAmB,MAAM,IAAI,SAAS,UAAU,MAAM,EAAE;AAAA,cACrF;AAAA,cACA,aAAa,MAAM,eAAe,MAAM,QAAQ;AAAA,cAChD,QAAQ,2BAA2B,MAAM;AAAA,cACzC,WAAW;AAAA,cACX,kBAAkB;AAAA,gBAChB;AAAA,gBACA;AAAA,cACF;AAAA,cACA,UAAU,qBAAqB,QAAQ;AAAA,cACvC,QAAQ,KAAK;AAAA,cACb;AAAA,YACF,CAAC;AACD;AAAA,UACF;AAGA,gBAAM,WAAW,MAAM,YAAY,CAAC;AACpC,qBAAW,MAAM,iBAAiB,MAAM,GAAG,EAAE,GAAG;AAC9C,gBAAI,GAAG,aAAc;AAErB,kBAAM,WAAW,kBAAkB,KAAK;AACxC,kBAAM,eAAe,GAAG,YAAY,CAAC;AAGrC,kBAAM,gBAAgB,SAAS,QAAQ,aAAa;AACpD,kBAAM,YAAY,SAAS,QAAQ,QAAQ;AAC3C,kBAAM,oBAAoB,iBAAiB,KAAK,aAAa,aAAa,IACtE,aAAa,aAAa,IAC1B,GAAG,cAAc;AACrB,kBAAM,gBAAgB,aAAa,KAAK,aAAa,SAAS,IAC1D,aAAa,SAAS,IACtB;AAEJ,qBAAS,KAAK;AAAA,cACZ;AAAA,cACA,OAAO,qBAAqB,MAAM,QAAQ,gBAAgB,KAAK,iBAAiB;AAAA,cAChF,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa,OAAO,SAAS,mBAAmB,aAAa,IAAI,SAAS,UAAU,MAAM,EAAE,IAAI,GAAG,cAAc,SAAS;AAAA,cAC1H,QAAQ;AAAA,cACR,aAAa,GAAG,MAAM,IAAI,KAAK,aAAa,KAAK,KAAK,CAAC;AAAA,cACvD,QAAQ,2BAA2B,MAAM,WAAM,MAAM,QAAQ,gBAAgB;AAAA,cAC7E,WAAW;AAAA,cACX,kBAAkB;AAAA,gBAChB,iCAAiC,MAAM,IAAI;AAAA,gBAC3C;AAAA,cACF;AAAA,cACA,UAAU,qBAAqB,QAAQ;AAAA,cACvC,QAAQ,KAAK;AAAA,cACb;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,SAAS,UAAU;AACjB,gBAAM,WAAW,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ;AAC/E,mBAAS,KAAK,yBAAyB,MAAM,QAAQ,MAAM,EAAE,YAAY,QAAQ,EAAE;AAAA,QACrF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAM,yBACJ,IAAI,SAAS,+BAA+B,KAC5C,IAAI,SAAS,cAAc,KAC3B,IAAI,SAAS,qBAAqB,KACjC,eAAe,SAAS,IAAI,SAAS;AAExC,UAAI,wBAAwB;AAC1B,iBAAS,KAAK,6EAA6E;AAC3F,eAAO;AAAA,UACL,QAAQ,KAAK;AAAA,UACb,QAAQ;AAAA,UACR;AAAA,UACA,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU,CAAC;AAAA,QACb;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,gCAAgC,GAAG;AAAA,QAC1C,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AC7LA;AAAA,EACE,uBAAAC;AAAA,EACA,yCAAAC;AAAA,OACK;AASA,IAAM,6BAAN,MAAoD;AAAA,EAChD,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,YAAM,SAAS,aAAaC,sBAAqB,QAAQ,IAAI,WAAW;AACxE,YAAM,OAAO,MAAM,OAAO,KAAK,IAAIC,uCAAsC,CAAC,CAAC,CAAC;AAC5E,YAAM,YAAY,KAAK,0BAA0B,CAAC;AAElD,UAAI,UAAU,WAAW,GAAG;AAC1B,iBAAS,KAAK,2CAA2C;AAAA,MAC3D;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAE3D,UACE,IAAI,SAAS,6BAA6B,KAC1C,IAAI,SAAS,4BAA4B,KACzC,IAAI,SAAS,2BAA2B,GACxC;AACA,iBAAS,KAAK,2CAA2C;AACzD,eAAO;AAAA,UACL,QAAQ,KAAK;AAAA,UACb,QAAQ;AAAA,UACR;AAAA,UACA,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU,CAAC;AAAA,QACb;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,wCAAwC,GAAG;AAAA,QAClD,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;ACrEA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AASA,IAAM,gCAAN,MAAuD;AAAA,EACnD,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,YAAM,SAAS,aAAa,sBAAsB,QAAQ,IAAI,WAAW;AAEzE,UAAI;AACJ,UAAI,oBAAoB;AAExB,SAAG;AACD,cAAM,OAAO,MAAM,OAAO;AAAA,UACxB,IAAI,qBAAqB,EAAE,WAAW,cAAc,CAAC;AAAA,QACvD;AACA,mBAAW,YAAY,KAAK,aAAa,CAAC,GAAG;AAC3C,cAAI,SAAS,WAAW,UAAU;AAChC,gCAAoB;AACpB;AAAA,UACF;AAAA,QACF;AACA,YAAI,kBAAmB;AACvB,wBAAgB,KAAK;AAAA,MACvB,SAAS;AAET,UAAI,CAAC,mBAAmB;AACtB,iBAAS,KAAK,+FAA+F;AAAA,MAC/G;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,2CAA2C,GAAG;AAAA,QACrD,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AClEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAMA,IAAM,iCAAN,MAAwD;AAAA,EACpD,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAC5B,QAAI,mBAAmB;AAEvB,QAAI;AACF,YAAM,SAAS,aAAa,WAAW,QAAQ,IAAI,WAAW;AAG9D,UAAI;AACJ,YAAM,YAAmC,CAAC;AAE1C,SAAG;AACD,cAAM,OAAO,MAAM,OAAO;AAAA,UACxB,IAAI,mCAAmC;AAAA,YACrC,YAAY;AAAA,YACZ,WAAW;AAAA,UACb,CAAC;AAAA,QACH;AACA,kBAAU,KAAK,GAAI,KAAK,2BAA2B,CAAC,CAAE;AACtD,oBAAY,KAAK;AAAA,MACnB,SAAS;AAET,UAAI,UAAU,WAAW,GAAG;AAC1B,iBAAS,KAAK,gDAAgD;AAC9D,eAAO;AAAA,UACL,QAAQ,KAAK;AAAA,UACb,QAAQ;AAAA,UACR;AAAA,UACA,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU,CAAC;AAAA,QACb;AAAA,MACF;AAEA,yBAAmB,UAAU;AAG7B,YAAM,cAAc,UAAU,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,OAAO;AACrE,YAAM,gBAAgB,oBAAI,IAAgC;AAG1D,eAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK,IAAI;AAC/C,cAAM,QAAQ,YAAY,MAAM,GAAG,IAAI,EAAE;AACzC,YAAI;AAEJ,WAAG;AACD,gBAAM,YAAY,MAAM,OAAO;AAAA,YAC7B,IAAI,mCAAmC;AAAA,cACrC,aAAa;AAAA,cACb,WAAW;AAAA,YACb,CAAC;AAAA,UACH;AAEA,qBAAW,MAAM,UAAU,uBAAuB,CAAC,GAAG;AACpD,gBAAI,GAAG,YAAY;AACjB,4BAAc,IAAI,GAAG,YAAY,EAAE;AAAA,YACrC;AAAA,UACF;AAEA,uBAAa,UAAU;AAAA,QACzB,SAAS;AAAA,MACX;AAGA,iBAAW,YAAY,WAAW;AAChC,cAAM,aAAa,SAAS,cAAc;AAC1C,cAAM,WAAW,SAAS,gBAAgB,SAAS,gBAAgB;AACnE,cAAM,cAAc,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,aAAa,UAAU;AAEtF,cAAM,aAAa,cAAc,IAAI,UAAU;AAE/C,YAAI,CAAC,YAAY;AAEf,gBAAMC,aAAY;AAClB,gBAAMC,YAAW,kBAAkBD,UAAS;AAC5C,mBAAS,KAAK;AAAA,YACZ,UAAAC;AAAA,YACA,OAAO,YAAY,UAAU;AAAA,YAC7B,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,aAAa;AAAA,YACb;AAAA,YACA,aAAa,YAAY,UAAU,KAAK,QAAQ;AAAA,YAChD,QAAQ;AAAA,YACR,WAAAD;AAAA,YACA,kBAAkB;AAAA,cAChB;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,YACA,UAAU,qBAAqBC,SAAQ;AAAA,YACvC,QAAQ,KAAK;AAAA,YACb;AAAA,UACF,CAAC;AACD;AAAA,QACF;AAEA,cAAM,eAAe,WAAW,gBAAgB;AAChD,cAAM,cAAc,WAAW,eAAe;AAC9C,cAAM,4BAA4B,WAAW,6BAA6B;AAC1E,cAAM,4BAA4B,WAAW,6BAA6B;AAC1E,cAAM,yBAAyB,WAAW,0BAA0B;AACpE,cAAM,eAAe,WAAW,kBAAkB,YAAY,KAAK;AAEnE,YACE,iBAAiB,KACjB,gBAAgB,KAChB,8BAA8B,KAC9B,8BAA8B,KAC9B,2BAA2B,GAC3B;AACA;AAAA,QACF;AAGA,YAAI;AACJ,YAAI,4BAA4B,KAAK,4BAA4B,KAAK,cAAc,GAAG;AACrF,sBAAY;AAAA,QACd,WAAW,yBAAyB,GAAG;AACrC,sBAAY;AAAA,QACd,OAAO;AACL,sBAAY;AAAA,QACd;AACA,cAAM,WAAW,kBAAkB,SAAS;AAE5C,cAAM,aAAuB,CAAC;AAC9B,YAAI,eAAe,EAAG,YAAW,KAAK,GAAG,YAAY,UAAU;AAC/D,YAAI,cAAc,EAAG,YAAW,KAAK,GAAG,WAAW,SAAS;AAC5D,YAAI,4BAA4B,EAAG,YAAW,KAAK,GAAG,yBAAyB,yBAAyB;AACxG,YAAI,4BAA4B,EAAG,YAAW,KAAK,GAAG,yBAAyB,yBAAyB;AACxG,YAAI,yBAAyB,EAAG,YAAW,KAAK,GAAG,sBAAsB,sBAAsB;AAE/F,cAAM,YAAY;AAAA,UAChB,aAAa,UAAU;AAAA,UACvB,aAAa,QAAQ;AAAA,UACrB,oBAAoB,YAAY;AAAA,UAChC,mBAAmB,WAAW;AAAA,UAC9B,2BAA2B,yBAAyB;AAAA,UACpD,2BAA2B,yBAAyB;AAAA,UACpD,wBAAwB,sBAAsB;AAAA,UAC9C,cAAc,YAAY;AAAA,QAC5B;AAEA,iBAAS,KAAK;AAAA,UACZ;AAAA,UACA,OAAO,YAAY,UAAU,QAAQ,WAAW,KAAK,IAAI,CAAC;AAAA,UAC1D,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,aAAa;AAAA,UACb;AAAA,UACA,aAAa,UAAU,KAAK,IAAI;AAAA,UAChC,QAAQ,gBAAgB,YAAY,gBAAgB,WAAW;AAAA,UAC/D;AAAA,UACA,kBAAkB;AAAA,YAChB,wCAAwC,UAAU;AAAA,YAClD;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,UAAU,qBAAqB,QAAQ;AAAA,UACvC,QAAQ,KAAK;AAAA,UACb;AAAA,QACF,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,iCAAiC,GAAG;AAAA,QAC3C,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C;AAAA,QACA,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AC/MA;AAAA,EACE,aAAAC;AAAA,EACA,4BAAAC;AAAA,OAEK;AAMP,SAASC,cAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEO,IAAM,2BAAN,MAAkD;AAAA,EAC9C,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,QAAQ,WAAW,UAAU,IAAI;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,YAAM,SAAS,aAAaC,YAAW,QAAQ,IAAI,WAAW;AAG9D,YAAM,YAAwB,CAAC;AAC/B,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,OAAO;AAAA,UACxB,IAAIC,0BAAyB;AAAA,YAC3B,SAAS,CAAC,EAAE,MAAM,uBAAuB,QAAQ,CAAC,SAAS,EAAE,CAAC;AAAA,YAC9D,WAAW;AAAA,UACb,CAAC;AAAA,QACH;AACA,YAAI,KAAK,cAAc;AACrB,qBAAW,eAAe,KAAK,cAAc;AAC3C,gBAAI,YAAY,WAAW;AACzB,wBAAU,KAAK,GAAG,YAAY,SAAS;AAAA,YACzC;AAAA,UACF;AAAA,QACF;AACA,oBAAY,KAAK;AAAA,MACnB,SAAS;AAET,iBAAW,YAAY,WAAW;AAChC,cAAM,aAAa,SAAS,cAAc;AAC1C,cAAM,eAAe,SAAS,gBAAgB;AAC9C,cAAM,QAAQ,SAAS,OAAO,QAAQ;AACtC,cAAM,aAAa,SAAS,iBAAiB,cAAc;AAC3D,cAAM,WAAW,SAAS,iBAAiB,2BAA2B;AACtE,cAAM,cAAc,OAAO,SAAS,QAAQ,MAAM,IAAI,SAAS,aAAa,UAAU;AAEtF,YAAI,eAAe,YAAY;AAC7B,gBAAM,cAAc;AAAA,YAClB,gBAAgB,UAAU,WAAW,YAAY,YAAY,KAAK,4BAA4B,UAAU;AAAA,YACxG;AAAA,UACF;AACA,cAAI,WAAW,GAAG;AAChB,wBAAY,KAAK,8BAA8B,QAAQ,kDAAkD;AAAA,UAC3G;AAEA,mBAAS;AAAA,YACPF,cAAY;AAAA,cACV,WAAW;AAAA,cACX,OAAO,gBAAgB,UAAU;AAAA,cACjC,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,aAAa;AAAA,cACb;AAAA,cACA,aAAa,YAAY,KAAK,GAAG;AAAA,cACjC,QAAQ;AAAA,cACR,kBAAkB;AAAA,gBAChB;AAAA,gBACA,iEAAiE,aAAa;AAAA,gBAC9E;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,WAAW,WAAW,GAAG;AAEvB,mBAAS;AAAA,YACP,YAAY,UAAU,mDAAmD,QAAQ;AAAA,UACnF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB,UAAU;AAAA,QAC5B,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACtD,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;AC1HA;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAMP,SAASG,cAAY,MAUT;AACV,QAAM,WAAW,kBAAkB,KAAK,SAAS;AACjD,SAAO,EAAE,GAAG,MAAM,UAAU,UAAU,qBAAqB,QAAQ,EAAE;AACvE;AAEO,IAAM,qBAAN,MAA4C;AAAA,EACxC,aAAa;AAAA,EAEtB,MAAM,KAAK,KAAuC;AAChD,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,WAAsB,CAAC;AAC7B,UAAM,WAAqB,CAAC;AAE5B,QAAI;AACF,YAAM,YAAY,aAAa,8BAA8B,QAAQ,IAAI,WAAW;AACpF,YAAM,YAAY,aAAa,aAAa,QAAQ,IAAI,WAAW;AAGnE,YAAM,gBAAgC,CAAC;AACvC,UAAI;AACJ,SAAG;AACD,cAAM,OAAO,MAAM,UAAU;AAAA,UAC3B,IAAI,6BAA6B,EAAE,QAAQ,OAAO,CAAC;AAAA,QACrD;AACA,YAAI,KAAK,eAAe;AACtB,wBAAc,KAAK,GAAG,KAAK,aAAa;AAAA,QAC1C;AACA,iBAAS,KAAK;AAAA,MAChB,SAAS;AAGT,YAAM,iBAAiB,cAAc,OAAO,CAAC,OAAO,GAAG,WAAW,iBAAiB;AAEnF,iBAAW,MAAM,gBAAgB;AAC/B,cAAM,SAAS,GAAG,oBAAoB;AACtC,cAAM,QAAQ,GAAG,mBAAmB;AACpC,cAAM,SAAS,GAAG,QAAQ;AAG1B,YAAI,WAAW,eAAe;AAC5B,mBAAS;AAAA,YACP,YAAY,MAAM,mBAAmB,MAAM;AAAA,UAC7C;AACA;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,UAAU,MAAM,UAAU;AAAA,YAC9B,IAAI,4BAA4B,EAAE,aAAa,MAAM,CAAC;AAAA,UACxD;AAEA,cAAI,CAAC,QAAQ,QAAQ;AACnB,qBAAS;AAAA,cACPA,cAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,uBAAuB,MAAM;AAAA,gBACpC,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,8CAA8C,MAAM;AAAA,gBACjE,QAAQ;AAAA,gBACR,kBAAkB;AAAA,kBAChB;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF,SAAS,QAAiB;AACxB,gBAAM,SAAS,kBAAkB,QAAQ,OAAO,UAAU,OAAO,MAAM;AACvE,gBAAM,UAAU,kBAAkB,QAAS,OAAe,QAAQ,KAAK;AAGvE,cAAI,YAAY,+BAA+B;AAE7C,qBAAS;AAAA,cACPA,cAAY;AAAA,gBACV,WAAW;AAAA,gBACX,OAAO,uBAAuB,MAAM;AAAA,gBACpC,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb;AAAA,gBACA,aAAa,8CAA8C,MAAM;AAAA,gBACjE,QAAQ;AAAA,gBACR,kBAAkB;AAAA,kBAChB;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF,WAAW,YAAY,2BAA2B,YAAY,gCAAgC;AAC5F,qBAAS;AAAA,cACP,gCAAgC,MAAM,MAAM,MAAM;AAAA,YACpD;AAAA,UACF,OAAO;AACL,qBAAS,KAAK,+BAA+B,MAAM,MAAM,MAAM,EAAE;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB,eAAe;AAAA,QACjC,eAAe,SAAS;AAAA,QACxB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC9D,YAAM,UAAU,eAAe,QAAS,IAAY,QAAQ,KAAK;AAGjE,UAAI,YAAY,2BAA2B,YAAY,+BAA+B;AACpF,eAAO;AAAA,UACL,QAAQ,KAAK;AAAA,UACb,QAAQ;AAAA,UACR,UAAU,CAAC,+BAA+B,MAAM,EAAE;AAAA,UAClD,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU,CAAC;AAAA,QACb;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC3C,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;;;ACvKO,IAAM,SAAe;AAAA;AAAA,EAE1B,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,mBAAmB;AAAA;AAAA,EAGnB,WAAW;AAAA,EACX,gBACE;AAAA,EACF,cAAc;AAAA,EACd,UAAU;AAAA,EACV,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,cAAc;AAAA,EACd,eAAe;AAAA,EACf,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,kBAAkB,CAAC,MACjB,8CAA8C,CAAC;AAAA,EACjD,aAAa;AAAA,EACb,kBAAkB,CAAC,MACjB,uCAAuC,CAAC;AAAA,EAC1C,eAAe,CAAC,MAAc,4BAA4B,CAAC;AAAA;AAAA,EAG3D,kBACE;AAAA,EACF,qBAAqB;AAAA,EACrB,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtB,mBAAmB;AAAA;AAAA;AAAA;AAAA,EAInB,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,kBAAkB;AAAA;AAAA;AAAA;AAAA,EAIlB,WAAW;AAAA;AAAA;AAAA;AAAA,EAIX,WAAW;AAAA;AAAA;AAAA;AAAA,EAIX,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf,oBAAoB;AAAA;AAAA;AAAA;AAAA,EAIpB,aACE;AAAA;AAAA,EAGF,sBACE;AAAA,EACF,uBACE;AAAA,EACF,eAAe;AAAA,EACf,eAAe;AAAA;AAAA,EAGf,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,SAAS;AAAA;AAAA,EAGT,wBAAwB,CAAC,MACvB,UAAU,CAAC;AAAA,EACb,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,uBAAuB,CAAC,MACtB,4BAA4B,CAAC;AAAA,EAC/B,YAAY;AAAA,EACZ,oBAAoB;AAAA,EACpB,eAAe,CAAC,MACd,4BAA4B,CAAC;AAAA;AAAA,EAG/B,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,gBAAgB;AAAA;AAAA;AAAA,EAIhB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,aAAa;AAAA,EACb,UAAU;AAAA,EACV,uBAAuB,CAAC,aAAqB,SAAS,QAAQ;AAAA,EAE9D,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,cAAc,CAAC,OAAe,OAAe,WAC3C,uBAAuB,KAAK,gDAAgD,KAAK,uCAAuC,MAAM;AAAA,EAChI,gBAAgB,CAAC,MACf,uBAAuB,CAAC;AAAA,EAC1B,oBAAoB,CAAC,MAAc,mCAAmC,CAAC;AAAA,EACvE,mBAAmB,CAAC,MAAc,mCAAmC,CAAC;AAAA,EACtE,SAAS,CAAC,MAAc,uBAAuB,CAAC;AAAA,EAChD,QAAQ,CAAC,MACP,6BAA6B,CAAC;AAAA,EAChC,aAAa,CAAC,MACZ,SAAS,CAAC;AAAA,EACZ,gBAAgB,CAAC,MACf,gBAAgB,CAAC;AAAA,EACnB,qBAAqB,CAAC,YACpB,mCAAmC,OAAO;AAAA,EAC5C,sBACE;AAAA,EACF,SAAS,CAAC,MAAc,0BAA0B,CAAC;AAAA,EACnD,uBACE;AAAA,EACF,mBAAmB,CAAC,MAAc,gBAAgB,CAAC;AAAA,EACnD,uBAAuB,CAAC,GAAW,QAAgB,gBAAgB,CAAC,iCAAiC,GAAG;AAAA,EACxG,qBAAqB;AAAA,IACnB,wCAAwC;AAAA,IACxC,wCAAwC;AAAA,IACxC,wCAAwC;AAAA,IACxC,wCAAwC;AAAA,IACxC,wCAAwC;AAAA,EAC1C;AAAA;AAAA,EAGA,aAAa;AAAA,IACX,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,sBAAsB;AAAA,IACtB,0BAA0B;AAAA,IAC1B,sBAAsB;AAAA,IACtB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,uBAAuB;AAAA,IACvB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,0BAA0B;AAAA,IAC1B,uBAAuB;AAAA,IACvB,0BAA0B;AAAA,IAC1B,2BAA2B;AAAA,IAC3B,oBAAoB;AAAA,IACpB,cAAc;AAAA;AAAA,IAEd,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,sBAAsB;AAAA,IACtB,YAAY;AAAA,EACd;AAAA;AAAA,EAGA,0BAA0B;AAAA,IACxB,MAAM,EAAE,OAAO,uCAAS;AAAA,IACxB,WAAW,EAAE,OAAO,2BAAO;AAAA,IAC3B,WAAW,EAAE,OAAO,2BAAO;AAAA,IAC3B,QAAQ,EAAE,OAAO,2BAAO;AAAA,IACxB,mBAAmB,EAAE,OAAO,2BAAO;AAAA,IACnC,OAAO,EAAE,OAAO,uCAAS;AAAA,EAC3B;AAAA;AAAA,EAGA,YAAY;AAAA,EACZ,wBAAwB;AAAA,IACtB,uBAAuB;AAAA,MACrB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,0BAA0B;AAAA,MACxB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,uBAAuB;AAAA,MACrB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,0BAA0B;AAAA,MACxB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,2BAA2B;AAAA,MACzB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAe;AAAA,EACf,eAAe;AAAA,EACf,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,eAAe,CAAC,MAAc,GAAG,CAAC;AAAA,EAClC,qBAAqB,CAAC,MAAc,+CAAY,CAAC;AAAA,EACjD,eAAe;AAAA,EACf,gBAAgB;AAAA,IACd,gBAAgB,EAAE,MAAM,kCAAS,MAAM,YAAK;AAAA,IAC5C,qBAAqB,EAAE,MAAM,8CAAW,MAAM,YAAK;AAAA,IACnD,qBAAqB,EAAE,MAAM,8CAAW,MAAM,YAAK;AAAA,IACnD,oBAAoB,EAAE,MAAM,8CAAW,MAAM,YAAK;AAAA,IAClD,mBAAmB,EAAE,MAAM,wCAAU,MAAM,kBAAM;AAAA,IACjD,oBAAoB,EAAE,MAAM,wCAAU,MAAM,YAAK;AAAA,IACjD,qBAAqB,EAAE,MAAM,4BAAQ,MAAM,kBAAM;AAAA,IACjD,aAAa,EAAE,MAAM,kCAAS,MAAM,YAAK;AAAA,EAC3C;AAAA,EACA,eAAe;AAAA,IACb,gBAAgB,CAAC,2JAA8B;AAAA,IAC/C,qBAAqB,CAAC,4HAAwB,iGAAsB;AAAA,IACpE,qBAAqB,CAAC,iDAAmB,kDAAoB,oDAAY,wEAAsB;AAAA,IAC/F,oBAAoB,CAAC,yEAAuB,gFAAe;AAAA,IAC3D,mBAAmB,CAAC,8EAA4B,2EAAyB,wFAA4B,8CAAqB;AAAA,IAC1H,oBAAoB,CAAC,0GAAoC,0NAAqD,yEAAoB,oIAAgC,yGAAmC;AAAA,IACrM,qBAAqB,CAAC,4EAAgB,6HAAyB,oHAAqB;AAAA,IACpF,aAAa,CAAC,kFAAiB,oGAAoB,kDAAU;AAAA,EAC/D;AAAA;AAAA,EAGA,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqDf;;;AC/VO,IAAM,SAAe;AAAA;AAAA,EAE1B,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,mBAAmB;AAAA;AAAA,EAGnB,WAAW;AAAA,EACX,gBACE;AAAA,EACF,cAAc;AAAA,EACd,UAAU;AAAA,EACV,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,cAAc;AAAA,EACd,eAAe;AAAA,EACf,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,kBAAkB,CAAC,MACjB,uBAAuB,CAAC,iBAAiB,MAAM,IAAI,KAAK,GAAG;AAAA,EAC7D,aAAa;AAAA,EACb,kBAAkB,CAAC,MACjB,sBAAsB,CAAC;AAAA,EACzB,eAAe,CAAC,MAAc,kBAAkB,CAAC;AAAA;AAAA,EAGjD,kBACE;AAAA,EACF,qBACE;AAAA,EACF,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtB,mBAAmB;AAAA;AAAA;AAAA;AAAA,EAInB,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,kBAAkB;AAAA;AAAA;AAAA;AAAA,EAIlB,WAAW;AAAA;AAAA;AAAA;AAAA,EAIX,WAAW;AAAA;AAAA;AAAA;AAAA,EAIX,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf,oBAAoB;AAAA;AAAA;AAAA;AAAA,EAIpB,aACE;AAAA;AAAA,EAGF,sBACE;AAAA,EACF,uBACE;AAAA,EACF,eAAe;AAAA,EACf,eAAe;AAAA;AAAA,EAGf,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,SAAS;AAAA;AAAA,EAGT,wBAAwB,CAAC,MACvB,OAAO,CAAC;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,uBAAuB,CAAC,MACtB,kBAAkB,CAAC;AAAA,EACrB,YAAY;AAAA,EACZ,oBAAoB;AAAA,EACpB,eAAe,CAAC,MACd,QAAQ,CAAC;AAAA;AAAA,EAGX,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,gBAAgB;AAAA;AAAA;AAAA,EAIhB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,aAAa;AAAA,EACb,UAAU;AAAA,EACV,uBAAuB,CAAC,aAAqB,MAAM,SAAS,YAAY,CAAC;AAAA,EAEzE,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,cAAc,CAAC,OAAe,OAAe,WAC3C,YAAY,KAAK,sBAAsB,KAAK,oBAAoB,MAAM;AAAA,EACxE,gBAAgB,CAAC,MACf,gBAAgB,CAAC;AAAA,EACnB,oBAAoB,CAAC,MACnB,+BAA+B,CAAC;AAAA,EAClC,mBAAmB,CAAC,MAClB,2BAA2B,CAAC;AAAA,EAC9B,SAAS,CAAC,MAAc,mBAAmB,CAAC;AAAA,EAC5C,QAAQ,CAAC,MACP,mBAAmB,CAAC;AAAA,EACtB,aAAa,CAAC,MACZ,IAAI,CAAC;AAAA,EACP,gBAAgB,CAAC,MACf,iBAAiB,CAAC;AAAA,EACpB,qBAAqB,CAAC,YACpB,yCAAyC,OAAO;AAAA,EAClD,sBACE;AAAA,EACF,SAAS,CAAC,MAAc,cAAc,CAAC;AAAA,EACvC,uBAAuB;AAAA,EACvB,mBAAmB,CAAC,MAAc,GAAG,CAAC,YAAY,MAAM,IAAI,KAAK,GAAG;AAAA,EACpE,uBAAuB,CAAC,GAAW,QAAgB,WAAW,CAAC,iBAAiB,MAAM,IAAI,KAAK,IAAI,KAAK,GAAG;AAAA,EAC3G,qBAAqB;AAAA,IACnB,wCAAwC;AAAA,IACxC,wCAAwC;AAAA,IACxC,wCAAwC;AAAA,IACxC,wCAAwC;AAAA,IACxC,wCAAwC;AAAA,EAC1C;AAAA;AAAA,EAGA,aAAa;AAAA,IACX,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,sBAAsB;AAAA,IACtB,0BAA0B;AAAA,IAC1B,sBAAsB;AAAA,IACtB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,uBAAuB;AAAA,IACvB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,0BAA0B;AAAA,IAC1B,uBAAuB;AAAA,IACvB,0BAA0B;AAAA,IAC1B,2BAA2B;AAAA,IAC3B,oBAAoB;AAAA,IACpB,cAAc;AAAA;AAAA,IAEd,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,sBAAsB;AAAA,IACtB,YAAY;AAAA,EACd;AAAA;AAAA,EAGA,0BAA0B;AAAA,IACxB,MAAM,EAAE,OAAO,0BAA0B;AAAA,IACzC,WAAW,EAAE,OAAO,2BAA2B;AAAA,IAC/C,WAAW,EAAE,OAAO,mBAAmB;AAAA,IACvC,QAAQ,EAAE,OAAO,2BAA2B;AAAA,IAC5C,mBAAmB,EAAE,OAAO,kBAAkB;AAAA,IAC9C,OAAO,EAAE,OAAO,0BAA0B;AAAA,EAC5C;AAAA;AAAA,EAGA,YAAY;AAAA,EACZ,wBAAwB;AAAA,IACtB,uBAAuB;AAAA,MACrB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,0BAA0B;AAAA,MACxB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,uBAAuB;AAAA,MACrB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,0BAA0B;AAAA,MACxB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,IACA,2BAA2B;AAAA,MACzB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QACE;AAAA,MACF,QACE;AAAA,IACJ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAe;AAAA,EACf,eAAe;AAAA,EACf,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,eAAe,CAAC,MAAc,GAAG,CAAC,eAAe,MAAM,IAAI,KAAK,GAAG;AAAA,EACnE,qBAAqB,CAAC,MAAc,4BAA4B,CAAC;AAAA,EACjE,eAAe;AAAA,EACf,gBAAgB;AAAA,IACd,gBAAgB,EAAE,MAAM,4BAA4B,MAAM,YAAK;AAAA,IAC/D,qBAAqB,EAAE,MAAM,oCAAoC,MAAM,YAAK;AAAA,IAC5E,qBAAqB,EAAE,MAAM,kCAAkC,MAAM,YAAK;AAAA,IAC1E,oBAAoB,EAAE,MAAM,iCAAiC,MAAM,YAAK;AAAA,IACxE,mBAAmB,EAAE,MAAM,2BAA2B,MAAM,kBAAM;AAAA,IAClE,oBAAoB,EAAE,MAAM,gCAAgC,MAAM,YAAK;AAAA,IACvE,qBAAqB,EAAE,MAAM,uBAAuB,MAAM,kBAAM;AAAA,IAChE,aAAa,EAAE,MAAM,2BAA2B,MAAM,YAAK;AAAA,EAC7D;AAAA,EACA,eAAe;AAAA,IACb,gBAAgB,CAAC,0FAA0F;AAAA,IAC3G,qBAAqB,CAAC,8EAA8E,qEAAqE;AAAA,IACzK,qBAAqB,CAAC,uCAAuC,4CAAuC,8BAA8B,sDAAsD;AAAA,IACxL,oBAAoB,CAAC,oDAAoD,4DAA4D;AAAA,IACrI,mBAAmB,CAAC,4DAA4D,8CAA8C,qDAAqD,oCAAoC;AAAA,IACvN,oBAAoB,CAAC,2EAA2E,mKAA0I,+CAA4C,oFAAoF,2EAA2E;AAAA,IACrb,qBAAqB,CAAC,0DAA0D,oFAAoF,mFAAmF;AAAA,IACvP,aAAa,CAAC,0DAA0D,4EAA4E,sCAAsC;AAAA,EAC5L;AAAA;AAAA,EAGA,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqDf;;;AC3MA,IAAM,eAAmC;AAAA,EACvC,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,SAAS,QAAQ,OAAa,MAAY;AAC/C,SAAO,aAAa,IAAI,KAAK,aAAa;AAC5C;;;AC5JA,IAAM,gBAA0C;AAAA,EAC9C,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AACP;AAEA,IAAM,iBAA6B,CAAC,YAAY,QAAQ,UAAU,KAAK;AAEvE,SAAS,eAAe,OAAe,KAAqB;AAC1D,QAAM,KAAK,IAAI,KAAK,GAAG,EAAE,QAAQ,IAAI,IAAI,KAAK,KAAK,EAAE,QAAQ;AAC7D,MAAI,KAAK,IAAM,QAAO,GAAG,EAAE;AAC3B,QAAM,OAAO,KAAK,MAAM,KAAK,GAAI;AACjC,MAAI,OAAO,GAAI,QAAO,GAAG,IAAI;AAC7B,QAAM,OAAO,KAAK,MAAM,OAAO,EAAE;AACjC,QAAM,aAAa,OAAO;AAC1B,SAAO,GAAG,IAAI,KAAK,UAAU;AAC/B;AAEO,SAAS,uBAAuB,aAA6B,MAAqB;AACvF,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,QAAM,EAAE,SAAS,SAAS,WAAW,QAAQ,WAAW,QAAQ,IAC9D;AACF,QAAM,OAAO,UAAU,MAAM,GAAG,EAAE,CAAC;AACnC,QAAM,WAAW,eAAe,WAAW,OAAO;AAElD,QAAM,WAAqC;AAAA,IACzC,UAAU,EAAE;AAAA,IACZ,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,KAAK,EAAE;AAAA,EACT;AAEA,WAAS,cAAc,GAAoB;AACzC,UAAM,QAAQ,EAAE,iBACb,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAChC,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,QAAQ,EAAE,KAAK;AAAA,MACf,OAAO,EAAE,QAAQ,OAAO,EAAE,UAAU,OAAO,EAAE,WAAW;AAAA,MACxD,OAAO,EAAE,WAAW,OAAO,EAAE,WAAW;AAAA,MACxC,OAAO,EAAE,MAAM,OAAO,EAAE,MAAM;AAAA,MAC9B,OAAO,EAAE,SAAS,OAAO,EAAE,SAAS;AAAA,MACpC,OAAO,EAAE,WAAW;AAAA,MACpB;AAAA,MACA,OAAO,EAAE,QAAQ,OAAO,EAAE,QAAQ;AAAA,IACpC,EAAE,KAAK,IAAI;AAAA,EACb;AAEA,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,KAAK,EAAE,mBAAmB,WAAW,IAAI,EAAE;AACtD,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,MAAM,EAAE,gBAAgB,EAAE;AACrC,QAAM,KAAK,OAAO,EAAE,OAAO,OAAO,SAAS,EAAE;AAC7C,QAAM,KAAK,OAAO,EAAE,MAAM,OAAO,MAAM,EAAE;AACzC,QAAM,KAAK,OAAO,EAAE,QAAQ,OAAO,QAAQ,EAAE;AAC7C,QAAM;AAAA,IACJ,OAAO,EAAE,kBAAkB,OAAO,QAAQ,aAAa,KAAK,cAAc,QAAQ,IAAI,QAAQ,QAAQ,IAAI,EAAE,QAAQ,MAAM,cAAc,IAAI,IAAI,QAAQ,IAAI,IAAI,EAAE,IAAI,MAAM,cAAc,MAAM,IAAI,QAAQ,MAAM,IAAI,EAAE,MAAM,MAAM,cAAc,GAAG,IAAI,QAAQ,GAAG,IAAI,EAAE,GAAG;AAAA,EAC/Q;AACA,QAAM,KAAK,EAAE;AAGb,MAAI,QAAQ,kBAAkB,GAAG;AAC/B,UAAM,KAAK,MAAM,EAAE,kBAAkB,EAAE;AACvC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,UAAU,EAAE,aAAa,EAAE;AACtC,UAAM,KAAK,EAAE;AAAA,EACf,OAAO;AAEL,UAAM,cAAyB,QAAQ,QAAQ,CAAC,MAAM,EAAE,QAAQ;AAGhE,UAAM,UAAU,oBAAI,IAAyB;AAC7C,eAAW,OAAO,gBAAgB;AAChC,cAAQ,IAAI,KAAK,CAAC,CAAC;AAAA,IACrB;AACA,eAAW,KAAK,aAAa;AAC3B,cAAQ,IAAI,EAAE,QAAQ,EAAG,KAAK,CAAC;AAAA,IACjC;AAEA,UAAM,KAAK,MAAM,EAAE,kBAAkB,EAAE;AACvC,UAAM,KAAK,EAAE;AAEb,eAAW,OAAO,gBAAgB;AAChC,YAAM,WAAW,QAAQ,IAAI,GAAG;AAChC,YAAM,OAAO,cAAc,GAAG;AAC9B,YAAM,KAAK,OAAO,IAAI,IAAI,SAAS,GAAG,CAAC,EAAE;AACzC,YAAM,KAAK,EAAE;AAEb,UAAI,SAAS,WAAW,GAAG;AACzB,cAAM,KAAK,EAAE,sBAAsB,SAAS,GAAG,CAAC,CAAC;AACjD,cAAM,KAAK,EAAE;AACb;AAAA,MACF;AAGA,eAAS,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AACjD,iBAAW,KAAK,UAAU;AACxB,cAAM,KAAK,cAAc,CAAC,CAAC;AAC3B,cAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAGA,QAAM,KAAK,MAAM,EAAE,cAAc,EAAE;AACnC,QAAM;AAAA,IACJ,KAAK,EAAE,MAAM,MAAM,EAAE,SAAS,MAAM,EAAE,QAAQ,MAAM,EAAE,MAAM;AAAA,EAC9D;AACA,QAAM,KAAK,mDAAmD;AAC9D,aAAW,KAAK,SAAS;AACvB,UAAM,SAAS,EAAE,WAAW,YAAY,WAAW;AACnD,UAAM;AAAA,MACJ,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK,EAAE,MAAM,MAAM,EAAE,gBAAgB,MAAM,EAAE,aAAa,MAAM,MAAM;AAAA,IACnG;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAGb,MAAI,QAAQ,gBAAgB,GAAG;AAC7B,UAAM,cAAyB,QAAQ,QAAQ,CAAC,MAAM,EAAE,QAAQ;AAChE,gBAAY,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAEpD,UAAM,KAAK,MAAM,EAAE,eAAe,EAAE;AACpC,aAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,YAAM,IAAI,YAAY,CAAC;AACvB,YAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,KAAK,EAAE,KAAK,KAAK,EAAE,iBAAiB,CAAC,KAAK,uBAAuB,EAAE;AAAA,IACxG;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AC3IA;AAAA,EACE;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,YAAc;AAAA,IACd,YAAc;AAAA,IACd,WAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,iBAAmB;AAAA,IACnB,kBAAoB;AAAA,EACtB;AACF;;;AC17DO,IAAM,uBACX;AAMK,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAcO,IAAM,sBAA0C;AAAA;AAAA;AAAA;AAAA,EAIrD,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA;AAAA,EAGjE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,qFAAoB;AAAA;AAAA,EAGtE,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA,EAG3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA,EAG3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAK3C,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,mEAAiB;AAAA,EACnE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,2CAAa;AAAA,EAC/D;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,OAAO;AAAA,EACjC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,SAAS,UAAU,QAAQ;AAAA,EACrD;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,8DAAiB;AAAA,EACnE;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB,uBAAuB;AAAA,IACpD,uBAAuB,CAAC,OAAO;AAAA,EACjC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB,uBAAuB;AAAA,IACpD,uBAAuB,CAAC,OAAO;AAAA,EACjC;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA,EAG3C,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,+BAAW;AAAA,EAC7D,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,uDAAe;AAAA,EACjE;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,gBAAgB,oBAAoB;AAAA,EACxE;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,mEAAiB;AAAA,EACnE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,6DAA0B;AAAA;AAAA,EAG5E,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAK3C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,gBAAgB,uBAAuB;AAAA,IACzE,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,gBAAgB,uBAAuB;AAAA,IACzE,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,gBAAgB,sBAAsB,uBAAuB;AAAA,IAC7F,uBAAuB,CAAC,aAAa;AAAA,EACvC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,gBAAgB,sBAAsB,uBAAuB;AAAA,IAC7F,uBAAuB,CAAC,aAAa;AAAA,EACvC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,gBAAgB,sBAAsB,uBAAuB;AAAA,IAC7F,uBAAuB,CAAC,aAAa;AAAA,EACvC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,cAAc;AAAA,EAChD;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,qBAAqB,yBAAyB,uBAAuB;AAAA,IAC/E,uBAAuB,CAAC,cAAc;AAAA,EACxC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,qBAAqB,uBAAuB;AAAA,IACtD,uBAAuB,CAAC,cAAc;AAAA,EACxC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,gBAAgB,gBAAgB,gBAAgB,cAAc;AAAA,EACxF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA,EAG3C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,cAAc;AAAA,EAChD;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,cAAc;AAAA,EAChD;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,oBAAoB;AAAA,EAChC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,cAAc;AAAA,EAChD;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,cAAc;AAAA,EACxC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,cAAc;AAAA,EACxC;AAAA;AAAA,EAGA,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA,EAG3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA,EAG3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAK3C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,4BAA4B,4BAA4B,uBAAuB;AAAA,IACzF,uBAAuB,CAAC,SAAS,UAAU,QAAQ;AAAA,EACrD;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB,uBAAuB;AAAA,IACpD,uBAAuB,CAAC,OAAO;AAAA,EACjC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,SAAS,OAAO;AAAA,EAC1C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,4BAA4B,0BAA0B;AAAA,EAClE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,yBAAyB,0BAA0B;AAAA,IAC7D,uBAAuB,CAAC,SAAS,SAAS,QAAQ;AAAA,EACpD;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,4BAA4B,uBAAuB;AAAA,IAC7D,uBAAuB,CAAC,SAAS,QAAQ;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,4BAA4B,0BAA0B;AAAA,EAClE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,4BAA4B,uBAAuB;AAAA,IAC7D,uBAAuB,CAAC,SAAS,QAAQ;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,qBAAqB,uBAAuB;AAAA,IACtD,uBAAuB,CAAC,cAAc;AAAA,EACxC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,qBAAqB,uBAAuB;AAAA,IACtD,uBAAuB,CAAC,cAAc;AAAA,EACxC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,gBAAgB,gBAAgB,gBAAgB,cAAc;AAAA,EACxF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,gBAAgB,cAAc;AAAA,EACxD;AAAA;AAAA,EAEA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,2BAA2B;AAAA,EAC7D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,cAAc;AAAA,EAChD;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB,uBAAuB;AAAA,IACpD,uBAAuB,CAAC,OAAO;AAAA,EACjC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB,uBAAuB;AAAA,IACpD,uBAAuB,CAAC,OAAO;AAAA,EACjC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,QAAQ,SAAS,OAAO;AAAA,EAClD;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB;AAAA,EAC/B;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,+EAAmB;AAAA,EACrE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,+EAAmB;AAAA,EACrE;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,SAAS,OAAO;AAAA,EAC1C;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,6EAAsB;AAAA,EACxE;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,wBAAwB,uBAAuB;AAAA,IACzD,uBAAuB,CAAC,UAAU,QAAQ;AAAA,EAC5C;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,6DAAgB;AAAA,EAClE;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,oBAAoB;AAAA,EAChC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,OAAO;AAAA,EACjC;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,+EAAmB;AAAA,EACrE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,yEAAkB;AAAA,EACpE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,iEAAoB;AAAA,EACtE;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,OAAO;AAAA,EACjC;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,qFAAoB;AAAA,EACtE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,yEAAkB;AAAA,EACpE,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,2GAA2B;AAAA,EAC7E,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,qFAAoB;AAAA;AAAA,EAGtE,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA,EAG3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA,EAG3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA,EAC3C,EAAE,IAAI,cAAc,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAK3C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,4BAA4B,uBAAuB;AAAA,IAC7D,uBAAuB,CAAC,SAAS,OAAO;AAAA,EAC1C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,yBAAyB,uBAAuB;AAAA,IAC1D,uBAAuB,CAAC,UAAU;AAAA,EACpC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,4BAA4B,uBAAuB;AAAA,IAC7D,uBAAuB,CAAC,SAAS,OAAO;AAAA,EAC1C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,cAAc;AAAA,EACxC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,4BAA4B,uBAAuB;AAAA,IAC7D,uBAAuB,CAAC,SAAS,OAAO;AAAA,EAC1C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,4BAA4B,uBAAuB;AAAA,IAC7D,uBAAuB,CAAC,SAAS,QAAQ;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB;AAAA,IAC7B,iBAAiB,CAAC,cAAc;AAAA,EAClC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,mBAAmB,uBAAuB;AAAA,IACpD,uBAAuB,CAAC,OAAO;AAAA,EACjC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,uBAAuB;AAAA,IACjC,uBAAuB,CAAC,cAAc;AAAA,EACxC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,CAAC,sBAAsB,uBAAuB;AAAA,IACvD,uBAAuB,CAAC,aAAa;AAAA,EACvC;AAAA;AAAA,EAGA,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,yEAAkB;AAAA,EACpE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,qFAAoB;AAAA,EACtE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,2FAAqB;AAAA,EACvE,EAAE,IAAI,cAAc,MAAM,kBAAkB,MAAM,2FAAqB;AACzE;AAMA,IAAM,gBAAgB,oBAAI,IAA8B;AACxD,WAAW,KAAK,qBAAqB;AACnC,gBAAc,IAAI,EAAE,IAAI,CAAC;AAC3B;AAEO,SAAS,eAAe,IAA0C;AACvE,SAAO,cAAc,IAAI,EAAE;AAC7B;;;AClpBO,SAAS,kBACd,MACA,SACA,aACA,aACiB;AACjB,MAAI,QAAQ,SAAS,kBAAkB;AACrC,WAAO,EAAE,MAAM,SAAS,QAAQ,kBAAkB,iBAAiB,CAAC,EAAE;AAAA,EACxE;AACA,MAAI,QAAQ,SAAS,kBAAkB;AACrC,WAAO,EAAE,MAAM,SAAS,QAAQ,kBAAkB,iBAAiB,CAAC,EAAE;AAAA,EACxE;AACA,MAAI,QAAQ,SAAS,UAAU;AAC7B,WAAO,EAAE,MAAM,SAAS,QAAQ,UAAU,iBAAiB,CAAC,EAAE;AAAA,EAChE;AAGA,QAAM,OAAO,QAAQ,WAAW,CAAC;AAEjC,QAAM,oBAAoB,KAAK;AAAA,IAAM,CAAC,QACpC,YAAY,KAAK,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE,WAAW,SAAS;AAAA,EACpE;AAEA,MAAI,CAAC,mBAAmB;AACtB,WAAO,EAAE,MAAM,SAAS,QAAQ,WAAW,iBAAiB,CAAC,EAAE;AAAA,EACjE;AAEA,MAAI;AAEJ,MAAI,QAAQ,uBAAuB,QAAQ;AAGzC,sBAAkB,YAAY,OAAO,CAAC,MAAM;AAC1C,UAAI,CAAC,KAAK,SAAS,EAAE,UAAU,EAAE,EAAG,QAAO;AAC3C,UAAI,EAAE,WAAW,yBAAyB;AACxC,eAAO,QAAQ,sBAAuB,KAAK,CAAC,OAAO,EAAE,MAAM,SAAS,EAAE,CAAC;AAAA,MACzE;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH,WAAW,QAAQ,iBAAiB,QAAQ;AAE1C,UAAM,WAAW,QAAQ;AACzB,sBAAkB,YAAY,OAAO,CAAC,MAAM;AAC1C,UAAI,CAAC,KAAK,SAAS,EAAE,UAAU,EAAE,EAAG,QAAO;AAC3C,YAAM,OAAO,GAAG,EAAE,KAAK,IAAI,EAAE,WAAW,GAAG,YAAY;AACvD,aAAO,SAAS,KAAK,CAAC,YAAY,KAAK,SAAS,QAAQ,YAAY,CAAC,CAAC;AAAA,IACxE,CAAC;AAAA,EACH,OAAO;AAEL,sBAAkB,YAAY,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,UAAU,EAAE,CAAC;AAAA,EAC3E;AAGA,QAAM,SAA0B,gBAAgB,WAAW,IAAI,UAAU;AAEzE,SAAO,EAAE,MAAM,SAAS,QAAQ,gBAAgB;AAClD;AAKO,SAAS,sBACd,aACmB;AACnB,QAAM,cAAyB,YAAY,QAAQ;AAAA,IAAQ,CAAC,MAC1D,EAAE,SAAS,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE;AAAA,EAChE;AACA,QAAM,cAAc,YAAY,QAAQ,IAAI,CAAC,OAAO;AAAA,IAClD,QAAQ,EAAE;AAAA,IACV,QAAQ,EAAE;AAAA,EACZ,EAAE;AAEF,SAAO,qBAAqB,IAAI,CAAC,SAAS;AACxC,UAAM,UAAU,eAAe,KAAK,EAAE;AACtC,QAAI,CAAC,SAAS;AAEZ,aAAO;AAAA,QACL;AAAA,QACA,SAAS,EAAE,IAAI,KAAK,IAAI,MAAM,UAAmB,UAAU,6CAAU;AAAA,QACrE,QAAQ;AAAA,QACR,iBAAiB,CAAC;AAAA,MACpB;AAAA,IACF;AACA,WAAO,kBAAkB,MAAM,SAAS,aAAa,WAAW;AAAA,EAClE,CAAC;AACH;AAoMO,SAAS,oBAAoB,aAA6B,MAAqB;AACpF,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,QAAM,QAAQ,QAAQ,UAAU;AAChC,QAAM,EAAE,WAAW,QAAQ,UAAU,IAAI;AACzC,QAAM,WAAW,UAAU,QAAQ,KAAK,GAAG,EAAE,QAAQ,WAAW,MAAM;AAGtE,QAAM,UAAU,sBAAsB,WAAW;AAGjD,QAAM,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,QAAQ,SAAS,MAAM;AACnE,QAAM,YAAY,YAAY,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AAClE,QAAM,aAAa,YAAY,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AACpE,QAAM,cAAc,YAAY,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AACtE,QAAM,eAAe,YAAY;AACjC,QAAM,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,gBAAgB,EAAE;AACxE,QAAM,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AACjE,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,gBAAgB,EAAE;AAGrE,QAAM,cAAc,CAAC,MAAuB,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK;AAC7E,QAAM,UAAU,CAAC,MAAuB,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK;AAE7E,QAAM,QAAkB,CAAC;AAGzB,QAAM,KAAK,KAAK,EAAE,SAAS,EAAE;AAC7B,QAAM,KAAK,OAAO,EAAE,cAAc,IAAI;AACtC,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,MAAM,EAAE,WAAW,EAAE;AAChC,QAAM,KAAK,KAAK,EAAE,OAAO,KAAK,SAAS,MAAM,EAAE,MAAM,KAAK,MAAM,MAAM,EAAE,QAAQ,KAAK,QAAQ,EAAE;AAC/F,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,MAAM,EAAE,gBAAgB,EAAE;AACrC,QAAM,KAAK,KAAK,EAAE,aAAa,cAAc,WAAW,UAAU,CAAC,EAAE;AACrE,MAAI,cAAc,GAAG;AACnB,UAAM,KAAK,KAAK,EAAE,eAAe,WAAW,CAAC,EAAE;AAAA,EACjD;AACA,QAAM,KAAK,KAAK,EAAE,mBAAmB,UAAU,CAAC,EAAE;AAClD,QAAM,KAAK,KAAK,EAAE,kBAAkB,WAAW,CAAC,EAAE;AAClD,MAAI,UAAU,GAAG;AACf,UAAM,KAAK,KAAK,EAAE,QAAQ,OAAO,CAAC,EAAE;AAAA,EACtC;AACA,QAAM,KAAK,EAAE;AAGb,aAAW,YAAY,sBAAsB;AAC3C,UAAM,eAAe,EAAE,oBAAoB,QAAQ,KAAK;AACxD,UAAM,aAAa,QAAQ;AAAA,MACzB,CAAC,MAAM,EAAE,KAAK,eAAe,YAAY,EAAE,WAAW;AAAA,IACxD;AACA,QAAI,WAAW,WAAW,EAAG;AAE7B,UAAM,KAAK,MAAM,YAAY,EAAE;AAC/B,UAAM,KAAK,EAAE;AAGb,UAAM,aAAa,oBAAI,IAA+B;AACtD,eAAW,KAAK,YAAY;AAC1B,YAAM,MAAM,EAAE,KAAK;AACnB,UAAI,CAAC,WAAW,IAAI,GAAG,EAAG,YAAW,IAAI,KAAK,CAAC,CAAC;AAChD,iBAAW,IAAI,GAAG,EAAG,KAAK,CAAC;AAAA,IAC7B;AAEA,eAAW,CAAC,aAAa,cAAc,KAAK,YAAY;AACtD,YAAM,cAAc,YAAY,eAAe,CAAC,CAAC;AACjD,YAAM,KAAK,OAAO,WAAW,EAAE;AAC/B,iBAAW,KAAK,gBAAgB;AAC9B,cAAM,OAAO,EAAE,WAAW,UAAU,WAChC,EAAE,WAAW,WAAW,WACxB,EAAE,WAAW,YAAY,iBACzB,EAAE,WAAW,WAAW,cACxB;AACJ,cAAM,SAAS,EAAE,WAAW,YAAY,WAAW,EAAE,UAAU,KAC3D,EAAE,WAAW,WAAW,WAAW,EAAE,QAAQ,YAAY,EAAE,YAAY,KACvE,EAAE,WAAW,mBAAmB,WAAW,EAAE,QAAQ,QAAQ,EAAE,aAAa,KAC5E,EAAE,WAAW,UAAU,IAAI,EAAE,QAAQ,KACrC,IAAI,EAAE,WAAW;AAErB,cAAM,UAAU,QAAQ,CAAC;AACzB,cAAM,KAAK,MAAM,IAAI,KAAK,EAAE,KAAK,EAAE,IAAI,QAAQ,MAAM,GAAG,EAAE,CAAC,GAAG,QAAQ,SAAS,KAAK,WAAW,EAAE,GAAG,MAAM,EAAE;AAC5G,YAAI,EAAE,WAAW,YAAY,EAAE,gBAAgB,SAAS,GAAG;AACzD,qBAAW,KAAK,EAAE,gBAAgB,MAAM,GAAG,CAAC,GAAG;AAC7C,kBAAM,KAAK,OAAO,EAAE,QAAQ,KAAK,EAAE,KAAK,EAAE;AAAA,UAC5C;AACA,cAAI,EAAE,gBAAgB,SAAS,GAAG;AAChC,kBAAM,KAAK,OAAO,EAAE,QAAQ,EAAE,gBAAgB,SAAS,CAAC,CAAC,EAAE;AAAA,UAC7D;AAAA,QACF;AAAA,MACF;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAGA,QAAM,gBAAgB,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ;AACjE,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,KAAK,MAAM,EAAE,qBAAqB,EAAE;AAC1C,UAAM,KAAK,EAAE;AAGb,UAAM,oBAAoB,oBAAI,IAAqB;AACnD,eAAW,KAAK,eAAe;AAC7B,iBAAW,KAAK,EAAE,iBAAiB;AACjC,cAAM,MAAM,GAAG,EAAE,UAAU,IAAI,EAAE,KAAK;AACtC,YAAI,CAAC,kBAAkB,IAAI,GAAG,GAAG;AAC/B,4BAAkB,IAAI,KAAK,CAAC;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,CAAC,GAAG,kBAAkB,OAAO,CAAC,EAAE;AAAA,MAC7C,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE;AAAA,IAC5B;AAEA,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,YAAM,IAAI,OAAO,CAAC;AAClB,YAAM,WAAW,EAAE,aAAa,IAAM,OAAO,EAAE,aAAa,IAAM,OAAO,EAAE,aAAa,IAAM,OAAO;AACrG,YAAM,cAAc,EAAE,iBAAiB,CAAC,KAAK;AAC7C,YAAM,KAAK,GAAG,IAAI,CAAC,MAAM,QAAQ,KAAK,EAAE,KAAK,WAAM,WAAW,EAAE;AAAA,IAClE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,UAAU,GAAG;AACf,UAAM,KAAK,KAAK,EAAE,OAAO,OAAO,CAAC,EAAE;AACnC,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACtbA,SAAS,IAAI,GAAmB;AAC9B,SAAO,EACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,OAAO;AAC1B;AAGA,SAAS,QAAQ,KAA4B;AAC3C,MAAI;AACF,UAAM,IAAI,IAAI,IAAI,GAAG;AACrB,QAAI,EAAE,aAAa,YAAY,EAAE,aAAa,QAAS,QAAO;AAC9D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,aAAa,GAAmB;AACvC,QAAM,QAAQ,EAAE,MAAM,kBAAkB;AACxC,SAAO,MAAM,IAAI,CAAC,MAAM,MAAM;AAC5B,QAAI,IAAI,MAAM,GAAG;AACf,YAAM,OAAO,QAAQ,IAAI;AACzB,UAAI,MAAM;AACR,eAAO,YAAY,IAAI,IAAI,CAAC,0DAA0D,IAAI,IAAI,CAAC;AAAA,MACjG;AACA,aAAO,IAAI,IAAI;AAAA,IACjB;AACA,WAAO,IAAI,IAAI;AAAA,EACjB,CAAC,EAAE,KAAK,EAAE;AACZ;AAEA,SAAS,UAAU,SAA4C;AAC7D,QAAM,MACJ,MACA,QAAQ,WAAW,KACnB,QAAQ,OAAO,IACf,QAAQ,SAAS,IACjB,QAAQ,MAAM;AAChB,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG,CAAC,CAAC;AACnD;AAEA,SAASC,gBAAe,OAAe,KAAqB;AAC1D,QAAM,KAAK,IAAI,KAAK,GAAG,EAAE,QAAQ,IAAI,IAAI,KAAK,KAAK,EAAE,QAAQ;AAC7D,MAAI,KAAK,IAAM,QAAO,GAAG,EAAE;AAC3B,QAAM,OAAO,KAAK,MAAM,KAAK,GAAI;AACjC,MAAI,OAAO,GAAI,QAAO,GAAG,IAAI;AAC7B,SAAO,GAAG,KAAK,MAAM,OAAO,EAAE,CAAC,KAAK,OAAO,EAAE;AAC/C;AAEA,IAAM,YAAsC;AAAA,EAC1C,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AACP;AAEA,IAAMC,kBAA6B,CAAC,YAAY,QAAQ,UAAU,KAAK;AAGvE,SAAS,0BAA0B,KAAqB;AACtD,SAAO,IACJ,QAAQ,sBAAsB,YAAY,EAC1C,QAAQ,wBAAwB,UAAU,EAC1C,QAAQ,uBAAuB,MAAM,EACrC,QAAQ,6BAA6B,OAAO,EAC5C,QAAQ,gCAAgC,OAAO,EAC/C,QAAQ,YAAY,QAAQ,EAC5B,QAAQ,eAAe,eAAe,EACtC,QAAQ,iBAAiB,eAAe,EACxC,QAAQ,eAAe,aAAa,EACpC,QAAQ,aAAa,aAAa;AACvC;AAEA,IAAM,6BAA6B,CAAC,QAAQ,aAAa,aAAa,UAAU,mBAAmB,OAAO;AAE1G,SAAS,WAAW,OAAuB;AACzC,MAAI,SAAS,GAAI,QAAO;AACxB,MAAI,SAAS,GAAI,QAAO;AACxB,SAAO;AACT;AAQA,IAAM,+BAA+B;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,oBAAoB,SAAuB,MAAuF;AACzI,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,QAAM,WAAqF,CAAC;AAC5F,aAAW,OAAO,SAAS;AACzB,UAAM,MAAM,EAAE,uBAAuB,IAAI,MAAM;AAC/C,QAAI,CAAC,IAAK;AACV,QAAI,CAAC,IAAI,UAAU,OAAQ;AAC3B,UAAM,gBAAgB,IAAI,SAAS;AAAA,MAAK,CAAC,MACvC,6BAA6B,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAAA,IACxD;AACA,QAAI,eAAe;AACjB,eAAS,KAAK,GAAG;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,yBAAyB,SAAuB,MAAqB;AAC5E,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,QAAM,WAAW,oBAAoB,SAAS,IAAI;AAClD,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,QAAM,QAAQ,SAAS,IAAI,CAAC,QAAQ;AAAA;AAAA,oDAEc,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,EAAE,UAAU,CAAC;AAAA,mEACvC,IAAI,EAAE,aAAa,CAAC,SAAS,IAAI,IAAI,MAAM,CAAC;AAAA,mEAC5C,IAAI,EAAE,aAAa,CAAC,SAAS,IAAI,IAAI,MAAM,CAAC;AAAA,WACpG,EAAE,KAAK,IAAI;AAEpB,SAAO;AAAA;AAAA;AAAA,uEAG8D,IAAI,EAAE,oBAAoB,CAAC;AAAA,QAC1F,KAAK;AAAA,kFACqE,IAAI,EAAE,qBAAqB,CAAC;AAAA;AAAA;AAG9G;AAMA,SAAS,YAAoB;AAC3B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8KT;AAMA,SAAS,WAAW,SAA4C;AAC9D,QAAM,QAAQ,QAAQ;AACtB,QAAM,IAAI;AACV,QAAM,OAAO,IAAI,KAAK,KAAK;AAE3B,MAAI,UAAU,GAAG;AACf,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AAEA,QAAM,WAAoD;AAAA,IACxD,EAAE,OAAO,QAAQ,UAAU,OAAO,UAAU,SAAS;AAAA,IACrD,EAAE,OAAO,QAAQ,MAAM,OAAO,UAAU,KAAK;AAAA,IAC7C,EAAE,OAAO,QAAQ,QAAQ,OAAO,UAAU,OAAO;AAAA,IACjD,EAAE,OAAO,QAAQ,KAAK,OAAO,UAAU,IAAI;AAAA,EAC7C,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;AAE3B,MAAI,SAAS;AACb,QAAM,UAAU,SAAS,IAAI,CAAC,MAAM;AAClC,UAAM,MAAO,EAAE,QAAQ,QAAS;AAChC,UAAM,KAAK,wDAAwD,EAAE,KAAK,yCAAyC,IAAI,QAAQ,CAAC,CAAC,KAAK,OAAO,KAAK,QAAQ,CAAC,CAAC,yBAAyB,CAAC,QAAQ,QAAQ,CAAC,CAAC;AACxM,cAAU;AACV,WAAO;AAAA,EACT,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,GAAG,QAAQ,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AAAA,IAC9B,gGAAgG,KAAK;AAAA,IACrG;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,SAAS,SAAoC,gBAAgB,qBAA6B;AACjG,QAAM,eAAe,QAClB,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACjC,KAAK,CAAC,GAAG,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAChD,MAAM,GAAG,EAAE;AAEd,MAAI,aAAa,WAAW,GAAG;AAC7B,WAAO;AAAA,MACL;AAAA,MACA,+FAA+F,IAAI,aAAa,CAAC;AAAA,MACjH;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AAEA,QAAM,WAAW,aAAa,CAAC,EAAE;AACjC,QAAM,OAAO;AACb,QAAM,MAAM;AACZ,QAAM,SAAS;AACf,QAAM,UAAU;AAChB,QAAM,SAAS,aAAa,UAAU,OAAO;AAE7C,QAAM,OAAO,aAAa,IAAI,CAAC,GAAG,MAAM;AACtC,UAAM,IAAI,KAAK,OAAO;AACtB,UAAM,IAAI,KAAK,IAAI,GAAI,EAAE,gBAAgB,WAAY,OAAO;AAC5D,UAAM,WAAW,EAAE,SAAS,OAAiB,CAAC,OAAO,MAAM;AACzD,YAAM,MAAMA,gBAAe,QAAQ,EAAE,QAAQ;AAC7C,aAAO,MAAMA,gBAAe,QAAQ,KAAK,IAAI,EAAE,WAAW;AAAA,IAC5D,GAAG,KAAK;AACR,UAAM,QAAQ,UAAU,QAAQ;AAChC,WAAO;AAAA,MACL,YAAY,SAAS,CAAC,QAAQ,IAAI,OAAO,IAAI,CAAC,qDAAqD,IAAI,EAAE,MAAM,CAAC;AAAA,MAChH,YAAY,MAAM,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,aAAa,IAAI,kBAAkB,KAAK;AAAA,MAC3F,YAAY,SAAS,IAAI,CAAC,QAAQ,IAAI,OAAO,IAAI,CAAC,mCAAmC,EAAE,aAAa;AAAA,IACtG,EAAE,KAAK,IAAI;AAAA,EACb,CAAC;AAED,SAAO;AAAA,IACL,yBAAyB,MAAM;AAAA,IAC/B,GAAG;AAAA,IACH;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,mBAAmB,SAA0C;AACpE,QAAM,UAAU,QAAQ,MAAM,GAAG;AACjC,MAAI,QAAQ,SAAS,EAAG,QAAO;AAE/B,QAAM,IAAI;AACV,QAAM,IAAI;AACV,QAAM,MAAM,EAAE,KAAK,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM,GAAG;AACvD,QAAM,QAAQ,IAAI,IAAI,OAAO,IAAI;AACjC,QAAM,QAAQ,IAAI,IAAI,MAAM,IAAI;AAEhC,QAAM,SAAS,KAAK;AAAA,IAClB;AAAA,IACA,GAAG,QAAQ,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC;AAAA,EACjE;AAEA,QAAM,OAAO,CAAC,MACZ,IAAI,OAAQ,IAAI,KAAK,IAAI,GAAG,QAAQ,SAAS,CAAC,IAAK;AACrD,QAAM,OAAO,CAAC,MAAc,IAAI,MAAM,QAAS,IAAI,SAAU;AAE7D,QAAM,QAID;AAAA,IACH,EAAE,KAAK,YAAY,OAAO,WAAW,OAAO,WAAW;AAAA,IACvD,EAAE,KAAK,QAAQ,OAAO,WAAW,OAAO,OAAO;AAAA,IAC/C,EAAE,KAAK,UAAU,OAAO,WAAW,OAAO,SAAS;AAAA,IACnD,EAAE,KAAK,OAAO,OAAO,WAAW,OAAO,MAAM;AAAA,EAC/C;AAEA,QAAM,YAAY,MACf,IAAI,CAAC,SAAS;AACb,UAAM,MAAM,QACT;AAAA,MACC,CAAC,GAAG,MACF,GAAG,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,IACzD,EACC,KAAK,GAAG;AACX,WAAO,qBAAqB,GAAG,yBAAyB,KAAK,KAAK;AAAA,EACpE,CAAC,EACA,KAAK,MAAM;AAEd,QAAM,UAAU,QACb,IAAI,CAAC,GAAG,MAAM;AACb,QAAI,IAAI,MAAM,KAAK,MAAM,QAAQ,SAAS,EAAG,QAAO;AACpD,WAAO,YAAY,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,IAAI,CAAC,wDAAwD,EAAE,KAAK,MAAM,CAAC,CAAC;AAAA,EAC3H,CAAC,EACA,OAAO,OAAO,EACd,KAAK,MAAM;AAEd,QAAM,SAAS;AACf,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,SAAS,EAAE,GAAG,CAAC,GAAG,MAAM;AAC3D,UAAM,MAAM,KAAK,MAAO,SAAS,SAAU,CAAC;AAC5C,WAAO;AAAA,MACL,YAAY,IAAI,OAAO,CAAC,QAAQ,KAAK,GAAG,EAAE,QAAQ,CAAC,CAAC,gFAAgF,GAAG;AAAA,MACvI,aAAa,IAAI,IAAI,SAAS,KAAK,GAAG,EAAE,QAAQ,CAAC,CAAC,SAAS,IAAI,IAAI,KAAK,SAAS,KAAK,GAAG,EAAE,QAAQ,CAAC,CAAC;AAAA,IACvG,EAAE,KAAK,MAAM;AAAA,EACf,CAAC,EAAE,KAAK,MAAM;AAEd,QAAM,SAAS,MACZ,IAAI,CAAC,MAAM,MAAM;AAChB,UAAM,KAAK,IAAI,OAAO,IAAI;AAC1B,WAAO,YAAY,EAAE,8CAA8C,KAAK,KAAK,eAAe,KAAK,EAAE,0CAA0C,KAAK,KAAK;AAAA,EACzJ,CAAC,EACA,KAAK,MAAM;AAEd,SAAO;AAAA,IACL,qBAAqB,CAAC,IAAI,CAAC;AAAA,IAC3B,KAAK,MAAM;AAAA,IACX,KAAK,OAAO;AAAA,IACZ,KAAK,SAAS;AAAA,IACd,KAAK,OAAO;AAAA,IACZ;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,gBAAgB,SAA0C;AACjE,QAAM,UAAU,QAAQ,MAAM,GAAG;AACjC,MAAI,QAAQ,SAAS,EAAG,QAAO;AAE/B,QAAM,IAAI;AACV,QAAM,IAAI;AACV,QAAM,MAAM,EAAE,KAAK,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM,GAAG;AACvD,QAAM,QAAQ,IAAI,IAAI,OAAO,IAAI;AACjC,QAAM,QAAQ,IAAI,IAAI,MAAM,IAAI;AAEhC,QAAM,OAAO,CAAC,MACZ,IAAI,OAAQ,IAAI,KAAK,IAAI,GAAG,QAAQ,SAAS,CAAC,IAAK;AACrD,QAAM,OAAO,CAAC,MAAc,IAAI,MAAM,QAAS,IAAI,MAAO;AAE1D,QAAM,MAAM,QACT,IAAI,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,EACjE,KAAK,GAAG;AAEX,QAAM,QAAQ;AAAA,IACZ,YAAY,IAAI,IAAI,QAAQ,KAAK,GAAG,EAAE,QAAQ,CAAC,CAAC,YAAY,KAAK,cAAc,KAAK,EAAE,IAAI,KAAK,GAAG,GAAG,QAAQ,CAAC,CAAC;AAAA,IAC/G,YAAY,IAAI,IAAI,QAAQ,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC,YAAY,KAAK,cAAc,KAAK,EAAE,IAAI,KAAK,EAAE,GAAG,QAAQ,CAAC,CAAC;AAAA,IAC7G,YAAY,IAAI,IAAI,QAAQ,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC,YAAY,KAAK,cAAc,KAAK,CAAC,IAAI,KAAK,EAAE,GAAG,QAAQ,CAAC,CAAC;AAAA,EAC9G,EAAE,KAAK,MAAM;AAEb,QAAM,UAAU,QACb,IAAI,CAAC,GAAG,MAAM;AACb,QAAI,IAAI,MAAM,KAAK,MAAM,QAAQ,SAAS,EAAG,QAAO;AACpD,WAAO,YAAY,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,IAAI,CAAC,wDAAwD,EAAE,KAAK,MAAM,CAAC,CAAC;AAAA,EAC3H,CAAC,EACA,OAAO,OAAO,EACd,KAAK,MAAM;AAEd,QAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,IAAI,GAAG;AACjC,QAAM,UAAU,MACb;AAAA,IACC,CAAC,QACC,YAAY,IAAI,OAAO,CAAC,QAAQ,KAAK,GAAG,EAAE,QAAQ,CAAC,CAAC,gFAAgF,GAAG;AAAA,cAAwB,IAAI,IAAI,SAAS,KAAK,GAAG,EAAE,QAAQ,CAAC,CAAC,SAAS,IAAI,IAAI,KAAK,SAAS,KAAK,GAAG,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC3P,EACC,KAAK,MAAM;AAEd,SAAO;AAAA,IACL,qBAAqB,CAAC,IAAI,CAAC;AAAA,IAC3B,KAAK,KAAK;AAAA,IACV,KAAK,OAAO;AAAA,IACZ,uBAAuB,GAAG;AAAA,IAC1B,KAAK,OAAO;AAAA,IACZ;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAMO,SAAS,mBACd,aACA,SACA,MACQ;AACR,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,QAAM,YAAY,QAAQ,UAAU,OAAO,UAAU;AACrD,QAAM,EAAE,SAAS,SAAS,WAAW,QAAQ,WAAW,QAAQ,IAC9D;AACF,QAAM,OAAO,UAAU,MAAM,GAAG,EAAE,CAAC;AACnC,QAAM,WAAWD,gBAAe,WAAW,OAAO;AAClD,QAAM,QAAQ,UAAU,OAAO;AAE/B,QAAM,cAAyB,QAAQ;AAAA,IAAQ,CAAC,MAC9C,EAAE,SAAS,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE;AAAA,EAChE;AAGA,QAAM,WAAW,QAAQ,KAAK,OAAK,EAAE,WAAW,uBAAuB;AACvE,QAAM,YAAuF,CAAC;AAC9F,MAAI,YAAY,SAAS,gBAAgB,GAAG;AAC1C,UAAM,SAAoC,CAAC;AAC3C,eAAW,KAAK,SAAS,UAAU;AACjC,YAAM,MAAM,qBAAqB,CAAC;AAClC,UAAI,CAAC,OAAO,GAAG,EAAG,QAAO,GAAG,IAAI,CAAC;AACjC,aAAO,GAAG,EAAE,KAAK,CAAC;AAAA,IACpB;AACA,eAAW,OAAO,4BAA4B;AAC5C,YAAM,cAAc,OAAO,GAAG;AAC9B,UAAI,eAAe,YAAY,SAAS,GAAG;AACzC,cAAM,OAAO,EAAE,yBAAyB,GAAG;AAC3C,cAAM,UAAU,EAAE,YAAY,MAAM,GAAG,EAAE,KAAK,MAAM,SAAS;AAC7D,kBAAU,KAAK;AAAA,UACb,KAAK;AAAA,UACL,OAAO;AAAA,UACP,OAAO,YAAY;AAAA,UACnB,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,QAAM,yBAAyB,oBAAI,IAAI;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,QAAM,kBAAgC,QAAQ,QAAQ,OAAK;AACzD,QAAI,uBAAuB,IAAI,EAAE,MAAM,EAAG,QAAO,CAAC;AAClD,QAAI,EAAE,WAAW,2BAA2B,UAAU,SAAS,GAAG;AAChE,aAAO,UAAU,IAAI,SAAO;AAAA,QAC1B,GAAG;AAAA,QACH,QAAQ,EAAE,YAAY,MAAM,GAAG,GAAG,EAAE,KAAK,GAAG;AAAA,QAC5C,eAAe,GAAG;AAAA,QAClB,UAAU,GAAG;AAAA,MACf,EAAE;AAAA,IACJ;AACA,WAAO,CAAC,EAAE,GAAG,GAAG,QAAQ,EAAE,YAAY,EAAE,MAAM,KAAK,EAAE,OAAO,CAAC;AAAA,EAC/D,CAAC;AAGD,MAAI,WAAW;AACf,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,OAAO,CAAC,GAAG,WAAW,EACzB,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EACxC,MAAM,GAAG,CAAC;AACb,UAAM,QAAQ,KACX;AAAA,MACC,CAAC,GAAG,MAAM;AAAA,kCACgB,IAAI,EAAE,SAAS,YAAY,CAAC,CAAC;AAAA,kCAC7B,IAAI,CAAC;AAAA;AAAA,qCAEF,IAAI,EAAE,SAAS,YAAY,CAAC,CAAC,KAAK,IAAI,EAAE,QAAQ,CAAC;AAAA,oCAClD,IAAI,EAAE,KAAK,CAAC;AAAA,6CACH,EAAE,QAAQ,cAAc,IAAI,EAAE,UAAU,CAAC;AAAA,6CACzC,EAAE,MAAM,cAAc,IAAI,EAAE,MAAM,CAAC;AAAA,6CACnC,EAAE,SAAS,cAAc,EAAE,SAAS;AAAA,gBACjE,EAAE,WAAW;AAAA,yCACY,EAAE,iBAAiB,IAAI,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA,IAGxG,EACC,KAAK,IAAI;AACZ,eAAW;AAAA;AAAA,YAEH,IAAI,EAAE,uBAAuB,KAAK,MAAM,CAAC,CAAC;AAAA,QAC9C,KAAK;AAAA;AAAA,EAEX;AAGA,MAAI;AACJ,MAAI,oBAAoB;AACxB,MAAI,QAAQ,kBAAkB,GAAG;AAC/B,mBAAe,4BAA4B,IAAI,EAAE,aAAa,CAAC;AAAA,EACjE,OAAO;AACL,UAAM,iBAAiB;AAEvB,UAAM,aAAa,CAAC,GAAY,cAA8B;AAC5D,YAAM,MAAM,EAAE,SAAS,YAAY;AACnC,aAAO,gCAAgC,IAAI,GAAG,CAAC,oBAAoB,IAAI,EAAE,QAAQ,CAAC,kBAAkB,IAAI,SAAS,CAAC;AAAA,mCACrF,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,QAAQ,CAAC;AAAA,2CACpB,IAAI,EAAE,KAAK,CAAC;AAAA,yCACd,IAAI,EAAE,eAAe,EAAE,UAAU,CAAC;AAAA,4BAC/C,EAAE,OAAO;AAAA,eACtB,IAAI,EAAE,WAAW,CAAC;AAAA,uBACV,EAAE,WAAW;AAAA,gBACpB,EAAE,iBAAiB,IAAI,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA,IAGjF;AAEA,UAAM,cAAc,CAAC,UAAqB,cAA8B;AACtE,UAAI,SAAS,UAAU,gBAAgB;AACrC,eAAO,SAAS,IAAI,OAAK,WAAW,GAAG,SAAS,CAAC,EAAE,KAAK,IAAI;AAAA,MAC9D;AACA,YAAM,QAAQ,SAAS,MAAM,GAAG,cAAc,EAAE,IAAI,OAAK,WAAW,GAAG,SAAS,CAAC,EAAE,KAAK,IAAI;AAC5F,YAAM,OAAO,SAAS,MAAM,cAAc,EAAE,IAAI,OAAK,WAAW,GAAG,SAAS,CAAC,EAAE,KAAK,IAAI;AACxF,aAAO,GAAG,KAAK;AAAA,oBAAuB,EAAE,sBAAsB,SAAS,SAAS,cAAc,CAAC;AAAA,EAAe,IAAI;AAAA;AAAA,IACpH;AAEA,UAAM,YAAoC;AAAA,MACxC,UAAU;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,KAAK;AAAA,IACP;AAGA,UAAM,YAAY,oBAAI,IAAuB;AAC7C,eAAW,KAAK,aAAa;AAC3B,YAAM,MAAM,EAAE,UAAU;AACxB,UAAI,CAAC,UAAU,IAAI,GAAG,EAAG,WAAU,IAAI,KAAK,CAAC,CAAC;AAC9C,gBAAU,IAAI,GAAG,EAAG,KAAK,CAAC;AAAA,IAC5B;AAGA,UAAM,kBAA6D,CAAC;AACpE,eAAW,CAAC,KAAK,QAAQ,KAAK,UAAU,QAAQ,GAAG;AACjD,UAAI,uBAAuB,IAAI,GAAG,EAAG;AACrC,UAAI,QAAQ,2BAA2B,UAAU,SAAS,GAAG;AAC3D,mBAAW,MAAM,WAAW;AAC1B,0BAAgB,KAAK,CAAC,GAAG,KAAK,GAAG,UAAU,GAAG,KAAK,CAAC;AAAA,QACtD;AAAA,MACF,OAAO;AACL,wBAAgB,KAAK,CAAC,KAAK,UAAU,IAAI,CAAC;AAAA,MAC5C;AAAA,IACF;AAGA,UAAM,gBAAgB,gBAAgB,KAAK,CAAC,GAAG,MAAM;AACnD,YAAM,eAAe,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,cAAc,EAAE,aAAa,MAAM;AACxF,YAAM,eAAe,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,cAAc,EAAE,aAAa,MAAM;AACxF,UAAI,iBAAiB,aAAc,QAAO,eAAe,KAAK;AAC9D,aAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE;AAAA,IAC5B,CAAC;AAED,UAAM,uBAAuB,CAAC,UAAqB,cAA8B;AAC/E,aAAOC,gBAAe,IAAI,CAAC,QAAQ;AACjC,cAAM,cAAc,SAAS,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG;AAC7D,YAAI,YAAY,WAAW,EAAG,QAAO;AACrC,oBAAY,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAEpD,cAAM,QAAQ,UAAU,GAAG,KAAK;AAChC,cAAM,QAAQ,IAAI,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,YAAY;AAEvD,eAAO;AAAA,yBACU,KAAK,IAAI,KAAK,KAAK,YAAY,MAAM;AAAA,YAClD,YAAY,aAAa,SAAS,CAAC;AAAA;AAAA,MAEzC,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAAA,IAC9B;AAEA,UAAM,qBAAqB,CAAC,aAAgC;AAC1D,YAAM,YAAoC,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,EAAE;AACpF,iBAAW,KAAK,SAAU,WAAU,EAAE,QAAQ;AAC9C,aAAOA,gBACJ,OAAO,CAAC,QAAQ,UAAU,GAAG,IAAI,CAAC,EAClC,IAAI,CAAC,QAAQ,4BAA4B,IAAI,YAAY,CAAC,KAAK,UAAU,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,YAAY,CAAC,SAAS,EACpI,KAAK,GAAG;AAAA,IACb;AAEA,mBAAe,cAAc,IAAI,CAAC,CAAC,SAAS,aAAa,WAAW,MAAM;AACxE,YAAM,SAAS,mBAAmB,WAAW;AAC7C,YAAM,cAAc,gBAAgB,EAAE,YAAY,OAAO,KAAK;AAE9D,aAAO,6CAA6C,IAAI,OAAO,CAAC;AAAA;AAAA,0BAE5C,IAAI,WAAW,CAAC,KAAK,YAAY,MAAM;AAAA,wCACzB,MAAM;AAAA;AAAA;AAAA,YAGlC,qBAAqB,aAAa,OAAO,CAAC;AAAA;AAAA;AAAA,IAGlD,CAAC,EAAE,KAAK,IAAI;AAGZ,UAAM,gBAAgB,cAAc,IAAI,CAAC,CAAC,QAAQ,EAAE,WAAW,MAAM;AACnE,YAAM,QAAQ,gBAAgB,EAAE,YAAY,MAAM,KAAK;AACvD,aAAO,kBAAkB,IAAI,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;AAAA,IACrD,CAAC,EAAE,KAAK,YAAY;AAEpB,wBAAoB;AAAA;AAAA,qCAEa,IAAI,EAAE,cAAc,CAAC;AAAA,gEACM,IAAI,EAAE,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAO3C,IAAI,EAAE,YAAY,CAAC;AAAA;AAAA,gCAExB,IAAI,EAAE,gBAAgB,CAAC;AAAA,YAC3C,aAAa;AAAA;AAAA;AAAA,6DAGoC,IAAI,EAAE,cAAc,CAAC;AAAA;AAAA,EAEhF;AAGA,MAAI,YAAY;AAChB,MAAI,WAAW,QAAQ,UAAU,GAAG;AAClC,gBAAY;AAAA;AAAA,YAEJ,IAAI,EAAE,UAAU,CAAC;AAAA;AAAA,mCAEM,IAAI,EAAE,kBAAkB,CAAC;AAAA,UAClD,mBAAmB,OAAO,CAAC;AAAA;AAAA;AAAA,mCAGF,IAAI,EAAE,aAAa,CAAC;AAAA,UAC7C,gBAAgB,OAAO,CAAC;AAAA;AAAA;AAAA,EAGhC;AAGA,QAAM,mBAAmB,CAAC,MAAsC;AAC9D,QAAI,CAAC,EAAE,UAAU,OAAQ,QAAO;AAChC,UAAM,IAAI,EAAE,SAAS;AAAA,MAAK,CAACC,OACzB,6BAA6B,KAAK,CAAC,MAAMA,GAAE,SAAS,CAAC,CAAC;AAAA,IACxD;AACA,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,QACf;AAAA,IACC,CAAC,MAAM;AAEL,UAAI,uBAAuB,IAAI,EAAE,MAAM,EAAG,QAAO,CAAC;AAElD,UAAI,EAAE,WAAW,2BAA2B,UAAU,SAAS,GAAG;AAChE,eAAO,UAAU;AAAA,UAAI,QACnB,WAAW,IAAI,GAAG,KAAK,CAAC,YAAY,EAAE,gBAAgB,YAAY,GAAG,KAAK;AAAA,QAC5E;AAAA,MACF;AAEA,YAAM,kBAAkB,iBAAiB,CAAC;AAC1C,UAAI,iBAAiB;AACnB,cAAM,MAAM,EAAE,uBAAuB,EAAE,MAAM;AAC7C,cAAM,SAAS,MAAM,IAAI,SAAS;AAClC,eAAO,CAAC,WAAW,IAAI,EAAE,YAAY,EAAE,MAAM,KAAK,EAAE,MAAM,CAAC,8DAA8D,IAAI,MAAM,CAAC,YAAY;AAAA,MAClJ;AACA,aAAO,CAAC,WAAW,IAAI,EAAE,YAAY,EAAE,MAAM,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,gBAAgB,YAAY,EAAE,aAAa,YAAY,EAAE,WAAW,YAAY,aAAa,UAAU,YAAY;AAAA,IAC9L;AAAA,EACF,EACC,KAAK,IAAI;AAGZ,MAAI,WAAW;AACf,MAAI,QAAQ,gBAAgB,GAAG;AAC7B,UAAM,SAAS,oBAAI,IAA+E;AAClG,UAAM,YAAsB,CAAC;AAC7B,QAAI,aAAuB;AAC3B,QAAI;AACJ,UAAM,UAAoB,CAAC;AAC3B,QAAI,cAAwB;AAC5B,QAAI;AACJ,UAAM,kBAAkB,CAAC,kBAAkB,iBAAiB,sBAAsB,uBAAuB;AAEzG,eAAW,KAAK,aAAa;AAC3B,YAAM,MAAM,EAAE,iBAAiB,CAAC,KAAK;AACrC,YAAM,MAAM,EAAE,iBAAiB,KAAK,CAAC,MAAM,EAAE,WAAW,gBAAgB,CAAC,GAAG,QAAQ,mBAAmB,EAAE;AAGzG,UAAI,gBAAgB,KAAK,OAAK,IAAI,WAAW,CAAC,CAAC,EAAG;AAGlD,YAAM,UAAU,EAAE,MAAM,MAAM,OAAO;AACrC,UAAI,YAAY,EAAE,WAAW,2BAA2B,EAAE,WAAW,uBAAuB;AAC1F,kBAAU,KAAK,QAAQ,CAAC,CAAC;AACzB,YAAID,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,UAAU,EAAG,cAAa,EAAE;AAC5F,YAAI,CAAC,SAAS,IAAK,SAAQ;AAC3B;AAAA,MACF;AAGA,YAAM,WAAW,EAAE,MAAM,MAAM,YAAY;AAC3C,UAAI,aAAa,EAAE,WAAW,2BAA2B,EAAE,WAAW,uBAAuB;AAC3F,gBAAQ,KAAK,SAAS,CAAC,CAAC;AACxB,YAAIA,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,WAAW,EAAG,eAAc,EAAE;AAC9F,YAAI,CAAC,UAAU,IAAK,UAAS;AAC7B;AAAA,MACF;AAGA,UAAI,EAAE,WAAW,yBAAyB;AACxC,cAAM,eAAe,EAAE,MAAM,MAAM,6BAA6B;AAChE,YAAI,cAAc;AAChB,gBAAM,YAAY,aAAa,CAAC;AAChC,gBAAM,MAAM,QAAQ,SAAS;AAC7B,gBAAME,YAAW,OAAO,IAAI,GAAG;AAC/B,cAAIA,WAAU;AACZ,YAAAA,UAAS;AACT,gBAAI,CAACA,UAAS,OAAO,IAAK,CAAAA,UAAS,MAAM;AACzC,gBAAIF,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQE,UAAS,QAAQ,EAAG,CAAAA,UAAS,WAAW,EAAE;AAAA,UAC5G,OAAO;AACL,mBAAO,IAAI,KAAK,EAAE,MAAM,IAAI,SAAS,KAAK,GAAG,IAAI,UAAU,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC;AAAA,UACxF;AACA;AAAA,QACF;AAAA,MACF;AAGA,UAAI,EAAE,WAAW,2BAA2B,EAAE,WAAW,sBAAsB;AAC7E,cAAM,WAAW,0BAA0B,GAAG;AAC9C,YAAI,aAAa,KAAK;AACpB,gBAAM,cAAc,QAAQ,EAAE,MAAM,IAAI,QAAQ;AAChD,gBAAM,eAAe,OAAO,IAAI,WAAW;AAC3C,cAAI,cAAc;AAChB,yBAAa;AACb,gBAAI,CAAC,aAAa,OAAO,IAAK,cAAa,MAAM;AACjD,gBAAIF,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,aAAa,QAAQ,GAAG;AACtF,2BAAa,WAAW,EAAE;AAAA,YAC5B;AACA;AAAA,UACF;AACA,iBAAO,IAAI,aAAa,EAAE,MAAM,KAAK,UAAU,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC;AAC1E;AAAA,QACF;AAAA,MACF;AAGA,YAAM,WAAW,OAAO,IAAI,GAAG;AAC/B,UAAI,UAAU;AACZ,iBAAS;AACT,YAAI,CAAC,SAAS,OAAO,IAAK,UAAS,MAAM;AACzC,YAAIA,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,SAAS,QAAQ,GAAG;AAClF,mBAAS,WAAW,EAAE;AAAA,QACxB;AAAA,MACF,OAAO;AACL,eAAO,IAAI,KAAK,EAAE,MAAM,KAAK,UAAU,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC;AAAA,MACpE;AAAA,IACF;AAGA,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,SAAS,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;AACrC,YAAM,SAAS,OAAO,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,KAAK,OAAO,SAAS,IAAI,aAAa;AACjF,aAAO,IAAI,UAAU,EAAE,MAAM,EAAE,sBAAsB,OAAO,QAAQ,MAAM,GAAG,UAAU,YAAY,OAAO,GAAG,KAAK,MAAM,CAAC;AAAA,IAC3H;AAGA,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,SAAS,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC;AACnC,YAAM,aAAa,OAAO,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,KAAK,OAAO,SAAS,IAAI,aAAa;AACrF,YAAM,WAAW,QAAQ,UAAU,OAC/B,gBAAgB,OAAO,MAAM,oCAAoC,UAAU,gGAC3E,OAAO,OAAO,MAAM,8BAA8B,UAAU;AAChE,aAAO,IAAI,WAAW,EAAE,MAAM,SAAS,UAAU,aAAa,OAAO,GAAG,KAAK,OAAO,CAAC;AAAA,IACvF;AAGA,eAAW,CAAC,KAAK,GAAG,KAAK,QAAQ;AAC/B,WAAK,IAAI,WAAW,OAAO,KAAK,IAAI,WAAW,OAAO,MAAM,IAAI,QAAQ,GAAG;AACzE,YAAI,QAAQ,WAAW,EAAE,kBAAkB,IAAI,KAAK,CAAC;AACrD,YAAI,QAAQ;AAAA,MACd;AAAA,IACF;AAEA,UAAM,aAAa,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM;AACrD,YAAM,UAAUA,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,EAAE,QAAQ;AACtF,UAAI,YAAY,EAAG,QAAO;AAC1B,aAAO,EAAE,QAAQ,EAAE;AAAA,IACrB,CAAC;AAED,UAAM,YAAY,CAAC,MAAiF;AAClG,YAAM,MAAM,EAAE,SAAS,YAAY;AACnC,YAAM,aAAa,EAAE,QAAQ,IAAI,aAAa,EAAE,KAAK,MAAM;AAC3D,YAAM,WAAW,EAAE,MAAM,QAAQ,EAAE,GAAG,IAAI;AAC1C,YAAM,WAAW,WAAW,aAAa,IAAI,QAAQ,CAAC,yEAAyE;AAC/H,aAAO,gCAAgC,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,QAAQ,CAAC,WAAW,IAAI,EAAE,IAAI,CAAC,GAAG,UAAU,GAAG,QAAQ;AAAA,IACnH;AAEA,UAAM,QAAQ;AACd,UAAM,WAAW,WAAW,MAAM,GAAG,KAAK,EAAE,IAAI,SAAS,EAAE,KAAK,IAAI;AACpE,UAAM,YAAY,WAAW,MAAM,KAAK;AACxC,UAAM,WAAW,UAAU,SAAS,IAChC;AAAA,oBAAuB,EAAE,cAAc,UAAU,MAAM,CAAC;AAAA,EAAe,UAAU,IAAI,SAAS,EAAE,KAAK,IAAI,CAAC;AAAA,cAC1G;AAEJ,eAAW;AAAA;AAAA,gEAEiD,IAAI,EAAE,eAAe,CAAC,KAAK,WAAW,MAAM,IAAI,IAAI,EAAE,MAAM,CAAC;AAAA;AAAA,gBAE7G,QAAQ,GAAG,QAAQ;AAAA;AAAA;AAAA,EAGjC;AAGA,QAAM,eAAe,QAAQ,gBAAgB,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAqCrC;AAEZ,SAAO;AAAA,cACK,QAAQ;AAAA;AAAA;AAAA;AAAA,SAIb,IAAI,EAAE,mBAAmB,CAAC,YAAY,IAAI,IAAI,CAAC;AAAA,SAC/C,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMM,IAAI,EAAE,mBAAmB,CAAC;AAAA,sBAC9B,IAAI,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,4CAKpG,WAAW,KAAK,CAAC,KAAK,KAAK;AAAA,+BACxC,IAAI,EAAE,aAAa,CAAC;AAAA;AAAA;AAAA,mEAGgB,QAAQ,QAAQ,iCAAiC,IAAI,EAAE,QAAQ,CAAC;AAAA,+DACpE,QAAQ,IAAI,iCAAiC,IAAI,EAAE,IAAI,CAAC;AAAA,iEACtD,QAAQ,MAAM,iCAAiC,IAAI,EAAE,MAAM,CAAC;AAAA,8DAC/D,QAAQ,GAAG,iCAAiC,IAAI,EAAE,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAMrF,IAAI,EAAE,oBAAoB,CAAC;AAAA,qCACrB,WAAW,OAAO,CAAC;AAAA;AAAA;AAAA,+BAGzB,IAAI,EAAE,gBAAgB,CAAC;AAAA,MAChD,SAAS,iBAAiB,EAAE,eAAe,CAAC;AAAA;AAAA;AAAA;AAAA,EAIhD,SAAS;AAAA;AAAA,EAET,QAAQ;AAAA;AAAA,EAER,yBAAyB,SAAS,IAAI,CAAC;AAAA;AAAA;AAAA,QAGjC,IAAI,EAAE,cAAc,CAAC;AAAA;AAAA,qBAER,IAAI,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,SAAS,CAAC,YAAY,IAAI,EAAE,QAAQ,CAAC,YAAY,IAAI,EAAE,MAAM,CAAC;AAAA,aACrG,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,QAKd,IAAI,EAAE,WAAW,CAAC;AAAA,IACtB,iBAAiB;AAAA,IACjB,YAAY;AAAA;AAAA;AAAA,EAGd,QAAQ;AAAA;AAAA;AAAA,OAGH,IAAI,EAAE,WAAW,CAAC,KAAK,OAAO;AAAA,OAC9B,IAAI,EAAE,iBAAiB,CAAC;AAAA;AAAA;AAAA;AAAA,EAI7B,YAAY;AAAA;AAAA;AAGd;AAMO,SAAS,wBACd,aACA,SACA,MACQ;AACR,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,QAAM,YAAY,QAAQ,UAAU,OAAO,UAAU;AACrD,QAAM,EAAE,WAAW,QAAQ,UAAU,IAAI;AACzC,QAAM,OAAO,UAAU,MAAM,GAAG,EAAE,CAAC;AACnC,QAAM,WAAW,UAAU,QAAQ,KAAK,GAAG,EAAE,QAAQ,WAAW,MAAM;AAGtE,QAAM,UAAU,sBAAsB,WAAW;AAGjD,QAAM,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,QAAQ,SAAS,MAAM;AACnE,QAAM,YAAY,YAAY,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AAClE,QAAM,aAAa,YAAY,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AACpE,QAAM,cAAc,YAAY,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AACtE,QAAM,eAAe,YAAY;AACjC,QAAM,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,gBAAgB,EAAE;AACxE,QAAM,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AACjE,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,gBAAgB,EAAE;AAGrE,MAAI,YAAY;AAChB,MAAI,WAAW,QAAQ,UAAU,GAAG;AAClC,gBAAY;AAAA;AAAA,YAEJ,IAAI,EAAE,UAAU,CAAC;AAAA;AAAA,mCAEM,IAAI,EAAE,kBAAkB,CAAC;AAAA,UAClD,mBAAmB,OAAO,CAAC;AAAA;AAAA;AAAA,mCAGF,IAAI,EAAE,aAAa,CAAC;AAAA,UAC7C,gBAAgB,OAAO,CAAC;AAAA;AAAA;AAAA,EAGhC;AAGA,QAAM,QAAQ,QAAQ,UAAU;AAChC,QAAM,cAAc,CAAC,MAAuB,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK;AAC7E,QAAM,UAAU,CAAC,MAAuB,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK;AAG7E,QAAM,cAAc,oBAAI,IAA+B;AACvD,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,WAAW,iBAAkB;AACnC,UAAM,MAAM,EAAE,KAAK;AACnB,QAAI,CAAC,YAAY,IAAI,GAAG,EAAG,aAAY,IAAI,KAAK,CAAC,CAAC;AAClD,gBAAY,IAAI,GAAG,EAAG,KAAK,CAAC;AAAA,EAC9B;AAGA,QAAM,mBAAmB,qBACtB,IAAI,CAAC,aAAa;AACjB,UAAM,eAAe,EAAE,oBAAoB,QAAQ,KAAK;AACxD,UAAM,aAAa,YAAY,IAAI,QAAQ;AAC3C,QAAI,CAAC,cAAc,WAAW,WAAW,EAAG,QAAO;AAGnD,UAAM,WAAW,WAAW,MAAM,CAAC,MAAM,EAAE,WAAW,gBAAgB;AACtE,QAAI,UAAU;AACZ,aAAO;AAAA;AAAA,mCAEoB,IAAI,YAAY,CAAC;AAAA,+EAC8B,WAAW,MAAM,IAAI,IAAI,EAAE,aAAa,CAAC;AAAA;AAAA;AAAA,mCAGxF,IAAI,EAAE,eAAe,WAAW,MAAM,CAAC,CAAC;AAAA,MACrE,WAAW,IAAI,CAAC,MAAM,yGAA4G,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC,CAAC,mCAAmC,IAAI,EAAE,QAAQ,QAAQ,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,IAG9P;AAGA,UAAM,WAAW,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AAChE,UAAM,YAAY,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AAClE,UAAM,aAAa,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AACpE,UAAM,WAAW,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,gBAAgB,EAAE;AACzE,UAAM,YAAY,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AAElE,UAAM,YAAY;AAAA,MAChB,WAAW,IAAI,+CAAkD,QAAQ,YAAY;AAAA,MACrF,YAAY,IAAI,gDAAmD,SAAS,YAAY;AAAA,MACxF,aAAa,IAAI,yCAAyC,UAAU,YAAY;AAAA,MAChF,WAAW,IAAI,+CAAkD,QAAQ,YAAY;AAAA,MACrF,YAAY,IAAI,gDAAmD,SAAS,YAAY;AAAA,IAC1F,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE;AAGzB,UAAM,aAAa,oBAAI,IAA+B;AACtD,eAAW,KAAK,YAAY;AAC1B,YAAM,MAAM,EAAE,KAAK;AACnB,UAAI,CAAC,WAAW,IAAI,GAAG,EAAG,YAAW,IAAI,KAAK,CAAC,CAAC;AAChD,iBAAW,IAAI,GAAG,EAAG,KAAK,CAAC;AAAA,IAC7B;AAEA,UAAM,gBAAgB,CAAC,GAAG,WAAW,QAAQ,CAAC,EAC3C,IAAI,CAAC,CAAC,aAAa,cAAc,MAAM;AACtC,YAAM,cAAc,YAAY,eAAe,CAAC,CAAC;AAEjD,YAAM,aAAa,eAAe,OAAO,CAAC,MAAM,EAAE,WAAW,gBAAgB;AAC7E,YAAM,gBAAgB,eAAe,OAAO,CAAC,MAAM,EAAE,WAAW,gBAAgB;AAEhF,UAAI,YAAY;AAGhB,iBAAW,KAAK,eAAe;AAC7B,cAAM,OAAO,EAAE,WAAW,UAAU,cAChC,EAAE,WAAW,WAAW,cACxB,EAAE,WAAW,YAAY,WACzB,EAAE,WAAW,WAAW,cACxB;AACJ,cAAM,MAAM,SAAS,EAAE,WAAW,mBAAmB,UAAU,EAAE,MAAM;AACvE,cAAM,SAAS,EAAE,WAAW,YAAY,WAAW,IAAI,EAAE,UAAU,CAAC,KAChE,EAAE,WAAW,WAAW,WAAW,IAAI,EAAE,QAAQ,YAAY,EAAE,YAAY,CAAC,KAC5E;AAEJ,YAAI,iBAAiB;AACrB,YAAI,EAAE,WAAW,SAAS;AACxB,2BAAiB,6BAA6B,IAAI,EAAE,eAAe,CAAC;AAAA,QACtE,WAAW,EAAE,WAAW,YAAY,EAAE,gBAAgB,SAAS,GAAG;AAChE,gBAAM,SAAS,EAAE,gBACd,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,OAAO,IAAI,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE,KAAK,CAAC,OAAO;AAC5D,cAAI,EAAE,gBAAgB,SAAS,GAAG;AAChC,mBAAO,KAAK,OAAO,IAAI,EAAE,QAAQ,EAAE,gBAAgB,SAAS,CAAC,CAAC,CAAC,OAAO;AAAA,UACxE;AACA,gBAAM,kBAAkB,EAAE,gBAAgB,CAAC,GAAG,mBAAmB,CAAC,IAC9D,0DAA0D,IAAI,EAAE,WAAW,CAAC,SAAS,aAAa,EAAE,gBAAgB,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,SAC3I;AACJ,2BAAiB,sDAAsD,IAAI,EAAE,iBAAiB,EAAE,gBAAgB,MAAM,CAAC,CAAC,wCAAwC,OAAO,KAAK,EAAE,CAAC,QAAQ,eAAe;AAAA,QACxM;AAEA,cAAM,UAAU,QAAQ,CAAC;AACzB,qBAAa,0BAA0B,GAAG,8BAA8B,IAAI,mCAAmC,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC,GAAG,QAAQ,SAAS,KAAK,WAAW,EAAE,GAAG,MAAM;AAAA,EAAkB,cAAc;AAAA,MAC3O;AAGA,UAAI,WAAW,SAAS,GAAG;AACzB,mBAAW,KAAK,YAAY;AAC1B,gBAAM,UAAU,QAAQ,CAAC;AACzB,uBAAa,yGAA4G,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC,GAAG,QAAQ,SAAS,KAAK,WAAW,EAAE,mCAAmC,IAAI,EAAE,aAAa,CAAC;AAAA;AAAA,QACnQ;AAAA,MACF;AAEA,YAAM,WAAW,eAAe,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AACpE,YAAM,YAAY,eAAe,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AACtE,YAAM,aAAa,eAAe,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AACxE,YAAM,WAAW,eAAe,OAAO,CAAC,MAAM,EAAE,WAAW,gBAAgB,EAAE;AAC7E,YAAM,YAAY,eAAe,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AAEtE,YAAM,WAAW;AAAA,QACf,WAAW,IAAI,+CAAkD,QAAQ,YAAY;AAAA,QACrF,YAAY,IAAI,gDAAmD,SAAS,YAAY;AAAA,QACxF,aAAa,IAAI,yCAAyC,UAAU,YAAY;AAAA,QAChF,WAAW,IAAI,+CAAkD,QAAQ,YAAY;AAAA,QACrF,YAAY,IAAI,gDAAmD,SAAS,YAAY;AAAA,MAC1F,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAG1B,YAAM,cAAc,YAAY;AAChC,aAAO,uCAAuC,cAAc,UAAU,EAAE,iBAAiB,IAAI,WAAW,CAAC,iCAAiC,QAAQ;AAAA,EAA2B,SAAS;AAAA;AAAA,IACxL,CAAC,EACA,KAAK,IAAI;AAEZ,WAAO;AAAA;AAAA,mCAEsB,IAAI,YAAY,CAAC;AAAA,mCACjB,SAAS;AAAA;AAAA,+BAEb,aAAa;AAAA;AAAA,EAExC,CAAC,EACA,OAAO,OAAO,EACd,KAAK,IAAI;AAGZ,QAAM,gBAAgB,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ;AACjE,MAAI,kBAAkB;AACtB,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,aAAa,oBAAI,IAA+E;AACtG,UAAM,gBAA0B,CAAC;AACjC,QAAI,iBAA2B;AAC/B,QAAI;AACJ,UAAM,cAAwB,CAAC;AAC/B,QAAI,kBAA4B;AAChC,QAAI;AACJ,UAAM,sBAAsB,CAAC,kBAAkB,iBAAiB,sBAAsB,uBAAuB;AAE7G,eAAW,KAAK,eAAe;AAC7B,iBAAW,KAAK,EAAE,iBAAiB;AACjC,cAAM,MAAM,EAAE,iBAAiB,CAAC,KAAK;AACrC,cAAM,MAAM,EAAE,iBAAiB,KAAK,CAAC,MAAM,EAAE,WAAW,gBAAgB,CAAC,GAAG,QAAQ,mBAAmB,EAAE;AAGzG,YAAI,oBAAoB,KAAK,OAAK,IAAI,WAAW,CAAC,CAAC,EAAG;AAGtD,cAAM,UAAU,EAAE,MAAM,MAAM,OAAO;AACrC,YAAI,YAAY,EAAE,WAAW,2BAA2B,EAAE,WAAW,uBAAuB;AAC1F,wBAAc,KAAK,QAAQ,CAAC,CAAC;AAC7B,cAAIA,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,cAAc,EAAG,kBAAiB,EAAE;AACpG,cAAI,CAAC,aAAa,IAAK,aAAY;AACnC;AAAA,QACF;AAGA,cAAM,WAAW,EAAE,MAAM,MAAM,YAAY;AAC3C,YAAI,UAAU;AACZ,sBAAY,KAAK,SAAS,CAAC,CAAC;AAC5B,cAAIA,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,eAAe,EAAG,mBAAkB,EAAE;AACtG,cAAI,CAAC,cAAc,IAAK,cAAa;AACrC;AAAA,QACF;AAGA,YAAI,EAAE,WAAW,yBAAyB;AACxC,gBAAM,eAAe,EAAE,MAAM,MAAM,6BAA6B;AAChE,cAAI,cAAc;AAChB,kBAAM,YAAY,aAAa,CAAC;AAChC,kBAAM,MAAM,QAAQ,SAAS;AAC7B,kBAAME,YAAW,WAAW,IAAI,GAAG;AACnC,gBAAIA,WAAU;AACZ,cAAAA,UAAS;AACT,kBAAI,CAACA,UAAS,OAAO,IAAK,CAAAA,UAAS,MAAM;AACzC,kBAAIF,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQE,UAAS,QAAQ,EAAG,CAAAA,UAAS,WAAW,EAAE;AAAA,YAC5G,OAAO;AACL,yBAAW,IAAI,KAAK,EAAE,MAAM,IAAI,SAAS,KAAK,GAAG,IAAI,UAAU,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC;AAAA,YAC5F;AACA;AAAA,UACF;AAAA,QACF;AAGA,YAAI,EAAE,WAAW,2BAA2B,EAAE,WAAW,sBAAsB;AAC7E,gBAAM,WAAW,0BAA0B,GAAG;AAC9C,cAAI,aAAa,KAAK;AACpB,kBAAM,cAAc,QAAQ,EAAE,MAAM,IAAI,QAAQ;AAChD,kBAAM,eAAe,WAAW,IAAI,WAAW;AAC/C,gBAAI,cAAc;AAChB,2BAAa;AACb,kBAAI,CAAC,aAAa,OAAO,IAAK,cAAa,MAAM;AACjD,kBAAIF,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,aAAa,QAAQ,GAAG;AACtF,6BAAa,WAAW,EAAE;AAAA,cAC5B;AACA;AAAA,YACF;AACA,uBAAW,IAAI,aAAa,EAAE,MAAM,KAAK,UAAU,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC;AAC9E;AAAA,UACF;AAAA,QACF;AAEA,cAAM,WAAW,WAAW,IAAI,GAAG;AACnC,YAAI,UAAU;AACZ,mBAAS;AACT,cAAI,CAAC,SAAS,OAAO,IAAK,UAAS,MAAM;AACzC,cAAIA,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,SAAS,QAAQ,GAAG;AAClF,qBAAS,WAAW,EAAE;AAAA,UACxB;AAAA,QACF,OAAO;AACL,qBAAW,IAAI,KAAK,EAAE,MAAM,KAAK,UAAU,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC;AAAA,QACxE;AAAA,MACF;AAAA,IACF;AAGA,QAAI,cAAc,SAAS,GAAG;AAC5B,YAAM,SAAS,CAAC,GAAG,IAAI,IAAI,aAAa,CAAC;AACzC,YAAM,SAAS,OAAO,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,KAAK,OAAO,SAAS,IAAI,aAAa;AACjF,iBAAW,IAAI,UAAU,EAAE,MAAM,EAAE,sBAAsB,OAAO,QAAQ,MAAM,GAAG,UAAU,gBAAgB,OAAO,GAAG,KAAK,UAAU,CAAC;AAAA,IACvI;AAEA,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,SAAS,CAAC,GAAG,IAAI,IAAI,WAAW,CAAC;AACvC,YAAM,aAAa,OAAO,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,KAAK,OAAO,SAAS,IAAI,aAAa;AACrF,YAAM,WAAW,QAAQ,UAAU,OAC/B,gBAAgB,OAAO,MAAM,oCAAoC,UAAU,gGAC3E,OAAO,OAAO,MAAM,8BAA8B,UAAU;AAChE,iBAAW,IAAI,WAAW,EAAE,MAAM,SAAS,UAAU,iBAAiB,OAAO,GAAG,KAAK,WAAW,CAAC;AAAA,IACnG;AAGA,eAAW,CAAC,KAAK,GAAG,KAAK,YAAY;AACnC,WAAK,IAAI,WAAW,OAAO,KAAK,IAAI,WAAW,OAAO,MAAM,IAAI,QAAQ,GAAG;AACzE,YAAI,QAAQ,WAAW,EAAE,kBAAkB,IAAI,KAAK,CAAC;AACrD,YAAI,QAAQ;AAAA,MACd;AAAA,IACF;AAEA,UAAM,iBAAiB,CAAC,GAAG,WAAW,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM;AAC7D,YAAM,UAAUA,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,EAAE,QAAQ;AACtF,UAAI,YAAY,EAAG,QAAO;AAC1B,aAAO,EAAE,QAAQ,EAAE;AAAA,IACrB,CAAC;AAED,QAAI,eAAe,SAAS,GAAG;AAC7B,YAAM,gBAAgB,CAAC,MAAiF;AACtG,cAAM,MAAM,EAAE,SAAS,YAAY;AACnC,cAAM,aAAa,EAAE,QAAQ,IAAI,aAAa,EAAE,KAAK,MAAM;AAC3D,cAAM,WAAW,EAAE,MAAM,QAAQ,EAAE,GAAG,IAAI;AAC1C,cAAM,WAAW,WAAW,aAAa,IAAI,QAAQ,CAAC,yEAAyE;AAC/H,eAAO,gCAAgC,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,QAAQ,CAAC,WAAW,IAAI,EAAE,IAAI,CAAC,GAAG,UAAU,GAAG,QAAQ;AAAA,MACnH;AAEA,YAAM,aAAa;AACnB,YAAM,eAAe,eAAe,MAAM,GAAG,UAAU,EAAE,IAAI,aAAa,EAAE,KAAK,IAAI;AACrF,YAAM,gBAAgB,eAAe,MAAM,UAAU;AACrD,YAAM,eAAe,cAAc,SAAS,IACxC;AAAA,oBAAuB,IAAI,EAAE,cAAc,cAAc,MAAM,CAAC,CAAC;AAAA,EAAuB,cAAc,IAAI,aAAa,EAAE,KAAK,IAAI,CAAC;AAAA,cACnI;AAEJ,wBAAkB;AAAA;AAAA,kEAE0C,IAAI,EAAE,iBAAiB,eAAe,MAAM,CAAC,CAAC;AAAA;AAAA,kBAE9F,YAAY,GAAG,YAAY;AAAA;AAAA;AAAA,IAGzC;AAAA,EACF;AAGA,QAAM,SAAS,UAAU,IACrB,2DAA2D,IAAI,EAAE,OAAO,OAAO,CAAC,CAAC,SACjF;AAEJ,QAAM,cACJ,cAAc,IACV,4DAA4D,IAAI,EAAE,YAAY,WAAW,CAAC,CAAC,WAC3F;AAEN,QAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBhB,SAAO;AAAA,cACK,QAAQ;AAAA;AAAA;AAAA;AAAA,SAIb,IAAI,EAAE,SAAS,CAAC,YAAY,IAAI,IAAI,CAAC;AAAA,SACrC,UAAU,CAAC,GAAG,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMJ,IAAI,EAAE,SAAS,CAAC;AAAA,4BACd,IAAI,EAAE,cAAc,CAAC;AAAA,sBAC3B,IAAI,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,kCAK/F,SAAS,sDAAsD,IAAI,EAAE,QAAQ,CAAC;AAAA;AAAA,kCAE9E,UAAU,sDAAsD,IAAI,EAAE,WAAW,CAAC;AAAA;AAAA;AAAA,mFAGjC,YAAY,iCAAiC,IAAI,EAAE,YAAY,CAAC;AAAA,mFAChE,UAAU,2CAA8C,IAAI,EAAE,aAAa,CAAC;AAAA,mFAC5E,WAAW,2CAA8C,IAAI,EAAE,YAAY,CAAC;AAAA,MACzJ,UAAU,IAAI,gFAAgF,OAAO,wCAAwC,IAAI,EAAE,aAAa,CAAC,iBAAiB,EAAE;AAAA;AAAA;AAAA,EAGxL,WAAW;AAAA;AAAA,EAEX,SAAS;AAAA;AAAA,EAET,yBAAyB,YAAY,SAAS,IAAI,CAAC;AAAA;AAAA,EAEnD,gBAAgB;AAAA;AAAA,EAEhB,eAAe;AAAA;AAAA,EAEf,MAAM;AAAA;AAAA;AAAA,OAGD,IAAI,EAAE,oBAAoB,OAAO,CAAC,CAAC;AAAA,OACnC,IAAI,EAAE,oBAAoB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAMlC;;;AC18CA,SAASG,KAAI,GAAmB;AAC9B,SAAO,EACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,OAAO;AAC1B;AAEA,SAASC,SAAQ,KAA4B;AAC3C,MAAI;AACF,UAAM,IAAI,IAAI,IAAI,GAAG;AACrB,QAAI,EAAE,aAAa,YAAY,EAAE,aAAa,QAAS,QAAO;AAC9D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,cAAa,GAAmB;AACvC,QAAM,QAAQ,EAAE,MAAM,kBAAkB;AACxC,SAAO,MACJ,IAAI,CAAC,MAAM,MAAM;AAChB,QAAI,IAAI,MAAM,GAAG;AACf,YAAM,OAAOD,SAAQ,IAAI;AACzB,UAAI,MAAM;AACR,eAAO,YAAYD,KAAI,IAAI,CAAC,0DAA0DA,KAAI,IAAI,CAAC;AAAA,MACjG;AACA,aAAOA,KAAI,IAAI;AAAA,IACjB;AACA,WAAOA,KAAI,IAAI;AAAA,EACjB,CAAC,EACA,KAAK,EAAE;AACZ;AAEA,IAAMG,kBAA6B,CAAC,YAAY,QAAQ,UAAU,KAAK;AAYvE,IAAM,cAA2B;AAAA,EAC/B;AAAA,IACE,IAAI;AAAA,IACJ,aAAa,CAAC,wBAAwB,gBAAgB,wBAAwB,cAAc;AAAA,IAC5F,YAAY,CAAC,WAAW,UAAU,YAAY,QAAQ,OAAO,YAAY,OAAO,eAAe;AAAA,EACjG;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa,CAAC,2BAA2B;AAAA,IACzC,YAAY,CAAC,iBAAiB,SAAS,OAAO,aAAa,UAAU;AAAA,EACvE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa,CAAC,4BAA4B,iBAAiB;AAAA,IAC3D,YAAY,CAAC,OAAO,UAAU,aAAa,cAAc,YAAY,OAAO,cAAc;AAAA,EAC5F;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa,CAAC,mBAAmB,oBAAoB;AAAA,IACrD,YAAY,CAAC,OAAO,OAAO,eAAe,QAAQ,UAAU;AAAA,EAC9D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa,CAAC,mBAAmB;AAAA,IACjC,YAAY,CAAC;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa,CAAC;AAAA,IACd,YAAY,CAAC;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa,CAAC;AAAA,IACd,YAAY,CAAC;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa,CAAC;AAAA,IACd,YAAY,CAAC;AAAA,EACf;AACF;AAMA,SAAS,QAAgB;AACvB,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgFT;AAMO,SAAS,4BACd,aACA,MACQ;AACR,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,QAAM,YAAY,QAAQ,UAAU,OAAO,UAAU;AACrD,QAAM,EAAE,WAAW,QAAQ,UAAU,IAAI;AACzC,QAAM,OAAO,UAAU,MAAM,GAAG,EAAE,CAAC;AACnC,QAAM,WAAW,UAAU,QAAQ,KAAK,GAAG,EAAE,QAAQ,WAAW,MAAM;AAGtE,QAAM,YAAY,oBAAI,IAAuB;AAC7C,aAAW,OAAO,YAAY,SAAS;AACrC,UAAM,WAAW,IAAI,SAAS,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,UAAU,IAAI,OAAO,EAAE;AACnF,cAAU,IAAI,IAAI,QAAQ,QAAQ;AAAA,EACpC;AAGA,QAAM,qBAAqB,oBAAI,IAAY;AAE3C,WAAS,aAAa,GAAoB;AACxC,WAAO,GAAG,EAAE,KAAK,IAAI,EAAE,UAAU,IAAI,EAAE,WAAW;AAAA,EACpD;AAWA,QAAM,iBAAkC,CAAC;AAEzC,aAAW,WAAW,aAAa;AACjC,UAAM,WAAsB,CAAC;AAG7B,eAAW,OAAO,QAAQ,aAAa;AACrC,UAAI,QAAQ,wBAAyB;AACrC,YAAM,cAAc,UAAU,IAAI,GAAG,KAAK,CAAC;AAC3C,eAAS,KAAK,GAAG,WAAW;AAAA,IAC9B;AAGA,QAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,YAAM,aAAa,UAAU,IAAI,uBAAuB,KAAK,CAAC;AAC9D,iBAAW,KAAK,YAAY;AAC1B,cAAM,MAAM,aAAa,CAAC;AAC1B,YAAI,mBAAmB,IAAI,GAAG,EAAG;AACjC,cAAM,aAAa,GAAG,EAAE,KAAK,IAAI,EAAE,WAAW,IAAI,EAAE,MAAM,GAAG,YAAY;AACzE,YAAI,QAAQ,WAAW,KAAK,CAAC,OAAO,WAAW,SAAS,EAAE,CAAC,GAAG;AAC5D,mBAAS,KAAK,CAAC;AACf,6BAAmB,IAAI,GAAG;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,iBAAiB,QAAQ,YAAY,SAAS,KAAK,QAAQ,WAAW,SAAS;AAGrF,UAAM,iBAAiB,mBACrB,QAAQ,YAAY,KAAK,CAAC,MAAM,UAAU,IAAI,CAAC,CAAC,KAC/C,QAAQ,WAAW,SAAS,KAAK,UAAU,IAAI,uBAAuB;AAIzE,UAAM,cAAc,EAAE,cAAc,QAAQ,EAAE,KAAK,CAAC;AAEpD,mBAAe,KAAK;AAAA,MAClB,IAAI,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,gBAAgB,eAAe,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,SAAS,QAAQ,CAAC;AAClF,QAAM,kBAAkB,eAAe,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,YAAY,SAAS,CAAC,EAAE;AACnG,QAAM,eAAe,eAAe,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE;AACpE,QAAM,mBAAmB,eAAe,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,YAAY,QAAQ,CAAC;AASxF,WAAS,cAAc,UAAqC;AAC1D,UAAM,SAAS,oBAAI,IAAuB;AAC1C,UAAM,cAAc,oBAAI,IAAoB;AAE5C,eAAW,KAAK,UAAU;AACxB,YAAM,WAAW,EAAE,MAAM,MAAM,gBAAgB;AAC/C,UAAI,UAAU;AACZ,cAAMC,OAAM,OAAO,SAAS,CAAC,EAAE,YAAY,CAAC;AAC5C,YAAI,CAAC,OAAO,IAAIA,IAAG,GAAG;AACpB,iBAAO,IAAIA,MAAK,CAAC,CAAC;AAClB,sBAAY,IAAIA,MAAK,EAAE,KAAK;AAAA,QAC9B;AACA,eAAO,IAAIA,IAAG,EAAG,KAAK,CAAC;AACvB;AAAA,MACF;AACA,YAAM,eAAe,EAAE,MAAM,MAAM,aAAa;AAChD,UAAI,cAAc;AAChB,cAAMA,OAAM,QAAQ,aAAa,CAAC,CAAC;AACnC,YAAI,CAAC,OAAO,IAAIA,IAAG,GAAG;AACpB,iBAAO,IAAIA,MAAK,CAAC,CAAC;AAClB,sBAAY,IAAIA,MAAK,EAAE,KAAK;AAAA,QAC9B;AACA,eAAO,IAAIA,IAAG,EAAG,KAAK,CAAC;AACvB;AAAA,MACF;AACA,YAAM,MAAM,SAAS,EAAE,KAAK;AAC5B,UAAI,CAAC,OAAO,IAAI,GAAG,GAAG;AACpB,eAAO,IAAI,KAAK,CAAC,CAAC;AAClB,oBAAY,IAAI,KAAK,EAAE,KAAK;AAAA,MAC9B;AACA,aAAO,IAAI,GAAG,EAAG,KAAK,CAAC;AAAA,IACzB;AAEA,UAAM,SAAyB,CAAC;AAChC,eAAW,CAAC,KAAK,SAAS,KAAK,QAAQ;AACrC,UAAI,kBAA4B;AAChC,iBAAW,KAAK,WAAW;AACzB,YAAID,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,eAAe,GAAG;AAChF,4BAAkB,EAAE;AAAA,QACtB;AAAA,MACF;AACA,aAAO,KAAK,EAAE,OAAO,YAAY,IAAI,GAAG,GAAI,UAAU,WAAW,gBAAgB,CAAC;AAAA,IACpF;AACA,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,CAAC,UAAgC;AACnD,UAAM,MAAM,MAAM,gBAAgB,YAAY;AAC9C,UAAM,QAAQ,MAAM,SAAS;AAC7B,UAAM,QAAQ,MAAM,SAAS,CAAC;AAC9B,UAAM,gBAAgB,MAAM,SACzB,IAAI,CAAC,MAAM,iCAAiCH,KAAI,EAAE,UAAU,CAAC,YAAYA,KAAI,EAAE,WAAW,CAAC,QAAQ,EACnG,KAAK,IAAI;AACZ,UAAM,mBAAmB,MAAM,iBAC5B,IAAI,CAAC,MAAM,OAAOE,cAAa,CAAC,CAAC,OAAO,EACxC,KAAK,EAAE;AACV,WAAO;AAAA;AAAA,+BAEoBF,KAAI,GAAG,CAAC,KAAKA,KAAI,MAAM,eAAe,CAAC;AAAA,qCACjCA,KAAI,MAAM,KAAK,CAAC;AAAA,4CACT,KAAK;AAAA;AAAA;AAAA,eAGlC,EAAE,oBAAoB,KAAK,CAAC;AAAA;AAAA,QAEnC,aAAa;AAAA;AAAA;AAAA,gBAGLA,KAAI,EAAE,aAAa,CAAC;AAAA,YACxB,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAI1B;AAGA,QAAM,eAAe,eAClB,IAAI,CAAC,YAAY;AAChB,UAAM,OAAO,EAAE,eAAe,QAAQ,EAAE;AACxC,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,cAAc,KAAK;AACzB,UAAM,cAAc,KAAK,QAAQ;AAGjC,UAAM,aAAuB,CAAC;AAC9B,QAAI,QAAQ,SAAS,SAAS,GAAG;AAE/B,YAAM,YAAoC,CAAC;AAC3C,iBAAW,KAAK,QAAQ,UAAU;AAChC,kBAAU,EAAE,QAAQ,KAAK,UAAU,EAAE,QAAQ,KAAK,KAAK;AAAA,MACzD;AACA,iBAAW,OAAOG,iBAAgB;AAChC,YAAI,UAAU,GAAG,GAAG;AAClB,qBAAW;AAAA,YACT,4BAA4B,IAAI,YAAY,CAAC,KAAK,UAAU,GAAG,CAAC,IAAI,GAAG;AAAA,UACzE;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,QAAQ,gBAAgB;AACjC,iBAAW,KAAK,uDAAuDH,KAAI,EAAE,OAAO,CAAC,SAAS;AAAA,IAChG;AACA,QAAI,QAAQ,YAAY,SAAS,GAAG;AAClC,iBAAW,KAAK,sDAAsDA,KAAI,EAAE,cAAc,QAAQ,YAAY,MAAM,CAAC,CAAC,SAAS;AAAA,IACjI;AAGA,QAAI;AACJ,QAAI,CAAC,QAAQ,gBAAgB;AAC3B,iBAAW,mCAAmCA,KAAI,EAAE,aAAa,CAAC;AAAA,IACpE,WAAW,CAAC,QAAQ,gBAAgB;AAClC,iBAAW,mCAAmCA,KAAI,EAAE,aAAa,CAAC;AAAA,IACpE,WAAW,QAAQ,SAAS,WAAW,GAAG;AACxC,iBAAW,kCAAkCA,KAAI,EAAE,OAAO,CAAC;AAAA,IAC7D,OAAO;AAEL,YAAM,SAAS,CAAC,GAAG,QAAQ,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM;AAClD,cAAM,UAAUG,gBAAe,QAAQ,EAAE,QAAQ,IAAIA,gBAAe,QAAQ,EAAE,QAAQ;AACtF,YAAI,YAAY,EAAG,QAAO;AAC1B,eAAO,EAAE,YAAY,EAAE;AAAA,MACzB,CAAC;AACD,YAAM,SAAS,cAAc,MAAM;AACnC,iBAAW,OAAO,IAAI,WAAW,EAAE,KAAK,IAAI;AAAA,IAC9C;AAGA,QAAI,aAAa;AACjB,QAAI,QAAQ,YAAY,SAAS,GAAG;AAClC,YAAM,QAAQ,QAAQ,YACnB,IAAI,CAAC,SAAS,8EAA8EH,KAAI,IAAI,CAAC,QAAQ,EAC7G,KAAK,IAAI;AACZ,mBAAa;AAAA;AAAA,0BAEKA,KAAI,EAAE,aAAa,CAAC;AAAA,YAClC,KAAK;AAAA;AAAA,IAEX;AAEA,WAAO;AAAA;AAAA,oCAEuBA,KAAI,WAAW,CAAC;AAAA,qCACfA,KAAI,WAAW,CAAC;AAAA,qCAChB,WAAW,KAAK,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA,sBAInCA,KAAI,EAAE,WAAW,CAAC;AAAA,QAChC,QAAQ;AAAA;AAAA,MAEV,UAAU;AAAA;AAAA;AAAA,EAGZ,CAAC,EACA,OAAO,OAAO,EACd,KAAK,IAAI;AAGZ,QAAM,gBAAgB,kBAAkB,IAAI,YAAY,iBAAiB,IAAI,YAAY;AAEzF,SAAO;AAAA,cACK,QAAQ;AAAA;AAAA;AAAA;AAAA,SAIbA,KAAI,EAAE,aAAa,CAAC,YAAYA,KAAI,IAAI,CAAC;AAAA,SACzC,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMUA,KAAI,EAAE,aAAa,CAAC;AAAA,sBACxBA,KAAI,EAAE,OAAO,CAAC,KAAKA,KAAI,SAAS,CAAC,MAAMA,KAAI,EAAE,MAAM,CAAC,KAAKA,KAAI,MAAM,CAAC,MAAMA,KAAI,EAAE,QAAQ,CAAC,KAAKA,KAAI,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA,mEAI9D,aAAa,KAAK,aAAa,iCAAiCA,KAAI,EAAE,eAAe,CAAC;AAAA,4EAC7E,eAAe,iCAAiCA,KAAI,EAAE,iBAAiB,CAAC;AAAA,4EACxE,YAAY,iCAAiCA,KAAI,EAAE,cAAc,CAAC;AAAA,4EAClE,gBAAgB,iCAAiCA,KAAI,EAAE,eAAe,CAAC;AAAA;AAAA;AAAA,EAGjJ,YAAY;AAAA;AAAA;AAAA,OAGPA,KAAI,EAAE,WAAW,CAAC,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOrC;;;AC1dA,SAAS,eAAe,cAAc,WAAW,kBAAkB;AACnE,SAAS,YAAY;AACrB,SAAS,eAAe;AAQjB,SAAS,eAAe,SAA4C;AACzE,QAAM,MACJ,MACA,QAAQ,WAAW,KACnB,QAAQ,OAAO,IACf,QAAQ,SAAS,IACjB,QAAQ,MAAM;AAChB,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC;AACvC;AAEO,SAAS,YACd,aACA,WACQ;AACR,QAAM,UAAU,aAAa,KAAK,QAAQ,GAAG,eAAe;AAC5D,QAAM,QAAQ,YAAY,UAAU,MAAM,GAAG,EAAE;AAG/C,QAAM,UAAU,KAAK,SAAS,SAAS,KAAK;AAC5C,QAAM,eAAe,KAAK,SAAS,WAAW;AAC9C,YAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACtC,YAAU,cAAc,EAAE,WAAW,KAAK,CAAC;AAG3C,gBAAc,KAAK,SAAS,WAAW,GAAG,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAG9E,QAAM,WAAW,KAAK,cAAc,WAAW;AAC/C,MAAI,WAAiC;AACrC,MAAI,WAAW,QAAQ,GAAG;AACxB,QAAI;AACF,iBAAW,KAAK,MAAM,aAAa,UAAU,OAAO,CAAC;AAAA,IACvD,QAAQ;AAEN,iBAAW;AAAA,IACb;AAAA,EACF;AAGA,QAAM,eAAsC;AAAA,IAC1C,MAAM;AAAA,IACN,OAAO,eAAe,YAAY,OAAO;AAAA,IACzC,UAAU,YAAY,QAAQ;AAAA,IAC9B,MAAM,YAAY,QAAQ;AAAA,IAC1B,QAAQ,YAAY,QAAQ;AAAA,IAC5B,KAAK,YAAY,QAAQ;AAAA,IACzB,eAAe,YAAY,QAAQ;AAAA,EACrC;AAGA,MAAI,UAAU,UAAU,WAAW,CAAC;AACpC,QAAM,MAAM,QAAQ,UAAU,CAAC,MAAM,EAAE,SAAS,KAAK;AACrD,MAAI,OAAO,GAAG;AACZ,YAAQ,GAAG,IAAI;AAAA,EACjB,OAAO;AACL,YAAQ,KAAK,YAAY;AAAA,EAC3B;AAEA,YAAU,QAAQ,MAAM,GAAG;AAG3B,QAAM,gBAA+B;AAAA,IACnC,UAAU;AAAA,MACR,WAAW,YAAY;AAAA,MACvB,SAAS,YAAY;AAAA,MACrB,QAAQ,YAAY;AAAA,MACpB,WAAW,YAAY;AAAA,MACvB,SAAS,YAAY;AAAA,MACrB,SAAS,YAAY,QAAQ,IAAI,CAAC,OAAO;AAAA,QACvC,QAAQ,EAAE;AAAA,QACV,eAAe,EAAE;AAAA,QACjB,QAAQ,EAAE;AAAA,MACZ,EAAE;AAAA,MACF,UAAU,YAAY,QAAQ;AAAA,QAAQ,CAAC,MACrC,EAAE,SAAS,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,OAAO,EAAE;AAAA,MACpD;AAAA,IACF;AAAA,IACA;AAAA,IACA,MAAM;AAAA,MACJ,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,SAAS;AAAA,MACT,mBAAmB;AAAA,IACrB;AAAA,EACF;AAEA,gBAAc,UAAU,KAAK,UAAU,eAAe,MAAM,CAAC,CAAC;AAC9D,SAAO;AACT;;;ACtFA,IAAMK,kBAAyC;AAAA,EAC7C,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,UAAU;AACZ;AAEO,SAAS,oBACd,YACA,UACA,QACiC;AACjC,MAAI,SAAS;AAGb,MAAI,OAAO,aAAa;AACtB,UAAM,WAAWA,gBAAe,OAAO,YAAY,YAAY,CAAC,KAAK;AACrE,aAAS,OAAO,OAAO,CAAC,OAAOA,gBAAe,EAAE,QAAQ,KAAK,MAAM,QAAQ;AAAA,EAC7E;AAGA,MAAI,eAAe,2BAA2B,OAAO,uBAAuB,QAAQ;AAClF,UAAM,WAAW,OAAO;AACxB,aAAS,OAAO;AAAA,MAAO,CAAC,MACtB,SAAS,KAAK,CAAC,OAAO;AACpB,cAAM,QAAQ,GAAG,YAAY;AAC7B,eACE,EAAE,MAAM,YAAY,EAAE,SAAS,KAAK,KACpC,EAAE,YAAY,YAAY,EAAE,SAAS,KAAK,KAC1C,EAAE,OAAO,YAAY,EAAE,SAAS,KAAK;AAAA,MAEzC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,eAAe,wBAAwB,OAAO,gBAAgB,QAAQ;AACxE,UAAM,WAAW,OAAO;AACxB,aAAS,OAAO;AAAA,MAAO,CAAC,MACtB,SAAS,KAAK,CAAC,WAAW,EAAE,OAAO,SAAS,MAAM,CAAC;AAAA,IACrD;AAAA,EACF;AAEA,MAAI,eAAe,wBAAwB,OAAO,gBAAgB,QAAQ;AACxE,UAAM,QAAQ,OAAO;AACrB,aAAS,OAAO;AAAA,MAAO,CAAC,MACtB,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS,CAAC,CAAC;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,cAMR;AAAA,EACH,gBAAgB;AAAA,IACd,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,qBAAqB,mBAAmB,mBAAmB,gBAAgB,wBAAwB,4BAA4B,kBAAkB,qBAAqB,yBAAyB,sBAAsB,sBAAsB,4BAA4B,yBAAyB,4BAA4B,6BAA6B,sBAAsB,cAAc;AAAA,IACvY,YAAY;AAAA,EACd;AAAA,EACA,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,qBAAqB,wBAAwB,gBAAgB,wBAAwB,mBAAmB,gBAAgB,sBAAsB,mBAAmB,4BAA4B,6BAA6B,uBAAuB;AAAA,IAC3P,gBAAgB;AAAA,MACd,uBAAuB,CAAC,WAAW,UAAU,YAAY,QAAQ,OAAO,iBAAiB,SAAS,OAAO,OAAO,UAAU,aAAa,UAAU,cAAc,YAAY,QAAQ,YAAY,OAAO,OAAO,iBAAiB,iBAAiB,OAAO,OAAO,aAAa,aAAa,YAAY,OAAO,OAAO,gBAAgB,OAAO,OAAO,OAAO,OAAO,eAAe,YAAY,cAAc,cAAc,WAAW,SAAS,YAAY;AAAA,MACpb,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,wBAAwB,gBAAgB,wBAAwB,mBAAmB,yBAAyB,4BAA4B,sBAAsB,cAAc;AAAA,IACtL,gBAAgB;AAAA,MACd,uBAAuB,CAAC,WAAW,UAAU,YAAY,MAAM;AAAA,IACjE;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,mBAAmB,uBAAuB;AAAA,IACpD,gBAAgB;AAAA,MACd,uBAAuB,CAAC,cAAc,YAAY;AAAA,IACpD;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,4BAA4B,yBAAyB,0BAA0B;AAAA,IACzF,gBAAgB;AAAA,MACd,uBAAuB,CAAC,OAAO,OAAO,UAAU,WAAW;AAAA,IAC7D;AAAA,EACF;AAAA,EACA,eAAe;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,qBAAqB,uBAAuB;AAAA,IACtD,gBAAgB;AAAA,MACd,uBAAuB,CAAC,WAAW,cAAc,OAAO;AAAA,IAC1D;AAAA,EACF;AAAA,EACA,mBAAmB;AAAA,IACjB,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,qBAAqB,uBAAuB;AAAA,EACxD;AAAA,EACA,gBAAgB;AAAA,IACd,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,kBAAkB,0BAA0B;AAAA,EACxD;AAAA,EACA,gBAAgB;AAAA,IACd,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,gBAAgB;AAAA,EAC5B;AAAA,EACA,sBAAsB;AAAA,IACpB,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,qBAAqB,mBAAmB,4BAA4B,yBAAyB,sBAAsB,4BAA4B,oBAAoB;AAAA,EAC/K;AAAA,EACA,aAAa;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC,yBAAyB,sBAAsB,sBAAsB,4BAA4B,yBAAyB,4BAA4B,2BAA2B;AAAA,EAC7L;AACF;;;AC9IO,IAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwG/B,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AtC/DpC,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,QAAAC,OAAM,eAAe;AAC9B,SAAS,qBAAqB;AAsB9B,IAAM,sBAA8C;AAAA,EAClD,mBACE;AAAA,EACF,iBACE;AAAA,EACF,iBACE;AAAA,EACF,cACE;AAAA,EACF,sBACE;AAAA,EACF,0BACE;AAAA,EACF,sBACE;AAAA,EACF,gBACE;AAAA,EACF,gBACE;AAAA,EACF,mBACE;AAAA,EACF,uBACE;AAAA,EACF,oBACE;AAAA,EACF,oBACE;AAAA,EACF,0BACE;AAAA,EACF,uBACE;AAAA,EACF,0BACE;AAAA,EACF,2BACE;AAAA,EACF,oBACE;AAAA,EACF,cACE;AACJ;AAEA,SAAS,sBAAsB,MAAqB;AAClD,SAAO,QAAQ,QAAQ,IAAI,EAAE;AAC/B;AAIA,IAAMC,gCAA+B;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,qBAAqB,SAAuB,MAAqB;AACxE,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,QAAM,mBAA6F,CAAC;AAEpG,aAAW,OAAO,SAAS;AACzB,UAAM,MAAM,EAAE,uBAAuB,IAAI,MAAM;AAC/C,QAAI,CAAC,IAAK;AACV,QAAI,CAAC,IAAI,UAAU,OAAQ;AAE3B,UAAM,gBAAgB,IAAI,SAAS;AAAA,MAAK,CAAC,MACvCA,8BAA6B,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAAA,IACxD;AACA,QAAI,eAAe;AACjB,uBAAiB,KAAK,GAAG;AAAA,IAC3B;AAAA,EACF;AAEA,MAAI,iBAAiB,WAAW,EAAG,QAAO;AAE1C,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,EAAE;AAAA,IACF;AAAA,EACF;AAEA,aAAW,OAAO,kBAAkB;AAClC,UAAM,KAAK,GAAG,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,EAAE,UAAU,EAAE;AACvD,UAAM,KAAK,MAAM,EAAE,aAAa,KAAK,IAAI,MAAM,EAAE;AACjD,UAAM,KAAK,MAAM,EAAE,aAAa,KAAK,IAAI,MAAM,EAAE;AACjD,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,EAAE,qBAAqB;AAElC,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,gBAAgB,QAAwB,MAAqB;AACpE,QAAM,EAAE,QAAQ,IAAI;AACpB,QAAM,QAAQ;AAAA,IACZ,6BAA6B,OAAO,SAAS,OAAO,OAAO,MAAM;AAAA,IACjE,mBAAmB,QAAQ,aAAa,KAAK,QAAQ,QAAQ,cAAc,QAAQ,IAAI,UAAU,QAAQ,MAAM,YAAY,QAAQ,GAAG;AAAA,IACtI,YAAY,QAAQ,cAAc,eAAe,QAAQ,YAAY;AAAA,EACvE;AAEA,QAAM,WAAW,qBAAqB,OAAO,SAAS,IAAI;AAC1D,MAAI,UAAU;AACZ,UAAM,KAAK,QAAQ;AAAA,EACrB;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,oBAAoB,QAA4B;AACvD,QAAM,QAAQ;AAAA,IACZ,WAAW,OAAO,MAAM,WAAM,OAAO,MAAM;AAAA,IAC3C,sBAAsB,OAAO,gBAAgB,eAAe,OAAO,aAAa;AAAA,EAClF;AACA,MAAI,OAAO,UAAU,QAAQ;AAC3B,UAAM,KAAK,aAAa,OAAO,SAAS,MAAM,EAAE;AAAA,EAClD;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAe,iBAAiB,QAAsC;AACpE,MAAI;AACJ,MAAI;AACF,gBAAY,MAAM,aAAa,MAAM;AAAA,EACvC,QAAQ;AACN,gBAAY;AAAA,EACd;AACA,SAAO,EAAE,QAAQ,WAAW,aAAa,MAAM,GAAG,UAAU;AAC9D;AAEO,SAAS,aAAa,eAAkC;AAC7D,QAAM,SAAS,IAAI;AAAA,IACjB,EAAE,MAAM,oBAAoB,SAAS,QAAQ;AAAA,IAC7C,EAAE,cAAc,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,GAAG,SAAS,CAAC,EAAE,EAAE;AAAA,EAC5D;AAEA,QAAM,cAAyB;AAAA,IAC7B,IAAI,wBAAwB;AAAA,IAC5B,IAAI,sBAAsB;AAAA,IAC1B,IAAI,sBAAsB;AAAA,IAC1B,IAAI,mBAAmB;AAAA,IACvB,IAAI,2BAA2B;AAAA,IAC/B,IAAI,8BAA8B;AAAA,IAClC,IAAI,0BAA0B;AAAA,IAC9B,IAAI,qBAAqB;AAAA,IACzB,IAAI,qBAAqB;AAAA,IACzB,IAAI,wBAAwB;AAAA,IAC5B,IAAI,2BAA2B;AAAA,IAC/B,IAAI,yBAAyB;AAAA,IAC7B,IAAI,yBAAyB;AAAA,IAC7B,IAAI,8BAA8B;AAAA,IAClC,IAAI,2BAA2B;AAAA,IAC/B,IAAI,8BAA8B;AAAA,IAClC,IAAI,+BAA+B;AAAA,IACnC,IAAI,yBAAyB;AAAA,IAC7B,IAAI,mBAAmB;AAAA,EACzB;AAEA,QAAM,aAAa,oBAAI,IAAqB;AAC5C,aAAW,KAAK,aAAa;AAC3B,eAAW,IAAI,EAAE,YAAY,CAAC;AAAA,EAChC;AAKA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,MACpF,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,qDAAqD;AAAA,MAC/F,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0EAA0E;AAAA,MACpH,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,0DAA0D;AAAA,MAC/G,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,IAChF;AAAA,IACA,OAAO,EAAE,QAAQ,UAAU,WAAW,aAAa,KAAK,MAAM;AAC5D,UAAI;AACF,cAAM,IAAI,UAAU;AACpB,YAAI;AAEJ,YAAI,UAAU;AACZ,mBAAS,MAAM,wBAAwB,aAAa,GAAG;AAAA,YACrD,SAAS;AAAA,YACT,UAAU,aAAa;AAAA,YACvB,YAAY;AAAA,UACd,CAAC;AAAA,QACH,OAAO;AACL,mBAAS,MAAM,eAAe,aAAa,CAAC;AAAA,QAC9C;AAEA,eAAO;AAAA,UACL,SAAS;AAAA,YACP,EAAE,MAAM,QAAQ,MAAM,gBAAgB,QAAQ,QAAQ,IAAI,EAAE;AAAA,YAC5D,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE;AAAA,UACxD;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,QAAM,qBAAqF;AAAA,IACzF,EAAE,UAAU,mBAAmB,YAAY,qBAAqB,OAAO,6BAA6B;AAAA,IACpG,EAAE,UAAU,wBAAwB,YAAY,mBAAmB,OAAO,kBAAkB;AAAA,IAC5F,EAAE,UAAU,wBAAwB,YAAY,mBAAmB,OAAO,kBAAkB;AAAA,IAC5F,EAAE,UAAU,qBAAqB,YAAY,gBAAgB,OAAO,eAAe;AAAA,IACnF,EAAE,UAAU,6BAA6B,YAAY,wBAAwB,OAAO,uBAAuB;AAAA,IAC3G,EAAE,UAAU,iCAAiC,YAAY,4BAA4B,OAAO,2BAA2B;AAAA,IACvH,EAAE,UAAU,6BAA6B,YAAY,wBAAwB,OAAO,uBAAuB;AAAA,IAC3G,EAAE,UAAU,uBAAuB,YAAY,kBAAkB,OAAO,iBAAiB;AAAA,IACzF,EAAE,UAAU,uBAAuB,YAAY,kBAAkB,OAAO,iBAAiB;AAAA,IACzF,EAAE,UAAU,0BAA0B,YAAY,qBAAqB,OAAO,oBAAoB;AAAA,IAClG,EAAE,UAAU,8BAA8B,YAAY,yBAAyB,OAAO,wBAAwB;AAAA,IAC9G,EAAE,UAAU,2BAA2B,YAAY,sBAAsB,OAAO,qBAAqB;AAAA,IACrG,EAAE,UAAU,2BAA2B,YAAY,sBAAsB,OAAO,qBAAqB;AAAA,IACrG,EAAE,UAAU,iCAAiC,YAAY,4BAA4B,OAAO,2BAA2B;AAAA,IACvH,EAAE,UAAU,8BAA8B,YAAY,yBAAyB,OAAO,wBAAwB;AAAA,IAC9G,EAAE,UAAU,iCAAiC,YAAY,4BAA4B,OAAO,2BAA2B;AAAA,IACvH,EAAE,UAAU,kCAAkC,YAAY,6BAA6B,OAAO,4BAA4B;AAAA,IAC1H,EAAE,UAAU,2BAA2B,YAAY,sBAAsB,OAAO,qBAAqB;AAAA,IACrG,EAAE,UAAU,qBAAqB,YAAY,gBAAgB,OAAO,eAAe;AAAA,EACrF;AAEA,aAAW,EAAE,UAAU,YAAY,MAAM,KAAK,oBAAoB;AAChE,WAAO;AAAA,MACL;AAAA,MACA,OAAO,KAAK;AAAA,MACZ,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6CAA6C,EAAE;AAAA,MACxF,OAAO,EAAE,OAAO,MAAM;AACpB,YAAI;AACF,gBAAM,IAAI,UAAU;AACpB,gBAAM,MAAM,MAAM,iBAAiB,CAAC;AACpC,gBAAM,UAAU,WAAW,IAAI,UAAU;AACzC,gBAAM,SAAqB,MAAM,QAAQ,KAAK,GAAG;AACjD,iBAAO;AAAA,YACL,SAAS;AAAA,cACP,EAAE,MAAM,QAAQ,MAAM,oBAAoB,MAAM,EAAE;AAAA,cAClD,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE;AAAA,YACxD;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,QAC1H;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO,EAAE,OAAO,EAAE,SAAS,4LAA4L;AAAA,MACvN,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,MACpF,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,qDAAqD;AAAA,MAC/F,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0EAA0E;AAAA,MACpH,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,0DAA0D;AAAA,MAC/G,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,IAChF;AAAA,IACA,OAAO,EAAE,OAAO,QAAQ,UAAU,WAAW,aAAa,KAAK,MAAM;AACnE,UAAI;AACF,cAAM,WAAW,YAAY,KAAK;AAClC,YAAI,CAAC,UAAU;AACb,gBAAM,YAAY,OAAO,KAAK,WAAW,EAAE,KAAK,IAAI;AACpD,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,8BAA8B,KAAK,wBAAwB,SAAS,GAAG,CAAC;AAAA,YACxG,SAAS;AAAA,UACX;AAAA,QACF;AAEA,cAAM,IAAI,UAAU;AAGpB,YAAI;AACJ,cAAM,iBAA2B,CAAC;AAElC,YAAI,SAAS,QAAQ,SAAS,KAAK,GAAG;AACpC,6BAAmB;AAAA,QACrB,OAAO;AACL,6BAAmB,CAAC;AACpB,qBAAW,OAAO,SAAS,SAAS;AAClC,kBAAM,UAAU,WAAW,IAAI,GAAG;AAClC,gBAAI,SAAS;AACX,+BAAiB,KAAK,OAAO;AAAA,YAC/B,OAAO;AACL,6BAAe,KAAK,GAAG;AAAA,YACzB;AAAA,UACF;AAAA,QACF;AAEA,YAAI,iBAAiB,WAAW,GAAG;AACjC,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,2CAA2C,KAAK,yBAAyB,SAAS,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC;AAAA,YACxI,SAAS;AAAA,UACX;AAAA,QACF;AAEA,YAAI;AAEJ,YAAI,UAAU;AACZ,mBAAS,MAAM,wBAAwB,kBAAkB,GAAG;AAAA,YAC1D,SAAS;AAAA,YACT,UAAU,aAAa;AAAA,YACvB,YAAY;AAAA,UACd,CAAC;AAAA,QACH,OAAO;AACL,mBAAS,MAAM,eAAe,kBAAkB,CAAC;AAAA,QACnD;AAGA,YAAI,SAAS,gBAAgB;AAC3B,qBAAW,OAAO,OAAO,SAAS;AAChC,kBAAM,gBAAgB,IAAI,SAAS;AACnC,gBAAI,WAAW,oBAAoB,IAAI,QAAQ,IAAI,UAAU,SAAS,cAAc;AACpF,gBAAI,gBAAgB,IAAI,SAAS;AACjC,gBAAI,IAAI,SAAS,SAAS,eAAe;AACvC,oBAAM,WAAW,gBAAgB,IAAI,SAAS;AAC9C,kBAAI,CAAC,IAAI,SAAU,KAAI,WAAW,CAAC;AACnC,kBAAI,SAAS,KAAK,uBAAuB,QAAQ,0CAA0C;AAAA,YAC7F;AAAA,UACF;AAEA,cAAI,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM;AAC9C,qBAAW,KAAK,OAAO,SAAS;AAC9B,uBAAW,KAAK,EAAE,UAAU;AAC1B,sBAAQ,EAAE,UAAU;AAAA,gBAClB,KAAK;AAAY;AAAY;AAAA,gBAC7B,KAAK;AAAQ;AAAQ;AAAA,gBACrB,KAAK;AAAU;AAAU;AAAA,gBACzB,KAAK;AAAO;AAAO;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AACA,iBAAO,QAAQ,gBAAgB,WAAW,OAAO,SAAS;AAC1D,iBAAO,QAAQ,WAAW;AAC1B,iBAAO,QAAQ,OAAO;AACtB,iBAAO,QAAQ,SAAS;AACxB,iBAAO,QAAQ,MAAM;AAAA,QACvB;AAEA,cAAM,QAAkB;AAAA,UACtB,eAAe,SAAS,IAAI,KAAK,KAAK;AAAA,UACtC,SAAS;AAAA,UACT;AAAA,UACA,gBAAgB,QAAQ,QAAQ,IAAI;AAAA,QACtC;AAEA,YAAI,eAAe,SAAS,GAAG;AAC7B,gBAAM,KAAK,EAAE;AACb,gBAAM,KAAK,YAAY,eAAe,MAAM,uCAAuC,eAAe,KAAK,IAAI,CAAC,EAAE;AAAA,QAChH;AAEA,cAAM,UAAiD;AAAA,UACrD,EAAE,MAAM,QAAQ,MAAM,MAAM,KAAK,IAAI,EAAE;AAAA,UACvC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE;AAAA,QACxD;AAEA,YAAI,UAAU,cAAc;AAE1B,gBAAM,iBAAiB,QAAQ,CAAC;AAChC,cAAI,kBAAkB,eAAe,SAAS,QAAQ;AACpD,2BAAe,QAAQ,SAAS,sBAAsB,QAAQ,IAAI;AAClE,2BAAe,QAAQ;AAAA,UACzB;AAAA,QACF;AAEA,eAAO,EAAE,QAAQ;AAAA,MACnB,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY;AACV,UAAI;AACF,cAAM,SAAS,OAAO,QAAQ,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,GAAG,OAAO;AAAA,UAC7D;AAAA,UACA,MAAM,IAAI;AAAA,UACV,aAAa,IAAI;AAAA,UACjB,SAAS,IAAI;AAAA,UACb,YAAY,IAAI;AAAA,QAClB,EAAE;AACF,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,cAAc,EAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,MAC/E,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,IAChF;AAAA,IACA,OAAO,EAAE,cAAc,KAAK,MAAM;AAChC,UAAI;AACF,cAAM,SAAyB,KAAK,MAAM,YAAY;AACtD,cAAM,SAAS,uBAAuB,QAAQ,QAAQ,IAAI;AAC1D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC,EAAE;AAAA,MACrD,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,cAAc,EAAE,OAAO,EAAE,SAAS,0EAA0E;AAAA,MAC5G,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,IAChF;AAAA,IACA,OAAO,EAAE,cAAc,KAAK,MAAM;AAChC,UAAI;AACF,cAAM,SAAyB,KAAK,MAAM,YAAY;AACtD,cAAM,SAAS,oBAAoB,QAAQ,QAAQ,IAAI;AACvD,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC,EAAE;AAAA,MACrD,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,cAAc,EAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,MAC/E,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yFAAyF;AAAA,MACjI,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,IAChF;AAAA,IACA,OAAO,EAAE,cAAc,SAAS,KAAK,MAAM;AACzC,UAAI;AACF,cAAM,SAAyB,KAAK,MAAM,YAAY;AACtD,cAAM,cAAc,UAAU,KAAK,MAAM,OAAO,IAAI;AACpD,cAAM,SAAS,mBAAmB,QAAQ,aAAa,QAAQ,IAAI;AACnE,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC,EAAE;AAAA,MACrD,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,cAAc,EAAE,OAAO,EAAE,SAAS,0EAA0E;AAAA,MAC5G,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yFAAyF;AAAA,MACjI,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,IAChF;AAAA,IACA,OAAO,EAAE,cAAc,SAAS,KAAK,MAAM;AACzC,UAAI;AACF,cAAM,SAAyB,KAAK,MAAM,YAAY;AACtD,cAAM,cAAc,UAAU,KAAK,MAAM,OAAO,IAAI;AACpD,cAAM,SAAS,wBAAwB,QAAQ,aAAa,QAAQ,IAAI;AACxE,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC,EAAE;AAAA,MACrD,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,cAAc,EAAE,OAAO,EAAE,SAAS,sEAAsE;AAAA,MACxG,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,IAChF;AAAA,IACA,OAAO,EAAE,cAAc,KAAK,MAAM;AAChC,UAAI;AACF,cAAM,SAAyB,KAAK,MAAM,YAAY;AACtD,cAAM,SAAS,4BAA4B,QAAQ,QAAQ,IAAI;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC,EAAE;AAAA,MACrD,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,cAAc,EAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,MAC/E,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,IAChF;AAAA,IACA,OAAO,EAAE,aAAa,MAAM;AAC1B,UAAI;AACF,cAAM,SAAyB,KAAK,MAAM,YAAY;AACtD,cAAM,WAAW,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,mBAAmB;AAC5E,YAAI,CAAC,UAAU;AACb,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,mFAAmF,CAAC;AAAA,YACpH,SAAS;AAAA,UACX;AAAA,QACF;AAGA,cAAM,YAAa,SAAwE;AAE3F,YAAI,CAAC,WAAW;AACd,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,oJAAoJ,CAAC;AAAA,YACrL,SAAS;AAAA,UACX;AAAA,QACF;AAEA,cAAM,iBAAyC;AAAA,UAC7C,cAAc;AAAA,UACd,gBAAgB;AAAA,UAChB,aAAa;AAAA,UACb,aAAa;AAAA,UACb,cAAc;AAAA,QAChB;AACA,cAAM,oBAA6C;AAAA,UACjD,gBAAgB;AAAA,UAChB,aAAa;AAAA,UACb,aAAa;AAAA,QACf;AAEA,cAAM,WAAW,UAAU;AAC3B,cAAM,kBAAkB,UAAU;AAClC,cAAM,gBAAgB,UAAU;AAEhC,cAAM,eAAe,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI,EAAE;AAChE,cAAM,aAAa,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI,EAAE;AAC9D,cAAM,gBAAgB,SAAS;AAG/B,cAAM,QAAkB,CAAC;AACzB,cAAM,KAAK,oCAAoC;AAC/C,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,eAAe,OAAO,SAAS,cAAc,OAAO,MAAM,EAAE;AACvE,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,iCAAiC,eAAe,GAAG;AAC9D,cAAM,KAAK,sBAAsB,cAAc,OAAO,CAAC,EAAE,YAAY,IAAI,cAAc,MAAM,CAAC,CAAC,EAAE;AACjG,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,oBAAoB;AAC/B,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,+BAA+B;AAC1C,cAAM,KAAK,+BAA+B;AAC1C,mBAAW,OAAO,UAAU;AAC1B,gBAAM,SAAS,IAAI,YAAY,OAAO,mBAAmB,IAAI,YAAY,QAAQ,uBAAuB;AACxG,gBAAM,SAAS,eAAe,IAAI,IAAI,KAAK;AAC3C,gBAAM,KAAK,KAAK,IAAI,IAAI,MAAM,MAAM,MAAM,MAAM,IAAI;AAAA,QACtD;AAEA,cAAM,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI;AAC1D,YAAI,SAAS,SAAS,GAAG;AACvB,gBAAM,KAAK,EAAE;AACb,gBAAM,KAAK,kBAAkB,SAAS,MAAM,iIAAiI;AAAA,QAC/K;AAGA,cAAM,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,KAAK;AAC3D,YAAI,SAAS,SAAS,GAAG;AACvB,gBAAM,KAAK,EAAE;AACb,gBAAM,KAAK,sCAAsC;AACjD,gBAAM,KAAK,EAAE;AAEb,gBAAM,gBAAgB,CAAC,gBAAgB,aAAa,aAAa,cAAc,YAAY;AAC3F,gBAAM,SAAS,SAAS;AAAA,YACtB,CAAC,GAAG,MAAM,cAAc,QAAQ,EAAE,IAAI,IAAI,cAAc,QAAQ,EAAE,IAAI;AAAA,UACxE;AACA,cAAI,MAAM;AACV,qBAAW,OAAO,QAAQ;AACxB,kBAAM,QAAQ,kBAAkB,IAAI,IAAI,IAAI,iCAAiC;AAC7E,kBAAM,KAAK,GAAG,GAAG,YAAY,IAAI,IAAI,GAAG,KAAK,EAAE;AAC/C;AAAA,UACF;AAAA,QACF;AAGA,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,sBAAsB;AACjC,cAAM,KAAK,EAAE;AACb,YAAI,SAAS,SAAS,GAAG;AACvB,gBAAM,KAAK,kBAAkB,cAAc,OAAO,CAAC,EAAE,YAAY,IAAI,cAAc,MAAM,CAAC,CAAC,KAAK,YAAY,IAAI,UAAU,oBAAoB,SAAS,MAAM,WAAW;AAAA,QAC1K,OAAO;AACL,gBAAM,KAAK,kBAAkB,cAAc,OAAO,CAAC,EAAE,YAAY,IAAI,cAAc,MAAM,CAAC,CAAC,KAAK,YAAY,IAAI,aAAa,YAAY;AAAA,QAC3I;AAEA,YAAI,kBAAkB,iBAAiB;AACrC,gBAAM,iBAA2F;AAAA,YAC/F,OAAO,EAAE,OAAO,gBAAgB,QAAQ,GAAG,aAAa,CAAC,gBAAgB,WAAW,EAAE;AAAA,YACtF,cAAc,EAAE,OAAO,YAAY,QAAQ,GAAG,aAAa,CAAC,aAAa,YAAY,EAAE;AAAA,YACvF,UAAU,EAAE,OAAO,iBAAiB,QAAQ,GAAG,aAAa,CAAC,YAAY,EAAE;AAAA,UAC7E;AACA,gBAAM,OAAO,eAAe,aAAa;AACzC,cAAI,MAAM;AACR,kBAAM,YAAY,KAAK,YAAY;AAAA,cAAO,CAAC,MACzC,SAAS,KAAK,CAAC,QAAQ,IAAI,SAAS,KAAK,CAAC,IAAI,OAAO;AAAA,YACvD;AACA,gBAAI,UAAU,SAAS,GAAG;AACxB,oBAAM,KAAK,yBAAyB,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,UAAU,mBAAmB,UAAU,KAAK,KAAK,CAAC,EAAE;AAAA,YACxH;AAAA,UACF;AACA,gBAAM,KAAK,gCAAgC,UAAU,IAAI,UAAU,GAAG;AAAA,QACxE;AAEA,cAAM,KAAK,EAAE;AAEb,cAAM,SAAS,MAAM,KAAK,IAAI;AAE9B,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC,EAAE;AAAA,MACrD,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC;AAAA,UAC9F,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,cAAc,EAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,MAC/E,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,IAC1F;AAAA,IACA,OAAO,EAAE,cAAc,WAAW,MAAM;AACtC,UAAI;AACF,cAAM,SAAyB,KAAK,MAAM,YAAY;AACtD,cAAM,WAAW,YAAY,QAAQ,UAAU;AAC/C,eAAO;AAAA,UACL,SAAS;AAAA,YACP,EAAE,MAAM,QAAQ,MAAM,2BAA2B,QAAQ,GAAG;AAAA,UAC9D;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC;AAAA,UAC9F,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY;AACV,UAAI;AACF,cAAM,UAAU,YAAY,IAAI,CAAC,OAAO;AAAA,UACtC,MAAM,EAAE;AAAA,UACR,aAAa,oBAAoB,EAAE,UAAU,KAAK,EAAE;AAAA,QACtD,EAAE;AACF,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC/E,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qCAAqC,EAAE;AAAA,IAChF,OAAO,EAAE,OAAO,MAAM;AACpB,UAAI;AACF,cAAM,IAAI,UAAU;AACpB,cAAM,WAAW,MAAM,gBAAgB,CAAC;AACxC,eAAO;AAAA,UACL,SAAS;AAAA,YACP,EAAE,MAAM,QAAQ,MAAM,SAAS,SAAS,MAAM,0CAA0C;AAAA,YACxF,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE;AAAA,UAC1D;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,KAAK,CAAC,QAAQ,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,IACtG;AAAA,IACA,OAAO,EAAE,OAAO,MAAM;AACpB,UAAI;AACF,cAAM,MAAM,WAAW,SAAS,SAAS;AACzC,cAAM,mBAAmB,uBAAuB,GAAG;AAEnD,YAAI;AACJ,YAAI;AAEF,gBAAM,aAAa,QAAQ,cAAc,YAAY,GAAG,CAAC;AACzD,gBAAM,eAAeD,MAAK,YAAY,MAAM,aAAa,gBAAgB;AACzE,4BAAkBD,cAAa,cAAc,OAAO;AAAA,QACtD,QAAQ;AACN,cAAI;AAEF,kBAAM,aAAa,QAAQ,cAAc,YAAY,GAAG,CAAC;AACzD,kBAAM,eAAeC,MAAK,YAAY,MAAM,MAAM,aAAa,gBAAgB;AAC/E,8BAAkBD,cAAa,cAAc,OAAO;AAAA,UACtD,QAAQ;AACN,mBAAO;AAAA,cACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,wBAAwB,gBAAgB,0EAA0E,CAAC;AAAA,cACnJ,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,UACL,SAAS;AAAA,YACP,EAAE,MAAM,QAAQ,MAAM,qCAAqC,IAAI,YAAY,CAAC;AAAA;AAAA,gFAAoH;AAAA,YAChM,EAAE,MAAM,QAAQ,MAAM,gBAAgB;AAAA,UACxC;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,MAC1H;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,aAAa,uDAAuD,UAAU,gBAAgB;AAAA,IAChG,aAAa;AAAA,MACX,UAAU,CAAC,EAAE,KAAK,oBAAoB,MAAM,wBAAwB,UAAU,gBAAgB,CAAC;AAAA,IACjG;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,aAAa,kEAAkE,UAAU,gBAAgB;AAAA,IAC3G,aAAa;AAAA,MACX,UAAU,CAAC,EAAE,KAAK,2BAA2B,MAAM,sBAAsB,UAAU,gBAAgB,CAAC;AAAA,IACtG;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,aAAa;AAAA,MACX,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,mDAAmD,EAAE;AAAA,IACpF,OAAO,EAAE,QAAQ,OAAO;AAAA,MACtB,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA;AAAA;AAAA,EAA8K,OAAO;AAAA,UAC7L;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,aAAa;AAAA,MACX,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA;AAAA,EAAiC,sBAAsB,IAAI,CAAC;AAAA;AAAA;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,YAAY,eAAsC;AACtE,QAAM,SAAS,aAAa,aAAa;AACzC,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;;;AuC72BA,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,IAAM,aAAa,KAAK,CAAC;AAEzB,IAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBb,IAAI,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI,GAAG;AAClD,UAAQ,IAAI,IAAI;AAChB,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAI,KAAK,SAAS,WAAW,GAAG;AAC9B,UAAQ,IAAI,oBAAoB,OAAO,EAAE;AACzC,UAAQ,KAAK,CAAC;AAChB;AAEA,SAAS,OAAO,MAAkC;AAChD,QAAM,MAAM,KAAK,QAAQ,IAAI;AAC7B,MAAI,QAAQ,MAAM,KAAK,MAAM,CAAC,EAAG,QAAO,KAAK,MAAM,CAAC;AACpD,SAAO;AACT;AAEA,SAAS,YAAoB;AAC3B,SACE,OAAO,UAAU,KACjB,QAAQ,IAAI,cACZ,QAAQ,IAAI,sBACZ;AAEJ;AAEA,IAAI,eAAe,aAAa;AAC9B,QAAM,OAAO,OAAO,OAAO,QAAQ,CAAC,KAAK;AACzC,sEAAuC,KAAK,CAAC,EAAE,gBAAAG,gBAAe,MAAM;AAClE,IAAAA,gBAAe,IAAI;AAAA,EACrB,CAAC;AACH,WAAW,eAAe,oBAAoB;AAC5C,QAAM,SAAS,OAAO,UAAU;AAChC,MAAI,CAAC,QAAQ;AACX,YAAQ,MAAM,yDAAyD;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,SAAS,UAAU;AACzB,oFAA8C,KAAK,CAAC,EAAE,iBAAAC,iBAAgB,MAAM;AAC1E,IAAAA,iBAAgB,QAAQ,MAAM,EAAE,MAAM,CAAC,QAAQ;AAC7C,cAAQ,MAAM,kBAAkB,IAAI,WAAW,GAAG;AAClD,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAAA,EACH,CAAC;AACH,WAAW,cAAc,CAAC,WAAW,WAAW,IAAI,GAAG;AACrD,UAAQ,MAAM,oBAAoB,UAAU,EAAE;AAC9C,UAAQ,MAAM,0CAA0C;AACxD,UAAQ,KAAK,CAAC;AAChB,OAAO;AAEL,QAAM,SAAS,UAAU;AACzB,cAAY,MAAM,EAAE,MAAM,CAAC,QAAQ;AACjC,YAAQ,MAAM,UAAU,GAAG;AAC3B,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;","names":["createServer","join","existsSync","fileURLToPath","readFileSync","existsSync","copyFileSync","join","extname","fileURLToPath","S3Client","__dirname","__filename","STSClient","GetCallerIdentityCommand","STSClient","makeFinding","makeFinding","makeFinding","EC2Client","DescribeInstancesCommand","makeFinding","EC2Client","DescribeInstancesCommand","makeFinding","S3Client","dns","makeFinding","S3Client","dns","EC2Client","DescribeInstancesCommand","RDSClient","DescribeDBInstancesCommand","S3Client","ListBucketsCommand","makeFinding","EC2Client","DescribeInstancesCommand","RDSClient","DescribeDBInstancesCommand","S3Client","ListBucketsCommand","EC2Client","DescribeAddressesCommand","DescribeInstancesCommand","DescribeSecurityGroupsCommand","makeFinding","EC2Client","DescribeAddressesCommand","DescribeInstancesCommand","DescribeSecurityGroupsCommand","RDSClient","DescribeDBInstancesCommand","EC2Client","DescribeVolumesCommand","S3Client","ListBucketsCommand","makeFinding","RDSClient","DescribeDBInstancesCommand","EC2Client","DescribeVolumesCommand","S3Client","ListBucketsCommand","SecurityHubClient","SecurityHubClient","isNotEnabled","GuardDutyClient","ListDetectorsCommand","GuardDutyClient","ListDetectorsCommand","Inspector2Client","BatchGetAccountStatusCommand","Inspector2Client","BatchGetAccountStatusCommand","isAccessDenied","ConfigServiceClient","DescribeConfigurationRecordersCommand","ConfigServiceClient","DescribeConfigurationRecordersCommand","riskScore","severity","EC2Client","DescribeInstancesCommand","makeFinding","EC2Client","DescribeInstancesCommand","makeFinding","formatDuration","SEVERITY_ORDER","w","existing","esc","safeUrl","escWithLinks","SEVERITY_ORDER","key","SEVERITY_ORDER","readFileSync","join","SERVICE_NOT_ENABLED_PATTERNS","startDashboard","deployDashboard"]}
|