@panguard-ai/panguard 1.4.14 → 1.4.16

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 (44) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cli/commands/scan.d.ts.map +1 -1
  3. package/dist/cli/commands/scan.js +56 -1
  4. package/dist/cli/commands/scan.js.map +1 -1
  5. package/dist/cli/commands/setup.d.ts.map +1 -1
  6. package/dist/cli/commands/setup.js +15 -2
  7. package/dist/cli/commands/setup.js.map +1 -1
  8. package/dist/cli/commands/up.d.ts.map +1 -1
  9. package/dist/cli/commands/up.js +180 -24
  10. package/dist/cli/commands/up.js.map +1 -1
  11. package/dist/cli/index.js +0 -0
  12. package/package.json +1 -1
  13. package/dist/cli/commands/admin.d.ts +0 -9
  14. package/dist/cli/commands/admin.d.ts.map +0 -1
  15. package/dist/cli/commands/admin.js +0 -130
  16. package/dist/cli/commands/admin.js.map +0 -1
  17. package/dist/cli/commands/manager.d.ts +0 -7
  18. package/dist/cli/commands/manager.d.ts.map +0 -1
  19. package/dist/cli/commands/manager.js +0 -113
  20. package/dist/cli/commands/manager.js.map +0 -1
  21. package/dist/cli/commands/serve-admin.d.ts +0 -11
  22. package/dist/cli/commands/serve-admin.d.ts.map +0 -1
  23. package/dist/cli/commands/serve-admin.js +0 -302
  24. package/dist/cli/commands/serve-admin.js.map +0 -1
  25. package/dist/cli/commands/serve-auth.d.ts +0 -11
  26. package/dist/cli/commands/serve-auth.d.ts.map +0 -1
  27. package/dist/cli/commands/serve-auth.js +0 -119
  28. package/dist/cli/commands/serve-auth.js.map +0 -1
  29. package/dist/cli/commands/serve-core.d.ts +0 -25
  30. package/dist/cli/commands/serve-core.d.ts.map +0 -1
  31. package/dist/cli/commands/serve-core.js +0 -215
  32. package/dist/cli/commands/serve-core.js.map +0 -1
  33. package/dist/cli/commands/serve-tc.d.ts +0 -12
  34. package/dist/cli/commands/serve-tc.d.ts.map +0 -1
  35. package/dist/cli/commands/serve-tc.js +0 -287
  36. package/dist/cli/commands/serve-tc.js.map +0 -1
  37. package/dist/cli/commands/serve-types.d.ts +0 -38
  38. package/dist/cli/commands/serve-types.d.ts.map +0 -1
  39. package/dist/cli/commands/serve-types.js +0 -108
  40. package/dist/cli/commands/serve-types.js.map +0 -1
  41. package/dist/cli/commands/serve.d.ts +0 -14
  42. package/dist/cli/commands/serve.d.ts.map +0 -1
  43. package/dist/cli/commands/serve.js +0 -383
  44. package/dist/cli/commands/serve.js.map +0 -1
