UNPKG

dev-services-dashboard

Version:

A lightweight development UI dashboard for managing and monitoring multiple services during local development

1 lines 329 kB
{"version":3,"sources":["../src/backend/index.ts","../src/backend/logger.ts","../src/backend/service-manager.ts","../src/backend/vfs-middleware.ts","../src/backend/frontend-vfs.ts","../src/backend/http-handler.ts","../src/backend/web-socket-handler.ts"],"sourcesContent":["import { WebSocketServer, WebSocket } from \"ws\";\nimport { Logger } from \"./logger\";\nimport { ServiceManager } from \"./service-manager\";\nimport { DevUIConfig, DevUIServer } from \"./types\";\nimport { HttpHandler } from \"./http-handler\";\nimport { createServer } from \"http\";\nimport { WebSocketHandler } from \"./web-socket-handler\";\n\n// --- Main export function ---\nexport function startDevServicesDashboard(\n config: DevUIConfig,\n): Promise<DevUIServer> {\n const PORT = config.port || 4000;\n const HOSTNAME = config.hostname || \"localhost\";\n const MAX_LOG_LINES = config.maxLogLines || 200;\n\n // Create logger - use provided logger or no logging if none provided\n const logger = new Logger(config.logger);\n\n return new Promise((resolve, reject) => {\n try {\n // Create broadcast function for WebSocket clients\n let wsServer: WebSocketServer;\n const broadcast = (message: object) => {\n const msgString = JSON.stringify(message);\n wsServer.clients.forEach((client) => {\n if (client.readyState === WebSocket.OPEN) {\n client.send(msgString);\n }\n });\n };\n\n // Initialize service manager\n const serviceManager = new ServiceManager(\n logger,\n config.services,\n MAX_LOG_LINES,\n broadcast,\n config.defaultCwd,\n );\n\n // Initialize HTTP handler\n const httpHandler = new HttpHandler(\n logger,\n serviceManager,\n config.dashboardName,\n );\n\n // Create HTTP server\n const httpServer = createServer((req, res) => {\n httpHandler.handleRequest(req, res);\n });\n\n // Create WebSocket server\n wsServer = new WebSocketServer({ server: httpServer });\n const wsHandler = new WebSocketHandler(logger, serviceManager);\n\n wsServer.on(\"connection\", (ws) => {\n wsHandler.handleConnection(ws);\n });\n\n // Shutdown handler\n const handleShutdownSignal = async (signal: string) => {\n logger.info(\n `Received ${signal}. Shutting down Dev Services Dashboard server and services...`,\n );\n\n await serviceManager.stopAllServices();\n\n logger.info(\"Stopping Dev Services Dashboard HTTP server...\");\n httpServer.close();\n wsServer.close();\n process.exit(0);\n };\n\n // Store signal handler references for cleanup\n const sigintHandler = () => handleShutdownSignal(\"SIGINT\");\n const sigtermHandler = () => handleShutdownSignal(\"SIGTERM\");\n\n process.on(\"SIGINT\", sigintHandler);\n process.on(\"SIGTERM\", sigtermHandler);\n\n // Start server\n httpServer.listen(PORT, HOSTNAME, () => {\n logger.info(\n `Dev Services Dashboard server running on http://${HOSTNAME}:${PORT}`,\n );\n\n resolve({\n httpServer,\n wsServer,\n port: PORT,\n stop: async () => {\n // Remove signal handlers to prevent interference\n process.removeListener(\"SIGINT\", sigintHandler);\n process.removeListener(\"SIGTERM\", sigtermHandler);\n\n await serviceManager.stopAllServices();\n httpServer.close();\n wsServer.close();\n },\n });\n });\n\n httpServer.on(\"error\", (error) => {\n logger.error(\n \"Fatal error starting Dev Services Dashboard server:\",\n error as object,\n );\n reject(error);\n });\n } catch (error) {\n logger.error(\n \"Fatal error starting Dev Services Dashboard server:\",\n error as object,\n );\n reject(error);\n }\n });\n}\n\n// Export all types and functions from the module\nexport * from \"./types\";\nexport { createConsoleLogger } from \"./logger\";\n","import { DevServicesDashboardLoggerFunction } from \"./types\";\n\n/**\n * Console-based logger implementation for DevUI\n * @param enabled Whether logging is enabled (default: true)\n */\nexport const createConsoleLogger = (\n enabled: boolean = true,\n): DevServicesDashboardLoggerFunction => {\n return (type, message, data) => {\n if (!enabled) return;\n\n const timestamp = new Date().toISOString();\n console[type](\n `[${timestamp}] [DevUI ${type.toUpperCase()}] ${message}`,\n data || \"\",\n );\n };\n};\n\n/**\n * Logger class that wraps a DevServicesDashboardLoggerFunction for dependency injection\n */\nexport class Logger {\n private loggerFn?: DevServicesDashboardLoggerFunction;\n\n constructor(logger?: DevServicesDashboardLoggerFunction) {\n this.loggerFn = logger;\n }\n\n info(message: string, data?: object): void {\n if (this.loggerFn) {\n this.loggerFn(\"info\", message, data);\n }\n }\n\n error(message: string, data?: object): void {\n if (this.loggerFn) {\n this.loggerFn(\"error\", message, data);\n }\n }\n\n warn(message: string, data?: object): void {\n if (this.loggerFn) {\n this.loggerFn(\"warn\", message, data);\n }\n }\n}\n","import { spawn } from \"child_process\";\nimport { Service, UserServiceConfig, LogEntry } from \"./types\";\nimport { Logger } from \"./logger\";\n\nexport class ServiceManager {\n private services: Service[] = [];\n private maxLogLines: number;\n private broadcastFn: (message: object) => void;\n private logger: Logger;\n\n constructor(\n logger: Logger,\n userServices: UserServiceConfig[],\n maxLogLines: number,\n broadcastFn: (message: object) => void,\n defaultCwd: string | undefined,\n ) {\n this.maxLogLines = maxLogLines;\n this.broadcastFn = broadcastFn;\n this.logger = logger;\n\n // Convert user service configs to full service objects\n this.services = userServices.map((userService) => ({\n id: userService.id,\n name: userService.name,\n command: userService.command,\n cwd: userService.cwd || defaultCwd || process.cwd(),\n env: userService.env,\n webLinks: userService.webLinks,\n process: null,\n status: \"stopped\",\n logs: [],\n errorDetails: null,\n }));\n }\n\n getServices(): Service[] {\n return this.services;\n }\n\n getService(serviceID: string): Service | undefined {\n return this.services.find((s) => s.id === serviceID);\n }\n\n addLog(\n serviceID: string,\n originalLine: string,\n logType: LogEntry[\"logType\"] = \"stdout\",\n ) {\n const service = this.getService(serviceID);\n if (!service) return;\n\n const line = originalLine.replace(/\\[[0-9;]*m/g, \"\"); // Strip ANSI escape codes\n\n const logEntry: LogEntry = { timestamp: Date.now(), line, logType };\n service.logs.push(logEntry);\n if (service.logs.length > this.maxLogLines) {\n service.logs.shift();\n }\n this.broadcastLog(serviceID, line, logType, logEntry.timestamp);\n }\n\n private broadcastLog(\n serviceID: string,\n line: string,\n logType: LogEntry[\"logType\"],\n timestamp: number,\n ) {\n this.broadcastFn({ type: \"log\", serviceID, line, logType, timestamp });\n }\n\n private broadcastStatus(\n serviceID: string,\n status: Service[\"status\"],\n errorDetails: string | null = null,\n ) {\n const service = this.getService(serviceID);\n if (service) service.errorDetails = errorDetails;\n this.broadcastFn({\n type: \"status_update\",\n serviceID,\n status,\n errorDetails,\n });\n }\n\n async startService(serviceID: string) {\n const service = this.getService(serviceID);\n if (\n !service ||\n (service.status !== \"stopped\" && service.status !== \"error\")\n ) {\n this.logger.warn(\n `Service ${service?.name} is ${service?.status}, cannot start.`,\n );\n return;\n }\n\n this.logger.info(`Starting service: ${service.name}...`);\n service.status = \"starting\";\n service.errorDetails = null;\n this.broadcastStatus(serviceID, service.status);\n this.addLog(serviceID, `Attempting to start ${service.name}...`, \"system\");\n\n try {\n service.process = spawn(service.command[0], service.command.slice(1), {\n cwd: service.cwd,\n env: { ...process.env, ...service.env },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n service.process.on(\"spawn\", () => {\n service.status = \"running\";\n this.logger.info(\n `Service ${service.name} started (PID: ${service.process?.pid}).`,\n );\n this.addLog(\n serviceID,\n `${service.name} started successfully.`,\n \"system\",\n );\n this.broadcastStatus(serviceID, service.status);\n });\n\n service.process.stdout?.on(\"data\", (data: Buffer) =>\n this.addLog(serviceID, data.toString(), \"stdout\"),\n );\n service.process.stderr?.on(\"data\", (data: Buffer) =>\n this.addLog(serviceID, data.toString(), \"stderr\"),\n );\n\n service.process.on(\"error\", (err) => {\n service.status = \"error\";\n this.logger.error(`Failed to start service ${service.name}:`, err);\n this.addLog(\n serviceID,\n `Error starting ${service.name}: ${err.message}`,\n \"system\",\n );\n this.broadcastStatus(serviceID, service.status, err.message);\n service.process = null;\n });\n\n service.process.on(\"exit\", (code, signal) => {\n const wasStopping = service.status === \"stopping\";\n\n // Determine exit type and status\n let newStatus: Service[\"status\"];\n let exitType: string;\n let errorDetails: string | null = null;\n\n if (wasStopping) {\n // Intentional stop\n newStatus = \"stopped\";\n exitType = \"clean shutdown\";\n } else if (code === 0) {\n // Clean exit\n newStatus = \"stopped\";\n exitType = \"clean exit\";\n } else if (signal === \"SIGTERM\" || signal === \"SIGINT\") {\n // Terminated by signal (but not by us)\n newStatus = \"stopped\";\n exitType = \"terminated by signal\";\n errorDetails = `Terminated by ${signal}`;\n } else if (signal === \"SIGKILL\") {\n // Force killed\n newStatus = \"crashed\";\n exitType = \"force killed\";\n errorDetails = `Process was force killed (SIGKILL)`;\n } else if (signal) {\n // Other signals (crashes)\n newStatus = \"crashed\";\n exitType = \"crashed\";\n errorDetails = `Process crashed with signal ${signal}`;\n } else if (code && code > 0) {\n // Non-zero exit code\n if (code === 1) {\n newStatus = \"error\";\n exitType = \"error\";\n errorDetails = `Exited with error code ${code} (general error)`;\n } else if (code >= 128) {\n newStatus = \"crashed\";\n exitType = \"crashed\";\n errorDetails = `Process crashed with exit code ${code}`;\n } else {\n newStatus = \"error\";\n exitType = \"error\";\n errorDetails = `Exited with error code ${code}`;\n }\n } else {\n newStatus = \"error\";\n exitType = \"unexpected exit\";\n errorDetails = `Unexpected exit (code: ${code}, signal: ${signal})`;\n }\n\n service.status = newStatus;\n service.errorDetails = errorDetails;\n\n const exitMessage = `Service ${service.name} ${exitType} (code ${code}, signal ${signal}).`;\n const logLevel = newStatus === \"stopped\" ? \"info\" : \"error\";\n\n if (logLevel === \"info\") {\n this.logger.info(exitMessage);\n } else {\n this.logger.error(exitMessage);\n }\n this.addLog(serviceID, exitMessage, \"system\");\n this.broadcastStatus(serviceID, service.status, service.errorDetails);\n service.process = null;\n });\n } catch (err: any) {\n service.status = \"error\";\n this.logger.error(`Exception starting service ${service.name}:`, err);\n this.addLog(\n serviceID,\n `Exception starting ${service.name}: ${err.message}`,\n \"system\",\n );\n this.broadcastStatus(serviceID, service.status, err.message);\n service.process = null;\n }\n }\n\n async stopService(serviceID: string): Promise<void> {\n const service = this.getService(serviceID);\n if (\n !service ||\n !service.process ||\n service.status === \"stopped\" ||\n service.status === \"stopping\"\n ) {\n if (\n service &&\n (service.status === \"stopped\" || service.status === \"stopping\")\n ) {\n this.broadcastStatus(serviceID, service.status, service.errorDetails);\n }\n return;\n }\n\n this.logger.info(`Stopping service: ${service.name}...`);\n service.status = \"stopping\";\n this.broadcastStatus(serviceID, service.status);\n this.addLog(serviceID, `Attempting to stop ${service.name}...`, \"system\");\n\n return new Promise((resolve) => {\n if (!service.process) {\n service.status = \"stopped\";\n this.broadcastStatus(serviceID, service.status);\n resolve();\n return;\n }\n\n service.process.removeAllListeners(\"exit\");\n service.process.on(\"exit\", (code, signal) => {\n this.logger.info(`Service ${service.name} confirmed stopped.`);\n this.addLog(serviceID, `${service.name} confirmed stopped.`, \"system\");\n if (service.status !== \"error\") service.status = \"stopped\";\n this.broadcastStatus(serviceID, service.status, service.errorDetails);\n service.process = null;\n clearTimeout(timeout);\n resolve();\n });\n\n service.process.kill(\"SIGTERM\");\n const timeout = setTimeout(() => {\n if (service.process) {\n this.logger.warn(\n `Service ${service.name} did not stop gracefully with SIGTERM, sending SIGKILL.`,\n );\n this.addLog(\n serviceID,\n `${service.name} did not stop gracefully, forcing SIGKILL.`,\n \"system\",\n );\n service.process.kill(\"SIGKILL\");\n }\n }, 5000);\n });\n }\n\n async restartService(serviceID: string) {\n const service = this.getService(serviceID);\n if (!service) return;\n\n this.logger.info(`Restarting service: ${service.name}...`);\n this.addLog(\n serviceID,\n `Attempting to restart ${service.name}...`,\n \"system\",\n );\n\n if (\n service.process &&\n service.status !== \"stopped\" &&\n service.status !== \"error\"\n ) {\n await this.stopService(serviceID);\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n await this.startService(serviceID);\n }\n\n clearServiceLogs(serviceID: string) {\n const service = this.getService(serviceID);\n if (service) {\n service.logs = [];\n this.logger.info(`Server-side logs cleared for service: ${service.name}`);\n this.addLog(serviceID, \"Log buffer cleared by user.\", \"system\");\n this.broadcastFn({ type: \"logs_cleared\", serviceID });\n }\n }\n\n async stopAllServices(): Promise<void> {\n const stopPromises = this.services\n .filter(\n (s) => s.process && (s.status === \"running\" || s.status === \"starting\"),\n )\n .map((s) => this.stopService(s.id));\n\n await Promise.all(stopPromises)\n .then(() => this.logger.info(\"All services stopped.\"))\n .catch((err) =>\n this.logger.error(\"Error stopping services during shutdown:\", err),\n );\n }\n}\n","import { IncomingMessage, ServerResponse } from \"http\";\nimport { createHash } from \"crypto\";\nimport * as mime from \"mime-types\";\n\ninterface VFSContent {\n [path: string]: Buffer;\n}\n\ninterface VFSMiddlewareOptions {\n excludedPaths?: string[];\n}\n\nfunction normalizePath(path: string): string {\n return path.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nfunction generateETag(content: Buffer): string {\n const hash = createHash(\"sha256\").update(content).digest(\"hex\");\n return `\"${hash.slice(0, 16)}\"`; // Use first 16 chars of hash for a shorter ETag\n}\n\nfunction getMimeType(path: string): string {\n const mimeType = mime.lookup(path);\n\n // For HTML files, ensure we include charset\n if (mimeType === \"text/html\") {\n return \"text/html; charset=utf-8\";\n }\n\n return mimeType || \"application/octet-stream\";\n}\n\n/**\n * Creates middleware to serve files from a virtual file system (VFS).\n *\n * Features:\n * - Serves static files from an in-memory VFS\n * - Supports GET and HEAD requests\n * - Handles ETags for caching\n * - Automatically detects content types\n * - Allows excluding specific paths\n *\n * @param vfs - Virtual file system mapping paths to content\n * @param options - Configuration options\n * @param options.excludedPaths - Paths to exclude from VFS serving\n * @returns Middleware function that returns true if request was handled, false otherwise\n */\nexport function createVFSMiddleware(\n vfs: VFSContent,\n options: VFSMiddlewareOptions = {},\n): (req: IncomingMessage, res: ServerResponse) => boolean {\n const normalizedExcludedPaths =\n options.excludedPaths?.map(normalizePath) || [];\n\n return (req: IncomingMessage, res: ServerResponse): boolean => {\n const url = new URL(req.url!, `http://${req.headers.host}`);\n let path = normalizePath(url.pathname);\n\n // Skip if not a GET or HEAD request\n if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n return false;\n }\n\n // Skip if path is in excluded paths\n if (normalizedExcludedPaths.includes(path)) {\n return false;\n }\n\n // Map root path to index.html (React build output)\n if (path === \"\" || path === \"/\") {\n path = \"index.html\";\n }\n\n // Try to find the file in VFS\n const content = vfs[path];\n\n if (!content) {\n return false;\n }\n\n // Determine content type\n const contentType = getMimeType(path);\n\n // Generate ETag - needed for both GET and HEAD\n const etag = generateETag(content);\n\n // Check if client has a fresh copy\n const ifNoneMatch = req.headers[\"if-none-match\"];\n\n if (ifNoneMatch === etag) {\n res.writeHead(304, {\n ETag: etag,\n \"Cache-Control\": \"public, max-age=0, must-revalidate\",\n });\n res.end();\n return true;\n }\n\n // Set response headers\n const headers: { [key: string]: string } = {\n \"Content-Type\": contentType,\n \"Content-Length\": content.length.toString(),\n ETag: etag,\n \"Cache-Control\": \"public, max-age=0, must-revalidate\",\n };\n\n res.writeHead(200, headers);\n\n // For HEAD requests, don't send the body\n if (req.method === \"HEAD\") {\n res.end();\n } else {\n res.end(content);\n }\n\n return true;\n };\n}\n","export default {\n \"favicon.ico\": Buffer.from(\"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LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP8/MCT/IxkX/yMZF/8/MCT/UD4s/1A+LP9QPiz/UD4s/1JAL//AubP////////////t6+r/YlJC/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/z8wJP8jGRf/IxkX/z8wJP9QPiz/UD4s/1A+LP9QPiz/UD4s/1JBL//s6+n///////////+KfnL/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/PzAk/yMZF/8jGRf/PzAk/1A+LP9QPiz/UD4s/1A+LP9SQC7/t6+o////////////1dHM/1ZFNP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP8/MCT/IxkX/yMZF/8/MCT/UD4s/1A+LP9QPiz/U0Iw/8G6tP///////////9nV0f9ZSDf/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/z8wJP8jGRf/IxkX/z8wJP9QPiz/UD4s/1ZEM//KxL/////////////c2dX/W0o6/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/PzAk/yMZF/8jGRf/PzAk/1A+LP9QPiz/qaCX////////////4N3Z/11NPP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP8/MCT/IxkX/yMZF/8/MCT/UD4s/1A+LP+Og3f//v7+/+Lf3f9fTz//UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+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LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/RjYn/yYbGP8jGRf/IhkXcCQaGM4jGRf/PC0j/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/zwtI/8jGRf/JBoYziQaF/omGxj/STgp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0k4Kf8mGxj/JBoX+iMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/WUg3/3ptX/+NgXX/jYF2/42Bdv+NgXb/jYF2/42Bdv+NgXb/jYF2/42Bdv+NgXX/em1f/1lIN/9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9TQjD/tKyk//38/P///////////////////////////////////////////////////////fz8/7SspP9TQjD/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1E/Lf90Zlf/pZyT/3xvYf9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9hUED/5uTh/////////////////////////////////////////////////////////////////+bk4f9hUED/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/2tcTP/s6uj///////X08/+UiH3/U0Iw/1A+LP9QPiz/UD4s/1A+LP9TQTD/x8K7//v7+///////////////////////////////////////////////////////+/v7/8fCu/9TQTD/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/4N3av/////////////////t6+r/lIh9/1A+LP9QPiz/UD4s/1A+LP9QPiz/YlJB/52Tif+poJf/qaCX/6mgl/+poJf/qaCX/6mgl/+poJf/qaCX/6mgl/+poJf/nZOJ/2JSQf9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/2pbS//q6Ob/////////////////9fTz/5mOg/9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9RPy3/UT8t/1E/Lf9RPy3/UT8t/1E/Lf9RPy3/UT8t/1E/Lf9RPy3/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1E/Lf+Lf3T/7+3r//////////////////X08/+UiH3/U0Iw/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9SQC//i390/+3r6v/////////////////t6+r/lIh9/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UT8t/4BzZv/t6+r/////////////////9fTz/5mOg/9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1E/Lf+Lf3T/7+3r//////////////////X08/+RhXr/UkAv/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9SQC//i390//Lx8P/////////////////Z1dH/YVBA/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UkEv/9zZ1v/////////////////f3Nj/Y1NC/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9cSzv/urOs//////////////////f39v+glo3/VEIw/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/19PPv+8ta7/+vr6////////////+/r6/6adlP9YRzb/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/WUg2/8zIwv/7+/r////////////8+/v/n5aM/1VEMv9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1E/Lf9mVkb/08/L//////////////////r5+f+spJz/VkU0/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/2BPP//Mx8L//f39/////////////f39/7Goof9cSzv/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/4F0Z//9/Pz////////////+/v7/rKSc/1dGNf9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/3BiU//z8vH///////v7+/+3sKj/WUg2/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1ZFM/+UiX7/xL64/6iflv9hUED/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9SQS//Wkk4/1RCMP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8oHRr/Sjkp/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/1A+LP9QPiz/UD4s/0o5Kf8oHRr/IxkX/yMZF/8qHhr/WUIu/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/2JJMf9iSTH/Ykkx/1lCLv8qHhr/IxkX/yMZF/8tIBv/c1E0/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/3NRNP8tIBv/IxkX/yMZF/8tIBv/c1E0/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/3NRNP8tIBv/IxkX/yMZF/8tIBv/c1E0/39aOf9/Wjn/f1o5/35aPf9wVWf/a1J2/31ZQf9/Wjn/f1o5/3xcPv9fcmj/WHdz/3xdP/9/Wjn/f1o5/35dOP92eDP/dXwy/35dOP9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/3NRNP8tIBv/IxkX/yMZF/8tIBv/c1E0/39aOf9/Wjn/f1o5/2JPlP9ERO3/RETv/1JJxv96WEj/f1o5/z6Lmf8Is+n/CLPq/yacvf93YEX/f1s5/2uZLP9exSL/XsUi/2imKf99YDj/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/3NRNP8tIBv/IxkX/yMZF/8tIBv/c1E0/39aOf9/Wjn/f1o5/0hF5P9ERO//RETv/0hF4/9tU3H/fF0+/wyw5P8Is+r/CLPq/xGs3f9fc2r/fWE3/1/DIv9exSL/XsUi/2G8JP93dDP/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/3NRNP8tIBv/IxkX/yMZF/8tIBv/c1E0/39aOf9/Wjn/f1o5/05I0P9ERO//RETv/0lG3/9xVWX/fls6/xeo1P8Is+r/CLPq/xSq2f9mbV7/fl05/2G7JP9exSL/XsUi/2K5Jf95bTX/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/3NRNP8tIBv/IxkX/yQaF/opHRn/cE8z/39aOf9/Wjn/f1o5/3JVYf9RScj/TUfV/2RQjf9/Wjv/f1o5/2FwZv8gocb/GqbP/0yAhP9/Wjr/f1o5/3Z4M/9lsCb/Y7Qm/3KEMP9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/3BPM/8pHRn/JBoX+iQaGM4jGRf/VT0q/39aOf9/Wjn/f1o5/39aOf98WUL/e1hF/39aOf9/Wjn/f1o5/39aOf95X0L/eGBE/39aOf9/Wjn/f1o5/39aOf99YDj/fWA4/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/1U9Kv8jGRf/JBoYziIZF3AjGRf/KR4Z/2lKMf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/f1o5/39aOf9/Wjn/aUox/ykeGf8jGRf/IhkXcCkfFBkkGRfIIxkX/ikeGf9VPSr/cE8z/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3NRNP9zUTT/c1E0/3BPM/9VPSr/KR4Z/yMZF/4kGRfIKR8UGQAAAAIkGBg/JBkXyCMZF/8jGRf/KR0Z/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/y0gG/8tIBv/LSAb/ykdGf8jGRf/IxkX/yQZF8gkGBg/AAAAAgAAAAAAAAACKR8UGSIZF3AkGhjOJBoX+iMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yMZF/8jGRf/IxkX/yQaF/okGhjOIhkXcCkfFBkAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\", \"base64\"),\n \"index.html\": Buffer.from(\"PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9IlVURi04IiAvPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+CiAgICA8dGl0bGU+RGV2IFNlcnZpY2VzIERhc2hib2FyZDwvdGl0bGU+CiAgICA8bGluayByZWw9Imljb24iIGhyZWY9Ii9mYXZpY29uLmljbyIgdHlwZT0iaW1hZ2UveC1pY29uIiAvPgogICAgPHNjcmlwdD4KICAgICAgLy8gUHJldmVudCB0aGVtZSBmbGlja2VyIGJ5IHNldHRpbmcgdGhlbWUgY2xhc3MgYmVmb3JlIFJlYWN0IGxvYWRzCiAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgZnVuY3Rpb24gZ2V0U3lzdGVtVGhlbWUoKSB7CiAgICAgICAgICByZXR1cm4gd2luZG93Lm1hdGNoTWVkaWEoIihwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaykiKS5tYXRjaGVzCiAgICAgICAgICAgID8gImRhcmsiCiAgICAgICAgICAgIDogImxpZ2h0IjsKICAgICAgICB9CgogICAgICAgIGNvbnN0IHRoZW1lTW9kZSA9CiAgICAgICAgICBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgiZGV2LXNlcnZpY2VzLWRhc2hib2FyZC10aGVtZS1tb2RlIikgfHwgImF1dG8iOwogICAgICAgIGNvbnN0IHRoZW1lID0gdGhlbWVNb2RlID09PSAiYXV0byIgPyBnZXRTeXN0ZW1UaGVtZSgpIDogdGhlbWVNb2RlOwoKICAgICAgICBpZiAodGhlbWUgPT09ICJkYXJrIikgewogICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoImRhcmsiKTsKICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAiIzExMTgyNyI7IC8vIE1hdGNoIGRhcms6YmctZ3JheS05MDAKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoImRhcmsiKTsKICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAiI2YzZjRmNiI7IC8vIE1hdGNoIGJnLWdyYXktMTAwCiAgICAgICAgfQogICAgICB9KSgpOwogICAgPC9zY3JpcHQ+CiAgICA8c2NyaXB0IHR5cGU9Im1vZHVsZSIgY3Jvc3NvcmlnaW4gc3JjPSIvYXNzZXRzL21haW4tQjdMcGdhLUEuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBjcm9zc29yaWdpbiBocmVmPSIvYXNzZXRzL21haW4tQ1pIdzYtUGkuY3NzIj4KICA8L2hlYWQ+CiAgPGJvZHk+CiAgICA8ZGl2IGlkPSJyb290Ij48L2Rpdj4KICA8L2JvZHk+CjwvaHRtbD4K\", \"base64\"),\n \".DS_Store\": Buffer.from(\"AAAAAUJ1ZDEAABAAAAAIAAAAEAAAAACGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAABAAAQAABjAG8AbgAuAGkAYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAALAGYAYQB2AGkAYwBvAG4ALgBpAGMAb0lsb2NibG9iAAAAEAAAAEEAAAAu////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAgLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAACAAAAABAAAAQAAAAAEAAACAAAAAAQAAAQAAAAABAAACAAAAAAEAAAQAAAAAAAAAAAEAABAAAAAAAQAAIAAAAAABAABAAAAAAAEAAIAAAAAAAQABAAAAAAABAAIAAAAAAAEABAAAAAAAAQAIAAAAAAABABAAAAAAAAEAIAAAAAAAAQBAAAAAAAABAIAAAAAAAAEBAAAAAAAAAQIAAAAAAAABBAAAAAAAAAEIAAAAAAAAARAAAAAAAAABIAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAEAsAAABFAAAAhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBERTREIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAIAAAAGAAAAABAAAAwAAAAAAAAAABAAABAAAAAAEAAAIAAAAAAQAABAAAAAACAAAIAAAAGAAAAAAAAAAAAQAAIAAAAAABAABAAAAAAAEAAIAAAAAAAQABAAAAAAABAAIAAAAAAAEABAAAAAAAAQAIAAAAAAABABAAAAAAAAEAIAAAAAAAAQBAAAAAAAABAIAAAAAAAAEBAAAAAAAAAQIAAAAAAAABBAAAAAAAAAEIAAAAAAAAARAAAAAAAAABIAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA