cerber-core 1.1.6 → 1.1.8

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/README.md +157 -1
  3. package/bin/cerber +14 -1
  4. package/dev/templates/BACKEND_SCHEMA.ts.tpl +87 -50
  5. package/dev/templates/cerber-guardian.mjs.tpl +255 -148
  6. package/dev/templates/cerber.yml.tpl +96 -53
  7. package/dev/templates/pre-commit.tpl +4 -4
  8. package/dist/cli/contract-parser.d.ts.map +1 -1
  9. package/dist/cli/contract-parser.js +47 -20
  10. package/dist/cli/contract-parser.js.map +1 -1
  11. package/dist/cli/doctor.d.ts +16 -0
  12. package/dist/cli/doctor.d.ts.map +1 -0
  13. package/dist/cli/doctor.js +140 -0
  14. package/dist/cli/doctor.js.map +1 -0
  15. package/dist/cli/init.d.ts.map +1 -1
  16. package/dist/cli/init.js +98 -8
  17. package/dist/cli/init.js.map +1 -1
  18. package/dist/cli/override-validator.d.ts +27 -0
  19. package/dist/cli/override-validator.d.ts.map +1 -0
  20. package/dist/cli/override-validator.js +100 -0
  21. package/dist/cli/override-validator.js.map +1 -0
  22. package/dist/cli/template-generator.d.ts.map +1 -1
  23. package/dist/cli/template-generator.js +71 -16
  24. package/dist/cli/template-generator.js.map +1 -1
  25. package/dist/cli/types.d.ts +7 -0
  26. package/dist/cli/types.d.ts.map +1 -1
  27. package/dist/index.d.ts +3 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +3 -3
  30. package/dist/index.js.map +1 -1
  31. package/package.json +117 -117
  32. package/solo/templates/BACKEND_SCHEMA.ts.tpl +87 -50
  33. package/solo/templates/cerber-guardian.mjs.tpl +255 -148
  34. package/solo/templates/cerber.yml.tpl +96 -53
  35. package/solo/templates/pre-commit.tpl +4 -4
  36. package/team/templates/BACKEND_SCHEMA.ts.tpl +87 -50
  37. package/team/templates/CODEOWNERS.tpl +18 -6
  38. package/team/templates/cerber-guardian.mjs.tpl +255 -148
  39. package/team/templates/cerber.yml.tpl +96 -53
  40. package/team/templates/pre-commit.tpl +4 -4