@@ -1,215 +0,0 @@
1
- /**
2
- * Core middleware, health check, static file serving, and rule seeding
3
- * for panguard serve.
4
- */
5
- import { join, dirname, resolve, relative } from 'node:path';
6
- import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
7
- import { fileURLToPath } from 'node:url';
8
- import { c } from '@panguard-ai/core';
9
- import { generateOpenApiSpec, generateSwaggerHtml } from '@panguard-ai/panguard-auth';
10
- import { sendJson } from './serve-types.js';
11
- // ── Security Headers & CORS Middleware ─────────────────────────
12
- /**
13
- * Apply security headers and CORS to every response.
14
- * Returns true if the request was fully handled (OPTIONS preflight).
15
- */
16
- export function applyMiddleware(req, res) {
17
- // Security headers
18
- res.setHeader('X-Content-Type-Options', 'nosniff');
19
- res.setHeader('X-Frame-Options', 'SAMEORIGIN');
20
- res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
21
- res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');
22
- res.setHeader('X-XSS-Protection', '0');
23
- if (process.env['NODE_ENV'] === 'production') {
24
- res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
25
- }
26
- // CORS -- default to same-origin only; set CORS_ALLOWED_ORIGINS to allow cross-origin
27
- const corsEnv = process.env['CORS_ALLOWED_ORIGINS'] ?? '';
28
- const allowedOrigins = corsEnv ? corsEnv.split(',').map((o) => o.trim()) : [];
29
- const origin = req.headers.origin ?? '';
30
- if (allowedOrigins.includes('*') && process.env['NODE_ENV'] !== 'production') {
31
- res.setHeader('Access-Control-Allow-Origin', origin || '*');
32
- }
33
- else if (origin && allowedOrigins.includes(origin)) {
34
- res.setHeader('Access-Control-Allow-Origin', origin);
35
- }
36
- res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE, OPTIONS');
37
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
38
- if (req.method === 'OPTIONS') {
39
- res.writeHead(204);
40
- res.end();
41
- return true;
42
- }
43
- return false;
44
- }
45
- // ── Core Routes (health, OpenAPI, static) ──────────────────────
46
- /**
47
- * Handle core routes: /health, /openapi.json, /docs/api, /admin/*.
48
- * Returns true if the route was handled, false otherwise.
49
- */
50
- export function handleCoreRoutes(req, res, pathname, db, threatDb, adminDir) {
51
- // OpenAPI spec (JSON)
52
- if (pathname === '/openapi.json') {
53
- const spec = generateOpenApiSpec(process.env['PANGUARD_BASE_URL'] ?? `http://${req.headers.host ?? 'localhost'}`);
54
- sendJson(res, 200, spec);
55
- return true;
56
- }
57
- // Swagger UI
58
- if (pathname === '/docs/api' || pathname === '/docs/api/') {
59
- const specUrl = '/openapi.json';
60
- const html = generateSwaggerHtml(specUrl);
61
- res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
62
- res.end(html);
63
- return true;
64
- }
65
- // Health check (minimal public response -- detailed status behind /api/admin/health)
66
- if (pathname === '/health') {
67
- try {
68
- db.healthCheck();
69
- sendJson(res, 200, {
70
- ok: true,
71
- data: {
72
- status: 'healthy',
73
- uptime: Math.round(process.uptime()),
74
- db: 'connected',
75
- threatCloud: threatDb ? 'connected' : 'unavailable',
76
- },
77
- });
78
- }
79
- catch {
80
- sendJson(res, 503, {
81
- ok: false,
82
- data: { status: 'unhealthy', db: 'disconnected' },
83
- });
84
- }
85
- return true;
86
- }
87
- // Admin static files
88
- if (adminDir && pathname.startsWith('/admin')) {
89
- serveStaticFile(req, res, adminDir, pathname);
90
- return true;
91
- }
92
- return false;
93
- }
94
- // ── Static File Serving ────────────────────────────────────────
95
- function serveStaticFile(_req, res, adminDir, pathname) {
96
- // Map /admin -> /admin/index.html
97
- const resolvedAdminDir = resolve(adminDir);
98
- let filePath;
99
- if (pathname === '/admin' || pathname === '/admin/') {
100
- filePath = join(resolvedAdminDir, 'index.html');
101
- }
102
- else {
103
- // Strip /admin prefix and leading slash
104
- const relativePath = pathname.slice('/admin'.length).replace(/^\//, '');
105
- filePath = join(resolvedAdminDir, relativePath);
106
- // If no extension, try .html
107
- if (!relativePath.includes('.')) {
108
- filePath = join(resolvedAdminDir, relativePath + '.html');
109
- if (!existsSync(filePath)) {
110
- filePath = join(resolvedAdminDir, relativePath, 'index.html');
111
- }
112
- }
113
- }
114
- // Prevent path traversal: resolved path must be within admin directory
115
- if (!filePath.startsWith(resolvedAdminDir)) {
116
- sendJson(res, 403, { ok: false, error: 'Forbidden' });
117
- return;
118
- }
119
- if (!existsSync(filePath)) {
120
- sendJson(res, 404, { ok: false, error: 'Not found' });
121
- return;
122
- }
123
- const ext = filePath.split('.').pop() ?? '';
124
- const mimeTypes = {
125
- html: 'text/html',
126
- css: 'text/css',
127
- js: 'application/javascript',
128
- json: 'application/json',
129
- png: 'image/png',
130
- svg: 'image/svg+xml',
131
- ico: 'image/x-icon',
132
- };
133
- const contentType = mimeTypes[ext] ?? 'application/octet-stream';
134
- const content = readFileSync(filePath);
135
- res.writeHead(200, { 'Content-Type': contentType });
136
- res.end(content);
137
- }
138
- // ── Rule Seeding ───────────────────────────────────────────────
139
- /**
140
- * Seed rules from bundled config/ directory into Threat Cloud DB.
141
- * Reads ATR YAML files.
142
- * Returns count of rules seeded.
143
- */
144
- export async function seedRulesFromBundled(threatDb) {
145
- let seeded = 0;
146
- const now = new Date().toISOString();
147
- // Resolve config directory (Docker: /app/config, monorepo: ../../config)
148
- const configDirs = [
149
- join(process.cwd(), 'config'),
150
- join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..', '..', '..', 'config'),
151
- ];
152
- const configDir = configDirs.find((d) => {
153
- try {
154
- return statSync(d).isDirectory();
155
- }
156
- catch {
157
- return false;
158
- }
159
- });
160
- if (!configDir) {
161
- console.log(` ${c.dim(' No config/ directory found -- skipping rule seeding')}`);
162
- console.log(` ${c.dim(` Searched: ${configDirs.join(', ')}`)}`);
163
- return 0;
164
- }
165
- console.log(` ${c.dim(` Using config directory: ${configDir}`)}`);
166
- /** Recursively collect files matching extensions */
167
- function collectFiles(dir, extensions) {
168
- const results = [];
169
- try {
170
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
171
- const fullPath = join(dir, entry.name);
172
- if (entry.isDirectory()) {
173
- results.push(...collectFiles(fullPath, extensions));
174
- }
175
- else if (extensions.some((ext) => entry.name.endsWith(ext))) {
176
- results.push(fullPath);
177
- }
178
- }
179
- }
180
- catch (err) {
181
- console.error(` [WARN] Cannot read directory ${dir}: ${err instanceof Error ? err.message : String(err)}`);
182
- }
183
- return results;
184
- }
185
- // ATR rules (.yaml, .yml) from atr package
186
- const atrDirs = [
187
- join(process.cwd(), 'node_modules', 'agent-threat-rules', 'rules'),
188
- join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..', '..', '..', 'packages', 'atr', 'rules'),
189
- ];
190
- const atrDir = atrDirs.find((d) => {
191
- try {
192
- return statSync(d).isDirectory();
193
- }
194
- catch {
195
- return false;
196
- }
197
- });
198
- if (atrDir) {
199
- try {
200
- const atrFiles = collectFiles(atrDir, ['.yaml', '.yml']);
201
- for (const file of atrFiles) {
202
- const content = readFileSync(file, 'utf-8');
203
- const ruleId = `atr:${relative(atrDir, file).replace(/\//g, ':')}`;
204
- threatDb.upsertRule({ ruleId, ruleContent: content, publishedAt: now, source: 'atr' });
205
- seeded++;
206
- }
207
- console.log(` ${c.dim(` ATR: ${atrFiles.length} files processed`)}`);
208
- }
209
- catch (err) {
210
- console.error(` [WARN] ATR rule seeding failed: ${err instanceof Error ? err.message : String(err)}`);
211
- }
212
- }
213
- return seeded;
214
- }
215
- //# sourceMappingURL=serve-core.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve-core.js","sourceRoot":"","sources":["../../../src/cli/commands/serve-core.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,kEAAkE;AAElE;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAoB,EAAE,GAAmB;IACvE,mBAAmB;IACnB,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;IACnD,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;IAC/C,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,iCAAiC,CAAC,CAAC;IACpE,GAAG,CAAC,SAAS,CAAC,oBAAoB,EAAE,0CAA0C,CAAC,CAAC;IAChF,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,EAAE,CAAC;QAC7C,GAAG,CAAC,SAAS,CAAC,2BAA2B,EAAE,8CAA8C,CAAC,CAAC;IAC7F,CAAC;IAED,sFAAsF;IACtF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC;IAC1D,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IACxC,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,EAAE,CAAC;QAC7E,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,MAAM,IAAI,GAAG,CAAC,CAAC;IAC9D,CAAC;SAAM,IAAI,MAAM,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;IACD,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,mCAAmC,CAAC,CAAC;IACnF,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,6BAA6B,CAAC,CAAC;IAE7E,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACnB,GAAG,CAAC,GAAG,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kEAAkE;AAElE;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAoB,EACpB,GAAmB,EACnB,QAAgB,EAChB,EAA2B,EAC3B,QAA+B,EAC/B,QAA4B;IAE5B,sBAAsB;IACtB,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,mBAAmB,CAC9B,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAChF,CAAC;QACF,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,aAAa;IACb,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,eAAe,CAAC;QAChC,MAAM,IAAI,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC1C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACnE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qFAAqF;IACrF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,EAAE,CAAC,WAAW,EAAE,CAAC;YACjB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE;oBACJ,MAAM,EAAE,SAAS;oBACjB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;oBACpC,EAAE,EAAE,WAAW;oBACf,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;iBACpD;aACF,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,cAAc,EAAE;aAClD,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qBAAqB;IACrB,IAAI,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9C,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kEAAkE;AAElE,SAAS,eAAe,CACtB,IAAqB,EACrB,GAAmB,EACnB,QAAgB,EAChB,QAAgB;IAEhB,kCAAkC;IAClC,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,QAAgB,CAAC;IACrB,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpD,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,wCAAwC;QACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxE,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;QAEhD,6BAA6B;QAC7B,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC;YAC1D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC3C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACtD,OAAO;IACT,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACtD,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAC5C,MAAM,SAAS,GAA2B;QACxC,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,UAAU;QACf,EAAE,EAAE,wBAAwB;QAC5B,IAAI,EAAE,kBAAkB;QACxB,GAAG,EAAE,WAAW;QAChB,GAAG,EAAE,eAAe;QACpB,GAAG,EAAE,cAAc;KACpB,CAAC;IAEF,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;IACjE,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;IACpD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACnB,CAAC;AAED,kEAAkE;AAElE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAA+B;IACxE,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,yEAAyE;IACzE,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC;KACtF,CAAC;IACF,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,uDAAuD,CAAC,EAAE,CAAC,CAAC;QACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,eAAe,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,6BAA6B,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;IAEpE,oDAAoD;IACpD,SAAS,YAAY,CAAC,GAAW,EAAE,UAAoB;QACrD,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;gBAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;gBACtD,CAAC;qBAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;oBAC9D,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CACX,kCAAkC,GAAG,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC7F,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,2CAA2C;IAC3C,MAAM,OAAO,GAAG;QACd,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,oBAAoB,EAAE,OAAO,CAAC;QAClE,IAAI,CACF,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvC,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,KAAK,EACL,OAAO,CACR;KACF,CAAC;IACF,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IACH,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;YACzD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAC5C,MAAM,MAAM,GAAG,OAAO,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;gBACnE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;gBACvF,MAAM,EAAE,CAAC;YACX,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAU,QAAQ,CAAC,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CACX,qCAAqC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACxF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,12 +0,0 @@
1
- /**
2
- * Threat Cloud route handlers for panguard serve.
3
- * Uses centralized Zod schemas from @panguard-ai/core for input validation.
4
- */
5
- import type { IncomingMessage, ServerResponse } from 'node:http';
6
- import type { RouteContext } from './serve-types.js';
7
- /**
8
- * Handle Threat Cloud API routes (/api/threats, /api/rules, /api/stats, etc.).
9
- * Returns true if the route was handled, false otherwise.
10
- */
11
- export declare function handleTCRoutes(req: IncomingMessage, res: ServerResponse, url: string, pathname: string, ctx: RouteContext): Promise<boolean>;
12
- //# sourceMappingURL=serve-tc.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve-tc.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve-tc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAgFrD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,OAAO,CAAC,CAoOlB"}
@@ -1,287 +0,0 @@
1
- /**
2
- * Threat Cloud route handlers for panguard serve.
3
- * Uses centralized Zod schemas from @panguard-ai/core for input validation.
4
- */
5
- import { sendJson, readRequestBody, requireTCWriteAuth, requireTCAdminAuth, requireJsonContentType, checkTCRateLimit, } from './serve-types.js';
6
- import { tryValidateInput, ClientIdSchema, ISODateSchema, PaginationLimitSchema, ReputationSchema, ThreatDataSchema, RulePublishSchema, ATRProposalSchema, ATRFeedbackSchema, SkillThreatSchema, SkillWhitelistItemSchema, } from '@panguard-ai/core';
7
- /** Threat Cloud rate-limited endpoint paths */
8
- const TC_RATE_LIMITED_PATHS = new Set([
9
- '/api/threats',
10
- '/api/rules',
11
- '/api/stats',
12
- '/api/atr-proposals',
13
- '/api/atr-feedback',
14
- '/api/skill-threats',
15
- '/api/atr-rules',
16
- '/api/feeds/ip-blocklist',
17
- '/api/feeds/domain-blocklist',
18
- ]);
19
- /**
20
- * Parse JSON body and validate against a Zod schema.
21
- * Sends 400 response on failure and returns null.
22
- */
23
- async function parseAndValidate(req, res, schema) {
24
- const body = await readRequestBody(req);
25
- let raw;
26
- try {
27
- raw = JSON.parse(body);
28
- }
29
- catch {
30
- sendJson(res, 400, { ok: false, error: 'Invalid JSON body' });
31
- return null;
32
- }
33
- const result = tryValidateInput(schema, raw);
34
- if (!result.ok) {
35
- sendJson(res, 400, { ok: false, error: result.error });
36
- return null;
37
- }
38
- return result.data;
39
- }
40
- /**
41
- * Extract and validate the x-panguard-client-id header.
42
- * Returns the client ID string or null if invalid/missing.
43
- */
44
- function extractClientId(req) {
45
- const raw = req.headers['x-panguard-client-id'];
46
- if (typeof raw !== 'string')
47
- return null;
48
- const result = ClientIdSchema.safeParse(raw);
49
- return result.success ? result.data : null;
50
- }
51
- /**
52
- * Parse URL search params with standard helpers.
53
- */
54
- function parseUrl(url, host) {
55
- return new URL(url, `http://${host ?? 'localhost'}`);
56
- }
57
- /**
58
- * Handle Threat Cloud API routes (/api/threats, /api/rules, /api/stats, etc.).
59
- * Returns true if the route was handled, false otherwise.
60
- */
61
- export async function handleTCRoutes(req, res, url, pathname, ctx) {
62
- const { threatDb, llmReviewer, db } = ctx;
63
- // Only handle TC paths when threatDb is available and path is a TC endpoint
64
- if (!threatDb || !pathname.startsWith('/api/'))
65
- return false;
66
- // Rate limiting for known TC endpoints
67
- if (TC_RATE_LIMITED_PATHS.has(pathname)) {
68
- const clientIP = req.socket.remoteAddress ?? 'unknown';
69
- if (!checkTCRateLimit(clientIP)) {
70
- sendJson(res, 429, { ok: false, error: 'Rate limit exceeded. Try again later.' });
71
- return true;
72
- }
73
- }
74
- // POST /api/threats - Upload anonymized threat data
75
- if (pathname === '/api/threats' && req.method === 'POST') {
76
- if (!requireTCWriteAuth(req, res))
77
- return true;
78
- if (!requireJsonContentType(req, res))
79
- return true;
80
- const data = await parseAndValidate(req, res, ThreatDataSchema);
81
- if (!data)
82
- return true;
83
- // Anonymize IP (zero last octet)
84
- const mutableData = { ...data };
85
- const ip = data.attackSourceIP;
86
- if (ip.includes('.')) {
87
- const parts = ip.split('.');
88
- if (parts.length === 4) {
89
- parts[3] = '0';
90
- mutableData['attackSourceIP'] = parts.join('.');
91
- }
92
- }
93
- threatDb.insertThreat(mutableData);
94
- sendJson(res, 201, { ok: true, data: { message: 'Threat data received' } });
95
- return true;
96
- }
97
- // GET /api/rules - Fetch rules (optional ?since= filter, paginated)
98
- if (pathname === '/api/rules' && req.method === 'GET') {
99
- const urlObj = parseUrl(url, req.headers.host);
100
- const rawSince = urlObj.searchParams.get('since');
101
- if (rawSince) {
102
- const sinceResult = ISODateSchema.safeParse(rawSince);
103
- if (!sinceResult.success) {
104
- sendJson(res, 400, { ok: false, error: 'Invalid since parameter: must be ISO 8601' });
105
- return true;
106
- }
107
- }
108
- const limit = PaginationLimitSchema.parse(urlObj.searchParams.get('limit') ?? '1000');
109
- const rules = rawSince ? threatDb.getRulesSince(rawSince) : threatDb.getAllRules(limit);
110
- sendJson(res, 200, { ok: true, data: rules });
111
- return true;
112
- }
113
- // POST /api/rules - Publish a new community rule
114
- if (pathname === '/api/rules' && req.method === 'POST') {
115
- if (!requireTCWriteAuth(req, res))
116
- return true;
117
- if (!requireJsonContentType(req, res))
118
- return true;
119
- const rule = await parseAndValidate(req, res, RulePublishSchema);
120
- if (!rule)
121
- return true;
122
- const ruleData = {
123
- ...rule,
124
- publishedAt: rule.publishedAt || new Date().toISOString(),
125
- };
126
- threatDb.upsertRule(ruleData);
127
- sendJson(res, 201, { ok: true, data: { message: 'Rule published', ruleId: rule.ruleId } });
128
- return true;
129
- }
130
- // GET /api/stats - Threat statistics
131
- if (pathname === '/api/stats' && req.method === 'GET') {
132
- const stats = threatDb.getStats();
133
- sendJson(res, 200, { ok: true, data: stats });
134
- return true;
135
- }
136
- // POST /api/atr-proposals - Submit ATR rule proposal
137
- if (pathname === '/api/atr-proposals' && req.method === 'POST') {
138
- if (!requireTCWriteAuth(req, res))
139
- return true;
140
- if (!requireJsonContentType(req, res))
141
- return true;
142
- const proposal = await parseAndValidate(req, res, ATRProposalSchema);
143
- if (!proposal)
144
- return true;
145
- const clientId = extractClientId(req);
146
- const proposalData = { ...proposal, clientId };
147
- const pHash = proposal.patternHash;
148
- // Check if this pattern already has a proposal - if so, increment confirmation
149
- const existing = threatDb
150
- .getATRProposals()
151
- .find((p) => p['pattern_hash'] === pHash);
152
- if (existing) {
153
- threatDb.confirmATRProposal(pHash);
154
- sendJson(res, 200, {
155
- ok: true,
156
- data: { message: 'Confirmation recorded', patternHash: pHash },
157
- });
158
- }
159
- else {
160
- threatDb.insertATRProposal(proposalData);
161
- // Fire-and-forget LLM review on first submission
162
- if (llmReviewer?.isAvailable()) {
163
- void llmReviewer.reviewProposal(pHash, proposal.ruleContent).catch((err) => {
164
- console.error(`LLM review error for ${pHash}:`, err);
165
- });
166
- }
167
- sendJson(res, 201, {
168
- ok: true,
169
- data: { message: 'Proposal submitted', patternHash: pHash },
170
- });
171
- }
172
- return true;
173
- }
174
- // GET /api/atr-proposals - List proposals (admin-only)
175
- if (pathname === '/api/atr-proposals' && req.method === 'GET') {
176
- if (!requireTCAdminAuth(req, res, db))
177
- return true;
178
- const urlObj = parseUrl(url, req.headers.host);
179
- const status = urlObj.searchParams.get('status') ?? undefined;
180
- const proposals = threatDb.getATRProposals(status);
181
- sendJson(res, 200, { ok: true, data: proposals });
182
- return true;
183
- }
184
- // POST /api/atr-feedback - Report ATR rule match feedback
185
- if (pathname === '/api/atr-feedback' && req.method === 'POST') {
186
- if (!requireTCWriteAuth(req, res))
187
- return true;
188
- if (!requireJsonContentType(req, res))
189
- return true;
190
- const feedback = await parseAndValidate(req, res, ATRFeedbackSchema);
191
- if (!feedback)
192
- return true;
193
- const cid = extractClientId(req);
194
- threatDb.insertATRFeedback(feedback.ruleId, feedback.isTruePositive, cid);
195
- sendJson(res, 201, { ok: true, data: { message: 'Feedback recorded' } });
196
- return true;
197
- }
198
- // POST /api/skill-threats - Submit skill audit result
199
- if (pathname === '/api/skill-threats' && req.method === 'POST') {
200
- if (!requireTCWriteAuth(req, res))
201
- return true;
202
- if (!requireJsonContentType(req, res))
203
- return true;
204
- const submission = await parseAndValidate(req, res, SkillThreatSchema);
205
- if (!submission)
206
- return true;
207
- const cid = extractClientId(req);
208
- const submissionData = { ...submission, clientId: cid };
209
- threatDb.insertSkillThreat(submissionData);
210
- sendJson(res, 201, { ok: true, data: { message: 'Skill threat recorded' } });
211
- return true;
212
- }
213
- // GET /api/skill-threats - List skill threats (admin-only)
214
- if (pathname === '/api/skill-threats' && req.method === 'GET') {
215
- if (!requireTCAdminAuth(req, res, db))
216
- return true;
217
- const urlObj = parseUrl(url, req.headers.host);
218
- const limit = PaginationLimitSchema.parse(urlObj.searchParams.get('limit') ?? '50');
219
- const threats = threatDb.getSkillThreats(Math.min(limit, 500));
220
- sendJson(res, 200, { ok: true, data: threats });
221
- return true;
222
- }
223
- // GET /api/atr-rules - Fetch confirmed ATR rules (for Guard sync)
224
- if (pathname === '/api/atr-rules' && req.method === 'GET') {
225
- const urlObj = parseUrl(url, req.headers.host);
226
- const since = urlObj.searchParams.get('since') ?? undefined;
227
- const rules = threatDb.getConfirmedATRRules(since);
228
- sendJson(res, 200, { ok: true, data: rules });
229
- return true;
230
- }
231
- // GET /api/feeds/ip-blocklist - IP blocklist feed (plain text)
232
- if (pathname === '/api/feeds/ip-blocklist' && req.method === 'GET') {
233
- const urlObj = parseUrl(url, req.headers.host);
234
- const minReputation = ReputationSchema.parse(urlObj.searchParams.get('minReputation') ?? '70');
235
- const ips = threatDb.getIPBlocklist(minReputation);
236
- res.setHeader('Content-Type', 'text/plain');
237
- res.writeHead(200);
238
- res.end(ips.join('\n'));
239
- return true;
240
- }
241
- // GET /api/feeds/domain-blocklist - Domain blocklist feed (plain text)
242
- if (pathname === '/api/feeds/domain-blocklist' && req.method === 'GET') {
243
- const urlObj = parseUrl(url, req.headers.host);
244
- const minReputation = ReputationSchema.parse(urlObj.searchParams.get('minReputation') ?? '70');
245
- const domains = threatDb.getDomainBlocklist(minReputation);
246
- res.setHeader('Content-Type', 'text/plain');
247
- res.writeHead(200);
248
- res.end(domains.join('\n'));
249
- return true;
250
- }
251
- // POST /api/skill-whitelist - Report safe skill (audit passed)
252
- if (pathname === '/api/skill-whitelist' && req.method === 'POST') {
253
- if (!requireTCWriteAuth(req, res))
254
- return true;
255
- if (!requireJsonContentType(req, res))
256
- return true;
257
- const body = await readRequestBody(req);
258
- let raw;
259
- try {
260
- raw = JSON.parse(body);
261
- }
262
- catch {
263
- sendJson(res, 400, { ok: false, error: 'Invalid JSON body' });
264
- return true;
265
- }
266
- const data = raw;
267
- const skills = 'skills' in data && Array.isArray(data['skills']) ? data['skills'] : [data];
268
- let count = 0;
269
- for (const skill of skills) {
270
- const result = SkillWhitelistItemSchema.safeParse(skill);
271
- if (!result.success)
272
- continue;
273
- threatDb.reportSafeSkill(result.data.skillName, result.data.fingerprintHash);
274
- count++;
275
- }
276
- sendJson(res, 201, { ok: true, data: { message: `${count} skill(s) reported`, count } });
277
- return true;
278
- }
279
- // GET /api/skill-whitelist - Fetch community whitelist
280
- if (pathname === '/api/skill-whitelist' && req.method === 'GET') {
281
- const whitelist = threatDb.getSkillWhitelist();
282
- sendJson(res, 200, { ok: true, data: whitelist });
283
- return true;
284
- }
285
- return false;
286
- }
287
- //# sourceMappingURL=serve-tc.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve-tc.js","sourceRoot":"","sources":["../../../src/cli/commands/serve-tc.ts"],"names":[],"mappings":"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"}
@@ -1,38 +0,0 @@
1
- /**
2
- * Shared types, helpers and middleware for serve sub-modules.
3
- */
4
- import type { IncomingMessage, ServerResponse } from 'node:http';
5
- import type { AuthDB } from '@panguard-ai/panguard-auth';
6
- import type { ManagerProxy } from '@panguard-ai/panguard-auth';
7
- import type { createAuthHandlers } from '@panguard-ai/panguard-auth';
8
- export type ThreatCloudDBInstance = any;
9
- export type LLMReviewerInstance = any;
10
- /** Context passed to every route handler module */
11
- export interface RouteContext {
12
- readonly handlers: ReturnType<typeof createAuthHandlers>;
13
- readonly db: AuthDB;
14
- readonly adminDir: string | undefined;
15
- readonly managerProxy: ManagerProxy;
16
- readonly threatDb: ThreatCloudDBInstance;
17
- readonly llmReviewer: LLMReviewerInstance;
18
- }
19
- export declare function sendJson(res: ServerResponse, status: number, data: unknown): void;
20
- /** Read request body with 1MB size limit */
21
- export declare function readRequestBody(req: IncomingMessage): Promise<string>;
22
- /** Timing-safe string comparison to prevent side-channel attacks */
23
- export declare function timingSafeCompare(a: string, b: string): boolean;
24
- /**
25
- * Require TC_API_KEY auth for write endpoints.
26
- * In production: BLOCK if TC_API_KEY not set (refuse unauthenticated writes).
27
- * In dev: allow passthrough with warning.
28
- */
29
- export declare function requireTCWriteAuth(req: IncomingMessage, res: ServerResponse): boolean;
30
- /**
31
- * Require admin session auth for admin-only GET endpoints.
32
- * Verifies the Bearer token is a valid session with admin role.
33
- */
34
- export declare function requireTCAdminAuth(req: IncomingMessage, res: ServerResponse, db: AuthDB): boolean;
35
- /** Validate Content-Type is application/json for POST requests */
36
- export declare function requireJsonContentType(req: IncomingMessage, res: ServerResponse): boolean;
37
- export declare function checkTCRateLimit(ip: string): boolean;
38
- //# sourceMappingURL=serve-types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve-types.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAIrE,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAExC,MAAM,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEtC,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;IACzD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;CAC3C;AAID,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAGjF;AAID,4CAA4C;AAC5C,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBrE;AAID,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAW/D;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAmBrF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAWjG;AAED,kEAAkE;AAClE,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAOzF;AAOD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CASpD"}