@bouncesecurity/aghast 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +111 -0
- package/config/prompts/generic-instructions.md +56 -0
- package/config/prompts/test-cheaper-instructions.md +57 -0
- package/dist/check-library.d.ts +87 -0
- package/dist/check-library.d.ts.map +1 -0
- package/dist/check-library.js +374 -0
- package/dist/check-library.js.map +1 -0
- package/dist/claude-code-provider.d.ts +26 -0
- package/dist/claude-code-provider.d.ts.map +1 -0
- package/dist/claude-code-provider.js +247 -0
- package/dist/claude-code-provider.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +78 -0
- package/dist/cli.js.map +1 -0
- package/dist/colors.d.ts +7 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +18 -0
- package/dist/colors.js.map +1 -0
- package/dist/error-codes.d.ts +42 -0
- package/dist/error-codes.d.ts.map +1 -0
- package/dist/error-codes.js +60 -0
- package/dist/error-codes.js.map +1 -0
- package/dist/formatters/index.d.ts +10 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +23 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/json-formatter.d.ts +11 -0
- package/dist/formatters/json-formatter.d.ts.map +1 -0
- package/dist/formatters/json-formatter.js +11 -0
- package/dist/formatters/json-formatter.js.map +1 -0
- package/dist/formatters/sarif-formatter.d.ts +18 -0
- package/dist/formatters/sarif-formatter.d.ts.map +1 -0
- package/dist/formatters/sarif-formatter.js +103 -0
- package/dist/formatters/sarif-formatter.js.map +1 -0
- package/dist/formatters/types.d.ts +11 -0
- package/dist/formatters/types.d.ts.map +1 -0
- package/dist/formatters/types.js +6 -0
- package/dist/formatters/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +406 -0
- package/dist/index.js.map +1 -0
- package/dist/logging.d.ts +26 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +79 -0
- package/dist/logging.js.map +1 -0
- package/dist/mock-ai-provider.d.ts +18 -0
- package/dist/mock-ai-provider.d.ts.map +1 -0
- package/dist/mock-ai-provider.js +28 -0
- package/dist/mock-ai-provider.js.map +1 -0
- package/dist/new-check.d.ts +13 -0
- package/dist/new-check.d.ts.map +1 -0
- package/dist/new-check.js +405 -0
- package/dist/new-check.js.map +1 -0
- package/dist/prompt-template.d.ts +12 -0
- package/dist/prompt-template.d.ts.map +1 -0
- package/dist/prompt-template.js +35 -0
- package/dist/prompt-template.js.map +1 -0
- package/dist/provider-registry.d.ts +15 -0
- package/dist/provider-registry.d.ts.map +1 -0
- package/dist/provider-registry.js +27 -0
- package/dist/provider-registry.js.map +1 -0
- package/dist/repository-analyzer.d.ts +68 -0
- package/dist/repository-analyzer.d.ts.map +1 -0
- package/dist/repository-analyzer.js +230 -0
- package/dist/repository-analyzer.js.map +1 -0
- package/dist/response-parser.d.ts +12 -0
- package/dist/response-parser.d.ts.map +1 -0
- package/dist/response-parser.js +109 -0
- package/dist/response-parser.js.map +1 -0
- package/dist/runtime-config.d.ts +15 -0
- package/dist/runtime-config.d.ts.map +1 -0
- package/dist/runtime-config.js +73 -0
- package/dist/runtime-config.js.map +1 -0
- package/dist/sarif-parser.d.ts +20 -0
- package/dist/sarif-parser.d.ts.map +1 -0
- package/dist/sarif-parser.js +76 -0
- package/dist/sarif-parser.js.map +1 -0
- package/dist/scan-runner.d.ts +29 -0
- package/dist/scan-runner.d.ts.map +1 -0
- package/dist/scan-runner.js +559 -0
- package/dist/scan-runner.js.map +1 -0
- package/dist/semgrep-runner.d.ts +25 -0
- package/dist/semgrep-runner.d.ts.map +1 -0
- package/dist/semgrep-runner.js +100 -0
- package/dist/semgrep-runner.js.map +1 -0
- package/dist/snippet-extractor.d.ts +25 -0
- package/dist/snippet-extractor.d.ts.map +1 -0
- package/dist/snippet-extractor.js +56 -0
- package/dist/snippet-extractor.js.map +1 -0
- package/dist/types.d.ts +206 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# AI Guided Hybrid Application Static Testing (AGHAST) - ALPHA VERSION
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
[](https://github.com/BounceSecurity/aghast/actions/workflows/ci.yml)
|
|
5
|
+
[](https://www.gnu.org/licenses/agpl-3.0)
|
|
6
|
+
[](https://bouncesecurity.com/)
|
|
7
|
+
|
|
8
|
+
> **Warning**
|
|
9
|
+
> AGHAST is in **early alpha**. APIs, CLI flags, configuration formats, and output schemas may change between releases without notice. Use in production CI/CD pipelines at your own risk.
|
|
10
|
+
|
|
11
|
+
An open source tool that combines static scanning rules with AI prompts to find code-specific and company-specific security issues.
|
|
12
|
+
|
|
13
|
+
Define static rules, security checks as markdown instructions, point AGHAST at a repo, and get structured results (JSON or SARIF).
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<img src="/assets/img/aghastbouncecaption.png" alt="AGHAST" width="50%">
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
## What AGHAST Does
|
|
20
|
+
|
|
21
|
+
You can read the full background to this tool in our blogpost [here](https://bouncesecurity.com/aghast) but, to cut to the chase, AGHAST helps you run three types of checks:
|
|
22
|
+
|
|
23
|
+
- Pure AI scanning rules - let the LLM do all the analysis
|
|
24
|
+
- A combination of a static rule and an AI scanning rule - the sweet spot for most use cases
|
|
25
|
+
- Purely static rules - for completeness, when a traditional static rule is all you need
|
|
26
|
+
|
|
27
|
+
The beauty of the approach is what you *don't* need:
|
|
28
|
+
|
|
29
|
+
- You don't need to modify the code
|
|
30
|
+
- You don't need to build something into the codebase
|
|
31
|
+
- You don't need to write code in the language of the codebase
|
|
32
|
+
|
|
33
|
+
All you need is:
|
|
34
|
+
|
|
35
|
+
- Access to the codebase
|
|
36
|
+
- An understanding of the problem you are trying to discover
|
|
37
|
+
- The ability to write some simple rules
|
|
38
|
+
|
|
39
|
+
There are almost certainly other ways of achieving this, but to our mind, this approach is both straightforward and deterministic.
|
|
40
|
+
|
|
41
|
+
## Prerequisites
|
|
42
|
+
|
|
43
|
+
- **Node.js 20+**
|
|
44
|
+
- **[Semgrep Community Edition](https://semgrep.dev/docs/getting-started/)** (LGPL-2.1, optional) — only needed for checks that use Semgrep rules
|
|
45
|
+
- **Anthropic API key** — for AI-based checks (not needed for semgrep-only checks)
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
See the [Getting Started Guide](docs/getting-started.md) for full installation and setup instructions.
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
Set your API key, create a check, and run a scan:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
export ANTHROPIC_API_KEY=your-api-key
|
|
57
|
+
aghast new-check --config-dir ./my-checks
|
|
58
|
+
aghast scan /path/to/target-repo --config-dir ./my-checks
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
See the [Getting Started Guide](docs/getting-started.md) for a full walkthrough.
|
|
62
|
+
|
|
63
|
+
## Example Output
|
|
64
|
+
|
|
65
|
+
Results are structured JSON (or SARIF) with per-check status and detailed issues:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"checks": [
|
|
70
|
+
{ "checkId": "aghast-api-authz", "checkName": "API Authorization Check", "status": "FAIL", "issuesFound": 1 },
|
|
71
|
+
{ "checkId": "aghast-sql-injection", "checkName": "SQL Injection Prevention", "status": "PASS", "issuesFound": 0 }
|
|
72
|
+
],
|
|
73
|
+
"issues": [
|
|
74
|
+
{
|
|
75
|
+
"checkId": "aghast-api-authz",
|
|
76
|
+
"checkName": "API Authorization Check",
|
|
77
|
+
"file": "src/api/users.ts",
|
|
78
|
+
"startLine": 45,
|
|
79
|
+
"endLine": 52,
|
|
80
|
+
"description": "Missing authorization check on DELETE endpoint.",
|
|
81
|
+
"codeSnippet": "router.delete('/users/:id', async (req, res) => {"
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
"summary": {
|
|
85
|
+
"totalChecks": 2,
|
|
86
|
+
"passedChecks": 1,
|
|
87
|
+
"failedChecks": 1,
|
|
88
|
+
"flaggedChecks": 0,
|
|
89
|
+
"errorChecks": 0,
|
|
90
|
+
"totalIssues": 1
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Documentation
|
|
96
|
+
|
|
97
|
+
- [Getting Started](docs/getting-started.md) — installation, setup, and first scan
|
|
98
|
+
- [Scanning](docs/scanning.md) — scan command options, environment variables, output formats
|
|
99
|
+
- [Creating Checks](docs/creating-checks.md) — scaffolding new security checks
|
|
100
|
+
- [Configuration Reference](docs/configuration.md) — check schemas, check types, runtime config
|
|
101
|
+
- [Development](docs/development.md) — setup, building, testing, releasing
|
|
102
|
+
|
|
103
|
+
## Contributing
|
|
104
|
+
|
|
105
|
+
We welcome bug reports and feature requests via [GitHub Issues](https://github.com/BounceSecurity/aghast/issues). We are not currently accepting pull requests.
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
This project is licensed under the [GNU Affero General Public License v3.0 or later](LICENSE).
|
|
110
|
+
|
|
111
|
+
Copyright (C) 2026 [Bounce Consulting Ltd.](https://bouncesecurity.com/)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
GENERIC INSTRUCTIONS:
|
|
2
|
+
|
|
3
|
+
You are performing a SPECIFIC security check as defined in the CHECK INSTRUCTIONS below.
|
|
4
|
+
|
|
5
|
+
IMPORTANT:
|
|
6
|
+
- Focus ONLY on what the CHECK INSTRUCTIONS ask you to validate
|
|
7
|
+
- Do NOT perform general security testing or look for unrelated vulnerabilities
|
|
8
|
+
- Do NOT report issues outside the scope of the specific check
|
|
9
|
+
- Follow the CHECK INSTRUCTIONS exactly as written
|
|
10
|
+
|
|
11
|
+
OUTPUT FORMAT:
|
|
12
|
+
|
|
13
|
+
Return your findings in the following JSON format:
|
|
14
|
+
|
|
15
|
+
{
|
|
16
|
+
"issues": [
|
|
17
|
+
{
|
|
18
|
+
"file": "relative/path/to/file.ts",
|
|
19
|
+
"startLine": 40,
|
|
20
|
+
"endLine": 45,
|
|
21
|
+
"description": "Detailed explanation (see requirements below)",
|
|
22
|
+
"dataFlow": [
|
|
23
|
+
{ "file": "src/routes/handler.ts", "lineNumber": 12, "label": "User input received from request parameter" },
|
|
24
|
+
{ "file": "src/services/query.ts", "lineNumber": 38, "label": "Input passed to SQL query without sanitization" }
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
DESCRIPTION FORMATTING REQUIREMENTS:
|
|
31
|
+
|
|
32
|
+
Your description field MUST be detailed and well-structured:
|
|
33
|
+
- Use markdown formatting with headings (## Heading), bullet points, code blocks
|
|
34
|
+
- Use \n for line breaks to create structured, readable content
|
|
35
|
+
- Include an "Attack Scenario" section demonstrating exploitation
|
|
36
|
+
- Include a "Recommendation" section with specific remediation steps
|
|
37
|
+
|
|
38
|
+
DATA FLOW REQUIREMENTS:
|
|
39
|
+
|
|
40
|
+
When the issue involves data flowing through multiple locations (e.g., user input reaching a dangerous sink), include a "dataFlow" array. Each step represents a point in the call stack or data flow:
|
|
41
|
+
- "file": relative path to the source file
|
|
42
|
+
- "lineNumber": the line number at that step
|
|
43
|
+
- "label": a short description of what happens at this point (e.g., "User input received", "Passed to database query")
|
|
44
|
+
- Order steps from source (e.g., user input) to sink (e.g., SQL execution)
|
|
45
|
+
- Omit "dataFlow" entirely if the issue is localized to a single location
|
|
46
|
+
|
|
47
|
+
CRITICAL: Return ONLY valid JSON. No markdown code blocks, no explanations outside the JSON.
|
|
48
|
+
|
|
49
|
+
If no issues found for this SPECIFIC check, return: {"issues": []}
|
|
50
|
+
|
|
51
|
+
If a TARGET LOCATION section appears at the end of this prompt, you must analyze ONLY that specific code location.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
CHECK INSTRUCTIONS:
|
|
56
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
GENERIC INSTRUCTIONS:
|
|
2
|
+
|
|
3
|
+
You are performing a SPECIFIC security check as defined in the CHECK INSTRUCTIONS below.
|
|
4
|
+
|
|
5
|
+
IMPORTANT:
|
|
6
|
+
- Focus ONLY on what the CHECK INSTRUCTIONS ask you to validate
|
|
7
|
+
- Make sure you read the CHECK INSTRUCTIONS in full and comply with them
|
|
8
|
+
- Do NOT perform general security testing or look for unrelated vulnerabilities
|
|
9
|
+
- Do NOT report issues outside the scope of the specific check
|
|
10
|
+
- Follow the CHECK INSTRUCTIONS exactly as written
|
|
11
|
+
|
|
12
|
+
OUTPUT FORMAT:
|
|
13
|
+
|
|
14
|
+
Return your findings in the following JSON format:
|
|
15
|
+
|
|
16
|
+
{
|
|
17
|
+
"issues": [
|
|
18
|
+
{
|
|
19
|
+
"file": "relative/path/to/file.ts",
|
|
20
|
+
"startLine": 40,
|
|
21
|
+
"endLine": 45,
|
|
22
|
+
"description": "Detailed explanation (see requirements below)",
|
|
23
|
+
"dataFlow": [
|
|
24
|
+
{ "file": "src/routes/handler.ts", "lineNumber": 12, "label": "User input received from request parameter" },
|
|
25
|
+
{ "file": "src/services/query.ts", "lineNumber": 38, "label": "Input passed to SQL query without sanitization" }
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
DESCRIPTION FORMATTING REQUIREMENTS:
|
|
32
|
+
|
|
33
|
+
Your description field MUST be detailed and well-structured:
|
|
34
|
+
- Use markdown formatting with headings (## Heading), bullet points
|
|
35
|
+
- Use \n for line breaks to create structured, readable content
|
|
36
|
+
- No need for "Example Attack" or a "Details" sections
|
|
37
|
+
- Keep description as short as possible.
|
|
38
|
+
|
|
39
|
+
DATA FLOW REQUIREMENTS:
|
|
40
|
+
|
|
41
|
+
When the issue involves data flowing through multiple locations (e.g., user input reaching a dangerous sink), include a "dataFlow" array. Each step represents a point in the call stack or data flow:
|
|
42
|
+
- "file": relative path to the source file
|
|
43
|
+
- "lineNumber": the line number at that step
|
|
44
|
+
- "label": a short description of what happens at this point (e.g., "User input received", "Passed to database query")
|
|
45
|
+
- Order steps from source (e.g., user input) to sink (e.g., SQL execution)
|
|
46
|
+
- Omit "dataFlow" entirely if the issue is localized to a single location
|
|
47
|
+
|
|
48
|
+
CRITICAL: Return ONLY valid JSON. No markdown code blocks, no explanations outside the JSON.
|
|
49
|
+
|
|
50
|
+
If no issues found for this SPECIFIC check, return: {"issues": []}
|
|
51
|
+
|
|
52
|
+
If a TARGET LOCATION section appears at the end of this prompt, you must analyze ONLY that specific code location.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
CHECK INSTRUCTIONS:
|
|
57
|
+
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check Library / Config Manager.
|
|
3
|
+
* Two-layer config: Layer 1 (registry) maps checks to repos,
|
|
4
|
+
* Layer 2 (<id>.json) defines each check in its own folder.
|
|
5
|
+
* Implements spec Appendix B.1.
|
|
6
|
+
*/
|
|
7
|
+
import type { SecurityCheck, CheckDetails, CheckRegistryEntry, CheckDefinition } from './types.js';
|
|
8
|
+
export interface CheckRegistry {
|
|
9
|
+
checks: CheckRegistryEntry[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Load and parse the Layer 1 registry from <configDir>/checks-config.json.
|
|
13
|
+
* Throws on missing file, malformed JSON, or invalid structure.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadCheckRegistry(configDir: string): Promise<CheckRegistry>;
|
|
16
|
+
/**
|
|
17
|
+
* Load and parse a Layer 2 check definition from <checkFolderPath>/<id>.json.
|
|
18
|
+
* Throws on missing file, malformed JSON, or missing required fields.
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadCheckDefinition(checkFolderPath: string): Promise<CheckDefinition>;
|
|
21
|
+
/**
|
|
22
|
+
* Scan check directories for subfolders containing <id>.json.
|
|
23
|
+
* Returns a map of check id → folder path.
|
|
24
|
+
*/
|
|
25
|
+
export declare function discoverCheckFolders(checksDirs: string[]): Promise<Map<string, string>>;
|
|
26
|
+
/**
|
|
27
|
+
* Merge Layer 1 registry entries with Layer 2 check definitions.
|
|
28
|
+
* Resolves instructionsFile and checkTarget.rules paths relative to check folder.
|
|
29
|
+
* Throws if a registry entry has no matching check folder.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveChecks(registry: CheckRegistry, checkFolders: Map<string, string>): Promise<SecurityCheck[]>;
|
|
32
|
+
export interface CheckLibraryConfig {
|
|
33
|
+
checks: SecurityCheck[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Load and parse a flat JSON config file (old format).
|
|
37
|
+
* Kept for backward compatibility with existing test fixtures.
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadConfig(configPath: string): Promise<CheckLibraryConfig>;
|
|
40
|
+
export interface ValidationResult {
|
|
41
|
+
valid: boolean;
|
|
42
|
+
errors: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Validate a single SecurityCheck definition.
|
|
46
|
+
* Checks that id is present and non-empty, and instructionsFile exists on disk.
|
|
47
|
+
* basePath is used to resolve instructionsFile if it's a relative path.
|
|
48
|
+
* If instructionsFile is already absolute, basePath is ignored.
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateCheck(check: SecurityCheck, basePath: string): Promise<ValidationResult>;
|
|
51
|
+
export { normalizeRepoPath } from './repository-analyzer.js';
|
|
52
|
+
/**
|
|
53
|
+
* Check if a single check matches the given repository URL/path.
|
|
54
|
+
* Empty repositories array matches all repos.
|
|
55
|
+
* Uses bidirectional substring matching on normalized paths.
|
|
56
|
+
*/
|
|
57
|
+
export declare function checkMatchesRepository(check: SecurityCheck, repositoryUrl: string): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Filter checks to those matching the given repository URL/path.
|
|
60
|
+
* Also filters out disabled checks (enabled === false).
|
|
61
|
+
*/
|
|
62
|
+
export declare function filterChecksForRepository(checks: SecurityCheck[], repositoryUrl: string): SecurityCheck[];
|
|
63
|
+
/**
|
|
64
|
+
* Parse a markdown check file into CheckDetails.
|
|
65
|
+
* Extracts name from first ### heading, overview from #### Overview section.
|
|
66
|
+
*/
|
|
67
|
+
export declare function parseCheckMarkdown(id: string, markdown: string): CheckDetails;
|
|
68
|
+
/**
|
|
69
|
+
* Load check instructions from the markdown file referenced by a SecurityCheck.
|
|
70
|
+
* Resolves instructionsFile relative to basePath (or uses absolute path if already resolved).
|
|
71
|
+
*/
|
|
72
|
+
export declare function loadCheckDetails(check: SecurityCheck, basePath: string): Promise<CheckDetails>;
|
|
73
|
+
/**
|
|
74
|
+
* Filter files to those matching applicablePaths globs.
|
|
75
|
+
* If applicablePaths is undefined or empty, returns all files.
|
|
76
|
+
*/
|
|
77
|
+
export declare function filterApplicablePaths(files: string[], applicablePaths?: string[]): string[];
|
|
78
|
+
/**
|
|
79
|
+
* Filter out files matching excludedPaths globs.
|
|
80
|
+
* If excludedPaths is undefined or empty, returns all files.
|
|
81
|
+
*/
|
|
82
|
+
export declare function filterExcludedPaths(files: string[], excludedPaths?: string[]): string[];
|
|
83
|
+
/**
|
|
84
|
+
* Apply both applicablePaths and excludedPaths filtering.
|
|
85
|
+
*/
|
|
86
|
+
export declare function filterCheckPaths(files: string[], check: SecurityCheck): string[];
|
|
87
|
+
//# sourceMappingURL=check-library.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-library.d.ts","sourceRoot":"","sources":["../src/check-library.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,eAAe,EAChB,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA0DjF;AAID;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA8E3F;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA2B9B;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,aAAa,EACvB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,aAAa,EAAE,CAAC,CAmD1B;AAID,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAiChF;AAID,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CAyB3B;AAKD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,aAAa,EACpB,aAAa,EAAE,MAAM,GACpB,OAAO,CAcT;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,aAAa,EAAE,EACvB,aAAa,EAAE,MAAM,GACpB,aAAa,EAAE,CAIjB;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAoB7E;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAgBvB;AAOD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EAAE,EACf,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,MAAM,EAAE,CAOV;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,MAAM,EAAE,CAOV;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,aAAa,GACnB,MAAM,EAAE,CAGV"}
|