@runtimescope/collector 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/dist/{chunk-6JZXAFPC.js → chunk-TUFSIGGJ.js} +214 -42
- package/dist/chunk-TUFSIGGJ.js.map +1 -0
- package/dist/index.d.ts +32 -3
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/standalone.js +30 -22
- package/dist/standalone.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6JZXAFPC.js.map +0 -1
package/dist/standalone.js
CHANGED
|
@@ -9,8 +9,9 @@ import {
|
|
|
9
9
|
Redactor,
|
|
10
10
|
SessionManager,
|
|
11
11
|
SqliteStore,
|
|
12
|
+
isSqliteAvailable,
|
|
12
13
|
resolveTlsConfig
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-TUFSIGGJ.js";
|
|
14
15
|
|
|
15
16
|
// src/standalone.ts
|
|
16
17
|
import { existsSync } from "fs";
|
|
@@ -70,35 +71,42 @@ async function main() {
|
|
|
70
71
|
} catch {
|
|
71
72
|
}
|
|
72
73
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
if (isSqliteAvailable()) {
|
|
75
|
+
const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1e3;
|
|
76
|
+
for (const projectName of projectManager.listProjects()) {
|
|
77
|
+
const dbPath = projectManager.getProjectDbPath(projectName);
|
|
78
|
+
if (existsSync(dbPath)) {
|
|
79
|
+
try {
|
|
80
|
+
const tempStore = new SqliteStore({ dbPath });
|
|
81
|
+
const deleted = tempStore.deleteOldEvents(cutoffMs);
|
|
82
|
+
if (deleted > 0) {
|
|
83
|
+
console.error(`[RuntimeScope] Pruned ${deleted} events older than ${RETENTION_DAYS}d from "${projectName}"`);
|
|
84
|
+
}
|
|
85
|
+
tempStore.close();
|
|
86
|
+
} catch {
|
|
82
87
|
}
|
|
83
|
-
tempStore.close();
|
|
84
|
-
} catch {
|
|
85
88
|
}
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
let pmStore;
|
|
92
|
+
let discovery;
|
|
93
|
+
if (isSqliteAvailable()) {
|
|
94
|
+
const pmDbPath = join(projectManager.rootDir, "pm.db");
|
|
95
|
+
pmStore = new PmStore({ dbPath: pmDbPath });
|
|
96
|
+
discovery = new ProjectDiscovery(pmStore, projectManager);
|
|
97
|
+
discovery.discoverAll().then((result) => {
|
|
98
|
+
console.error(`[RuntimeScope] PM: ${result.projectsDiscovered} projects, ${result.sessionsDiscovered} sessions discovered`);
|
|
99
|
+
}).catch((err) => {
|
|
100
|
+
console.error("[RuntimeScope] PM discovery error:", err.message);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
96
103
|
const httpServer = new HttpServer(store, void 0, {
|
|
97
104
|
authManager,
|
|
98
105
|
allowedOrigins: corsOrigins,
|
|
99
106
|
rateLimiter: collector.getRateLimiter(),
|
|
100
107
|
pmStore,
|
|
101
|
-
discovery
|
|
108
|
+
discovery,
|
|
109
|
+
getConnectedSessions: () => collector.getConnectedSessions()
|
|
102
110
|
});
|
|
103
111
|
try {
|
|
104
112
|
await httpServer.start({ port: HTTP_PORT, host: HOST, tls: tlsConfig });
|
|
@@ -125,7 +133,7 @@ async function main() {
|
|
|
125
133
|
console.error("[RuntimeScope] Shutting down...");
|
|
126
134
|
await httpServer.stop();
|
|
127
135
|
collector.stop();
|
|
128
|
-
pmStore
|
|
136
|
+
pmStore?.close();
|
|
129
137
|
process.exit(0);
|
|
130
138
|
};
|
|
131
139
|
process.on("SIGINT", () => {
|
package/dist/standalone.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/standalone.ts"],"sourcesContent":["#!/usr/bin/env node\n\n// ============================================================\n// RuntimeScope Standalone Collector\n// Runs CollectorServer + HttpServer as a standalone service\n// without MCP, Playwright, or ProcessMonitor.\n//\n// Usage:\n// node dist/standalone.js\n// npx @runtimescope/collector\n// docker run runtimescope\n// ============================================================\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { CollectorServer } from './server.js';\nimport { HttpServer } from './http-server.js';\nimport { ProjectManager } from './project-manager.js';\nimport { PmStore } from './pm/pm-store.js';\nimport { ProjectDiscovery } from './pm/project-discovery.js';\nimport { SessionManager } from './session-manager.js';\nimport { SqliteStore } from './sqlite-store.js';\nimport { AuthManager } from './auth.js';\nimport { Redactor } from './redactor.js';\nimport { resolveTlsConfig } from './tls.js';\n\nconst HOST = process.env.RUNTIMESCOPE_HOST ?? '127.0.0.1';\n// Standalone defaults to 9092/9093 to avoid conflicting with the MCP server (9090/9091)\nconst COLLECTOR_PORT = parseInt(process.env.RUNTIMESCOPE_PORT ?? '9092', 10);\nconst HTTP_PORT = parseInt(process.env.RUNTIMESCOPE_HTTP_PORT ?? '9093', 10);\nconst BUFFER_SIZE = parseInt(process.env.RUNTIMESCOPE_BUFFER_SIZE ?? '10000', 10);\nconst RETENTION_DAYS = parseInt(process.env.RUNTIMESCOPE_RETENTION_DAYS ?? '30', 10);\n\nasync function main() {\n console.error('[RuntimeScope] Starting standalone collector...');\n\n // 1. Initialize project management + config\n const projectManager = new ProjectManager();\n projectManager.ensureGlobalDir();\n const globalConfig = projectManager.getGlobalConfig();\n\n // 2. Security: auth, TLS, redaction, CORS\n const authManager = new AuthManager({\n enabled: globalConfig.auth?.enabled ?? false,\n apiKeys: globalConfig.auth?.apiKeys ?? [],\n });\n\n const tlsConfig = resolveTlsConfig() ?? globalConfig.tls ?? undefined;\n\n const redactor = new Redactor({\n enabled: globalConfig.redaction?.enabled ?? false,\n useBuiltIn: true,\n rules: globalConfig.redaction?.rules?.map(r => ({\n name: r.name,\n pattern: new RegExp(r.pattern, 'gi'),\n replacement: r.replacement,\n })),\n });\n\n const corsOrigins = process.env.RUNTIMESCOPE_CORS_ORIGINS?.split(',').map(s => s.trim())\n ?? globalConfig.corsOrigins;\n\n if (authManager.isEnabled()) {\n console.error(`[RuntimeScope] Auth enabled (${globalConfig.auth?.apiKeys?.length ?? 0} API keys)`);\n }\n if (tlsConfig) {\n console.error(`[RuntimeScope] TLS enabled (cert: ${tlsConfig.certPath})`);\n }\n if (redactor.isEnabled()) {\n console.error('[RuntimeScope] Payload redaction enabled');\n }\n\n // 3. Start collector WebSocket server\n const collector = new CollectorServer({\n bufferSize: BUFFER_SIZE,\n projectManager,\n authManager,\n rateLimits: globalConfig.rateLimits,\n tls: tlsConfig,\n });\n await collector.start({ port: COLLECTOR_PORT, host: HOST, maxRetries: 5, retryDelayMs: 1000 });\n\n const store = collector.getStore();\n\n // Wire redactor for defense-in-depth\n if (redactor.isEnabled()) {\n store.setRedactor(redactor);\n }\n\n // 4. Session management — auto-snapshot on disconnect\n const sqliteStores = collector.getSqliteStores();\n const sessionManager = new SessionManager(projectManager, sqliteStores, store);\n\n collector.onDisconnect((sessionId, projectName) => {\n try {\n sessionManager.createSnapshot(sessionId, projectName);\n console.error(`[RuntimeScope] Session ${sessionId} metrics saved`);\n } catch {\n // Non-fatal\n }\n });\n\n // 5. Retention pruning\n const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1000;\n for (const projectName of projectManager.listProjects()) {\n const dbPath = projectManager.getProjectDbPath(projectName);\n if (existsSync(dbPath)) {\n try {\n const tempStore = new SqliteStore({ dbPath });\n const deleted = tempStore.deleteOldEvents(cutoffMs);\n if (deleted > 0) {\n console.error(`[RuntimeScope] Pruned ${deleted} events older than ${RETENTION_DAYS}d from \"${projectName}\"`);\n }\n tempStore.close();\n } catch {\n // Non-fatal\n }\n }\n }\n\n // 6. Project Management layer\n const pmDbPath = join(projectManager.rootDir, 'pm.db');\n const pmStore = new PmStore({ dbPath: pmDbPath });\n const discovery = new ProjectDiscovery(pmStore, projectManager);\n\n // Run discovery in background (non-blocking)\n discovery.discoverAll().then((result) => {\n console.error(`[RuntimeScope] PM: ${result.projectsDiscovered} projects, ${result.sessionsDiscovered} sessions discovered`);\n }).catch((err) => {\n console.error('[RuntimeScope] PM discovery error:', (err as Error).message);\n });\n\n // 7. Start HTTP API server (with POST /api/events + PM routes)\n const httpServer = new HttpServer(store, undefined, {\n authManager,\n allowedOrigins: corsOrigins,\n rateLimiter: collector.getRateLimiter(),\n pmStore,\n discovery,\n });\n\n try {\n await httpServer.start({ port: HTTP_PORT, host: HOST, tls: tlsConfig });\n } catch (err) {\n console.error('[RuntimeScope] HTTP API failed to start:', (err as Error).message);\n }\n\n // Push session connect/disconnect to dashboard in real-time\n collector.onConnect((sessionId, projectName) => {\n httpServer.broadcastSessionChange('session_connected', sessionId, projectName);\n });\n collector.onDisconnect((sessionId, projectName) => {\n httpServer.broadcastSessionChange('session_disconnected', sessionId, projectName);\n });\n\n // 7. Startup summary\n const proto = tlsConfig ? 'wss' : 'ws';\n const httpProto = tlsConfig ? 'https' : 'http';\n console.error(`[RuntimeScope] Standalone collector ready`);\n console.error(`[RuntimeScope] WebSocket: ${proto}://${HOST}:${COLLECTOR_PORT}`);\n console.error(`[RuntimeScope] HTTP API: ${httpProto}://${HOST}:${HTTP_PORT}`);\n console.error(`[RuntimeScope] Health: ${httpProto}://${HOST}:${HTTP_PORT}/api/health`);\n console.error(`[RuntimeScope] Ingest: POST ${httpProto}://${HOST}:${HTTP_PORT}/api/events`);\n\n // 8. Graceful shutdown\n let shuttingDown = false;\n const shutdown = async () => {\n if (shuttingDown) return;\n shuttingDown = true;\n console.error('[RuntimeScope] Shutting down...');\n\n await httpServer.stop();\n collector.stop();\n pmStore.close();\n\n process.exit(0);\n };\n\n process.on('SIGINT', () => { shutdown(); });\n process.on('SIGTERM', () => { shutdown(); });\n}\n\nmain().catch((err) => {\n console.error('[RuntimeScope] Fatal error:', err);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/standalone.ts"],"sourcesContent":["#!/usr/bin/env node\n\n// ============================================================\n// RuntimeScope Standalone Collector\n// Runs CollectorServer + HttpServer as a standalone service\n// without MCP, Playwright, or ProcessMonitor.\n//\n// Usage:\n// node dist/standalone.js\n// npx @runtimescope/collector\n// docker run runtimescope\n// ============================================================\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { CollectorServer } from './server.js';\nimport { HttpServer } from './http-server.js';\nimport { ProjectManager } from './project-manager.js';\nimport { PmStore } from './pm/pm-store.js';\nimport { ProjectDiscovery } from './pm/project-discovery.js';\nimport { SessionManager } from './session-manager.js';\nimport { SqliteStore } from './sqlite-store.js';\nimport { isSqliteAvailable } from './sqlite-check.js';\nimport { AuthManager } from './auth.js';\nimport { Redactor } from './redactor.js';\nimport { resolveTlsConfig } from './tls.js';\n\nconst HOST = process.env.RUNTIMESCOPE_HOST ?? '127.0.0.1';\n// Standalone defaults to 9092/9093 to avoid conflicting with the MCP server (9090/9091)\nconst COLLECTOR_PORT = parseInt(process.env.RUNTIMESCOPE_PORT ?? '9092', 10);\nconst HTTP_PORT = parseInt(process.env.RUNTIMESCOPE_HTTP_PORT ?? '9093', 10);\nconst BUFFER_SIZE = parseInt(process.env.RUNTIMESCOPE_BUFFER_SIZE ?? '10000', 10);\nconst RETENTION_DAYS = parseInt(process.env.RUNTIMESCOPE_RETENTION_DAYS ?? '30', 10);\n\nasync function main() {\n console.error('[RuntimeScope] Starting standalone collector...');\n\n // 1. Initialize project management + config\n const projectManager = new ProjectManager();\n projectManager.ensureGlobalDir();\n const globalConfig = projectManager.getGlobalConfig();\n\n // 2. Security: auth, TLS, redaction, CORS\n const authManager = new AuthManager({\n enabled: globalConfig.auth?.enabled ?? false,\n apiKeys: globalConfig.auth?.apiKeys ?? [],\n });\n\n const tlsConfig = resolveTlsConfig() ?? globalConfig.tls ?? undefined;\n\n const redactor = new Redactor({\n enabled: globalConfig.redaction?.enabled ?? false,\n useBuiltIn: true,\n rules: globalConfig.redaction?.rules?.map(r => ({\n name: r.name,\n pattern: new RegExp(r.pattern, 'gi'),\n replacement: r.replacement,\n })),\n });\n\n const corsOrigins = process.env.RUNTIMESCOPE_CORS_ORIGINS?.split(',').map(s => s.trim())\n ?? globalConfig.corsOrigins;\n\n if (authManager.isEnabled()) {\n console.error(`[RuntimeScope] Auth enabled (${globalConfig.auth?.apiKeys?.length ?? 0} API keys)`);\n }\n if (tlsConfig) {\n console.error(`[RuntimeScope] TLS enabled (cert: ${tlsConfig.certPath})`);\n }\n if (redactor.isEnabled()) {\n console.error('[RuntimeScope] Payload redaction enabled');\n }\n\n // 3. Start collector WebSocket server\n const collector = new CollectorServer({\n bufferSize: BUFFER_SIZE,\n projectManager,\n authManager,\n rateLimits: globalConfig.rateLimits,\n tls: tlsConfig,\n });\n await collector.start({ port: COLLECTOR_PORT, host: HOST, maxRetries: 5, retryDelayMs: 1000 });\n\n const store = collector.getStore();\n\n // Wire redactor for defense-in-depth\n if (redactor.isEnabled()) {\n store.setRedactor(redactor);\n }\n\n // 4. Session management — auto-snapshot on disconnect\n const sqliteStores = collector.getSqliteStores();\n const sessionManager = new SessionManager(projectManager, sqliteStores, store);\n\n collector.onDisconnect((sessionId, projectName) => {\n try {\n sessionManager.createSnapshot(sessionId, projectName);\n console.error(`[RuntimeScope] Session ${sessionId} metrics saved`);\n } catch {\n // Non-fatal\n }\n });\n\n // 5. Retention pruning (only if SQLite is available)\n if (isSqliteAvailable()) {\n const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1000;\n for (const projectName of projectManager.listProjects()) {\n const dbPath = projectManager.getProjectDbPath(projectName);\n if (existsSync(dbPath)) {\n try {\n const tempStore = new SqliteStore({ dbPath });\n const deleted = tempStore.deleteOldEvents(cutoffMs);\n if (deleted > 0) {\n console.error(`[RuntimeScope] Pruned ${deleted} events older than ${RETENTION_DAYS}d from \"${projectName}\"`);\n }\n tempStore.close();\n } catch {\n // Non-fatal\n }\n }\n }\n }\n\n // 6. Project Management layer (requires SQLite)\n let pmStore: PmStore | undefined;\n let discovery: ProjectDiscovery | undefined;\n\n if (isSqliteAvailable()) {\n const pmDbPath = join(projectManager.rootDir, 'pm.db');\n pmStore = new PmStore({ dbPath: pmDbPath });\n discovery = new ProjectDiscovery(pmStore, projectManager);\n\n // Run discovery in background (non-blocking)\n discovery.discoverAll().then((result) => {\n console.error(`[RuntimeScope] PM: ${result.projectsDiscovered} projects, ${result.sessionsDiscovered} sessions discovered`);\n }).catch((err) => {\n console.error('[RuntimeScope] PM discovery error:', (err as Error).message);\n });\n }\n\n // 7. Start HTTP API server (with POST /api/events + PM routes)\n const httpServer = new HttpServer(store, undefined, {\n authManager,\n allowedOrigins: corsOrigins,\n rateLimiter: collector.getRateLimiter(),\n pmStore,\n discovery,\n getConnectedSessions: () => collector.getConnectedSessions(),\n });\n\n try {\n await httpServer.start({ port: HTTP_PORT, host: HOST, tls: tlsConfig });\n } catch (err) {\n console.error('[RuntimeScope] HTTP API failed to start:', (err as Error).message);\n }\n\n // Push session connect/disconnect to dashboard in real-time\n collector.onConnect((sessionId, projectName) => {\n httpServer.broadcastSessionChange('session_connected', sessionId, projectName);\n });\n collector.onDisconnect((sessionId, projectName) => {\n httpServer.broadcastSessionChange('session_disconnected', sessionId, projectName);\n });\n\n // 7. Startup summary\n const proto = tlsConfig ? 'wss' : 'ws';\n const httpProto = tlsConfig ? 'https' : 'http';\n console.error(`[RuntimeScope] Standalone collector ready`);\n console.error(`[RuntimeScope] WebSocket: ${proto}://${HOST}:${COLLECTOR_PORT}`);\n console.error(`[RuntimeScope] HTTP API: ${httpProto}://${HOST}:${HTTP_PORT}`);\n console.error(`[RuntimeScope] Health: ${httpProto}://${HOST}:${HTTP_PORT}/api/health`);\n console.error(`[RuntimeScope] Ingest: POST ${httpProto}://${HOST}:${HTTP_PORT}/api/events`);\n\n // 8. Graceful shutdown\n let shuttingDown = false;\n const shutdown = async () => {\n if (shuttingDown) return;\n shuttingDown = true;\n console.error('[RuntimeScope] Shutting down...');\n\n await httpServer.stop();\n collector.stop();\n pmStore?.close();\n\n process.exit(0);\n };\n\n process.on('SIGINT', () => { shutdown(); });\n process.on('SIGTERM', () => { shutdown(); });\n}\n\nmain().catch((err) => {\n console.error('[RuntimeScope] Fatal error:', err);\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;;;;;AAaA,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AAarB,IAAM,OAAO,QAAQ,IAAI,qBAAqB;AAE9C,IAAM,iBAAiB,SAAS,QAAQ,IAAI,qBAAqB,QAAQ,EAAE;AAC3E,IAAM,YAAY,SAAS,QAAQ,IAAI,0BAA0B,QAAQ,EAAE;AAC3E,IAAM,cAAc,SAAS,QAAQ,IAAI,4BAA4B,SAAS,EAAE;AAChF,IAAM,iBAAiB,SAAS,QAAQ,IAAI,+BAA+B,MAAM,EAAE;AAEnF,eAAe,OAAO;AACpB,UAAQ,MAAM,iDAAiD;AAG/D,QAAM,iBAAiB,IAAI,eAAe;AAC1C,iBAAe,gBAAgB;AAC/B,QAAM,eAAe,eAAe,gBAAgB;AAGpD,QAAM,cAAc,IAAI,YAAY;AAAA,IAClC,SAAS,aAAa,MAAM,WAAW;AAAA,IACvC,SAAS,aAAa,MAAM,WAAW,CAAC;AAAA,EAC1C,CAAC;AAED,QAAM,YAAY,iBAAiB,KAAK,aAAa,OAAO;AAE5D,QAAM,WAAW,IAAI,SAAS;AAAA,IAC5B,SAAS,aAAa,WAAW,WAAW;AAAA,IAC5C,YAAY;AAAA,IACZ,OAAO,aAAa,WAAW,OAAO,IAAI,QAAM;AAAA,MAC9C,MAAM,EAAE;AAAA,MACR,SAAS,IAAI,OAAO,EAAE,SAAS,IAAI;AAAA,MACnC,aAAa,EAAE;AAAA,IACjB,EAAE;AAAA,EACJ,CAAC;AAED,QAAM,cAAc,QAAQ,IAAI,2BAA2B,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC,KAClF,aAAa;AAElB,MAAI,YAAY,UAAU,GAAG;AAC3B,YAAQ,MAAM,gCAAgC,aAAa,MAAM,SAAS,UAAU,CAAC,YAAY;AAAA,EACnG;AACA,MAAI,WAAW;AACb,YAAQ,MAAM,qCAAqC,UAAU,QAAQ,GAAG;AAAA,EAC1E;AACA,MAAI,SAAS,UAAU,GAAG;AACxB,YAAQ,MAAM,0CAA0C;AAAA,EAC1D;AAGA,QAAM,YAAY,IAAI,gBAAgB;AAAA,IACpC,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,YAAY,aAAa;AAAA,IACzB,KAAK;AAAA,EACP,CAAC;AACD,QAAM,UAAU,MAAM,EAAE,MAAM,gBAAgB,MAAM,MAAM,YAAY,GAAG,cAAc,IAAK,CAAC;AAE7F,QAAM,QAAQ,UAAU,SAAS;AAGjC,MAAI,SAAS,UAAU,GAAG;AACxB,UAAM,YAAY,QAAQ;AAAA,EAC5B;AAGA,QAAM,eAAe,UAAU,gBAAgB;AAC/C,QAAM,iBAAiB,IAAI,eAAe,gBAAgB,cAAc,KAAK;AAE7E,YAAU,aAAa,CAAC,WAAW,gBAAgB;AACjD,QAAI;AACF,qBAAe,eAAe,WAAW,WAAW;AACpD,cAAQ,MAAM,0BAA0B,SAAS,gBAAgB;AAAA,IACnE,QAAQ;AAAA,IAER;AAAA,EACF,CAAC;AAGD,MAAI,kBAAkB,GAAG;AACvB,UAAM,WAAW,KAAK,IAAI,IAAI,iBAAiB,KAAK,KAAK,KAAK;AAC9D,eAAW,eAAe,eAAe,aAAa,GAAG;AACvD,YAAM,SAAS,eAAe,iBAAiB,WAAW;AAC1D,UAAI,WAAW,MAAM,GAAG;AACtB,YAAI;AACF,gBAAM,YAAY,IAAI,YAAY,EAAE,OAAO,CAAC;AAC5C,gBAAM,UAAU,UAAU,gBAAgB,QAAQ;AAClD,cAAI,UAAU,GAAG;AACf,oBAAQ,MAAM,yBAAyB,OAAO,sBAAsB,cAAc,WAAW,WAAW,GAAG;AAAA,UAC7G;AACA,oBAAU,MAAM;AAAA,QAClB,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AAEJ,MAAI,kBAAkB,GAAG;AACvB,UAAM,WAAW,KAAK,eAAe,SAAS,OAAO;AACrD,cAAU,IAAI,QAAQ,EAAE,QAAQ,SAAS,CAAC;AAC1C,gBAAY,IAAI,iBAAiB,SAAS,cAAc;AAGxD,cAAU,YAAY,EAAE,KAAK,CAAC,WAAW;AACvC,cAAQ,MAAM,sBAAsB,OAAO,kBAAkB,cAAc,OAAO,kBAAkB,sBAAsB;AAAA,IAC5H,CAAC,EAAE,MAAM,CAAC,QAAQ;AAChB,cAAQ,MAAM,sCAAuC,IAAc,OAAO;AAAA,IAC5E,CAAC;AAAA,EACH;AAGA,QAAM,aAAa,IAAI,WAAW,OAAO,QAAW;AAAA,IAClD;AAAA,IACA,gBAAgB;AAAA,IAChB,aAAa,UAAU,eAAe;AAAA,IACtC;AAAA,IACA;AAAA,IACA,sBAAsB,MAAM,UAAU,qBAAqB;AAAA,EAC7D,CAAC;AAED,MAAI;AACF,UAAM,WAAW,MAAM,EAAE,MAAM,WAAW,MAAM,MAAM,KAAK,UAAU,CAAC;AAAA,EACxE,SAAS,KAAK;AACZ,YAAQ,MAAM,4CAA6C,IAAc,OAAO;AAAA,EAClF;AAGA,YAAU,UAAU,CAAC,WAAW,gBAAgB;AAC9C,eAAW,uBAAuB,qBAAqB,WAAW,WAAW;AAAA,EAC/E,CAAC;AACD,YAAU,aAAa,CAAC,WAAW,gBAAgB;AACjD,eAAW,uBAAuB,wBAAwB,WAAW,WAAW;AAAA,EAClF,CAAC;AAGD,QAAM,QAAQ,YAAY,QAAQ;AAClC,QAAM,YAAY,YAAY,UAAU;AACxC,UAAQ,MAAM,2CAA2C;AACzD,UAAQ,MAAM,+BAA+B,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE;AAChF,UAAQ,MAAM,+BAA+B,SAAS,MAAM,IAAI,IAAI,SAAS,EAAE;AAC/E,UAAQ,MAAM,+BAA+B,SAAS,MAAM,IAAI,IAAI,SAAS,aAAa;AAC1F,UAAQ,MAAM,oCAAoC,SAAS,MAAM,IAAI,IAAI,SAAS,aAAa;AAG/F,MAAI,eAAe;AACnB,QAAM,WAAW,YAAY;AAC3B,QAAI,aAAc;AAClB,mBAAe;AACf,YAAQ,MAAM,iCAAiC;AAE/C,UAAM,WAAW,KAAK;AACtB,cAAU,KAAK;AACf,aAAS,MAAM;AAEf,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,GAAG,UAAU,MAAM;AAAE,aAAS;AAAA,EAAG,CAAC;AAC1C,UAAQ,GAAG,WAAW,MAAM;AAAE,aAAS;AAAA,EAAG,CAAC;AAC7C;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,+BAA+B,GAAG;AAChD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
|