@@ -1,148 +1,255 @@
1
- #!/usr/bin/env node
2
- // Generated by Cerber init - DO NOT EDIT MANUALLY
3
- // To regenerate: npx cerber init --force
4
-
5
- import { execSync } from 'child_process';
6
- import fs from 'fs';
7
- import { join } from 'path';
8
-
9
- const SCHEMA_FILE = '{{SCHEMA_FILE}}';
10
- const APPROVALS_TAG = '{{APPROVALS_TAG}}';
11
-
12
- async function main() {
13
- console.log('🛡️ Cerber Guardian: Validating staged files...');
14
-
15
- if (!fs.existsSync(SCHEMA_FILE)) {
16
- console.error(`❌ Schema file not found: ${SCHEMA_FILE}`);
17
- console.error('Create your schema file to enable validation.');
18
- console.error(`Example: npx cerber init --print-schema-template > ${SCHEMA_FILE}`);
19
- process.exit(1);
20
- }
21
-
22
- // Import schema
23
- let schema;
24
- try {
25
- const schemaPath = join(process.cwd(), SCHEMA_FILE);
26
- const schemaModule = await import(`file://${schemaPath}`);
27
- schema = schemaModule.BACKEND_SCHEMA || schemaModule.default || schemaModule;
28
- } catch (err) {
29
- console.error(`❌ Failed to load schema from ${SCHEMA_FILE}:`, err.message);
30
- process.exit(1);
31
- }
32
-
33
- // Get staged files
34
- let stagedFiles;
35
- try {
36
- stagedFiles = execSync('git diff --cached --name-only', { encoding: 'utf-8' })
37
- .trim()
38
- .split('\n')
39
- .filter(Boolean);
40
- } catch (err) {
41
- console.error('❌ Failed to get staged files');
42
- process.exit(1);
43
- }
44
-
45
- if (stagedFiles.length === 0) {
46
- console.log('✅ No files staged for commit');
47
- return;
48
- }
49
-
50
- console.log(`Checking ${stagedFiles.length} file(s)...`);
51
-
52
- const violations = [];
53
-
54
- // Validate each staged file
55
- for (const file of stagedFiles) {
56
- if (!fs.existsSync(file)) continue;
57
-
58
- const content = fs.readFileSync(file, 'utf-8');
59
-
60
- // Check forbidden patterns
61
- if (schema.forbiddenPatterns && Array.isArray(schema.forbiddenPatterns)) {
62
- for (const rule of schema.forbiddenPatterns) {
63
- if (!rule.pattern) continue;
64
-
65
- const pattern = typeof rule.pattern === 'string'
66
- ? new RegExp(rule.pattern, rule.flags || 'i')
67
- : rule.pattern;
68
-
69
- // Check if file is in exceptions
70
- if (rule.exceptions && rule.exceptions.some(ex => file.includes(ex))) {
71
- continue;
72
- }
73
-
74
- if (pattern.test(content)) {
75
- // Check for architect approval
76
- const hasApproval = content.includes(APPROVALS_TAG);
77
-
78
- if (!hasApproval) {
79
- violations.push({
80
- file,
81
- rule: rule.name || 'Unnamed rule',
82
- severity: rule.severity || 'error'
83
- });
84
- }
85
- }
86
- }
87
- }
88
-
89
- // Check required imports (rules)
90
- if (schema.rules && Array.isArray(schema.rules)) {
91
- for (const rule of schema.rules) {
92
- if (!rule.pattern || !rule.requiredImports) continue;
93
-
94
- const filePattern = typeof rule.pattern === 'string' ? new RegExp(rule.pattern) : rule.pattern;
95
-
96
- if (!filePattern.test(file)) continue;
97
-
98
- // Check if file is in exceptions
99
- if (rule.exceptions && rule.exceptions.some(ex => file.includes(ex))) {
100
- continue;
101
- }
102
-
103
- // Check each required import
104
- for (const requiredImport of rule.requiredImports) {
105
- const importPattern = new RegExp(`import.*${requiredImport}`, 'i');
106
-
107
- if (!importPattern.test(content)) {
108
- // Check for architect approval
109
- const hasApproval = content.includes(APPROVALS_TAG);
110
-
111
- if (!hasApproval) {
112
- violations.push({
113
- file,
114
- rule: `${rule.name || 'Unnamed rule'}: missing import '${requiredImport}'`,
115
- severity: rule.severity || 'error'
116
- });
117
- }
118
- }
119
- }
120
- }
121
- }
122
- }
123
-
124
- // Report violations
125
- if (violations.length > 0) {
126
- console.error('\n❌ Architecture violations detected:\n');
127
-
128
- for (const v of violations) {
129
- const icon = v.severity === 'error' ? '🔴' : '⚠️';
130
- console.error(`${icon} [${v.severity.toUpperCase()}] ${v.file}`);
131
- console.error(` ${v.rule}`);
132
- console.error(` Add ${APPROVALS_TAG} comment to override\n`);
133
- }
134
-
135
- const errorCount = violations.filter(v => v.severity === 'error').length;
136
- if (errorCount > 0) {
137
- console.error(`\n❌ Commit blocked: ${errorCount} error(s) found`);
138
- process.exit(1);
139
- }
140
- }
141
-
142
- console.log('✅ All checks passed');
143
- }
144
-
145
- main().catch(err => {
146
- console.error('❌ Guardian check failed:', err?.message || err);
147
- process.exit(1);
148
- });
1
+ #!/usr/bin/env node
2
+ // Generated by Cerber init - DO NOT EDIT MANUALLY
3
+ // To regenerate: npx cerber init --force
4
+
5
+ import { execSync } from 'child_process';
6
+ import fs from 'fs';
7
+ import { join } from 'path';
8
+
9
+ const APPROVALS_TAG = '{{APPROVALS_TAG}}';
10
+
11
+ function readYamlValue(text, key) {
12
+ const re = new RegExp(`^\\s*${key}\\s*:\\s*(.*)\\s*$`, "m");
13
+ const m = text.match(re);
14
+ if (!m) return "";
15
+ let v = (m[1] ?? "").trim();
16
+
17
+ // Remove quotes
18
+ v = v.replace(/^["']/,"").replace(/["']$/,"");
19
+ return v.trim();
20
+ }
21
+
22
+ function parseOverride(cerberContent) {
23
+ const enabledRaw = readYamlValue(cerberContent, "enabled");
24
+ const enabled = enabledRaw.toLowerCase() === "true";
25
+
26
+ const reason = readYamlValue(cerberContent, "reason");
27
+ const expiresRaw = readYamlValue(cerberContent, "expires");
28
+ const approvedBy = readYamlValue(cerberContent, "approvedBy");
29
+
30
+ if (!enabled) return { state: "DISABLED", reason, expires: expiresRaw, approvedBy };
31
+
32
+ if (!expiresRaw) return { state: "ACTIVE", reason, expires: "", approvedBy };
33
+
34
+ const expiresDate = new Date(expiresRaw);
35
+ if (Number.isNaN(expiresDate.getTime())) {
36
+ return { state: "INVALID", reason, expires: expiresRaw, approvedBy };
37
+ }
38
+
39
+ if (expiresDate.getTime() < Date.now()) {
40
+ return { state: "EXPIRED", reason, expires: expiresRaw, approvedBy };
41
+ }
42
+
43
+ return { state: "ACTIVE", reason, expires: expiresRaw, approvedBy };
44
+ }
45
+
46
+ async function main() {
47
+ console.log('🛡️ Cerber Guardian: Validating staged files...');
48
+
49
+ // Check for emergency override
50
+ const cerberMdPath = join(process.cwd(), 'CERBER.md');
51
+ if (fs.existsSync(cerberMdPath)) {
52
+ const cerberContent = fs.readFileSync(cerberMdPath, 'utf-8');
53
+ const overrideMatch = cerberContent.match(/CERBER_OVERRIDE:\s*\n\s*enabled:\s*(true|false)/);
54
+
55
+ if (overrideMatch && overrideMatch[1] === 'true') {
56
+ const override = parseOverride(cerberContent);
57
+ const { state, reason, expires, approvedBy } = override;
58
+
59
+ if (state === 'ACTIVE') {
60
+ // Override ACTIVE - allow commit with warning
61
+ console.log('');
62
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
63
+ console.log('⚠️ CERBER EMERGENCY OVERRIDE ACTIVE');
64
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
65
+ console.log('');
66
+ console.log(`Status: ACTIVE`);
67
+ console.log(`Reason: ${reason}`);
68
+ console.log(`Expires: ${expires}`);
69
+ console.log(`Approved By: ${approvedBy}`);
70
+ console.log('');
71
+ console.log('Guardian checks: BYPASSED WITH WARNING');
72
+ console.log('Self-protection: STILL ACTIVE (cerber-integrity runs)');
73
+ console.log('');
74
+ console.log('⚠️ Create follow-up PR to fix properly + disable override');
75
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
76
+ console.log('');
77
+ process.exit(0); // Allow commit
78
+ } else if (state === 'EXPIRED') {
79
+ console.log('⚠️ Override expired - proceeding with normal validation');
80
+ } else {
81
+ console.log('⚠️ Override invalid (missing required fields) - proceeding with normal validation');
82
+ }
83
+ }
84
+ }
85
+
86
+ // Load schema from CERBER.md
87
+ if (!fs.existsSync(cerberMdPath)) {
88
+ console.error('❌ CERBER.md not found');
89
+ console.error('Run: npx cerber init');
90
+ process.exit(5);
91
+ }
92
+
93
+ const cerberContent = fs.readFileSync(cerberMdPath, 'utf-8');
94
+
95
+ // Parse SCHEMA section
96
+ const schemaMatch = cerberContent.match(/SCHEMA:\s*\n\s*mode:\s*(\w+)/);
97
+ if (!schemaMatch) {
98
+ console.error('❌ SCHEMA section not found in CERBER.md');
99
+ console.error('Add SCHEMA section with mode: required or mode: disabled');
100
+ process.exit(5);
101
+ }
102
+
103
+ const schemaMode = schemaMatch[1];
104
+ if (schemaMode === 'disabled') {
105
+ console.log('⚠️ Schema validation disabled (SCHEMA.mode: disabled)');
106
+ console.log('✅ Bypassing validation');
107
+ return;
108
+ }
109
+
110
+ // Extract forbidden patterns
111
+ const forbiddenPatterns = [];
112
+ const patternsMatch = cerberContent.match(/forbiddenPatterns:\s*\n([\s\S]*?)(?=\n\w|\nSCHEMA:|$)/);
113
+ if (patternsMatch) {
114
+ const patternLines = patternsMatch[1].match(/- "([^"]+)"/g);
115
+ if (patternLines) {
116
+ patternLines.forEach(line => {
117
+ const pattern = line.match(/- "([^"]+)"/)?.[1];
118
+ if (pattern) {
119
+ forbiddenPatterns.push({
120
+ pattern: pattern,
121
+ name: `Forbidden: ${pattern}`,
122
+ severity: 'error'
123
+ });
124
+ }
125
+ });
126
+ }
127
+ }
128
+
129
+ if (schemaMode === 'required' && forbiddenPatterns.length === 0) {
130
+ console.error('❌ SCHEMA.mode: required but no rules defined');
131
+ console.error('Add forbiddenPatterns to SCHEMA section in CERBER.md');
132
+ process.exit(5);
133
+ }
134
+
135
+ const schema = {
136
+ forbiddenPatterns: forbiddenPatterns,
137
+ rules: []
138
+ };
139
+
140
+ // Get staged files
141
+ let stagedFiles;
142
+ try {
143
+ stagedFiles = execSync('git diff --cached --name-only', { encoding: 'utf-8' })
144
+ .trim()
145
+ .split('\n')
146
+ .filter(Boolean);
147
+ } catch (err) {
148
+ console.error('❌ Failed to get staged files');
149
+ process.exit(1);
150
+ }
151
+
152
+ if (stagedFiles.length === 0) {
153
+ console.log('✅ No files staged for commit');
154
+ return;
155
+ }
156
+
157
+ console.log(`Checking ${stagedFiles.length} file(s)...`);
158
+
159
+ const violations = [];
160
+
161
+ // Validate each staged file
162
+ for (const file of stagedFiles) {
163
+ if (!fs.existsSync(file)) continue;
164
+
165
+ const content = fs.readFileSync(file, 'utf-8');
166
+
167
+ // Check forbidden patterns
168
+ if (schema.forbiddenPatterns && Array.isArray(schema.forbiddenPatterns)) {
169
+ for (const rule of schema.forbiddenPatterns) {
170
+ if (!rule.pattern) continue;
171
+
172
+ const pattern = typeof rule.pattern === 'string'
173
+ ? new RegExp(rule.pattern, rule.flags || 'i')
174
+ : rule.pattern;
175
+
176
+ // Check if file is in exceptions
177
+ if (rule.exceptions && rule.exceptions.some(ex => file.includes(ex))) {
178
+ continue;
179
+ }
180
+
181
+ if (pattern.test(content)) {
182
+ // Check for architect approval
183
+ const hasApproval = content.includes(APPROVALS_TAG);
184
+
185
+ if (!hasApproval) {
186
+ violations.push({
187
+ file,
188
+ rule: rule.name || 'Unnamed rule',
189
+ severity: rule.severity || 'error'
190
+ });
191
+ }
192
+ }
193
+ }
194
+ }
195
+
196
+ // Check required imports (rules)
197
+ if (schema.rules && Array.isArray(schema.rules)) {
198
+ for (const rule of schema.rules) {
199
+ if (!rule.pattern || !rule.requiredImports) continue;
200
+
201
+ const filePattern = typeof rule.pattern === 'string' ? new RegExp(rule.pattern) : rule.pattern;
202
+
203
+ if (!filePattern.test(file)) continue;
204
+
205
+ // Check if file is in exceptions
206
+ if (rule.exceptions && rule.exceptions.some(ex => file.includes(ex))) {
207
+ continue;
208
+ }
209
+
210
+ // Check each required import
211
+ for (const requiredImport of rule.requiredImports) {
212
+ const importPattern = new RegExp(`import.*${requiredImport}`, 'i');
213
+
214
+ if (!importPattern.test(content)) {
215
+ // Check for architect approval
216
+ const hasApproval = content.includes(APPROVALS_TAG);
217
+
218
+ if (!hasApproval) {
219
+ violations.push({
220
+ file,
221
+ rule: `${rule.name || 'Unnamed rule'}: missing import '${requiredImport}'`,
222
+ severity: rule.severity || 'error'
223
+ });
224
+ }
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ // Report violations
232
+ if (violations.length > 0) {
233
+ console.error('\n❌ Architecture violations detected:\n');
234
+
235
+ for (const v of violations) {
236
+ const icon = v.severity === 'error' ? '🔴' : '⚠️';
237
+ console.error(`${icon} [${v.severity.toUpperCase()}] ${v.file}`);
238
+ console.error(` ${v.rule}`);
239
+ console.error(` Add ${APPROVALS_TAG} comment to override\n`);
240
+ }
241
+
242
+ const errorCount = violations.filter(v => v.severity === 'error').length;
243
+ if (errorCount > 0) {
244
+ console.error(`\n❌ Commit blocked: ${errorCount} error(s) found`);
245
+ process.exit(1);
246
+ }
247
+ }
248
+
249
+ console.log('✅ All checks passed');
250
+ }
251
+
252
+ main().catch(err => {
253
+ console.error('❌ Guardian check failed:', err?.message || err);
254
+ process.exit(1);
255
+ });
@@ -1,53 +1,96 @@
1
- # Generated by Cerber init
2
- name: Cerber CI
3
-
4
- on:
5
- push:
6
- branches: {{CI_BRANCHES}}
7
- pull_request:
8
- branches: {{CI_BRANCHES}}
9
- workflow_dispatch:
10
-
11
- jobs:
12
- cerber-ci:
13
- name: Cerber CI
14
- runs-on: ubuntu-latest
15
-
16
- steps:
17
- - name: Checkout code
18
- uses: actions/checkout@v4
19
-
20
- - name: Setup Node.js
21
- uses: actions/setup-node@v4
22
- with:
23
- node-version: '20'
24
- cache: 'npm'
25
-
26
- - name: Install dependencies
27
- run: npm ci
28
-
29
- - name: Build (if script exists)
30
- run: |
31
- if npm run | grep -q "build"; then
32
- npm run build
33
- else
34
- echo "No build script defined; skipping"
35
- fi
36
-
37
- - name: Test (if script exists)
38
- run: |
39
- if npm run | grep -q "test"; then
40
- npm test
41
- else
42
- echo "No test script defined; skipping"
43
- fi
44
-
45
- - name: Run Guardian
46
- run: |
47
- if npm run | grep -q "cerber:guardian"; then
48
- npm run cerber:guardian
49
- else
50
- node scripts/cerber-guardian.mjs
51
- fi
52
-
53
- {{POST_DEPLOY_BLOCK}}
1
+ # Generated by Cerber init
2
+ name: Cerber CI
3
+
4
+ on:
5
+ push:
6
+ branches: {{CI_BRANCHES}}
7
+ pull_request:
8
+ branches: {{CI_BRANCHES}}
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ cerber-integrity:
13
+ name: Cerber Self-Protection
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Verify protected files exist
21
+ run: |
22
+ echo "🛡️ Cerber Integrity Check"
23
+ MISSING=0
24
+
25
+ # Check core files
26
+ [ ! -f "CERBER.md" ] && echo "❌ CERBER.md missing" && MISSING=1
27
+ [ ! -f ".github/workflows/cerber.yml" ] && echo "❌ cerber.yml missing" && MISSING=1
28
+ [ ! -f "scripts/cerber-guardian.mjs" ] && echo "❌ cerber-guardian.mjs missing" && MISSING=1
29
+ [ ! -f ".husky/pre-commit" ] && echo "❌ pre-commit hook missing" && MISSING=1
30
+
31
+ # Check schema file (strict mode only)
32
+ SCHEMA_MODE=$(grep -A 10 "^schema:" CERBER.md | grep "mode:" | awk '{print $2}' | head -1)
33
+ if [ "$SCHEMA_MODE" = "strict" ]; then
34
+ SCHEMA_FILE=$(grep -A 10 "^schema:" CERBER.md | grep "file:" | awk '{print $2}' | head -1)
35
+ [ ! -f "$SCHEMA_FILE" ] && echo "❌ Schema file $SCHEMA_FILE missing (strict mode)" && MISSING=1
36
+ fi
37
+
38
+ if [ $MISSING -eq 1 ]; then
39
+ echo "🚨 Protected files missing. Cerber self-protection compromised."
40
+ exit 1
41
+ fi
42
+
43
+ echo "✅ All protected files present"
44
+
45
+ - name: Verify cerber-ci job exists
46
+ run: |
47
+ if ! grep -q "cerber-ci:" .github/workflows/cerber.yml; then
48
+ echo "🚨 Job 'cerber-ci' not found in cerber.yml"
49
+ echo "Never rename or remove the cerber-ci job ID"
50
+ exit 1
51
+ fi
52
+ echo "✅ cerber-ci job ID intact"
53
+
54
+ cerber-ci:
55
+ name: Cerber CI
56
+ runs-on: ubuntu-latest
57
+ needs: [cerber-integrity]
58
+
59
+ steps:
60
+ - name: Checkout code
61
+ uses: actions/checkout@v4
62
+
63
+ - name: Setup Node.js
64
+ uses: actions/setup-node@v4
65
+ with:
66
+ node-version: '20'
67
+ cache: 'npm'
68
+
69
+ - name: Install dependencies
70
+ run: npm ci
71
+
72
+ - name: Build (if script exists)
73
+ run: |
74
+ if npm run | grep -q "build"; then
75
+ npm run build
76
+ else
77
+ echo "No build script defined; skipping"
78
+ fi
79
+
80
+ - name: Test (if script exists)
81
+ run: |
82
+ if npm run | grep -q "test"; then
83
+ npm test
84
+ else
85
+ echo "No test script defined; skipping"
86
+ fi
87
+
88
+ - name: Run Guardian
89
+ run: |
90
+ if npm run | grep -q "cerber:guardian"; then
91
+ npm run cerber:guardian
92
+ else
93
+ node scripts/cerber-guardian.mjs
94
+ fi
95
+
96
+ {{POST_DEPLOY_BLOCK}}
@@ -1,4 +1,4 @@
1
- #!/bin/sh
2
- # Generated by Cerber init
3
-
4
- npm run cerber:guardian
1
+ #!/bin/sh
2
+ # Generated by Cerber init
3
+
4
+ npm run cerber:guardian
@@ -1 +1 @@
1
- {"version":3,"file":"contract-parser.d.ts","sourceRoot":"","sources":["../../src/cli/contract-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMjE,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAU3F;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CA8EpE;AAyID,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,MAAM,GAAG,KAAK,GAAG,MAAc,GAAG,cAAc,CAqCxF"}
1
+ {"version":3,"file":"contract-parser.d.ts","sourceRoot":"","sources":["../../src/cli/contract-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMjE,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAU3F;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CA4HpE;AA+HD,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,MAAM,GAAG,KAAK,GAAG,MAAc,GAAG,cAAc,CAqCxF"}