galactic.ts 1.0.1 → 1.1.0
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/index.d.mts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +45 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/bridge/BridgeClientCluster.ts","../src/general/EventManager.ts","../src/bridge/BridgeClientConnection.ts","../src/bridge/Bridge.ts","../src/bridge/ClusterCalculator.ts","../src/general/ShardingUtil.ts","../src/cluster/Cluster.ts","../src/cluster/ClusterProcess.ts","../src/instance/BotInstance.ts","../src/instance/ManagedInstance.ts","../src/instance/StandaloneInstance.ts"],"sourcesContent":["export * from './bridge/BridgeClientCluster';\nexport * from './bridge/BridgeClientConnection';\nexport * from './bridge/Bridge';\nexport * from './bridge/ClusterCalculator';\n\nexport * from './cluster/Cluster';\nexport * from './cluster/ClusterProcess';\n\nexport * from './general/EventManager';\nexport * from './general/ShardingUtil';\nexport * from './general/EventPayload';\n\nexport * from './instance/BotInstance';\nexport * from './instance/ManagedInstance';\nexport * from './instance/StandaloneInstance';","import {BridgeClientConnection} from \"./BridgeClientConnection\";\n\nexport enum BridgeClientClusterConnectionStatus {\n REQUESTING = 'requesting',\n STARTING = 'starting',\n CONNECTED = 'connected',\n RECLUSTERING = 'reclustering',\n DISCONNECTED = 'disconnected',\n}\n\nexport class BridgeClientCluster {\n public readonly clusterID: number;\n public readonly shardList: number[];\n public connectionStatus: BridgeClientClusterConnectionStatus = BridgeClientClusterConnectionStatus.DISCONNECTED;\n\n public connection?: BridgeClientConnection;\n\n public oldConnection?: BridgeClientConnection;\n\n public missedHeartbeats: number = 0;\n\n public heartbeatResponse?: HeartbeatResponse;\n\n public heartbeatPending = false;\n\n public startedAt?: number;\n\n constructor(clusterID: number, shardList: number[]) {\n this.clusterID = clusterID;\n this.shardList = shardList;\n }\n\n setConnection(connection?: BridgeClientConnection): void {\n if(connection == undefined){\n this.connectionStatus = BridgeClientClusterConnectionStatus.DISCONNECTED;\n this.connection = undefined;\n return;\n }\n\n if (this.connection) {\n throw new Error(`Connection already set for cluster ${this.clusterID}`);\n }\n\n this.connectionStatus = BridgeClientClusterConnectionStatus.REQUESTING;\n this.connection = connection;\n }\n\n setOldConnection(connection?: BridgeClientConnection): void {\n this.oldConnection = connection;\n }\n\n isUsed(): boolean {\n return this.connection != undefined && this.connectionStatus !== BridgeClientClusterConnectionStatus.DISCONNECTED;\n }\n\n reclustering(connection: BridgeClientConnection): void {\n this.connectionStatus = BridgeClientClusterConnectionStatus.RECLUSTERING;\n this.oldConnection = this.connection;\n this.connection = connection;\n }\n\n addMissedHeartbeat(): void {\n this.missedHeartbeats++;\n }\n\n removeMissedHeartbeat(): void {\n if (this.missedHeartbeats > 0) {\n this.missedHeartbeats--;\n }\n }\n\n resetMissedHeartbeats(): void {\n this.missedHeartbeats = 0;\n }\n}\n\nexport type HeartbeatResponse = {\n cpu: {\n raw: {\n user: number,\n system: number,\n }\n cpuPercent: string\n },\n memory: {\n raw: {\n rss: number,\n heapTotal: number,\n heapUsed: number,\n external: number,\n arrayBuffers: number,\n },\n memoryPercent: string\n usage: number\n },\n ping: number,\n shardPings: {\n id: number,\n ping: number,\n status: number,\n guilds: number,\n members: number\n }[]\n}","import {EventPayload} from \"./EventPayload\";\n\nexport class EventManager {\n\n private pendingPayloads = new Map<string, {\n resolve: (value: unknown) => void;\n reject: (error: unknown) => void;\n }>();\n\n // Track per-request timeout handles so we can clear them on resolve/reject\n private pendingTimeouts = new Map<string, ReturnType<typeof setTimeout>>();\n\n private readonly _send: (payload: EventPayload) => Promise<void>;\n\n private readonly _on: (payload: unknown) => void;\n\n private readonly _request: (payload: unknown) => unknown;\n\n constructor(send: (payload: EventPayload) => Promise<void>, on: (message: unknown) => void, request: (message: unknown) => unknown) {\n this._send = send;\n this._on = on;\n this._request = request\n }\n\n async send(data: unknown) {\n return this._send({\n id: crypto.randomUUID(),\n type: 'message',\n data: data\n });\n }\n\n async request<T>(payload: unknown, timeout: number): Promise<T> {\n const id = crypto.randomUUID();\n\n return new Promise<T>((resolve, reject) => {\n this._send({\n id: id,\n type: 'request',\n data: payload\n });\n\n this.pendingPayloads.set(id, {\n resolve: resolve as (value: unknown) => void,\n reject\n });\n\n const t = setTimeout(() => {\n if (this.pendingPayloads.has(id)) {\n this.pendingPayloads.delete(id);\n this.pendingTimeouts.delete(id);\n reject({\n error: `Request with id ${id} timed out`,\n });\n }\n }, timeout);\n this.pendingTimeouts.set(id, t);\n })\n }\n\n receive(possiblePayload: unknown) {\n if (typeof possiblePayload !== 'object' || possiblePayload === null) {\n return;\n }\n\n const payload = possiblePayload as EventPayload;\n\n if (!payload.id || !payload.type) {\n return;\n }\n\n if (payload.type === 'message') {\n this._on(payload.data);\n return;\n }\n\n if (payload.type === 'response') {\n // Handle requests\n const resolve = this.pendingPayloads.get(payload.id)?.resolve;\n if (resolve) {\n resolve(payload.data);\n this.pendingPayloads.delete(payload.id);\n const to = this.pendingTimeouts.get(payload.id);\n if (to) clearTimeout(to);\n this.pendingTimeouts.delete(payload.id);\n }\n return;\n }\n\n if (payload.type === 'response_error') {\n // Handle requests\n const reject = this.pendingPayloads.get(payload.id)?.reject;\n if (reject) {\n reject(payload.data);\n this.pendingPayloads.delete(payload.id);\n const to = this.pendingTimeouts.get(payload.id);\n if (to) clearTimeout(to);\n this.pendingTimeouts.delete(payload.id);\n }\n return;\n }\n\n if (payload.type === 'request') {\n // Handle requests\n const data = this._request(payload.data);\n if(data instanceof Promise) {\n data.then((result) => {\n this._send({\n id: payload.id,\n type: 'response',\n data: result\n });\n }).catch((error) => {\n this._send({\n id: payload.id,\n type: 'response_error',\n data: error\n });\n });\n } else {\n this._send({\n id: payload.id,\n type: 'response',\n data: data\n });\n }\n return;\n }\n }\n\n // Reject and clear all pending requests to avoid memory leaks when a connection/process closes\n close(reason?: string) {\n if (this.pendingPayloads.size === 0 && this.pendingTimeouts.size === 0) return;\n const err = { error: reason || 'EventManager closed' };\n for (const [id, handlers] of this.pendingPayloads.entries()) {\n try { handlers.reject(err); } catch (_) { /* ignore */ }\n this.pendingPayloads.delete(id);\n const to = this.pendingTimeouts.get(id);\n if (to) clearTimeout(to);\n this.pendingTimeouts.delete(id);\n }\n // In case there are any stray timeouts with no pending payload\n for (const to of this.pendingTimeouts.values()) {\n clearTimeout(to);\n }\n this.pendingTimeouts.clear();\n }\n}\n\n","import {EventManager} from \"../general/EventManager\";\nimport {Connection} from \"net-ipc\";\n\nexport enum BridgeClientConnectionStatus {\n READY = 'ready',\n PENDING_STOP = 'pending_stop',\n}\nexport class BridgeClientConnection {\n public readonly instanceID: number;\n public readonly eventManager: EventManager;\n public readonly connection: Connection;\n public readonly data: unknown;\n public connectionStatus: BridgeClientConnectionStatus = BridgeClientConnectionStatus.READY;\n public readonly dev: boolean = false;\n\n private _onMessage?: (message: unknown) => void;\n private _onRequest?: (message: unknown) => unknown;\n\n constructor(instanceID: number, connection: Connection, data: unknown, dev: boolean) {\n this.instanceID = instanceID;\n this.connection = connection;\n this.data = data;\n this.dev = dev || false;\n this.eventManager = new EventManager((message) => {\n if(!this.connection?.connection?.closed){\n return this.connection.send(message);\n }\n return Promise.reject(new Error('Connection is closed, cannot send message'));\n }, (message) => {\n if (this._onMessage) {\n this._onMessage(message);\n }\n }, (message) => {\n if (this._onRequest) {\n return this._onRequest(message);\n }\n return undefined;\n })\n }\n\n messageReceive(message: any) {\n this.eventManager.receive(message);\n }\n\n onRequest(callback: (message: unknown) => unknown) {\n this._onRequest = callback;\n }\n\n onMessage(callback: (message: unknown) => void) {\n this._onMessage = callback;\n }\n}","import {Server} from 'net-ipc';\nimport {BridgeClientConnection, BridgeClientConnectionStatus} from \"./BridgeClientConnection\";\nimport {GatewayIntentsString} from \"discord.js\";\nimport {ClusterCalculator} from \"./ClusterCalculator\";\nimport {BridgeClientCluster, BridgeClientClusterConnectionStatus, HeartbeatResponse} from \"./BridgeClientCluster\";\nimport {ShardingUtil} from \"../general/ShardingUtil\";\nimport * as cluster from \"node:cluster\";\n\nexport class Bridge {\n public readonly port: number;\n public readonly server: Server;\n public readonly connectedClients: Map<string, BridgeClientConnection> = new Map();\n private readonly token: string;\n private readonly intents: GatewayIntentsString[];\n private readonly shardsPerCluster: number = 1;\n private readonly clusterToStart: number = 1\n\n private readonly clusterCalculator: ClusterCalculator;\n\n private readonly eventMap: BridgeEventListeners = {\n CLUSTER_READY: undefined, CLUSTER_HEARTBEAT_FAILED: undefined,\n CLUSTER_STOPPED: undefined, CLIENT_CONNECTED: undefined, CLIENT_DISCONNECTED: undefined,\n CLUSTER_SPAWNED: undefined, CLUSTER_RECLUSTER: undefined, ERROR: undefined,\n CLIENT_STOP: undefined\n }\n\n constructor(port: number, token: string, intents: GatewayIntentsString[], shardsPerCluster: number, clusterToStart: number) {\n this.port = port;\n this.token = token;\n this.intents = intents;\n this.clusterToStart = clusterToStart;\n this.shardsPerCluster = shardsPerCluster;\n\n this.clusterCalculator = new ClusterCalculator(this.clusterToStart, this.shardsPerCluster);\n\n this.server = new Server({\n port: this.port,\n })\n }\n\n public start(): void {\n this.server.start().then(() => {\n this.startListening();\n })\n\n this.interval();\n }\n\n private interval(): void {\n setInterval(() => {\n this.checkCreate();\n this.checkRecluster();\n this.heartbeat();\n }, 5000)\n }\n\n private checkRecluster(): void {\n // check if all clusters are used\n const up = this.clusterCalculator.checkAllClustersConnected()\n if (!up) {\n return;\n }\n\n const connectedClients: BridgeClientConnection[] = this.connectedClients.values().filter(c => c.connectionStatus == BridgeClientConnectionStatus.READY && !c.dev).toArray();\n const {most, least} = this.clusterCalculator.findMostAndLeastClustersForConnections(connectedClients);\n if (most) {\n const clusterToSteal = this.clusterCalculator.getClusterForConnection(most)[0] || undefined;\n if (least && clusterToSteal) {\n clusterToSteal.reclustering(least);\n\n if(this.eventMap.CLUSTER_RECLUSTER) this.eventMap.CLUSTER_RECLUSTER(clusterToSteal, least, clusterToSteal.oldConnection!);\n this.createCluster(least, clusterToSteal, true);\n\n return;\n }\n }\n }\n\n private heartbeat(): void {\n const clusters = this.clusterCalculator.clusterList;\n\n clusters.forEach((cluster) => {\n if(cluster.connection && cluster.connectionStatus == BridgeClientClusterConnectionStatus.CONNECTED && !cluster.heartbeatPending) {\n cluster.heartbeatPending = true;\n cluster.connection.eventManager.request<HeartbeatResponse>({\n type: 'CLUSTER_HEARTBEAT',\n data: {\n clusterID: cluster.clusterID\n }\n }, 20000).then((r) => {\n cluster.removeMissedHeartbeat();\n cluster.heartbeatResponse = r;\n }).catch((err) => {\n if(this.eventMap.CLUSTER_HEARTBEAT_FAILED) this.eventMap.CLUSTER_HEARTBEAT_FAILED(cluster, err)\n cluster.addMissedHeartbeat()\n\n if(cluster.missedHeartbeats > 7 && !cluster.connection?.dev){\n cluster.connection?.eventManager.send({\n type: 'CLUSTER_STOP',\n data: {\n id: cluster.clusterID\n }\n });\n cluster.connectionStatus = BridgeClientClusterConnectionStatus.DISCONNECTED;\n cluster.resetMissedHeartbeats()\n }\n }).finally(() => {\n cluster.heartbeatPending = false;\n })\n }\n });\n }\n\n private checkCreate(): void {\n const optionalCluster = this.clusterCalculator.getNextCluster();\n\n if (!optionalCluster) {\n return;\n }\n\n const lowestLoadClient = this.clusterCalculator.getClusterWithLowestLoad(this.connectedClients);\n if (!lowestLoadClient) {\n return;\n }\n\n this.createCluster(lowestLoadClient, optionalCluster)\n }\n\n private createCluster(connection: BridgeClientConnection, cluster: BridgeClientCluster, recluster = false) {\n cluster.resetMissedHeartbeats()\n cluster.heartbeatResponse = undefined;\n if (!recluster) {\n cluster.setConnection(connection)\n } else {\n cluster.oldConnection?.eventManager.send({\n type: 'CLUSTER_RECLUSTER',\n data: {\n clusterID: cluster.clusterID\n }\n })\n }\n if(this.eventMap.CLUSTER_SPAWNED) this.eventMap.CLUSTER_SPAWNED(cluster, connection)\n connection.eventManager.send({\n type: 'CLUSTER_CREATE',\n data: {\n clusterID: cluster.clusterID,\n instanceID: connection.instanceID,\n totalShards: this.getTotalShards(),\n shardList: cluster.shardList,\n token: this.token,\n intents: this.intents\n }\n });\n }\n\n public startListening(): void {\n this.server.on('connect', (connection, payload) => {\n const id = payload?.id;\n const data = payload.data as unknown;\n const dev = payload?.dev || false;\n if (!id) {\n connection.close('Invalid payload', false);\n return;\n }\n\n if (this.connectedClients.values().some(client => client.instanceID === id)) {\n connection.close('Already connected', false);\n return;\n }\n\n const bridgeConnection = new BridgeClientConnection(payload.id, connection, data, dev);\n if(this.eventMap.CLIENT_CONNECTED) this.eventMap.CLIENT_CONNECTED(bridgeConnection);\n\n bridgeConnection.onMessage((m: any) => {\n if (m.type == 'CLUSTER_SPAWNED') {\n const cluster = this.clusterCalculator.getClusterForConnection(bridgeConnection).find(c => c.clusterID === m.data.id);\n if (cluster) {\n cluster.connectionStatus = BridgeClientClusterConnectionStatus.STARTING;\n }\n return;\n }\n\n if (m.type == 'CLUSTER_READY') {\n const cluster = this.clusterCalculator.getClusterForConnection(bridgeConnection).find(c => c.clusterID === m.data.id);\n if (cluster) {\n cluster.startedAt = Date.now();\n if(this.eventMap.CLUSTER_READY) this.eventMap.CLUSTER_READY(cluster, m.data.guilds || 0, m.data.members || 0);\n cluster.connectionStatus = BridgeClientClusterConnectionStatus.CONNECTED;\n if (cluster.oldConnection) {\n cluster.oldConnection.eventManager.send({\n type: 'CLUSTER_STOP',\n data: {\n id: cluster.clusterID\n }\n });\n cluster.oldConnection = undefined;\n }\n }\n return;\n }\n\n if (m.type == 'CLUSTER_STOPPED') {\n const cluster = this.clusterCalculator.getClusterForConnection(bridgeConnection).find(c => c.clusterID === m.data.id);\n if (cluster) {\n cluster.startedAt = undefined;\n if(this.eventMap.CLUSTER_STOPPED) this.eventMap.CLUSTER_STOPPED(cluster);\n cluster.setConnection(undefined);\n }\n return;\n }\n\n if(m.type == \"INSTANCE_STOP\") {\n this.stopInstance(bridgeConnection);\n }\n\n return;\n })\n\n bridgeConnection.onRequest((m: any) => {\n if(m.type == 'REDIRECT_REQUEST_TO_GUILD'){\n const guildID = m.guildID;\n const shardID = ShardingUtil.getShardIDForGuild(guildID, this.getTotalShards());\n const cluster = this.clusterCalculator.getClusterOfShard(shardID);\n if(!cluster){\n return Promise.reject(new Error(\"cluster not found\"))\n }\n if(cluster.connectionStatus != BridgeClientClusterConnectionStatus.CONNECTED){\n return Promise.reject(new Error(\"cluster not connected.\"))\n }\n\n if(!cluster.connection?.eventManager){\n return Promise.reject(new Error(\"no connection defined.\"))\n }\n\n return cluster.connection.eventManager.request({\n type: 'REDIRECT_REQUEST_TO_GUILD',\n clusterID: cluster.clusterID,\n guildID: guildID,\n data: m.data\n }, 5000)\n }\n\n if(m.type == 'BROADCAST_EVAL') {\n const responses = Promise.all(\n this.connectedClients.values().map(c => {\n return c.eventManager.request<unknown[]>({\n type: 'BROADCAST_EVAL',\n data: m.data,\n }, 5000);\n })\n )\n return new Promise<unknown[]>((resolve, reject) => {\n responses.then((r) => {\n resolve(r.flatMap(f => f))\n }).catch(reject);\n })\n }\n\n if(m.type == 'SELF_CHECK') {\n return {\n clusterList: [\n ...this.clusterCalculator.getClusterForConnection(bridgeConnection).map(c => c.clusterID),\n ...this.clusterCalculator.getOldClusterForConnection(bridgeConnection).map(c => c.clusterID)\n ]\n }\n }\n\n return Promise.reject(new Error(\"unknown type\"))\n })\n\n this.connectedClients.set(connection.id, bridgeConnection)\n });\n\n this.server.on('disconnect', (connection, reason) => {\n const closedConnection = this.connectedClients.get(connection.id);\n if (!closedConnection) {\n return;\n }\n\n const clusters = this.clusterCalculator.getClusterForConnection(closedConnection);\n for (const cluster of clusters) {\n this.clusterCalculator.clearClusterConnection(cluster.clusterID);\n }\n\n this.connectedClients.delete(connection.id);\n if(this.eventMap.CLIENT_DISCONNECTED) this.eventMap.CLIENT_DISCONNECTED(closedConnection, reason);\n });\n\n this.server.on(\"message\", (message, connection) => {\n this.sendMessageToClient(connection.id, message);\n })\n }\n\n sendMessageToClient(clientId: string, message: unknown): void {\n if (!this.connectedClients.has(clientId)) {\n return;\n }\n\n const client = this.connectedClients.get(clientId);\n if (client) {\n client.messageReceive(message);\n }\n }\n\n private getTotalShards() {\n return this.shardsPerCluster * this.clusterToStart;\n }\n\n\n public on<K extends keyof BridgeEventListeners>(event: K, listener: BridgeEventListeners[K]): void {\n this.eventMap[event] = listener;\n }\n\n public getClusters() {\n return this.clusterCalculator.clusterList;\n }\n\n async stopAllInstances() {\n const instances = Array.from(this.connectedClients.values());\n for (const instance of instances) {\n instance.connectionStatus = BridgeClientConnectionStatus.PENDING_STOP;\n }\n\n for (const instance of instances) {\n await this.stopInstance(instance, false);\n }\n }\n\n async stopAllInstancesWithRestart() {\n const instances = Array.from(this.connectedClients.values());\n\n for (const instance of instances) {\n await this.stopInstance(instance);\n await new Promise<void>((resolve) => {\n setTimeout(async () => {\n resolve();\n }, 1000 * 10);\n })\n }\n }\n\n async moveCluster(instance: BridgeClientConnection, cluster: BridgeClientCluster) {\n cluster.reclustering(instance);\n\n this.createCluster(instance, cluster, true);\n }\n\n async stopInstance(instance: BridgeClientConnection, recluster = true) {\n if(this.eventMap.CLIENT_STOP) this.eventMap.CLIENT_STOP(instance);\n instance.connectionStatus = BridgeClientConnectionStatus.PENDING_STOP;\n\n let clusterToSteal: BridgeClientCluster | undefined;\n\n await instance.eventManager.send({\n type: 'INSTANCE_STOP'\n });\n\n if(recluster) {\n while ((clusterToSteal = this.clusterCalculator.getClusterForConnection(instance).filter(c =>\n c.connectionStatus === BridgeClientClusterConnectionStatus.CONNECTED ||\n c.connectionStatus == BridgeClientClusterConnectionStatus.STARTING ||\n c.connectionStatus == BridgeClientClusterConnectionStatus.RECLUSTERING)[0]) !== undefined) {\n // skip if the cluster is not connected\n if(clusterToSteal.connectionStatus != BridgeClientClusterConnectionStatus.CONNECTED) break;\n\n const least = this.clusterCalculator.getClusterWithLowestLoad(this.connectedClients);\n if (!least) {\n if (this.eventMap.ERROR) {\n this.eventMap.ERROR(\"Reclustering failed: No least cluster found.\");\n }\n await instance.eventManager.send({\n type: 'CLUSTER_STOP',\n data: {\n id: clusterToSteal.clusterID\n }\n });\n clusterToSteal.connection = undefined;\n clusterToSteal.connectionStatus = BridgeClientClusterConnectionStatus.DISCONNECTED;\n continue;\n }\n\n clusterToSteal.reclustering(least);\n\n if (this.eventMap.CLUSTER_RECLUSTER) {\n this.eventMap.CLUSTER_RECLUSTER(clusterToSteal, least, clusterToSteal.oldConnection!);\n }\n\n this.createCluster(least, clusterToSteal, true);\n }\n\n return new Promise<void>((resolve, reject) => {\n const interval = setInterval(async () => {\n const cluster = this.clusterCalculator.getOldClusterForConnection(instance)[0] || undefined;\n if (!cluster) {\n clearInterval(interval);\n await instance.eventManager.send({\n type: 'INSTANCE_STOPPED'\n })\n await instance.connection.close(\"Instance stopped.\", false);\n resolve();\n return;\n }\n }, 1000);\n })\n } else {\n for(const cluster of this.clusterCalculator.getClusterForConnection(instance)) {\n await instance.eventManager.send({\n type: 'CLUSTER_STOP',\n data: {\n id: cluster.clusterID\n }\n });\n }\n\n\n await instance.eventManager.send({\n type: 'INSTANCE_STOPPED'\n })\n await instance.connection.close(\"Instance stopped.\", false);\n }\n }\n}\n\n\n\nexport type BridgeEventListeners = {\n 'CLUSTER_READY': ((cluster: BridgeClientCluster, guilds: number, members: number) => void) | undefined,\n 'CLUSTER_STOPPED': ((cluster: BridgeClientCluster) => void) | undefined,\n 'CLUSTER_SPAWNED': ((cluster: BridgeClientCluster, connection: BridgeClientConnection) => void) | undefined,\n 'CLUSTER_RECLUSTER': ((cluster: BridgeClientCluster, newConnection: BridgeClientConnection, oldConnection: BridgeClientConnection) => void) | undefined,\n 'CLUSTER_HEARTBEAT_FAILED': ((cluster: BridgeClientCluster, error: unknown) => void) | undefined,\n 'CLIENT_CONNECTED': ((client: BridgeClientConnection) => void) | undefined,\n 'CLIENT_DISCONNECTED': ((client: BridgeClientConnection, reason: string) => void) | undefined,\n 'ERROR': ((error: string) => void) | undefined,\n 'CLIENT_STOP': ((instance: BridgeClientConnection) => void) | undefined\n};","import {BridgeClientCluster, BridgeClientClusterConnectionStatus} from \"./BridgeClientCluster\";\nimport {BridgeClientConnection, BridgeClientConnectionStatus} from \"./BridgeClientConnection\";\n\n/**\n * Manages the calculation and distribution of clusters for a Discord bot sharding system.\n * This class is responsible for creating clusters with their assigned shards,\n * tracking which clusters are in use, and providing methods to retrieve available clusters.\n */\nexport class ClusterCalculator {\n /** The total number of clusters to initialize */\n private readonly clusterToStart: number;\n\n /** The number of shards that each cluster will manage */\n private readonly shardsPerCluster: number;\n\n /** List of all clusters managed by this calculator */\n public readonly clusterList: BridgeClientCluster[]= [];\n\n /**\n * Creates a new ClusterCalculator and initializes the clusters.\n * \n * @param clusterToStart - The number of clusters to create\n * @param shardsPerCluster - The number of shards each cluster will manage\n */\n constructor(clusterToStart: number, shardsPerCluster: number) {\n this.shardsPerCluster = shardsPerCluster;\n this.clusterToStart = clusterToStart;\n\n this.calculateClusters();\n }\n\n /**\n * Calculates and initializes all clusters with their assigned shards.\n * Each cluster is assigned a sequential range of shard IDs based on its cluster index.\n */\n private calculateClusters(): void {\n const clusters: Map<number, number[]> = new Map();\n for (let i = 0; i < this.clusterToStart; i++) {\n clusters.set(i, []);\n for (let j = 0; j < this.shardsPerCluster; j++) {\n clusters.get(i)?.push(i * this.shardsPerCluster + j);\n }\n }\n\n for (let [clusterIndex, clusterShards] of clusters.entries()) {\n this.clusterList.push(new BridgeClientCluster(clusterIndex, clusterShards));\n }\n }\n\n /**\n * Retrieves the next available (unused) cluster and marks it as used.\n * \n * @returns The next available cluster, or undefined if all clusters are in use\n */\n public getNextCluster(): BridgeClientCluster | undefined {\n for (const cluster of this.clusterList) {\n if (!cluster.isUsed()) {\n return cluster;\n }\n }\n return undefined; // No available clusters\n }\n\n /**\n * Retrieves multiple available clusters up to the specified count.\n * Each returned cluster is marked as used.\n * \n * @param count - The maximum number of clusters to retrieve\n * @returns An array of available clusters (may be fewer than requested if not enough are available)\n */\n public getNextClusters(count: number): BridgeClientCluster[] {\n const availableClusters: BridgeClientCluster[] = [];\n for (const cluster of this.clusterList) {\n if (!cluster.isUsed() && availableClusters.length < count) {\n availableClusters.push(cluster);\n }\n }\n return availableClusters; // Returns the clusters that were found\n }\n\n /**\n * Sets the used status of a specific cluster by its ID.\n *\n * @param clusterID - The ID of the cluster to update\n * @param connection - The connection to associate with the cluster\n */\n public clearClusterConnection(clusterID: number): void {\n const cluster = this.clusterList.find(c => c.clusterID === clusterID);\n if (cluster) {\n cluster.setConnection(undefined);\n }\n }\n\n public getClusterForConnection(connection: BridgeClientConnection): BridgeClientCluster[] {\n return this.clusterList.filter(cluster =>\n cluster.connection?.instanceID === connection.instanceID\n );\n }\n\n public getOldClusterForConnection(connection: BridgeClientConnection): BridgeClientCluster[] {\n return this.clusterList.filter(cluster =>\n cluster.oldConnection?.instanceID === connection.instanceID\n );\n }\n\n public checkAllClustersConnected(): boolean {\n for (const cluster of this.clusterList) {\n if (cluster.connectionStatus != BridgeClientClusterConnectionStatus.CONNECTED){\n return false; // At least one cluster is not in use\n }\n }\n return true; // All clusters are in use\n }\n\n\n findMostAndLeastClustersForConnections(\n connectedClients: BridgeClientConnection[]\n ): {\n most: BridgeClientConnection | undefined,\n least: BridgeClientConnection | undefined\n } {\n\n const openClients = connectedClients.filter(x => !x.dev)\n\n const devClients = connectedClients.filter(x => x.dev)\n const summDevConnectedClusters = devClients.map(c => this.getClusterForConnection(c).length).reduce((a, b) => a + b, 0);\n\n let most: BridgeClientConnection | undefined;\n let least: BridgeClientConnection | undefined;\n let remainder = ((this.clusterToStart - summDevConnectedClusters) % openClients.length || 0);\n\n for (const client of openClients) {\n const clusters = this.getClusterForConnection(client);\n\n if (!most || clusters.length > this.getClusterForConnection(most).length) {\n most = client;\n }\n\n if (!least || clusters.length < this.getClusterForConnection(least).length) {\n least = client;\n }\n }\n\n if (most && least) {\n const mostCount = this.getClusterForConnection(most).length;\n const leastCount = this.getClusterForConnection(least).length;\n\n // Only recluster if the difference is greater than remainder\n if (mostCount - leastCount <= remainder) {\n return {most: undefined, least: undefined};\n }\n }\n\n return {most, least};\n }\n\n getClusterWithLowestLoad(connectedClients: Map<string, BridgeClientConnection>): BridgeClientConnection | undefined {\n let lowestLoadClient: BridgeClientConnection | undefined;\n let lowestLoad = Infinity;\n\n for (const client of connectedClients.values().filter(c =>\n c.connectionStatus === BridgeClientConnectionStatus.READY && !c.dev)) {\n const clusters = this.getClusterForConnection(client);\n\n const load = clusters.length; // Assuming load is determined by the number of clusters assigned\n if (load < lowestLoad) {\n lowestLoad = load;\n lowestLoadClient = client;\n }\n }\n\n return lowestLoadClient; // Returns the client with the lowest load, or undefined if no clients are connected\n }\n\n getClusterOfShard(shardID: number) {\n return this.clusterList.find(c => c.shardList.includes(shardID));\n }\n}\n","export class ShardingUtil {\n public static getShardIDForGuild(guildID: string, totalShards: number): number {\n if (!guildID || totalShards <= 0) {\n throw new Error(\"Invalid guild ID or total shards\");\n }\n\n return Number(BigInt(guildID) >> 22n) % totalShards;\n }\n}","import {Client, GatewayIntentsString, Status} from \"discord.js\";\nimport {EventManager} from \"../general/EventManager\";\nimport os from \"os\";\nexport class Cluster<T extends Client> {\n\n public readonly instanceID: number;\n\n public readonly clusterID: number;\n\n public readonly shardList: number[] = [];\n\n public readonly totalShards: number;\n\n public readonly token: string;\n\n public readonly intents: GatewayIntentsString[];\n\n public eventManager: EventManager;\n\n public client!: T;\n\n private readonly eventMap: {\n 'message': ((message: unknown) => void) | undefined,\n 'request': ((message: unknown, resolve: (data: unknown) => void, reject: (error: any) => void) => void) | undefined,\n 'CLUSTER_READY': (() => void) | undefined,\n } = {\n message: undefined, request: undefined, CLUSTER_READY: undefined,\n }\n\n constructor(instanceID: number, clusterID: number, shardList: number[], totalShards: number, token: string, intents: GatewayIntentsString[]) {\n this.instanceID = instanceID;\n this.clusterID = clusterID;\n this.shardList = shardList;\n this.totalShards = totalShards;\n this.token = token;\n this.intents = intents;\n this.eventManager = new EventManager((message: unknown) => {\n return new Promise((resolve, reject) => {\n if (typeof process.send !== 'function') {\n reject(new Error(\"Process does not support sending messages\"));\n return;\n }\n\n process.send?.(message, undefined, undefined, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }, (message: unknown) => {\n this._onMessage(message);\n }, (message: unknown) => {\n return this._onRequest(message);\n });\n process.on(\"message\", (message) => {\n this.eventManager.receive(message);\n })\n }\n\n static initial<T extends Client>(): Cluster<T> {\n const args = process.env;\n\n if (args.SHARD_LIST == undefined || args.INSTANCE_ID == undefined || args.TOTAL_SHARDS == undefined || args.TOKEN == undefined || args.INTENTS == undefined || args.CLUSTER_ID == undefined) {\n throw new Error(\"Missing required environment variables\");\n }\n\n const shardList = args.SHARD_LIST.split(',').map(Number);\n\n const totalShards = Number(args.TOTAL_SHARDS);\n\n const instanceID = Number(args.INSTANCE_ID);\n const clusterID = Number(args.CLUSTER_ID);\n\n const token = args.TOKEN;\n\n const intents = args.INTENTS.split(',').map(i => i.trim()) as GatewayIntentsString[];\n\n return new Cluster<T>(instanceID, clusterID, shardList, totalShards, token, intents);\n }\n\n triggerReady(guilds: number, members: number) {\n this.eventManager.send({\n type: 'CLUSTER_READY',\n id: this.clusterID,\n guilds: guilds,\n members: members,\n });\n\n if(this.eventMap?.CLUSTER_READY) {\n this.eventMap?.CLUSTER_READY();\n }\n }\n\n triggerError(e: any) {\n this.eventManager.send({\n type: 'CLUSTER_ERROR',\n id: this.clusterID,\n });\n }\n\n private async wait(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private _onMessage(message: unknown): void {\n const m = message as { type: string, data: unknown };\n if(m.type == 'CUSTOM' && this.eventMap.message) {\n this.eventMap.message!(m.data);\n }\n }\n\n private _onRequest(message: unknown): unknown {\n const m = message as { type: string, data: unknown };\n if(m.type == 'CUSTOM' && this.eventMap.request) {\n return new Promise((resolve, reject) => {\n this.eventMap.request!(m.data, resolve, reject);\n });\n } else if(m.type == 'CLUSTER_HEARTBEAT'){\n const startTime = process.hrtime.bigint();\n const startUsage = process.cpuUsage();\n\n (async () => {\n await this.wait(500);\n })();\n\n const endTime = process.hrtime.bigint();\n const usageDiff = process.cpuUsage(startUsage);\n\n const elapsedTimeUs = Number((endTime - startTime) / 1000n);\n const totalCPUTime = usageDiff.user + usageDiff.system;\n\n const cpuCount = os.cpus().length;\n const cpuPercent = (totalCPUTime / (elapsedTimeUs * cpuCount)) * 100;\n\n // Collect per-shard ping information in addition to the overall ws ping\n let shardPings: { id: number, ping: number, status: Status, uptime?: unknown, guilds: number, members: number }[] = [];\n try {\n const shards = this.client.ws.shards;\n\n if(shards) {\n shards.forEach((shard) => {\n shardPings.push({ id: shard.id, ping: shard.ping, status: shard.status,\n guilds: this.client.guilds.cache.filter(g => g.shardId === shard.id).size,\n members: this.client.guilds.cache.filter(g => g.shardId === shard.id).reduce((acc, g) => acc + g.memberCount, 0)\n });\n\n this.client.shard?.fetchClientValues('uptime', shard.id).then(values => {\n shardPings[shard.id][\"uptime\"] = values\n console.log(values)\n }).catch(e => {\n\n })\n })\n }\n } catch (_) {\n // ignore and keep empty shardPings on failure\n }\n\n return {\n cpu: { raw: process.cpuUsage(), cpuPercent: cpuPercent.toFixed(2) },\n memory: { raw: process.memoryUsage(),\n memoryPercent: ((process.memoryUsage().heapUsed / process.memoryUsage().heapTotal) * 100).toFixed(2) + '%',\n usage: (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2) + 'MB'\n },\n ping: this.client.ws.ping,\n shardPings: shardPings,\n }\n } else if(m.type == 'BROADCAST_EVAL'){\n const broadcast = message as { type: 'BROADCAST_EVAL', data: string }\n\n const fn = eval(`(${broadcast.data})`);\n\n const result = fn(this.client);\n if(result instanceof Promise){\n return new Promise((resolve, reject) => {\n result.then(res => {\n resolve(res);\n }).catch(err => {\n reject(err);\n });\n });\n } else {\n return result;\n }\n }\n return undefined;\n }\n\n public on<K extends keyof ClusterEventListeners>(event: K, listener: ClusterEventListeners[K]): void {\n this.eventMap[event] = listener;\n }\n\n public sendMessage(data: unknown) {\n this.eventManager.send({\n type: 'CUSTOM',\n data: data,\n });\n }\n\n public sendRequest(data: unknown, timeout = 5000): Promise<unknown> {\n return this.eventManager.request({\n type: 'CUSTOM',\n data: data,\n }, timeout);\n }\n\n public broadcastEval<Result>(fn: (cluster: T) => Result, timeout = 20000): Promise<Result[]> {\n return this.eventManager.request({\n type: 'BROADCAST_EVAL',\n data: fn.toString(),\n }, timeout);\n }\n\n\n public sendMessageToClusterOfGuild(guildID: string, message: unknown): void {\n if (this.eventManager) {\n this.eventManager.send({\n type: 'REDIRECT_MESSAGE_TO_GUILD',\n guildID: guildID,\n data: message\n });\n }\n }\n\n public sendRequestToClusterOfGuild(guildID: string, message: unknown, timeout = 5000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n if (this.eventManager) {\n this.eventManager.request({\n type: 'REDIRECT_REQUEST_TO_GUILD',\n guildID: guildID,\n data: message\n }, timeout).then((response) => {\n resolve(response);\n }).catch((error) => {\n reject(error);\n });\n } else {\n reject(new Error(\"Event manager is not initialized\"));\n }\n });\n }\n}\n\nexport type ClusterEventListeners = {\n message: (message: unknown) => void;\n request: (message: unknown, resolve: (data: unknown) => void, reject: (error: any) => void) => void;\n\n CLUSTER_READY: () => void;\n};","import {ChildProcess} from \"child_process\";\nimport {EventManager} from \"../general/EventManager\";\n\nexport type ClusterProcessState = 'starting' | 'running' | 'stopped';\n\nexport class ClusterProcess {\n public readonly child: ChildProcess;\n public readonly eventManager: EventManager;\n public readonly id: number;\n public readonly shardList: number[];\n public readonly totalShards: number;\n public status: ClusterProcessState;\n public readonly createdAt: number = Date.now();\n\n private _onMessage?: (message: unknown) => void;\n private _onRequest?: (message: unknown) => unknown;\n\n constructor(id: number, child: ChildProcess, shardList: number[], totalShards: number) {\n this.id = id;\n this.child = child;\n this.shardList = shardList;\n this.totalShards = totalShards;\n this.status = 'starting';\n this.eventManager = new EventManager((message) => {\n return new Promise<void>((resolve, reject) => {\n this.child.send(message, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n })\n }, (message) => {\n if (this._onMessage) {\n this._onMessage(message);\n }\n }, (message) => {\n if (this._onRequest) {\n return this._onRequest(message);\n }\n return undefined;\n })\n\n this.child.on('message', (message) => {\n this.eventManager.receive(message);\n });\n\n // Ensure we do not retain pending requests if the child dies or errors\n this.child.on('exit', () => {\n this.eventManager.close('child process exited');\n });\n this.child.on('error', () => {\n this.eventManager.close('child process error');\n });\n }\n\n onMessage(callback: (message: unknown) => void) {\n this._onMessage = callback;\n }\n\n onRequest(callback: (message: unknown) => unknown) {\n this._onRequest = callback;\n }\n\n public sendMessage(data: unknown) {\n this.eventManager.send({\n type: 'CUSTOM',\n data: data,\n });\n }\n\n public sendRequest(data: unknown, timeout = 5000): Promise<unknown> {\n return this.eventManager.request({\n type: 'CUSTOM',\n data: data,\n }, timeout);\n }\n}","import {fork} from 'child_process';\nimport {ClusterProcess} from \"../cluster/ClusterProcess\";\nimport {GatewayIntentsString} from \"discord.js\";\nimport {ShardingUtil} from \"../general/ShardingUtil\";\n\nexport abstract class BotInstance {\n\n private readonly entryPoint: string;\n\n private readonly execArgv: string[];\n\n public readonly clients: Map<number, ClusterProcess> = new Map();\n\n protected constructor(entryPoint: string, execArgv?: string[]) {\n this.entryPoint = entryPoint;\n this.execArgv = execArgv ?? [];\n }\n\n protected readonly eventMap: BotInstanceEventListeners = {\n 'message': undefined,\n 'request': undefined,\n\n 'PROCESS_KILLED': undefined,\n 'PROCESS_SPAWNED': undefined,\n 'ERROR': undefined,\n 'PROCESS_ERROR': undefined,\n 'CLUSTER_READY': undefined,\n 'CLUSTER_ERROR': undefined,\n 'CLUSTER_RECLUSTER': undefined,\n 'BRIDGE_CONNECTION_ESTABLISHED': undefined,\n 'BRIDGE_CONNECTION_CLOSED': undefined,\n 'BRIDGE_CONNECTION_STATUS_CHANGE': undefined,\n 'INSTANCE_STOP': undefined,\n 'INSTANCE_STOPPED': undefined,\n 'SELF_CHECK_SUCCESS': undefined,\n 'SELF_CHECK_ERROR': undefined,\n 'SELF_CHECK_RECEIVED': undefined,\n }\n\n protected startProcess(instanceID: number, clusterID: number, shardList: number[], totalShards: number, token: string, intents: GatewayIntentsString[]): void {\n try {\n const child = fork(this.entryPoint, {\n env: {\n INSTANCE_ID: instanceID.toString(),\n CLUSTER_ID: clusterID.toString(),\n SHARD_LIST: shardList.join(','),\n TOTAL_SHARDS: totalShards.toString(),\n TOKEN: token,\n INTENTS: intents.join(','),\n FORCE_COLOR: 'true'\n },\n stdio: 'inherit',\n execArgv: this.execArgv,\n silent: false,\n })\n\n const client = new ClusterProcess(clusterID, child, shardList, totalShards);\n\n child.stdout?.on('data', (data) => {\n process.stdout.write(data);\n });\n\n child.stderr?.on('data', (data) => {\n process.stderr.write(data);\n });\n\n child.on(\"spawn\", () => {\n if(this.eventMap.PROCESS_SPAWNED) this.eventMap.PROCESS_SPAWNED(client);\n\n this.setClusterSpawned(client);\n\n this.clients.set(clusterID, client);\n\n client.onMessage((message) => {\n this.onMessage(client, message);\n })\n\n client.onRequest((message) => {\n return this.onRequest(client, message);\n });\n });\n\n child.on(\"error\", (err) => {\n if(this.eventMap.PROCESS_ERROR) this.eventMap.PROCESS_ERROR(client, err);\n })\n\n child.on(\"exit\", (err: Error) => {\n if(client.status !== 'stopped') {\n client.status = 'stopped';\n this.killProcess(client, `Process exited: ${err?.message}`);\n }\n })\n } catch (error) {\n throw new Error(`Failed to start process for cluster ${clusterID}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n protected killProcess(client: ClusterProcess, reason: string): void {\n client.status = 'stopped';\n if (client.child && client.child.pid) {\n if(client.child.kill(\"SIGKILL\")) {\n if(this.eventMap.PROCESS_KILLED) this.eventMap.PROCESS_KILLED(client, reason, true);\n } else {\n if(this.eventMap.ERROR) this.eventMap.ERROR(`Failed to kill process for cluster ${client.id}`);\n client.child.kill(\"SIGKILL\");\n }\n } else {\n if(this.eventMap.PROCESS_KILLED) this.eventMap.PROCESS_KILLED(client, reason, false);\n }\n this.clients.delete(client.id);\n this.setClusterStopped(client, reason);\n }\n\n protected abstract setClusterStopped(client: ClusterProcess, reason: string): void;\n\n protected abstract setClusterReady(client: ClusterProcess, guilds: number, members: number): void;\n\n protected abstract setClusterSpawned(client: ClusterProcess): void;\n\n public abstract start(): void;\n\n private onMessage(client: ClusterProcess, message: any): void {\n if(message.type === 'CLUSTER_READY') {\n client.status = 'running';\n if(this.eventMap.CLUSTER_READY) this.eventMap.CLUSTER_READY(client);\n this.setClusterReady(client, message.guilds || 0, message.members || 0);\n }\n\n if (message.type === 'CLUSTER_ERROR') {\n client.status = 'stopped';\n if(this.eventMap.CLUSTER_ERROR) this.eventMap.CLUSTER_ERROR(client, message.error);\n this.killProcess(client, 'Cluster error: ' + message.error);\n }\n\n if(message.type == 'CUSTOM' && this.eventMap.message) {\n this.eventMap.message!(client, message.data);\n }\n }\n\n protected abstract onRequest(client: ClusterProcess, message: any): Promise<unknown>;\n\n public on<K extends keyof BotInstanceEventListeners>(event: K, listener: BotInstanceEventListeners[K]): void {\n this.eventMap[event] = listener;\n }\n\n public sendRequestToClusterOfGuild(guildID: string, message: unknown, timeout = 5000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n for (const client of this.clients.values()) {\n const shardID = ShardingUtil.getShardIDForGuild(guildID, client.totalShards);\n if (client.shardList.includes(shardID)) {\n client.eventManager.request({\n type: 'CUSTOM',\n data: message\n }, timeout).then(resolve).catch(reject);\n return;\n }\n }\n reject(new Error(`No cluster found for guild ${guildID}`));\n });\n }\n\n public sendRequestToCluster(cluster: ClusterProcess, message: unknown, timeout = 5000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n cluster.eventManager.request({\n type: 'CUSTOM',\n data: message\n }, timeout).then(resolve).catch(reject);\n return;\n });\n }\n}\n\nexport type BotInstanceEventListeners = {\n 'message': ((client: ClusterProcess,message: unknown) => void) | undefined,\n 'request': ((client: ClusterProcess, message: unknown, resolve: (data: unknown) => void, reject: (error: any) => void) => void) | undefined,\n\n 'PROCESS_KILLED': ((client: ClusterProcess, reason: string, processKilled: boolean) => void) | undefined,\n 'PROCESS_SPAWNED': ((client: ClusterProcess) => void) | undefined,\n 'PROCESS_ERROR': ((client: ClusterProcess, error: unknown) => void) | undefined,\n 'CLUSTER_READY': ((client: ClusterProcess) => void) | undefined,\n 'CLUSTER_ERROR': ((client: ClusterProcess, error: unknown) => void) | undefined,\n 'CLUSTER_RECLUSTER': ((client: ClusterProcess) => void) | undefined,\n 'ERROR': ((error: string) => void) | undefined,\n\n 'BRIDGE_CONNECTION_ESTABLISHED': (() => void) | undefined,\n 'BRIDGE_CONNECTION_CLOSED': ((reason: string) => void) | undefined,\n 'BRIDGE_CONNECTION_STATUS_CHANGE': ((status: number) => void) | undefined,\n 'INSTANCE_STOP': (() => void) | undefined,\n 'INSTANCE_STOPPED': (() => void) | undefined,\n\n 'SELF_CHECK_SUCCESS': (() => void) | undefined,\n 'SELF_CHECK_ERROR': ((error: string) => void) | undefined,\n 'SELF_CHECK_RECEIVED': ((data: { clusterList: number[] }) => void) | undefined,\n};","import {BotInstance} from \"./BotInstance\";\nimport {ClusterProcess, ClusterProcessState} from \"../cluster/ClusterProcess\";\nimport {Client} from \"net-ipc\";\nimport {EventManager} from \"../general/EventManager\";\nimport {GatewayIntentsString} from \"discord.js\";\nimport {ShardingUtil} from \"../general/ShardingUtil\";\n\nexport enum BridgeConnectionStatus {\n CONNECTED,\n DISCONNECTED,\n}\n\nexport class ManagedInstance extends BotInstance {\n\n private readonly host: string;\n\n private readonly port: number;\n\n private readonly instanceID: number;\n\n private eventManager!: EventManager;\n\n private connectionStatus: BridgeConnectionStatus = BridgeConnectionStatus.DISCONNECTED;\n\n private data: unknown;\n\n private dev: boolean = false;\n\n constructor(entryPoint: string, host: string, port: number, instanceID: number, data: unknown, execArgv?: string[], dev?: boolean) {\n super(entryPoint, execArgv);\n\n this.host = host;\n this.port = port;\n this.instanceID = instanceID;\n this.data = data;\n this.dev = dev || false;\n }\n\n public start() {\n const client = new Client({\n host: this.host,\n port: this.port,\n reconnect: true,\n retries: 100\n });\n\n this.eventManager = new EventManager((message) => {\n if(client.status == 3) {\n return client.send(message);\n }\n return Promise.reject(new Error('Client is not ready to send messages'));\n }, (message) => {\n const m = message as { type: string, data: unknown };\n if(m.type == 'CLUSTER_CREATE') {\n this.onClusterCreate(m.data)\n } else if (m.type == 'CLUSTER_STOP') {\n this.onClusterStop(m.data);\n } else if(m.type == 'CLUSTER_RECLUSTER') {\n this.onClusterRecluster(m.data);\n } else if(m.type == 'INSTANCE_STOP') {\n if(this.eventMap.INSTANCE_STOP) {\n this.eventMap.INSTANCE_STOP();\n }\n } else if(m.type == 'INSTANCE_STOPPED') {\n if(this.eventMap.INSTANCE_STOPPED) {\n this.eventMap.INSTANCE_STOPPED();\n }\n }\n }, (message) => {\n return this.onBridgeRequest(message);\n });\n\n setInterval(() => {\n if(this.connectionStatus == BridgeConnectionStatus.CONNECTED) {\n this.selfCheck();\n }\n }, 2500); // 5 minutes\n\n client.connect({\n id: this.instanceID,\n dev: this.dev,\n data: this.data,\n }).then(_ => {\n if(this.eventMap.BRIDGE_CONNECTION_ESTABLISHED) this.eventMap.BRIDGE_CONNECTION_ESTABLISHED();\n this.connectionStatus = BridgeConnectionStatus.CONNECTED;\n\n client.on(\"message\", (message) => {\n this.eventManager?.receive(message);\n })\n client.on(\"close\", (reason) => {\n if(this.eventMap.BRIDGE_CONNECTION_CLOSED) this.eventMap.BRIDGE_CONNECTION_CLOSED(reason);\n\n // kill all\n if(this.connectionStatus == BridgeConnectionStatus.CONNECTED) {\n this.clients.forEach((client) => {\n this.killProcess(client, 'Bridge connection closed');\n });\n }\n this.connectionStatus = BridgeConnectionStatus.DISCONNECTED;\n });\n\n client.on(\"status\", (status) => {\n if(this.eventMap.BRIDGE_CONNECTION_STATUS_CHANGE) this.eventMap.BRIDGE_CONNECTION_STATUS_CHANGE(status);\n\n if(status == 4){\n if(this.connectionStatus == BridgeConnectionStatus.CONNECTED) {\n this.clients.forEach((client) => {\n this.killProcess(client, 'Bridge connection closed');\n });\n }\n this.connectionStatus = BridgeConnectionStatus.DISCONNECTED;\n } else if(status == 3){\n this.connectionStatus = BridgeConnectionStatus.CONNECTED;\n if(this.eventMap.BRIDGE_CONNECTION_ESTABLISHED) this.eventMap.BRIDGE_CONNECTION_ESTABLISHED();\n }\n });\n })\n }\n\n private selfCheck() {\n this.eventManager.request({\n type: 'SELF_CHECK'\n }, 1000 * 60).then((r) => {\n const response = r as { clusterList: number[] };\n\n if(this.eventMap.SELF_CHECK_RECEIVED) {\n this.eventMap.SELF_CHECK_RECEIVED(response);\n }\n\n const startingClusters = this.clients.values().filter(c => c.status == 'starting').toArray();\n startingClusters.forEach((c: ClusterProcess) => {\n if (Date.now() - c.createdAt > 10 * 60 * 1000) {\n this.killProcess(c, 'Cluster took too long to start');\n }\n })\n\n // check if there is an wrong cluster on this host\n const wrongClusters = this.clients.values().filter(c => !response.clusterList.includes(c.id)).toArray();\n if(wrongClusters.length > 0) {\n if(this.eventMap.SELF_CHECK_ERROR) {\n this.eventMap.SELF_CHECK_ERROR(`Self check found wrong clusters: ${wrongClusters.map(c => c.id).join(', ')}`);\n }\n wrongClusters.forEach(c => {\n this.killProcess(c, 'Self check found wrong cluster');\n });\n } else {\n if(this.eventMap.SELF_CHECK_SUCCESS) {\n this.eventMap.SELF_CHECK_SUCCESS();\n }\n }\n }).catch((err) => {\n if(this.eventMap.SELF_CHECK_ERROR) {\n this.eventMap.SELF_CHECK_ERROR(`Self check failed: ${err}`);\n }\n });\n }\n\n protected setClusterStopped(client: ClusterProcess, reason: string): void {\n this.eventManager?.send({\n type: 'CLUSTER_STOPPED',\n data: {\n id: client.id,\n reason: reason\n }\n }).catch(() => {\n return null\n });\n }\n\n protected setClusterReady(client: ClusterProcess, guilds: number, members: number): void {\n this.eventManager?.send({\n type: 'CLUSTER_READY',\n data: {\n id: client.id,\n guilds: guilds,\n members: members\n }\n });\n }\n\n protected setClusterSpawned(client: ClusterProcess): void {\n this.eventManager?.send({\n type: 'CLUSTER_SPAWNED',\n data: {\n id: client.id\n }\n });\n }\n\n private onClusterCreate(message: unknown){\n const m = message as { clusterID: number, shardList: number[], totalShards: number, token: string, intents: GatewayIntentsString[] }\n\n if(this.clients.has(m.clusterID)) {\n this.eventManager?.send({\n type: 'CLUSTER_STOPPED',\n data: {\n id: m.clusterID,\n reason: 'Cluster already exists'\n }\n }).catch(() => {\n return null\n });\n return;\n }\n\n this.startProcess(this.instanceID, m.clusterID, m.shardList, m.totalShards, m.token, m.intents);\n }\n\n private onClusterStop(message: unknown) {\n const m = message as { id: number };\n const cluster = this.clients.get(m.id)\n if (cluster) {\n this.killProcess(cluster, `Request to stop cluster ${m.id}`);\n }\n }\n\n private onClusterRecluster(message: unknown) {\n const m = message as { clusterID: number }\n const cluster = this.clients.get(m.clusterID);\n if (this.eventMap.CLUSTER_RECLUSTER && cluster) {\n this.eventMap.CLUSTER_RECLUSTER(cluster);\n }\n }\n\n protected onRequest(client: ClusterProcess, message: any): Promise<unknown> {\n if(message.type === 'REDIRECT_REQUEST_TO_GUILD'){\n const guildID = message.guildID;\n const data = message.data;\n\n const shardID = ShardingUtil.getShardIDForGuild(guildID, client.totalShards);\n if(client.shardList.includes(shardID)) {\n return client.eventManager.request({\n type: 'CUSTOM',\n data: data\n }, 5000)\n } else {\n return this.eventManager.request({\n type: 'REDIRECT_REQUEST_TO_GUILD',\n guildID: guildID,\n data: data\n }, 5000)\n }\n }\n\n if(message.type == 'BROADCAST_EVAL') {\n return this.eventManager.request({\n type: 'BROADCAST_EVAL',\n data: message.data\n }, 5000)\n }\n\n if(message.type == 'CUSTOM' && this.eventMap.request) {\n return new Promise((resolve, reject) => {\n this.eventMap.request!(client, message.data, resolve, reject);\n });\n }\n\n return Promise.reject(new Error(`Unknown request type: ${message.type}`));\n }\n\n private onBridgeRequest(message: any): Promise<unknown> {\n if(message.type === 'REDIRECT_REQUEST_TO_GUILD'){\n const clusterID = message.clusterID;\n const data = message.data;\n\n const cluster = this.clients.get(clusterID);\n if(cluster){\n return cluster.eventManager.request({\n type: 'CUSTOM',\n data: data\n }, 5000)\n } else {\n return Promise.reject(new Error(`Cluster is not here. Cluster ID: ${clusterID}`));\n }\n } else if(message.type == 'CLUSTER_HEARTBEAT'){\n const clusterID = message.data.clusterID;\n const cluster = this.clients.get(clusterID);\n if (cluster) {\n return new Promise<unknown>((resolve, reject) => {\n cluster.eventManager.request({\n type: 'CLUSTER_HEARTBEAT'\n }, 15000).then((r) => {\n resolve(r);\n }).catch((err) => {\n reject(err);\n });\n })\n } else {\n return Promise.reject(new Error(`Cluster is not here. Cluster ID: ${clusterID}`));\n }\n } else if(message.type == 'BROADCAST_EVAL') {\n return Promise.all(this.clients.values().filter(c => c.status == 'running').map(c => {\n return c.eventManager.request({\n type: 'BROADCAST_EVAL',\n data: message.data,\n }, 5000);\n }));\n }\n\n return Promise.reject(new Error(`Unknown request type: ${message.type}`));\n }\n\n stopInstance(): void {\n this.eventManager?.send({\n type: 'INSTANCE_STOP'\n });\n }\n\n}","import {BotInstance} from \"./BotInstance\";\nimport {ClusterProcess} from \"../cluster/ClusterProcess\";\nimport {GatewayIntentsString} from \"discord.js\";\nimport {ShardingUtil} from \"../general/ShardingUtil\";\n\nexport class StandaloneInstance extends BotInstance {\n private readonly totalClusters: number;\n private readonly shardsPerCluster: number;\n\n public readonly token: string;\n public readonly intents: GatewayIntentsString[];\n\n constructor(entryPoint: string, shardsPerCluster: number, totalClusters: number, token: string, intents: GatewayIntentsString[], execArgv?: string[]) {\n super(entryPoint, execArgv);\n this.shardsPerCluster = shardsPerCluster;\n this.totalClusters = totalClusters;\n this.token = token;\n this.intents = intents;\n }\n\n get totalShards(): number {\n return this.shardsPerCluster * this.totalClusters;\n }\n\n private calculateClusters(): Record<number, number[]> {\n const clusters: Record<number, number[]> = {};\n for (let i = 0; i < this.totalClusters; i++) {\n clusters[i] = [];\n for (let j = 0; j < this.shardsPerCluster; j++) {\n clusters[i].push(i * this.shardsPerCluster + j);\n }\n }\n return clusters;\n }\n\n public start(): void {\n const clusters = this.calculateClusters();\n for (const [id, shardList] of Object.entries(clusters)) {\n this.startProcess(1, Number(id), shardList, this.totalShards, this.token, this.intents);\n }\n }\n\n protected setClusterStopped(client: ClusterProcess, reason: string): void {\n this.clients.delete(client.id);\n this.restartProcess(client);\n }\n\n protected setClusterReady(client: ClusterProcess): void {\n \n }\n\n protected setClusterSpawned(client: ClusterProcess): void {\n\n }\n\n private restartProcess(client: ClusterProcess): void {\n this.startProcess(1, client.id, client.shardList, this.totalShards, this.token, this.intents);\n }\n\n protected onRequest(client: ClusterProcess, message: any): Promise<unknown> {\n if(message.type === 'REDIRECT_REQUEST_TO_GUILD'){\n const guildID = message.guildID;\n const data = message.data;\n\n const shardID = ShardingUtil.getShardIDForGuild(guildID, client.totalShards);\n if(client.shardList.includes(shardID)) {\n return client.eventManager.request({\n type: 'CUSTOM',\n data: data\n }, 5000)\n } else {\n return Promise.reject(new Error(`Shard ID ${shardID} not found in cluster ${client.id} for guild ${guildID}`));\n }\n }\n\n if(message.type == 'BROADCAST_EVAL') {\n return Promise.all(\n this.clients.values().map(c => {\n return c.eventManager.request({\n type: 'BROADCAST_EVAL',\n data: message.data,\n }, 5000);\n })\n );\n }\n\n if(message.type == 'CUSTOM' && this.eventMap.request) {\n return new Promise((resolve, reject) => {\n this.eventMap.request!(client, message.data, resolve, reject);\n });\n }\n\n return Promise.reject(new Error(`Unknown request type: ${message.type}`));\n }\n\n}"],"mappings":"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","names":["BridgeClientClusterConnectionStatus","result","BridgeClientConnectionStatus","message","m","message","message","m","os","fn","message","message","import_net_ipc","BridgeConnectionStatus","message","m","client","message"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/bridge/BridgeClientCluster.ts","../src/general/EventManager.ts","../src/bridge/BridgeClientConnection.ts","../src/bridge/Bridge.ts","../src/bridge/ClusterCalculator.ts","../src/general/ShardingUtil.ts","../src/cluster/Cluster.ts","../src/cluster/ClusterProcess.ts","../src/instance/BotInstance.ts","../src/instance/ManagedInstance.ts","../src/instance/StandaloneInstance.ts"],"sourcesContent":["export * from './bridge/BridgeClientCluster';\nexport * from './bridge/BridgeClientConnection';\nexport * from './bridge/Bridge';\nexport * from './bridge/ClusterCalculator';\n\nexport * from './cluster/Cluster';\nexport * from './cluster/ClusterProcess';\n\nexport * from './general/EventManager';\nexport * from './general/ShardingUtil';\nexport * from './general/EventPayload';\n\nexport * from './instance/BotInstance';\nexport * from './instance/ManagedInstance';\nexport * from './instance/StandaloneInstance';","import {BridgeClientConnection} from \"./BridgeClientConnection\";\n\nexport enum BridgeClientClusterConnectionStatus {\n REQUESTING = 'requesting',\n STARTING = 'starting',\n CONNECTED = 'connected',\n RECLUSTERING = 'reclustering',\n DISCONNECTED = 'disconnected',\n}\n\nexport class BridgeClientCluster {\n public readonly clusterID: number;\n public readonly shardList: number[];\n public connectionStatus: BridgeClientClusterConnectionStatus = BridgeClientClusterConnectionStatus.DISCONNECTED;\n\n public connection?: BridgeClientConnection;\n\n public oldConnection?: BridgeClientConnection;\n\n public missedHeartbeats: number = 0;\n\n public heartbeatResponse?: HeartbeatResponse;\n\n public heartbeatPending = false;\n\n public startedAt?: number;\n\n constructor(clusterID: number, shardList: number[]) {\n this.clusterID = clusterID;\n this.shardList = shardList;\n }\n\n setConnection(connection?: BridgeClientConnection): void {\n if(connection == undefined){\n this.connectionStatus = BridgeClientClusterConnectionStatus.DISCONNECTED;\n this.connection = undefined;\n return;\n }\n\n if (this.connection) {\n throw new Error(`Connection already set for cluster ${this.clusterID}`);\n }\n\n this.connectionStatus = BridgeClientClusterConnectionStatus.REQUESTING;\n this.connection = connection;\n }\n\n setOldConnection(connection?: BridgeClientConnection): void {\n this.oldConnection = connection;\n }\n\n isUsed(): boolean {\n return this.connection != undefined && this.connectionStatus !== BridgeClientClusterConnectionStatus.DISCONNECTED;\n }\n\n reclustering(connection: BridgeClientConnection): void {\n this.connectionStatus = BridgeClientClusterConnectionStatus.RECLUSTERING;\n this.oldConnection = this.connection;\n this.connection = connection;\n }\n\n addMissedHeartbeat(): void {\n this.missedHeartbeats++;\n }\n\n removeMissedHeartbeat(): void {\n if (this.missedHeartbeats > 0) {\n this.missedHeartbeats--;\n }\n }\n\n resetMissedHeartbeats(): void {\n this.missedHeartbeats = 0;\n }\n}\n\nexport type HeartbeatResponse = {\n cpu: {\n raw: {\n user: number,\n system: number,\n }\n cpuPercent: string\n },\n memory: {\n raw: {\n rss: number,\n heapTotal: number,\n heapUsed: number,\n external: number,\n arrayBuffers: number,\n },\n memoryPercent: string\n usage: number\n },\n ping: number,\n shardPings: {\n id: number,\n ping: number,\n status: number,\n guilds: number,\n members: number\n }[]\n}","import {EventPayload} from \"./EventPayload\";\n\nexport class EventManager {\n\n private pendingPayloads = new Map<string, {\n resolve: (value: unknown) => void;\n reject: (error: unknown) => void;\n }>();\n\n // Track per-request timeout handles so we can clear them on resolve/reject\n private pendingTimeouts = new Map<string, ReturnType<typeof setTimeout>>();\n\n private readonly _send: (payload: EventPayload) => Promise<void>;\n\n private readonly _on: (payload: unknown) => void;\n\n private readonly _request: (payload: unknown) => unknown;\n\n constructor(send: (payload: EventPayload) => Promise<void>, on: (message: unknown) => void, request: (message: unknown) => unknown) {\n this._send = send;\n this._on = on;\n this._request = request\n }\n\n async send(data: unknown) {\n return this._send({\n id: crypto.randomUUID(),\n type: 'message',\n data: data\n });\n }\n\n async request<T>(payload: unknown, timeout: number): Promise<T> {\n const id = crypto.randomUUID();\n\n return new Promise<T>((resolve, reject) => {\n this._send({\n id: id,\n type: 'request',\n data: payload\n });\n\n this.pendingPayloads.set(id, {\n resolve: resolve as (value: unknown) => void,\n reject\n });\n\n const t = setTimeout(() => {\n if (this.pendingPayloads.has(id)) {\n this.pendingPayloads.delete(id);\n this.pendingTimeouts.delete(id);\n reject({\n error: `Request with id ${id} timed out`,\n });\n }\n }, timeout);\n this.pendingTimeouts.set(id, t);\n })\n }\n\n receive(possiblePayload: unknown) {\n if (typeof possiblePayload !== 'object' || possiblePayload === null) {\n return;\n }\n\n const payload = possiblePayload as EventPayload;\n\n if (!payload.id || !payload.type) {\n return;\n }\n\n if (payload.type === 'message') {\n this._on(payload.data);\n return;\n }\n\n if (payload.type === 'response') {\n // Handle requests\n const resolve = this.pendingPayloads.get(payload.id)?.resolve;\n if (resolve) {\n resolve(payload.data);\n this.pendingPayloads.delete(payload.id);\n const to = this.pendingTimeouts.get(payload.id);\n if (to) clearTimeout(to);\n this.pendingTimeouts.delete(payload.id);\n }\n return;\n }\n\n if (payload.type === 'response_error') {\n // Handle requests\n const reject = this.pendingPayloads.get(payload.id)?.reject;\n if (reject) {\n reject(payload.data);\n this.pendingPayloads.delete(payload.id);\n const to = this.pendingTimeouts.get(payload.id);\n if (to) clearTimeout(to);\n this.pendingTimeouts.delete(payload.id);\n }\n return;\n }\n\n if (payload.type === 'request') {\n // Handle requests\n const data = this._request(payload.data);\n if(data instanceof Promise) {\n data.then((result) => {\n this._send({\n id: payload.id,\n type: 'response',\n data: result\n });\n }).catch((error) => {\n this._send({\n id: payload.id,\n type: 'response_error',\n data: error\n });\n });\n } else {\n this._send({\n id: payload.id,\n type: 'response',\n data: data\n });\n }\n return;\n }\n }\n\n // Reject and clear all pending requests to avoid memory leaks when a connection/process closes\n close(reason?: string) {\n if (this.pendingPayloads.size === 0 && this.pendingTimeouts.size === 0) return;\n const err = { error: reason || 'EventManager closed' };\n for (const [id, handlers] of this.pendingPayloads.entries()) {\n try { handlers.reject(err); } catch (_) { /* ignore */ }\n this.pendingPayloads.delete(id);\n const to = this.pendingTimeouts.get(id);\n if (to) clearTimeout(to);\n this.pendingTimeouts.delete(id);\n }\n // In case there are any stray timeouts with no pending payload\n for (const to of this.pendingTimeouts.values()) {\n clearTimeout(to);\n }\n this.pendingTimeouts.clear();\n }\n}\n\n","import {EventManager} from \"../general/EventManager\";\nimport {Connection} from \"net-ipc\";\n\nexport enum BridgeClientConnectionStatus {\n READY = 'ready',\n PENDING_STOP = 'pending_stop',\n}\nexport class BridgeClientConnection {\n public readonly instanceID: number;\n public readonly eventManager: EventManager;\n public readonly connection: Connection;\n public readonly data: unknown;\n public connectionStatus: BridgeClientConnectionStatus = BridgeClientConnectionStatus.READY;\n public readonly dev: boolean = false;\n public readonly establishedAt: number = Date.now();\n\n private _onMessage?: (message: unknown) => void;\n private _onRequest?: (message: unknown) => unknown;\n\n constructor(instanceID: number, connection: Connection, data: unknown, dev: boolean) {\n this.instanceID = instanceID;\n this.connection = connection;\n this.data = data;\n this.dev = dev || false;\n this.eventManager = new EventManager((message) => {\n if(!this.connection?.connection?.closed){\n return this.connection.send(message);\n }\n return Promise.reject(new Error('Connection is closed, cannot send message'));\n }, (message) => {\n if (this._onMessage) {\n this._onMessage(message);\n }\n }, (message) => {\n if (this._onRequest) {\n return this._onRequest(message);\n }\n return undefined;\n })\n }\n\n messageReceive(message: any) {\n this.eventManager.receive(message);\n }\n\n onRequest(callback: (message: unknown) => unknown) {\n this._onRequest = callback;\n }\n\n onMessage(callback: (message: unknown) => void) {\n this._onMessage = callback;\n }\n}","import {Server} from 'net-ipc';\nimport {BridgeClientConnection, BridgeClientConnectionStatus} from \"./BridgeClientConnection\";\nimport {GatewayIntentsString, Snowflake} from \"discord.js\";\nimport {ClusterCalculator} from \"./ClusterCalculator\";\nimport {BridgeClientCluster, BridgeClientClusterConnectionStatus, HeartbeatResponse} from \"./BridgeClientCluster\";\nimport {ShardingUtil} from \"../general/ShardingUtil\";\n\nexport class Bridge {\n public readonly port: number;\n public readonly server: Server;\n public readonly connectedClients: Map<string, BridgeClientConnection> = new Map();\n private readonly token: string;\n private readonly intents: GatewayIntentsString[];\n private readonly shardsPerCluster: number = 1;\n private readonly clusterToStart: number = 1\n private readonly reclusteringTimeoutInMs: number;\n\n private readonly clusterCalculator: ClusterCalculator;\n\n private readonly eventMap: BridgeEventListeners = {\n CLUSTER_READY: undefined, CLUSTER_HEARTBEAT_FAILED: undefined,\n CLUSTER_STOPPED: undefined, CLIENT_CONNECTED: undefined, CLIENT_DISCONNECTED: undefined,\n CLUSTER_SPAWNED: undefined, CLUSTER_RECLUSTER: undefined, ERROR: undefined,\n CLIENT_STOP: undefined\n }\n\n constructor(port: number, token: string, intents: GatewayIntentsString[], shardsPerCluster: number, clusterToStart: number, reclusteringTimeoutInMs: number) {\n this.port = port;\n this.token = token;\n this.intents = intents;\n this.clusterToStart = clusterToStart;\n this.shardsPerCluster = shardsPerCluster;\n this.reclusteringTimeoutInMs = reclusteringTimeoutInMs;\n\n this.clusterCalculator = new ClusterCalculator(this.clusterToStart, this.shardsPerCluster);\n\n this.server = new Server({\n port: this.port,\n })\n }\n\n public start(): void {\n this.server.start().then(() => {\n this.startListening();\n })\n\n this.interval();\n }\n\n private interval(): void {\n setInterval(() => {\n this.checkCreate();\n this.checkRecluster();\n this.heartbeat();\n }, 5000)\n }\n\n private checkRecluster(): void {\n // check if all clusters are used\n const up = this.clusterCalculator.checkAllClustersConnected()\n if (!up) {\n return;\n }\n\n const connectedClients: BridgeClientConnection[] = this.connectedClients.values()\n .filter(c => c.connectionStatus == BridgeClientConnectionStatus.READY)\n .filter(c => !c.dev)\n .filter(c => c.establishedAt + this.reclusteringTimeoutInMs < Date.now())\n .toArray();\n\n const {most, least} = this.clusterCalculator.findMostAndLeastClustersForConnections(connectedClients);\n if (most) {\n const clusterToSteal = this.clusterCalculator.getClusterForConnection(most)[0] || undefined;\n if (least && clusterToSteal) {\n clusterToSteal.reclustering(least);\n\n if(this.eventMap.CLUSTER_RECLUSTER) this.eventMap.CLUSTER_RECLUSTER(clusterToSteal, least, clusterToSteal.oldConnection!);\n this.createCluster(least, clusterToSteal, true);\n\n return;\n }\n }\n }\n\n private heartbeat(): void {\n const clusters = this.clusterCalculator.clusterList;\n\n clusters.forEach((cluster) => {\n if(cluster.connection && cluster.connectionStatus == BridgeClientClusterConnectionStatus.CONNECTED && !cluster.heartbeatPending) {\n cluster.heartbeatPending = true;\n cluster.connection.eventManager.request<HeartbeatResponse>({\n type: 'CLUSTER_HEARTBEAT',\n data: {\n clusterID: cluster.clusterID\n }\n }, 20000).then((r) => {\n cluster.removeMissedHeartbeat();\n cluster.heartbeatResponse = r;\n }).catch((err) => {\n if(this.eventMap.CLUSTER_HEARTBEAT_FAILED) this.eventMap.CLUSTER_HEARTBEAT_FAILED(cluster, err)\n cluster.addMissedHeartbeat()\n\n if(cluster.missedHeartbeats > 7 && !cluster.connection?.dev){\n cluster.connection?.eventManager.send({\n type: 'CLUSTER_STOP',\n data: {\n id: cluster.clusterID\n }\n });\n cluster.connectionStatus = BridgeClientClusterConnectionStatus.DISCONNECTED;\n cluster.resetMissedHeartbeats()\n }\n }).finally(() => {\n cluster.heartbeatPending = false;\n })\n }\n });\n }\n\n private checkCreate(): void {\n const optionalCluster = this.clusterCalculator.getNextCluster();\n\n if (!optionalCluster) {\n return;\n }\n\n const lowestLoadClient = this.clusterCalculator.getClusterWithLowestLoad(this.connectedClients);\n if (!lowestLoadClient) {\n return;\n }\n\n this.createCluster(lowestLoadClient, optionalCluster)\n }\n\n private createCluster(connection: BridgeClientConnection, cluster: BridgeClientCluster, recluster = false) {\n cluster.resetMissedHeartbeats()\n cluster.heartbeatResponse = undefined;\n if (!recluster) {\n cluster.setConnection(connection)\n } else {\n cluster.oldConnection?.eventManager.send({\n type: 'CLUSTER_RECLUSTER',\n data: {\n clusterID: cluster.clusterID\n }\n })\n }\n if(this.eventMap.CLUSTER_SPAWNED) this.eventMap.CLUSTER_SPAWNED(cluster, connection)\n connection.eventManager.send({\n type: 'CLUSTER_CREATE',\n data: {\n clusterID: cluster.clusterID,\n instanceID: connection.instanceID,\n totalShards: this.getTotalShards(),\n shardList: cluster.shardList,\n token: this.token,\n intents: this.intents\n }\n });\n }\n\n public startListening(): void {\n this.server.on('connect', (connection, payload) => {\n const id = payload?.id;\n const data = payload.data as unknown;\n const dev = payload?.dev || false;\n if (!id) {\n connection.close('Invalid payload', false);\n return;\n }\n\n if (this.connectedClients.values().some(client => client.instanceID === id)) {\n connection.close('Already connected', false);\n return;\n }\n\n const bridgeConnection = new BridgeClientConnection(payload.id, connection, data, dev);\n if(this.eventMap.CLIENT_CONNECTED) this.eventMap.CLIENT_CONNECTED(bridgeConnection);\n\n bridgeConnection.onMessage((m: any) => {\n if (m.type == 'CLUSTER_SPAWNED') {\n const cluster = this.clusterCalculator.getClusterForConnection(bridgeConnection).find(c => c.clusterID === m.data.id);\n if (cluster) {\n cluster.connectionStatus = BridgeClientClusterConnectionStatus.STARTING;\n }\n return;\n }\n\n if (m.type == 'CLUSTER_READY') {\n const cluster = this.clusterCalculator.getClusterForConnection(bridgeConnection).find(c => c.clusterID === m.data.id);\n if (cluster) {\n cluster.startedAt = Date.now();\n if(this.eventMap.CLUSTER_READY) this.eventMap.CLUSTER_READY(cluster, m.data.guilds || 0, m.data.members || 0);\n cluster.connectionStatus = BridgeClientClusterConnectionStatus.CONNECTED;\n if (cluster.oldConnection) {\n cluster.oldConnection.eventManager.send({\n type: 'CLUSTER_STOP',\n data: {\n id: cluster.clusterID\n }\n });\n cluster.oldConnection = undefined;\n }\n }\n return;\n }\n\n if (m.type == 'CLUSTER_STOPPED') {\n const cluster = this.clusterCalculator.getClusterForConnection(bridgeConnection).find(c => c.clusterID === m.data.id);\n if (cluster) {\n cluster.startedAt = undefined;\n if(this.eventMap.CLUSTER_STOPPED) this.eventMap.CLUSTER_STOPPED(cluster);\n cluster.setConnection(undefined);\n }\n return;\n }\n\n if(m.type == \"INSTANCE_STOP\") {\n this.stopInstance(bridgeConnection);\n }\n\n return;\n })\n\n bridgeConnection.onRequest((m: any) => {\n if(m.type == 'REDIRECT_REQUEST_TO_GUILD'){\n const guildID = m.guildID;\n const shardID = ShardingUtil.getShardIDForGuild(guildID, this.getTotalShards());\n const cluster = this.clusterCalculator.getClusterOfShard(shardID);\n if(!cluster){\n return Promise.reject(new Error(\"cluster not found\"))\n }\n if(cluster.connectionStatus != BridgeClientClusterConnectionStatus.CONNECTED){\n return Promise.reject(new Error(\"cluster not connected.\"))\n }\n\n if(!cluster.connection?.eventManager){\n return Promise.reject(new Error(\"no connection defined.\"))\n }\n\n return cluster.connection.eventManager.request({\n type: 'REDIRECT_REQUEST_TO_GUILD',\n clusterID: cluster.clusterID,\n guildID: guildID,\n data: m.data\n }, 5000)\n }\n\n if(m.type == 'BROADCAST_EVAL') {\n const responses = Promise.all(\n this.connectedClients.values().map(c => {\n return c.eventManager.request<unknown[]>({\n type: 'BROADCAST_EVAL',\n data: m.data,\n }, 5000);\n })\n )\n return new Promise<unknown[]>((resolve, reject) => {\n responses.then((r) => {\n resolve(r.flatMap(f => f))\n }).catch(reject);\n })\n }\n\n if(m.type == 'SELF_CHECK') {\n return {\n clusterList: [\n ...this.clusterCalculator.getClusterForConnection(bridgeConnection).map(c => c.clusterID),\n ...this.clusterCalculator.getOldClusterForConnection(bridgeConnection).map(c => c.clusterID)\n ]\n }\n }\n\n return Promise.reject(new Error(\"unknown type\"))\n })\n\n this.connectedClients.set(connection.id, bridgeConnection)\n });\n\n this.server.on('disconnect', (connection, reason) => {\n const closedConnection = this.connectedClients.get(connection.id);\n if (!closedConnection) {\n return;\n }\n\n const clusters = this.clusterCalculator.getClusterForConnection(closedConnection);\n for (const cluster of clusters) {\n this.clusterCalculator.clearClusterConnection(cluster.clusterID);\n }\n\n this.connectedClients.delete(connection.id);\n if(this.eventMap.CLIENT_DISCONNECTED) this.eventMap.CLIENT_DISCONNECTED(closedConnection, reason);\n });\n\n this.server.on(\"message\", (message, connection) => {\n this.sendMessageToClient(connection.id, message);\n })\n }\n\n sendMessageToClient(clientId: string, message: unknown): void {\n if (!this.connectedClients.has(clientId)) {\n return;\n }\n\n const client = this.connectedClients.get(clientId);\n if (client) {\n client.messageReceive(message);\n }\n }\n\n private getTotalShards() {\n return this.shardsPerCluster * this.clusterToStart;\n }\n\n\n public on<K extends keyof BridgeEventListeners>(event: K, listener: BridgeEventListeners[K]): void {\n this.eventMap[event] = listener;\n }\n\n public getClusters() {\n return this.clusterCalculator.clusterList;\n }\n\n async stopAllInstances() {\n const instances = Array.from(this.connectedClients.values());\n for (const instance of instances) {\n instance.connectionStatus = BridgeClientConnectionStatus.PENDING_STOP;\n }\n\n for (const instance of instances) {\n await this.stopInstance(instance, false);\n }\n }\n\n async stopAllInstancesWithRestart() {\n const instances = Array.from(this.connectedClients.values());\n\n for (const instance of instances) {\n await this.stopInstance(instance);\n await new Promise<void>((resolve) => {\n setTimeout(async () => {\n resolve();\n }, 1000 * 10);\n })\n }\n }\n\n async moveCluster(instance: BridgeClientConnection, cluster: BridgeClientCluster) {\n cluster.reclustering(instance);\n\n this.createCluster(instance, cluster, true);\n }\n\n async stopInstance(instance: BridgeClientConnection, recluster = true) {\n if(this.eventMap.CLIENT_STOP) this.eventMap.CLIENT_STOP(instance);\n instance.connectionStatus = BridgeClientConnectionStatus.PENDING_STOP;\n\n let clusterToSteal: BridgeClientCluster | undefined;\n\n await instance.eventManager.send({\n type: 'INSTANCE_STOP'\n });\n\n if(recluster) {\n while ((clusterToSteal = this.clusterCalculator.getClusterForConnection(instance).filter(c =>\n c.connectionStatus === BridgeClientClusterConnectionStatus.CONNECTED ||\n c.connectionStatus == BridgeClientClusterConnectionStatus.STARTING ||\n c.connectionStatus == BridgeClientClusterConnectionStatus.RECLUSTERING)[0]) !== undefined) {\n // skip if the cluster is not connected\n if(clusterToSteal.connectionStatus != BridgeClientClusterConnectionStatus.CONNECTED) break;\n\n const least = this.clusterCalculator.getClusterWithLowestLoad(this.connectedClients);\n if (!least) {\n if (this.eventMap.ERROR) {\n this.eventMap.ERROR(\"Reclustering failed: No least cluster found.\");\n }\n await instance.eventManager.send({\n type: 'CLUSTER_STOP',\n data: {\n id: clusterToSteal.clusterID\n }\n });\n clusterToSteal.connection = undefined;\n clusterToSteal.connectionStatus = BridgeClientClusterConnectionStatus.DISCONNECTED;\n continue;\n }\n\n clusterToSteal.reclustering(least);\n\n if (this.eventMap.CLUSTER_RECLUSTER) {\n this.eventMap.CLUSTER_RECLUSTER(clusterToSteal, least, clusterToSteal.oldConnection!);\n }\n\n this.createCluster(least, clusterToSteal, true);\n }\n\n return new Promise<void>((resolve, reject) => {\n const interval = setInterval(async () => {\n const cluster = this.clusterCalculator.getOldClusterForConnection(instance)[0] || undefined;\n if (!cluster) {\n clearInterval(interval);\n await instance.eventManager.send({\n type: 'INSTANCE_STOPPED'\n })\n await instance.connection.close(\"Instance stopped.\", false);\n resolve();\n return;\n }\n }, 1000);\n })\n } else {\n for(const cluster of this.clusterCalculator.getClusterForConnection(instance)) {\n await instance.eventManager.send({\n type: 'CLUSTER_STOP',\n data: {\n id: cluster.clusterID\n }\n });\n }\n\n\n await instance.eventManager.send({\n type: 'INSTANCE_STOPPED'\n })\n await instance.connection.close(\"Instance stopped.\", false);\n }\n }\n\n sendRequestToGuild(cluster: BridgeClientCluster, guildID: Snowflake, data: unknown, timeout = 5000): Promise<unknown> {\n if(!cluster.connection){\n return Promise.reject(new Error(\"No connection defined for cluster \" + cluster.clusterID));\n }\n\n return cluster.connection.eventManager.request({\n type: 'REDIRECT_REQUEST_TO_GUILD',\n clusterID: cluster.clusterID,\n guildID: guildID,\n data: data\n }, timeout);\n }\n}\n\n\n\nexport type BridgeEventListeners = {\n 'CLUSTER_READY': ((cluster: BridgeClientCluster, guilds: number, members: number) => void) | undefined,\n 'CLUSTER_STOPPED': ((cluster: BridgeClientCluster) => void) | undefined,\n 'CLUSTER_SPAWNED': ((cluster: BridgeClientCluster, connection: BridgeClientConnection) => void) | undefined,\n 'CLUSTER_RECLUSTER': ((cluster: BridgeClientCluster, newConnection: BridgeClientConnection, oldConnection: BridgeClientConnection) => void) | undefined,\n 'CLUSTER_HEARTBEAT_FAILED': ((cluster: BridgeClientCluster, error: unknown) => void) | undefined,\n 'CLIENT_CONNECTED': ((client: BridgeClientConnection) => void) | undefined,\n 'CLIENT_DISCONNECTED': ((client: BridgeClientConnection, reason: string) => void) | undefined,\n 'ERROR': ((error: string) => void) | undefined,\n 'CLIENT_STOP': ((instance: BridgeClientConnection) => void) | undefined\n};","import {BridgeClientCluster, BridgeClientClusterConnectionStatus} from \"./BridgeClientCluster\";\nimport {BridgeClientConnection, BridgeClientConnectionStatus} from \"./BridgeClientConnection\";\n\n/**\n * Manages the calculation and distribution of clusters for a Discord bot sharding system.\n * This class is responsible for creating clusters with their assigned shards,\n * tracking which clusters are in use, and providing methods to retrieve available clusters.\n */\nexport class ClusterCalculator {\n /** The total number of clusters to initialize */\n private readonly clusterToStart: number;\n\n /** The number of shards that each cluster will manage */\n private readonly shardsPerCluster: number;\n\n /** List of all clusters managed by this calculator */\n public readonly clusterList: BridgeClientCluster[]= [];\n\n /**\n * Creates a new ClusterCalculator and initializes the clusters.\n * \n * @param clusterToStart - The number of clusters to create\n * @param shardsPerCluster - The number of shards each cluster will manage\n */\n constructor(clusterToStart: number, shardsPerCluster: number) {\n this.shardsPerCluster = shardsPerCluster;\n this.clusterToStart = clusterToStart;\n\n this.calculateClusters();\n }\n\n /**\n * Calculates and initializes all clusters with their assigned shards.\n * Each cluster is assigned a sequential range of shard IDs based on its cluster index.\n */\n private calculateClusters(): void {\n const clusters: Map<number, number[]> = new Map();\n for (let i = 0; i < this.clusterToStart; i++) {\n clusters.set(i, []);\n for (let j = 0; j < this.shardsPerCluster; j++) {\n clusters.get(i)?.push(i * this.shardsPerCluster + j);\n }\n }\n\n for (let [clusterIndex, clusterShards] of clusters.entries()) {\n this.clusterList.push(new BridgeClientCluster(clusterIndex, clusterShards));\n }\n }\n\n /**\n * Retrieves the next available (unused) cluster and marks it as used.\n * \n * @returns The next available cluster, or undefined if all clusters are in use\n */\n public getNextCluster(): BridgeClientCluster | undefined {\n for (const cluster of this.clusterList) {\n if (!cluster.isUsed()) {\n return cluster;\n }\n }\n return undefined; // No available clusters\n }\n\n /**\n * Retrieves multiple available clusters up to the specified count.\n * Each returned cluster is marked as used.\n * \n * @param count - The maximum number of clusters to retrieve\n * @returns An array of available clusters (may be fewer than requested if not enough are available)\n */\n public getNextClusters(count: number): BridgeClientCluster[] {\n const availableClusters: BridgeClientCluster[] = [];\n for (const cluster of this.clusterList) {\n if (!cluster.isUsed() && availableClusters.length < count) {\n availableClusters.push(cluster);\n }\n }\n return availableClusters; // Returns the clusters that were found\n }\n\n /**\n * Sets the used status of a specific cluster by its ID.\n *\n * @param clusterID - The ID of the cluster to update\n * @param connection - The connection to associate with the cluster\n */\n public clearClusterConnection(clusterID: number): void {\n const cluster = this.clusterList.find(c => c.clusterID === clusterID);\n if (cluster) {\n cluster.setConnection(undefined);\n }\n }\n\n public getClusterForConnection(connection: BridgeClientConnection): BridgeClientCluster[] {\n return this.clusterList.filter(cluster =>\n cluster.connection?.instanceID === connection.instanceID\n );\n }\n\n public getOldClusterForConnection(connection: BridgeClientConnection): BridgeClientCluster[] {\n return this.clusterList.filter(cluster =>\n cluster.oldConnection?.instanceID === connection.instanceID\n );\n }\n\n public checkAllClustersConnected(): boolean {\n for (const cluster of this.clusterList) {\n if (cluster.connectionStatus != BridgeClientClusterConnectionStatus.CONNECTED){\n return false; // At least one cluster is not in use\n }\n }\n return true; // All clusters are in use\n }\n\n\n findMostAndLeastClustersForConnections(\n connectedClients: BridgeClientConnection[]\n ): {\n most: BridgeClientConnection | undefined,\n least: BridgeClientConnection | undefined\n } {\n\n const openClients = connectedClients.filter(x => !x.dev)\n\n const devClients = connectedClients.filter(x => x.dev)\n const summDevConnectedClusters = devClients.map(c => this.getClusterForConnection(c).length).reduce((a, b) => a + b, 0);\n\n let most: BridgeClientConnection | undefined;\n let least: BridgeClientConnection | undefined;\n let remainder = ((this.clusterToStart - summDevConnectedClusters) % openClients.length || 0);\n\n for (const client of openClients) {\n const clusters = this.getClusterForConnection(client);\n\n if (!most || clusters.length > this.getClusterForConnection(most).length) {\n most = client;\n }\n\n if (!least || clusters.length < this.getClusterForConnection(least).length) {\n least = client;\n }\n }\n\n if (most && least) {\n const mostCount = this.getClusterForConnection(most).length;\n const leastCount = this.getClusterForConnection(least).length;\n\n // Only recluster if the difference is greater than remainder\n if (mostCount - leastCount <= remainder) {\n return {most: undefined, least: undefined};\n }\n }\n\n return {most, least};\n }\n\n getClusterWithLowestLoad(connectedClients: Map<string, BridgeClientConnection>): BridgeClientConnection | undefined {\n let lowestLoadClient: BridgeClientConnection | undefined;\n let lowestLoad = Infinity;\n\n for (const client of connectedClients.values().filter(c =>\n c.connectionStatus === BridgeClientConnectionStatus.READY && !c.dev)) {\n const clusters = this.getClusterForConnection(client);\n\n const load = clusters.length; // Assuming load is determined by the number of clusters assigned\n if (load < lowestLoad) {\n lowestLoad = load;\n lowestLoadClient = client;\n }\n }\n\n return lowestLoadClient; // Returns the client with the lowest load, or undefined if no clients are connected\n }\n\n getClusterOfShard(shardID: number) {\n return this.clusterList.find(c => c.shardList.includes(shardID));\n }\n}\n","export class ShardingUtil {\n public static getShardIDForGuild(guildID: string, totalShards: number): number {\n if (!guildID || totalShards <= 0) {\n throw new Error(\"Invalid guild ID or total shards\");\n }\n\n return Number(BigInt(guildID) >> 22n) % totalShards;\n }\n}","import {Client, GatewayIntentsString, Status} from \"discord.js\";\nimport {EventManager} from \"../general/EventManager\";\nimport os from \"os\";\nexport class Cluster<T extends Client> {\n\n public readonly instanceID: number;\n\n public readonly clusterID: number;\n\n public readonly shardList: number[] = [];\n\n public readonly totalShards: number;\n\n public readonly token: string;\n\n public readonly intents: GatewayIntentsString[];\n\n public eventManager: EventManager;\n\n public client!: T;\n\n public onSelfDestruct?: () => void;\n\n private readonly eventMap: {\n 'message': ((message: unknown) => void) | undefined,\n 'request': ((message: unknown, resolve: (data: unknown) => void, reject: (error: any) => void) => void) | undefined,\n 'CLUSTER_READY': (() => void) | undefined,\n } = {\n message: undefined, request: undefined, CLUSTER_READY: undefined,\n }\n\n constructor(instanceID: number, clusterID: number, shardList: number[], totalShards: number, token: string, intents: GatewayIntentsString[]) {\n this.instanceID = instanceID;\n this.clusterID = clusterID;\n this.shardList = shardList;\n this.totalShards = totalShards;\n this.token = token;\n this.intents = intents;\n this.eventManager = new EventManager((message: unknown) => {\n return new Promise((resolve, reject) => {\n if (typeof process.send !== 'function') {\n reject(new Error(\"Process does not support sending messages\"));\n return;\n }\n\n process.send?.(message, undefined, undefined, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }, (message: unknown) => {\n this._onMessage(message);\n }, (message: unknown) => {\n return this._onRequest(message);\n });\n process.on(\"message\", (message) => {\n this.eventManager.receive(message);\n })\n }\n\n static initial<T extends Client>(): Cluster<T> {\n const args = process.env;\n\n if (args.SHARD_LIST == undefined || args.INSTANCE_ID == undefined || args.TOTAL_SHARDS == undefined || args.TOKEN == undefined || args.INTENTS == undefined || args.CLUSTER_ID == undefined) {\n throw new Error(\"Missing required environment variables\");\n }\n\n const shardList = args.SHARD_LIST.split(',').map(Number);\n\n const totalShards = Number(args.TOTAL_SHARDS);\n\n const instanceID = Number(args.INSTANCE_ID);\n const clusterID = Number(args.CLUSTER_ID);\n\n const token = args.TOKEN;\n\n const intents = args.INTENTS.split(',').map(i => i.trim()) as GatewayIntentsString[];\n\n return new Cluster<T>(instanceID, clusterID, shardList, totalShards, token, intents);\n }\n\n triggerReady(guilds: number, members: number) {\n this.eventManager.send({\n type: 'CLUSTER_READY',\n id: this.clusterID,\n guilds: guilds,\n members: members,\n });\n\n if(this.eventMap?.CLUSTER_READY) {\n this.eventMap?.CLUSTER_READY();\n }\n }\n\n triggerError(e: any) {\n this.eventManager.send({\n type: 'CLUSTER_ERROR',\n id: this.clusterID,\n });\n }\n\n private async wait(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private _onMessage(message: unknown): void {\n const m = message as { type: string, data: unknown };\n if(m.type == 'CUSTOM' && this.eventMap.message) {\n this.eventMap.message!(m.data);\n }\n }\n\n private _onRequest(message: unknown): unknown {\n const m = message as { type: string, data: unknown };\n if(m.type == 'CUSTOM' && this.eventMap.request) {\n return new Promise((resolve, reject) => {\n this.eventMap.request!(m.data, resolve, reject);\n });\n } else if(m.type == 'CLUSTER_HEARTBEAT'){\n const startTime = process.hrtime.bigint();\n const startUsage = process.cpuUsage();\n\n (async () => {\n await this.wait(500);\n })();\n\n const endTime = process.hrtime.bigint();\n const usageDiff = process.cpuUsage(startUsage);\n\n const elapsedTimeUs = Number((endTime - startTime) / 1000n);\n const totalCPUTime = usageDiff.user + usageDiff.system;\n\n const cpuCount = os.cpus().length;\n const cpuPercent = (totalCPUTime / (elapsedTimeUs * cpuCount)) * 100;\n\n // Collect per-shard ping information in addition to the overall ws ping\n let shardPings: { id: number, ping: number, status: Status, uptime?: unknown, guilds: number, members: number }[] = [];\n try {\n const shards = this.client.ws.shards;\n\n if(shards) {\n shards.forEach((shard) => {\n shardPings.push({ id: shard.id, ping: shard.ping, status: shard.status,\n guilds: this.client.guilds.cache.filter(g => g.shardId === shard.id).size,\n members: this.client.guilds.cache.filter(g => g.shardId === shard.id).reduce((acc, g) => acc + g.memberCount, 0)\n });\n\n this.client.shard?.fetchClientValues('uptime', shard.id).then(values => {\n shardPings[shard.id][\"uptime\"] = values\n console.log(values)\n }).catch(e => {\n\n })\n })\n }\n } catch (_) {\n // ignore and keep empty shardPings on failure\n }\n\n return {\n cpu: { raw: process.cpuUsage(), cpuPercent: cpuPercent.toFixed(2) },\n memory: { raw: process.memoryUsage(),\n memoryPercent: ((process.memoryUsage().heapUsed / process.memoryUsage().heapTotal) * 100).toFixed(2) + '%',\n usage: (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2) + 'MB'\n },\n ping: this.client.ws.ping,\n shardPings: shardPings,\n }\n } else if(m.type == 'BROADCAST_EVAL'){\n const broadcast = message as { type: 'BROADCAST_EVAL', data: string }\n\n const fn = eval(`(${broadcast.data})`);\n\n const result = fn(this.client);\n if(result instanceof Promise){\n return new Promise((resolve, reject) => {\n result.then(res => {\n resolve(res);\n }).catch(err => {\n reject(err);\n });\n });\n } else {\n return result;\n }\n } else if(m.type == 'SELF_DESTRUCT') {\n if(this.onSelfDestruct) {\n this.onSelfDestruct();\n }\n }\n return undefined;\n }\n\n public on<K extends keyof ClusterEventListeners>(event: K, listener: ClusterEventListeners[K]): void {\n this.eventMap[event] = listener;\n }\n\n public sendMessage(data: unknown) {\n this.eventManager.send({\n type: 'CUSTOM',\n data: data,\n });\n }\n\n public sendRequest(data: unknown, timeout = 5000): Promise<unknown> {\n return this.eventManager.request({\n type: 'CUSTOM',\n data: data,\n }, timeout);\n }\n\n public broadcastEval<Result>(fn: (cluster: T) => Result, timeout = 20000): Promise<Result[]> {\n return this.eventManager.request({\n type: 'BROADCAST_EVAL',\n data: fn.toString(),\n }, timeout);\n }\n\n\n public sendMessageToClusterOfGuild(guildID: string, message: unknown): void {\n if (this.eventManager) {\n this.eventManager.send({\n type: 'REDIRECT_MESSAGE_TO_GUILD',\n guildID: guildID,\n data: message\n });\n }\n }\n\n public sendRequestToClusterOfGuild(guildID: string, message: unknown, timeout = 5000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n if (this.eventManager) {\n this.eventManager.request({\n type: 'REDIRECT_REQUEST_TO_GUILD',\n guildID: guildID,\n data: message\n }, timeout).then((response) => {\n resolve(response);\n }).catch((error) => {\n reject(error);\n });\n } else {\n reject(new Error(\"Event manager is not initialized\"));\n }\n });\n }\n}\n\nexport type ClusterEventListeners = {\n message: (message: unknown) => void;\n request: (message: unknown, resolve: (data: unknown) => void, reject: (error: any) => void) => void;\n\n CLUSTER_READY: () => void;\n};","import {ChildProcess} from \"child_process\";\nimport {EventManager} from \"../general/EventManager\";\n\nexport type ClusterProcessState = 'starting' | 'running' | 'stopped';\n\nexport class ClusterProcess {\n public readonly child: ChildProcess;\n public readonly eventManager: EventManager;\n public readonly id: number;\n public readonly shardList: number[];\n public readonly totalShards: number;\n public status: ClusterProcessState;\n public readonly createdAt: number = Date.now();\n\n private _onMessage?: (message: unknown) => void;\n private _onRequest?: (message: unknown) => unknown;\n\n constructor(id: number, child: ChildProcess, shardList: number[], totalShards: number) {\n this.id = id;\n this.child = child;\n this.shardList = shardList;\n this.totalShards = totalShards;\n this.status = 'starting';\n this.eventManager = new EventManager((message) => {\n return new Promise<void>((resolve, reject) => {\n this.child.send(message, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n })\n }, (message) => {\n if (this._onMessage) {\n this._onMessage(message);\n }\n }, (message) => {\n if (this._onRequest) {\n return this._onRequest(message);\n }\n return undefined;\n })\n\n this.child.on('message', (message) => {\n this.eventManager.receive(message);\n });\n\n // Ensure we do not retain pending requests if the child dies or errors\n this.child.on('exit', () => {\n this.eventManager.close('child process exited');\n });\n this.child.on('error', () => {\n this.eventManager.close('child process error');\n });\n }\n\n onMessage(callback: (message: unknown) => void) {\n this._onMessage = callback;\n }\n\n onRequest(callback: (message: unknown) => unknown) {\n this._onRequest = callback;\n }\n\n public sendMessage(data: unknown) {\n this.eventManager.send({\n type: 'CUSTOM',\n data: data,\n });\n }\n\n public sendRequest(data: unknown, timeout = 5000): Promise<unknown> {\n return this.eventManager.request({\n type: 'CUSTOM',\n data: data,\n }, timeout);\n }\n}","import {fork} from 'child_process';\nimport {ClusterProcess} from \"../cluster/ClusterProcess\";\nimport {GatewayIntentsString} from \"discord.js\";\nimport {ShardingUtil} from \"../general/ShardingUtil\";\n\nexport abstract class BotInstance {\n\n private readonly entryPoint: string;\n\n private readonly execArgv: string[];\n\n public readonly clients: Map<number, ClusterProcess> = new Map();\n\n protected constructor(entryPoint: string, execArgv?: string[]) {\n this.entryPoint = entryPoint;\n this.execArgv = execArgv ?? [];\n }\n\n protected readonly eventMap: BotInstanceEventListeners = {\n 'message': undefined,\n 'request': undefined,\n\n 'PROCESS_KILLED': undefined,\n 'PROCESS_SELF_DESTRUCT_ERROR': undefined,\n 'PROCESS_SPAWNED': undefined,\n 'ERROR': undefined,\n 'PROCESS_ERROR': undefined,\n 'CLUSTER_READY': undefined,\n 'CLUSTER_ERROR': undefined,\n 'CLUSTER_RECLUSTER': undefined,\n 'BRIDGE_CONNECTION_ESTABLISHED': undefined,\n 'BRIDGE_CONNECTION_CLOSED': undefined,\n 'BRIDGE_CONNECTION_STATUS_CHANGE': undefined,\n 'INSTANCE_STOP': undefined,\n 'INSTANCE_STOPPED': undefined,\n 'SELF_CHECK_SUCCESS': undefined,\n 'SELF_CHECK_ERROR': undefined,\n 'SELF_CHECK_RECEIVED': undefined,\n }\n\n protected startProcess(instanceID: number, clusterID: number, shardList: number[], totalShards: number, token: string, intents: GatewayIntentsString[]): void {\n try {\n const child = fork(this.entryPoint, {\n env: {\n INSTANCE_ID: instanceID.toString(),\n CLUSTER_ID: clusterID.toString(),\n SHARD_LIST: shardList.join(','),\n TOTAL_SHARDS: totalShards.toString(),\n TOKEN: token,\n INTENTS: intents.join(','),\n FORCE_COLOR: 'true'\n },\n stdio: 'inherit',\n execArgv: this.execArgv,\n silent: false,\n detached: true,\n })\n\n const client = new ClusterProcess(clusterID, child, shardList, totalShards);\n\n child.stdout?.on('data', (data) => {\n process.stdout.write(data);\n });\n\n child.stderr?.on('data', (data) => {\n process.stderr.write(data);\n });\n\n child.on(\"spawn\", () => {\n if(this.eventMap.PROCESS_SPAWNED) this.eventMap.PROCESS_SPAWNED(client);\n\n this.setClusterSpawned(client);\n\n this.clients.set(clusterID, client);\n\n client.onMessage((message) => {\n this.onMessage(client, message);\n })\n\n client.onRequest((message) => {\n return this.onRequest(client, message);\n });\n });\n\n child.on(\"error\", (err) => {\n if(this.eventMap.PROCESS_ERROR) this.eventMap.PROCESS_ERROR(client, err);\n })\n\n child.on(\"exit\", (err: Error) => {\n if(client.status !== 'stopped') {\n client.status = 'stopped';\n this.killProcess(client, `Process exited: ${err?.message}`);\n }\n })\n } catch (error) {\n throw new Error(`Failed to start process for cluster ${clusterID}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n protected killProcess(client: ClusterProcess, reason: string): void {\n client.status = 'stopped';\n\n client.eventManager.request({\n type: 'SELF_DESTRUCT',\n reason: reason\n }, 5000).catch(() => {\n if(this.eventMap.PROCESS_SELF_DESTRUCT_ERROR) this.eventMap.PROCESS_SELF_DESTRUCT_ERROR(client, reason, 'Cluster didnt respond to shot-call.');\n }).finally(() => {\n if (client.child && client.child.pid) {\n if(client.child.kill(\"SIGKILL\")) {\n if(this.eventMap.PROCESS_KILLED) this.eventMap.PROCESS_KILLED(client, reason, true);\n } else {\n if(this.eventMap.ERROR) this.eventMap.ERROR(`Failed to kill process for cluster ${client.id}`);\n client.child.kill(\"SIGKILL\");\n }\n try { process.kill(-client.child.pid) } catch {}\n } else {\n if(this.eventMap.PROCESS_KILLED) this.eventMap.PROCESS_KILLED(client, reason, false);\n }\n this.clients.delete(client.id);\n this.setClusterStopped(client, reason);\n })\n }\n\n protected abstract setClusterStopped(client: ClusterProcess, reason: string): void;\n\n protected abstract setClusterReady(client: ClusterProcess, guilds: number, members: number): void;\n\n protected abstract setClusterSpawned(client: ClusterProcess): void;\n\n public abstract start(): void;\n\n private onMessage(client: ClusterProcess, message: any): void {\n if(message.type === 'CLUSTER_READY') {\n client.status = 'running';\n if(this.eventMap.CLUSTER_READY) this.eventMap.CLUSTER_READY(client);\n this.setClusterReady(client, message.guilds || 0, message.members || 0);\n }\n\n if (message.type === 'CLUSTER_ERROR') {\n client.status = 'stopped';\n if(this.eventMap.CLUSTER_ERROR) this.eventMap.CLUSTER_ERROR(client, message.error);\n this.killProcess(client, 'Cluster error: ' + message.error);\n }\n\n if(message.type == 'CUSTOM' && this.eventMap.message) {\n this.eventMap.message!(client, message.data);\n }\n }\n\n protected abstract onRequest(client: ClusterProcess, message: any): Promise<unknown>;\n\n public on<K extends keyof BotInstanceEventListeners>(event: K, listener: BotInstanceEventListeners[K]): void {\n this.eventMap[event] = listener;\n }\n\n public sendRequestToClusterOfGuild(guildID: string, message: unknown, timeout = 5000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n for (const client of this.clients.values()) {\n const shardID = ShardingUtil.getShardIDForGuild(guildID, client.totalShards);\n if (client.shardList.includes(shardID)) {\n client.eventManager.request({\n type: 'CUSTOM',\n data: message\n }, timeout).then(resolve).catch(reject);\n return;\n }\n }\n reject(new Error(`No cluster found for guild ${guildID}`));\n });\n }\n\n public sendRequestToCluster(cluster: ClusterProcess, message: unknown, timeout = 5000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n cluster.eventManager.request({\n type: 'CUSTOM',\n data: message\n }, timeout).then(resolve).catch(reject);\n return;\n });\n }\n}\n\nexport type BotInstanceEventListeners = {\n 'message': ((client: ClusterProcess,message: unknown) => void) | undefined,\n 'request': ((client: ClusterProcess, message: unknown, resolve: (data: unknown) => void, reject: (error: any) => void) => void) | undefined,\n\n 'PROCESS_KILLED': ((client: ClusterProcess, reason: string, processKilled: boolean) => void) | undefined,\n 'PROCESS_SELF_DESTRUCT_ERROR': ((client: ClusterProcess, reason: string, error: unknown) => void) | undefined,\n 'PROCESS_SPAWNED': ((client: ClusterProcess) => void) | undefined,\n 'PROCESS_ERROR': ((client: ClusterProcess, error: unknown) => void) | undefined,\n 'CLUSTER_READY': ((client: ClusterProcess) => void) | undefined,\n 'CLUSTER_ERROR': ((client: ClusterProcess, error: unknown) => void) | undefined,\n 'CLUSTER_RECLUSTER': ((client: ClusterProcess) => void) | undefined,\n 'ERROR': ((error: string) => void) | undefined,\n\n 'BRIDGE_CONNECTION_ESTABLISHED': (() => void) | undefined,\n 'BRIDGE_CONNECTION_CLOSED': ((reason: string) => void) | undefined,\n 'BRIDGE_CONNECTION_STATUS_CHANGE': ((status: number) => void) | undefined,\n 'INSTANCE_STOP': (() => void) | undefined,\n 'INSTANCE_STOPPED': (() => void) | undefined,\n\n 'SELF_CHECK_SUCCESS': (() => void) | undefined,\n 'SELF_CHECK_ERROR': ((error: string) => void) | undefined,\n 'SELF_CHECK_RECEIVED': ((data: { clusterList: number[] }) => void) | undefined,\n};","import {BotInstance} from \"./BotInstance\";\nimport {ClusterProcess} from \"../cluster/ClusterProcess\";\nimport {Client} from \"net-ipc\";\nimport {EventManager} from \"../general/EventManager\";\nimport {GatewayIntentsString} from \"discord.js\";\nimport {ShardingUtil} from \"../general/ShardingUtil\";\n\nexport enum BridgeConnectionStatus {\n CONNECTED,\n DISCONNECTED,\n}\n\nexport class ManagedInstance extends BotInstance {\n\n private readonly host: string;\n\n private readonly port: number;\n\n private readonly instanceID: number;\n\n private eventManager!: EventManager;\n\n private connectionStatus: BridgeConnectionStatus = BridgeConnectionStatus.DISCONNECTED;\n\n private data: unknown;\n\n private dev: boolean = false;\n\n constructor(entryPoint: string, host: string, port: number, instanceID: number, data: unknown, execArgv?: string[], dev?: boolean) {\n super(entryPoint, execArgv);\n\n this.host = host;\n this.port = port;\n this.instanceID = instanceID;\n this.data = data;\n this.dev = dev || false;\n }\n\n public start() {\n const client = new Client({\n host: this.host,\n port: this.port,\n reconnect: true,\n retries: 100\n });\n\n this.eventManager = new EventManager((message) => {\n if(client.status == 3) {\n return client.send(message);\n }\n return Promise.reject(new Error('Client is not ready to send messages'));\n }, (message) => {\n const m = message as { type: string, data: unknown };\n if(m.type == 'CLUSTER_CREATE') {\n this.onClusterCreate(m.data)\n } else if (m.type == 'CLUSTER_STOP') {\n this.onClusterStop(m.data);\n } else if(m.type == 'CLUSTER_RECLUSTER') {\n this.onClusterRecluster(m.data);\n } else if(m.type == 'INSTANCE_STOP') {\n if(this.eventMap.INSTANCE_STOP) {\n this.eventMap.INSTANCE_STOP();\n }\n } else if(m.type == 'INSTANCE_STOPPED') {\n if(this.eventMap.INSTANCE_STOPPED) {\n this.eventMap.INSTANCE_STOPPED();\n }\n }\n }, (message) => {\n return this.onBridgeRequest(message);\n });\n\n setInterval(() => {\n if(this.connectionStatus == BridgeConnectionStatus.CONNECTED) {\n this.selfCheck();\n }\n }, 2500); // 5 minutes\n\n client.connect({\n id: this.instanceID,\n dev: this.dev,\n data: this.data,\n }).then(_ => {\n if(this.eventMap.BRIDGE_CONNECTION_ESTABLISHED) this.eventMap.BRIDGE_CONNECTION_ESTABLISHED();\n this.connectionStatus = BridgeConnectionStatus.CONNECTED;\n\n client.on(\"message\", (message) => {\n this.eventManager?.receive(message);\n })\n client.on(\"close\", (reason) => {\n if(this.eventMap.BRIDGE_CONNECTION_CLOSED) this.eventMap.BRIDGE_CONNECTION_CLOSED(reason);\n\n // kill all\n if(this.connectionStatus == BridgeConnectionStatus.CONNECTED) {\n this.clients.forEach((client) => {\n this.killProcess(client, 'Bridge connection closed');\n });\n }\n this.connectionStatus = BridgeConnectionStatus.DISCONNECTED;\n });\n\n client.on(\"status\", (status) => {\n if(this.eventMap.BRIDGE_CONNECTION_STATUS_CHANGE) this.eventMap.BRIDGE_CONNECTION_STATUS_CHANGE(status);\n\n if(status == 4){\n if(this.connectionStatus == BridgeConnectionStatus.CONNECTED) {\n this.clients.forEach((client) => {\n this.killProcess(client, 'Bridge connection closed');\n });\n }\n this.connectionStatus = BridgeConnectionStatus.DISCONNECTED;\n } else if(status == 3){\n this.connectionStatus = BridgeConnectionStatus.CONNECTED;\n if(this.eventMap.BRIDGE_CONNECTION_ESTABLISHED) this.eventMap.BRIDGE_CONNECTION_ESTABLISHED();\n }\n });\n })\n }\n\n private selfCheck() {\n this.eventManager.request({\n type: 'SELF_CHECK'\n }, 1000 * 60).then((r) => {\n const response = r as { clusterList: number[] };\n\n if(this.eventMap.SELF_CHECK_RECEIVED) {\n this.eventMap.SELF_CHECK_RECEIVED(response);\n }\n\n const startingClusters = this.clients.values().filter(c => c.status == 'starting').toArray();\n startingClusters.forEach((c: ClusterProcess) => {\n if (Date.now() - c.createdAt > 10 * 60 * 1000) {\n this.killProcess(c, 'Cluster took too long to start');\n }\n })\n\n // check if there is an wrong cluster on this host\n const wrongClusters = this.clients.values().filter(c => !response.clusterList.includes(c.id)).toArray();\n if(wrongClusters.length > 0) {\n if(this.eventMap.SELF_CHECK_ERROR) {\n this.eventMap.SELF_CHECK_ERROR(`Self check found wrong clusters: ${wrongClusters.map(c => c.id).join(', ')}`);\n }\n wrongClusters.forEach(c => {\n this.killProcess(c, 'Self check found wrong cluster');\n });\n } else {\n if(this.eventMap.SELF_CHECK_SUCCESS) {\n this.eventMap.SELF_CHECK_SUCCESS();\n }\n }\n }).catch((err) => {\n if(this.eventMap.SELF_CHECK_ERROR) {\n this.eventMap.SELF_CHECK_ERROR(`Self check failed: ${err}`);\n }\n });\n }\n\n protected setClusterStopped(client: ClusterProcess, reason: string): void {\n this.eventManager?.send({\n type: 'CLUSTER_STOPPED',\n data: {\n id: client.id,\n reason: reason\n }\n }).catch(() => {\n return null\n });\n }\n\n protected setClusterReady(client: ClusterProcess, guilds: number, members: number): void {\n this.eventManager?.send({\n type: 'CLUSTER_READY',\n data: {\n id: client.id,\n guilds: guilds,\n members: members\n }\n });\n }\n\n protected setClusterSpawned(client: ClusterProcess): void {\n this.eventManager?.send({\n type: 'CLUSTER_SPAWNED',\n data: {\n id: client.id\n }\n });\n }\n\n private onClusterCreate(message: unknown){\n const m = message as { clusterID: number, shardList: number[], totalShards: number, token: string, intents: GatewayIntentsString[] }\n\n if(this.clients.has(m.clusterID)) {\n this.eventManager?.send({\n type: 'CLUSTER_STOPPED',\n data: {\n id: m.clusterID,\n reason: 'Cluster already exists'\n }\n }).catch(() => {\n return null\n });\n return;\n }\n\n this.startProcess(this.instanceID, m.clusterID, m.shardList, m.totalShards, m.token, m.intents);\n }\n\n private onClusterStop(message: unknown) {\n const m = message as { id: number };\n const cluster = this.clients.get(m.id)\n if (cluster) {\n this.killProcess(cluster, `Request to stop cluster ${m.id}`);\n }\n }\n\n private onClusterRecluster(message: unknown) {\n const m = message as { clusterID: number }\n const cluster = this.clients.get(m.clusterID);\n if (this.eventMap.CLUSTER_RECLUSTER && cluster) {\n this.eventMap.CLUSTER_RECLUSTER(cluster);\n }\n }\n\n protected onRequest(client: ClusterProcess, message: any): Promise<unknown> {\n if(message.type === 'REDIRECT_REQUEST_TO_GUILD'){\n const guildID = message.guildID;\n const data = message.data;\n\n const shardID = ShardingUtil.getShardIDForGuild(guildID, client.totalShards);\n if(client.shardList.includes(shardID)) {\n return client.eventManager.request({\n type: 'CUSTOM',\n data: data\n }, 5000)\n } else {\n return this.eventManager.request({\n type: 'REDIRECT_REQUEST_TO_GUILD',\n guildID: guildID,\n data: data\n }, 5000)\n }\n }\n\n if(message.type == 'BROADCAST_EVAL') {\n return this.eventManager.request({\n type: 'BROADCAST_EVAL',\n data: message.data\n }, 5000)\n }\n\n if(message.type == 'CUSTOM' && this.eventMap.request) {\n return new Promise((resolve, reject) => {\n this.eventMap.request!(client, message.data, resolve, reject);\n });\n }\n\n return Promise.reject(new Error(`Unknown request type: ${message.type}`));\n }\n\n private onBridgeRequest(message: any): Promise<unknown> {\n if(message.type === 'REDIRECT_REQUEST_TO_GUILD'){\n const clusterID = message.clusterID;\n const data = message.data;\n\n const cluster = this.clients.get(clusterID);\n if(cluster){\n return cluster.eventManager.request({\n type: 'CUSTOM',\n data: data\n }, 5000)\n } else {\n return Promise.reject(new Error(`Cluster is not here. Cluster ID: ${clusterID}`));\n }\n } else if(message.type == 'CLUSTER_HEARTBEAT'){\n const clusterID = message.data.clusterID;\n const cluster = this.clients.get(clusterID);\n if (cluster) {\n return new Promise<unknown>((resolve, reject) => {\n cluster.eventManager.request({\n type: 'CLUSTER_HEARTBEAT'\n }, 15000).then((r) => {\n resolve(r);\n }).catch((err) => {\n reject(err);\n });\n })\n } else {\n return Promise.reject(new Error(`Cluster is not here. Cluster ID: ${clusterID}`));\n }\n } else if(message.type == 'BROADCAST_EVAL') {\n return Promise.all(this.clients.values().filter(c => c.status == 'running').map(c => {\n return c.eventManager.request({\n type: 'BROADCAST_EVAL',\n data: message.data,\n }, 5000);\n }));\n }\n\n return Promise.reject(new Error(`Unknown request type: ${message.type}`));\n }\n\n stopInstance(): void {\n this.eventManager?.send({\n type: 'INSTANCE_STOP'\n });\n }\n\n}","import {BotInstance} from \"./BotInstance\";\nimport {ClusterProcess} from \"../cluster/ClusterProcess\";\nimport {GatewayIntentsString} from \"discord.js\";\nimport {ShardingUtil} from \"../general/ShardingUtil\";\n\nexport class StandaloneInstance extends BotInstance {\n private readonly totalClusters: number;\n private readonly shardsPerCluster: number;\n\n public readonly token: string;\n public readonly intents: GatewayIntentsString[];\n\n constructor(entryPoint: string, shardsPerCluster: number, totalClusters: number, token: string, intents: GatewayIntentsString[], execArgv?: string[]) {\n super(entryPoint, execArgv);\n this.shardsPerCluster = shardsPerCluster;\n this.totalClusters = totalClusters;\n this.token = token;\n this.intents = intents;\n }\n\n get totalShards(): number {\n return this.shardsPerCluster * this.totalClusters;\n }\n\n private calculateClusters(): Record<number, number[]> {\n const clusters: Record<number, number[]> = {};\n for (let i = 0; i < this.totalClusters; i++) {\n clusters[i] = [];\n for (let j = 0; j < this.shardsPerCluster; j++) {\n clusters[i].push(i * this.shardsPerCluster + j);\n }\n }\n return clusters;\n }\n\n public start(): void {\n const clusters = this.calculateClusters();\n for (const [id, shardList] of Object.entries(clusters)) {\n this.startProcess(1, Number(id), shardList, this.totalShards, this.token, this.intents);\n }\n }\n\n protected setClusterStopped(client: ClusterProcess, reason: string): void {\n this.clients.delete(client.id);\n this.restartProcess(client);\n }\n\n protected setClusterReady(client: ClusterProcess): void {\n \n }\n\n protected setClusterSpawned(client: ClusterProcess): void {\n\n }\n\n private restartProcess(client: ClusterProcess): void {\n this.startProcess(1, client.id, client.shardList, this.totalShards, this.token, this.intents);\n }\n\n protected onRequest(client: ClusterProcess, message: any): Promise<unknown> {\n if(message.type === 'REDIRECT_REQUEST_TO_GUILD'){\n const guildID = message.guildID;\n const data = message.data;\n\n const shardID = ShardingUtil.getShardIDForGuild(guildID, client.totalShards);\n if(client.shardList.includes(shardID)) {\n return client.eventManager.request({\n type: 'CUSTOM',\n data: data\n }, 5000)\n } else {\n return Promise.reject(new Error(`Shard ID ${shardID} not found in cluster ${client.id} for guild ${guildID}`));\n }\n }\n\n if(message.type == 'BROADCAST_EVAL') {\n return Promise.all(\n this.clients.values().map(c => {\n return c.eventManager.request({\n type: 'BROADCAST_EVAL',\n data: message.data,\n }, 5000);\n })\n );\n }\n\n if(message.type == 'CUSTOM' && this.eventMap.request) {\n return new Promise((resolve, reject) => {\n this.eventMap.request!(client, message.data, resolve, reject);\n });\n }\n\n return Promise.reject(new Error(`Unknown request type: ${message.type}`));\n }\n\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAK,sCAAL,kBAAKA,yCAAL;AACH,EAAAA,qCAAA,gBAAa;AACb,EAAAA,qCAAA,cAAW;AACX,EAAAA,qCAAA,eAAY;AACZ,EAAAA,qCAAA,kBAAe;AACf,EAAAA,qCAAA,kBAAe;AALP,SAAAA;AAAA,GAAA;AAQL,IAAM,sBAAN,MAA0B;AAAA,EACb;AAAA,EACA;AAAA,EACT,mBAAwD;AAAA,EAExD;AAAA,EAEA;AAAA,EAEA,mBAA2B;AAAA,EAE3B;AAAA,EAEA,mBAAmB;AAAA,EAEnB;AAAA,EAEP,YAAY,WAAmB,WAAqB;AAChD,SAAK,YAAY;AACjB,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,cAAc,YAA2C;AACrD,QAAG,cAAc,QAAU;AACvB,WAAK,mBAAmB;AACxB,WAAK,aAAa;AAClB;AAAA,IACJ;AAEA,QAAI,KAAK,YAAY;AACjB,YAAM,IAAI,MAAM,sCAAsC,KAAK,SAAS,EAAE;AAAA,IAC1E;AAEA,SAAK,mBAAmB;AACxB,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,iBAAiB,YAA2C;AACxD,SAAK,gBAAgB;AAAA,EACzB;AAAA,EAEA,SAAkB;AACd,WAAO,KAAK,cAAc,UAAa,KAAK,qBAAqB;AAAA,EACrE;AAAA,EAEA,aAAa,YAA0C;AACnD,SAAK,mBAAmB;AACxB,SAAK,gBAAgB,KAAK;AAC1B,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,qBAA2B;AACvB,SAAK;AAAA,EACT;AAAA,EAEA,wBAA8B;AAC1B,QAAI,KAAK,mBAAmB,GAAG;AAC3B,WAAK;AAAA,IACT;AAAA,EACJ;AAAA,EAEA,wBAA8B;AAC1B,SAAK,mBAAmB;AAAA,EAC5B;AACJ;;;ACxEO,IAAM,eAAN,MAAmB;AAAA,EAEd,kBAAkB,oBAAI,IAG3B;AAAA;AAAA,EAGK,kBAAkB,oBAAI,IAA2C;AAAA,EAExD;AAAA,EAEA;AAAA,EAEA;AAAA,EAEjB,YAAY,MAAgD,IAAgC,SAAwC;AAChI,SAAK,QAAQ;AACb,SAAK,MAAM;AACX,SAAK,WAAW;AAAA,EACpB;AAAA,EAEA,MAAM,KAAK,MAAe;AACtB,WAAO,KAAK,MAAM;AAAA,MACd,IAAI,OAAO,WAAW;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,QAAW,SAAkB,SAA6B;AAC5D,UAAM,KAAK,OAAO,WAAW;AAE7B,WAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACvC,WAAK,MAAM;AAAA,QACP;AAAA,QACA,MAAM;AAAA,QACN,MAAM;AAAA,MACV,CAAC;AAED,WAAK,gBAAgB,IAAI,IAAI;AAAA,QACzB;AAAA,QACA;AAAA,MACJ,CAAC;AAED,YAAM,IAAI,WAAW,MAAM;AACvB,YAAI,KAAK,gBAAgB,IAAI,EAAE,GAAG;AAC9B,eAAK,gBAAgB,OAAO,EAAE;AAC9B,eAAK,gBAAgB,OAAO,EAAE;AAC9B,iBAAO;AAAA,YACH,OAAO,mBAAmB,EAAE;AAAA,UAChC,CAAC;AAAA,QACL;AAAA,MACJ,GAAG,OAAO;AACV,WAAK,gBAAgB,IAAI,IAAI,CAAC;AAAA,IAClC,CAAC;AAAA,EACL;AAAA,EAEA,QAAQ,iBAA0B;AAC9B,QAAI,OAAO,oBAAoB,YAAY,oBAAoB,MAAM;AACjE;AAAA,IACJ;AAEA,UAAM,UAAU;AAEhB,QAAI,CAAC,QAAQ,MAAM,CAAC,QAAQ,MAAM;AAC9B;AAAA,IACJ;AAEA,QAAI,QAAQ,SAAS,WAAW;AAC5B,WAAK,IAAI,QAAQ,IAAI;AACrB;AAAA,IACJ;AAEA,QAAI,QAAQ,SAAS,YAAY;AAE7B,YAAM,UAAU,KAAK,gBAAgB,IAAI,QAAQ,EAAE,GAAG;AACtD,UAAI,SAAS;AACT,gBAAQ,QAAQ,IAAI;AACpB,aAAK,gBAAgB,OAAO,QAAQ,EAAE;AACtC,cAAM,KAAK,KAAK,gBAAgB,IAAI,QAAQ,EAAE;AAC9C,YAAI,GAAI,cAAa,EAAE;AACvB,aAAK,gBAAgB,OAAO,QAAQ,EAAE;AAAA,MAC1C;AACA;AAAA,IACJ;AAEA,QAAI,QAAQ,SAAS,kBAAkB;AAEnC,YAAM,SAAS,KAAK,gBAAgB,IAAI,QAAQ,EAAE,GAAG;AACrD,UAAI,QAAQ;AACR,eAAO,QAAQ,IAAI;AACnB,aAAK,gBAAgB,OAAO,QAAQ,EAAE;AACtC,cAAM,KAAK,KAAK,gBAAgB,IAAI,QAAQ,EAAE;AAC9C,YAAI,GAAI,cAAa,EAAE;AACvB,aAAK,gBAAgB,OAAO,QAAQ,EAAE;AAAA,MAC1C;AACA;AAAA,IACJ;AAEA,QAAI,QAAQ,SAAS,WAAW;AAE5B,YAAM,OAAO,KAAK,SAAS,QAAQ,IAAI;AACvC,UAAG,gBAAgB,SAAS;AACxB,aAAK,KAAK,CAACC,YAAW;AAClB,eAAK,MAAM;AAAA,YACP,IAAI,QAAQ;AAAA,YACZ,MAAM;AAAA,YACN,MAAMA;AAAA,UACV,CAAC;AAAA,QACL,CAAC,EAAE,MAAM,CAAC,UAAU;AAChB,eAAK,MAAM;AAAA,YACP,IAAI,QAAQ;AAAA,YACZ,MAAM;AAAA,YACN,MAAM;AAAA,UACV,CAAC;AAAA,QACL,CAAC;AAAA,MACL,OAAO;AACH,aAAK,MAAM;AAAA,UACP,IAAI,QAAQ;AAAA,UACZ,MAAM;AAAA,UACN;AAAA,QACJ,CAAC;AAAA,MACL;AACA;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA,EAGA,MAAM,QAAiB;AACnB,QAAI,KAAK,gBAAgB,SAAS,KAAK,KAAK,gBAAgB,SAAS,EAAG;AACxE,UAAM,MAAM,EAAE,OAAO,UAAU,sBAAsB;AACrD,eAAW,CAAC,IAAI,QAAQ,KAAK,KAAK,gBAAgB,QAAQ,GAAG;AACzD,UAAI;AAAE,iBAAS,OAAO,GAAG;AAAA,MAAG,SAAS,GAAG;AAAA,MAAe;AACvD,WAAK,gBAAgB,OAAO,EAAE;AAC9B,YAAM,KAAK,KAAK,gBAAgB,IAAI,EAAE;AACtC,UAAI,GAAI,cAAa,EAAE;AACvB,WAAK,gBAAgB,OAAO,EAAE;AAAA,IAClC;AAEA,eAAW,MAAM,KAAK,gBAAgB,OAAO,GAAG;AAC5C,mBAAa,EAAE;AAAA,IACnB;AACA,SAAK,gBAAgB,MAAM;AAAA,EAC/B;AACJ;;;AChJO,IAAK,+BAAL,kBAAKC,kCAAL;AACH,EAAAA,8BAAA,WAAQ;AACR,EAAAA,8BAAA,kBAAe;AAFP,SAAAA;AAAA,GAAA;AAIL,IAAM,yBAAN,MAA6B;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,mBAAiD;AAAA,EACxC,MAAe;AAAA,EACf,gBAAwB,KAAK,IAAI;AAAA,EAEzC;AAAA,EACA;AAAA,EAER,YAAY,YAAoB,YAAwB,MAAe,KAAc;AACjF,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,OAAO;AACZ,SAAK,MAAM,OAAO;AAClB,SAAK,eAAe,IAAI,aAAa,CAACC,aAAY;AAC9C,UAAG,CAAC,KAAK,YAAY,YAAY,QAAO;AACpC,eAAO,KAAK,WAAW,KAAKA,QAAO;AAAA,MACvC;AACA,aAAO,QAAQ,OAAO,IAAI,MAAM,2CAA2C,CAAC;AAAA,IAChF,GAAG,CAACA,aAAY;AACZ,UAAI,KAAK,YAAY;AACjB,aAAK,WAAWA,QAAO;AAAA,MAC3B;AAAA,IACJ,GAAG,CAACA,aAAY;AACZ,UAAI,KAAK,YAAY;AACjB,eAAO,KAAK,WAAWA,QAAO;AAAA,MAClC;AACA,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEA,eAAeA,UAAc;AACzB,SAAK,aAAa,QAAQA,QAAO;AAAA,EACrC;AAAA,EAEA,UAAU,UAAyC;AAC/C,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,UAAU,UAAsC;AAC5C,SAAK,aAAa;AAAA,EACtB;AACJ;;;ACpDA,qBAAqB;;;ACQd,IAAM,oBAAN,MAAwB;AAAA;AAAA,EAEV;AAAA;AAAA,EAGA;AAAA;AAAA,EAGD,cAAoC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrD,YAAY,gBAAwB,kBAA0B;AAC1D,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AAEtB,SAAK,kBAAkB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,oBAA0B;AAC9B,UAAM,WAAkC,oBAAI,IAAI;AAChD,aAAS,IAAI,GAAG,IAAI,KAAK,gBAAgB,KAAK;AAC1C,eAAS,IAAI,GAAG,CAAC,CAAC;AAClB,eAAS,IAAI,GAAG,IAAI,KAAK,kBAAkB,KAAK;AAC5C,iBAAS,IAAI,CAAC,GAAG,KAAK,IAAI,KAAK,mBAAmB,CAAC;AAAA,MACvD;AAAA,IACJ;AAEA,aAAS,CAAC,cAAc,aAAa,KAAK,SAAS,QAAQ,GAAG;AAC1D,WAAK,YAAY,KAAK,IAAI,oBAAoB,cAAc,aAAa,CAAC;AAAA,IAC9E;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,iBAAkD;AACrD,eAAW,WAAW,KAAK,aAAa;AACpC,UAAI,CAAC,QAAQ,OAAO,GAAG;AACnB,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,gBAAgB,OAAsC;AACzD,UAAM,oBAA2C,CAAC;AAClD,eAAW,WAAW,KAAK,aAAa;AACpC,UAAI,CAAC,QAAQ,OAAO,KAAK,kBAAkB,SAAS,OAAO;AACvD,0BAAkB,KAAK,OAAO;AAAA,MAClC;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,uBAAuB,WAAyB;AACnD,UAAM,UAAU,KAAK,YAAY,KAAK,OAAK,EAAE,cAAc,SAAS;AACpE,QAAI,SAAS;AACT,cAAQ,cAAc,MAAS;AAAA,IACnC;AAAA,EACJ;AAAA,EAEO,wBAAwB,YAA2D;AACtF,WAAO,KAAK,YAAY;AAAA,MAAO,aAC3B,QAAQ,YAAY,eAAe,WAAW;AAAA,IAClD;AAAA,EACJ;AAAA,EAEO,2BAA2B,YAA2D;AACzF,WAAO,KAAK,YAAY;AAAA,MAAO,aAC3B,QAAQ,eAAe,eAAe,WAAW;AAAA,IACrD;AAAA,EACJ;AAAA,EAEO,4BAAqC;AACxC,eAAW,WAAW,KAAK,aAAa;AACpC,UAAI,QAAQ,iDAAkE;AAC1E,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAGA,uCACI,kBAIF;AAEE,UAAM,cAAc,iBAAiB,OAAO,OAAK,CAAC,EAAE,GAAG;AAEvD,UAAM,aAAa,iBAAiB,OAAO,OAAK,EAAE,GAAG;AACrD,UAAM,2BAA2B,WAAW,IAAI,OAAK,KAAK,wBAAwB,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAEtH,QAAI;AACJ,QAAI;AACJ,QAAI,aAAc,KAAK,iBAAiB,4BAA4B,YAAY,UAAU;AAE1F,eAAW,UAAU,aAAa;AAC9B,YAAM,WAAW,KAAK,wBAAwB,MAAM;AAEpD,UAAI,CAAC,QAAQ,SAAS,SAAS,KAAK,wBAAwB,IAAI,EAAE,QAAQ;AACtE,eAAO;AAAA,MACX;AAEA,UAAI,CAAC,SAAS,SAAS,SAAS,KAAK,wBAAwB,KAAK,EAAE,QAAQ;AACxE,gBAAQ;AAAA,MACZ;AAAA,IACJ;AAEA,QAAI,QAAQ,OAAO;AACf,YAAM,YAAY,KAAK,wBAAwB,IAAI,EAAE;AACrD,YAAM,aAAa,KAAK,wBAAwB,KAAK,EAAE;AAGvD,UAAI,YAAY,cAAc,WAAW;AACrC,eAAO,EAAC,MAAM,QAAW,OAAO,OAAS;AAAA,MAC7C;AAAA,IACJ;AAEA,WAAO,EAAC,MAAM,MAAK;AAAA,EACvB;AAAA,EAEA,yBAAyB,kBAA2F;AAChH,QAAI;AACJ,QAAI,aAAa;AAEjB,eAAW,UAAU,iBAAiB,OAAO,EAAE,OAAO,OAClD,EAAE,4CAA2D,CAAC,EAAE,GAAG,GAAG;AACtE,YAAM,WAAW,KAAK,wBAAwB,MAAM;AAEpD,YAAM,OAAO,SAAS;AACtB,UAAI,OAAO,YAAY;AACnB,qBAAa;AACb,2BAAmB;AAAA,MACvB;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,kBAAkB,SAAiB;AAC/B,WAAO,KAAK,YAAY,KAAK,OAAK,EAAE,UAAU,SAAS,OAAO,CAAC;AAAA,EACnE;AACJ;;;ACjLO,IAAM,eAAN,MAAmB;AAAA,EACtB,OAAc,mBAAmB,SAAiB,aAA6B;AAC3E,QAAI,CAAC,WAAW,eAAe,GAAG;AAC9B,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACtD;AAEA,WAAQ,OAAO,OAAO,OAAO,KAAK,GAAG,IAAI;AAAA,EAC7C;AACJ;;;AFDO,IAAM,SAAN,MAAa;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAwD,oBAAI,IAAI;AAAA,EAC/D;AAAA,EACA;AAAA,EACA,mBAA2B;AAAA,EAC3B,iBAAyB;AAAA,EACzB;AAAA,EAEA;AAAA,EAEA,WAAiC;AAAA,IAC9C,eAAe;AAAA,IAAW,0BAA0B;AAAA,IACpD,iBAAiB;AAAA,IAAW,kBAAkB;AAAA,IAAW,qBAAqB;AAAA,IAC9E,iBAAiB;AAAA,IAAW,mBAAmB;AAAA,IAAW,OAAO;AAAA,IACjE,aAAa;AAAA,EACjB;AAAA,EAEA,YAAY,MAAc,OAAe,SAAiC,kBAA0B,gBAAwB,yBAAiC;AACzJ,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AACxB,SAAK,0BAA0B;AAE/B,SAAK,oBAAoB,IAAI,kBAAkB,KAAK,gBAAgB,KAAK,gBAAgB;AAEzF,SAAK,SAAS,IAAI,sBAAO;AAAA,MACrB,MAAM,KAAK;AAAA,IACf,CAAC;AAAA,EACL;AAAA,EAEO,QAAc;AACjB,SAAK,OAAO,MAAM,EAAE,KAAK,MAAM;AAC3B,WAAK,eAAe;AAAA,IACxB,CAAC;AAED,SAAK,SAAS;AAAA,EAClB;AAAA,EAEQ,WAAiB;AACrB,gBAAY,MAAM;AACd,WAAK,YAAY;AACjB,WAAK,eAAe;AACpB,WAAK,UAAU;AAAA,IACnB,GAAG,GAAI;AAAA,EACX;AAAA,EAEQ,iBAAuB;AAE3B,UAAM,KAAK,KAAK,kBAAkB,0BAA0B;AAC5D,QAAI,CAAC,IAAI;AACL;AAAA,IACJ;AAEA,UAAM,mBAA6C,KAAK,iBAAiB,OAAO,EAC3E,OAAO,OAAK,EAAE,uCAAsD,EACpE,OAAO,OAAK,CAAC,EAAE,GAAG,EAClB,OAAO,OAAK,EAAE,gBAAgB,KAAK,0BAA0B,KAAK,IAAI,CAAC,EACvE,QAAQ;AAEb,UAAM,EAAC,MAAM,MAAK,IAAI,KAAK,kBAAkB,uCAAuC,gBAAgB;AACpG,QAAI,MAAM;AACN,YAAM,iBAAiB,KAAK,kBAAkB,wBAAwB,IAAI,EAAE,CAAC,KAAK;AAClF,UAAI,SAAS,gBAAgB;AACzB,uBAAe,aAAa,KAAK;AAEjC,YAAG,KAAK,SAAS,kBAAmB,MAAK,SAAS,kBAAkB,gBAAgB,OAAO,eAAe,aAAc;AACxH,aAAK,cAAc,OAAO,gBAAgB,IAAI;AAE9C;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEQ,YAAkB;AACtB,UAAM,WAAW,KAAK,kBAAkB;AAExC,aAAS,QAAQ,CAAC,YAAY;AAC1B,UAAG,QAAQ,cAAc,QAAQ,mDAAqE,CAAC,QAAQ,kBAAkB;AAC7H,gBAAQ,mBAAmB;AAC3B,gBAAQ,WAAW,aAAa,QAA2B;AAAA,UACvD,MAAM;AAAA,UACN,MAAM;AAAA,YACF,WAAW,QAAQ;AAAA,UACvB;AAAA,QACJ,GAAG,GAAK,EAAE,KAAK,CAAC,MAAM;AAClB,kBAAQ,sBAAsB;AAC9B,kBAAQ,oBAAoB;AAAA,QAChC,CAAC,EAAE,MAAM,CAAC,QAAQ;AACd,cAAG,KAAK,SAAS,yBAA0B,MAAK,SAAS,yBAAyB,SAAS,GAAG;AAC9F,kBAAQ,mBAAmB;AAE3B,cAAG,QAAQ,mBAAmB,KAAK,CAAC,QAAQ,YAAY,KAAI;AACxD,oBAAQ,YAAY,aAAa,KAAK;AAAA,cAClC,MAAM;AAAA,cACN,MAAM;AAAA,gBACF,IAAI,QAAQ;AAAA,cAChB;AAAA,YACJ,CAAC;AACD,oBAAQ;AACR,oBAAQ,sBAAsB;AAAA,UAClC;AAAA,QACJ,CAAC,EAAE,QAAQ,MAAM;AACb,kBAAQ,mBAAmB;AAAA,QAC/B,CAAC;AAAA,MACL;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEQ,cAAoB;AACxB,UAAM,kBAAkB,KAAK,kBAAkB,eAAe;AAE9D,QAAI,CAAC,iBAAiB;AAClB;AAAA,IACJ;AAEA,UAAM,mBAAmB,KAAK,kBAAkB,yBAAyB,KAAK,gBAAgB;AAC9F,QAAI,CAAC,kBAAkB;AACnB;AAAA,IACJ;AAEA,SAAK,cAAc,kBAAkB,eAAe;AAAA,EACxD;AAAA,EAEQ,cAAc,YAAoC,SAA8B,YAAY,OAAO;AACvG,YAAQ,sBAAsB;AAC9B,YAAQ,oBAAoB;AAC5B,QAAI,CAAC,WAAW;AACZ,cAAQ,cAAc,UAAU;AAAA,IACpC,OAAO;AACH,cAAQ,eAAe,aAAa,KAAK;AAAA,QACrC,MAAM;AAAA,QACN,MAAM;AAAA,UACF,WAAW,QAAQ;AAAA,QACvB;AAAA,MACJ,CAAC;AAAA,IACL;AACA,QAAG,KAAK,SAAS,gBAAiB,MAAK,SAAS,gBAAgB,SAAS,UAAU;AACnF,eAAW,aAAa,KAAK;AAAA,MACzB,MAAM;AAAA,MACN,MAAM;AAAA,QACF,WAAW,QAAQ;AAAA,QACnB,YAAY,WAAW;AAAA,QACvB,aAAa,KAAK,eAAe;AAAA,QACjC,WAAW,QAAQ;AAAA,QACnB,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA,MAClB;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEO,iBAAuB;AAC1B,SAAK,OAAO,GAAG,WAAW,CAAC,YAAY,YAAY;AAC/C,YAAM,KAAK,SAAS;AACpB,YAAM,OAAO,QAAQ;AACrB,YAAM,MAAM,SAAS,OAAO;AAC5B,UAAI,CAAC,IAAI;AACL,mBAAW,MAAM,mBAAmB,KAAK;AACzC;AAAA,MACJ;AAEA,UAAI,KAAK,iBAAiB,OAAO,EAAE,KAAK,YAAU,OAAO,eAAe,EAAE,GAAG;AACzE,mBAAW,MAAM,qBAAqB,KAAK;AAC3C;AAAA,MACJ;AAEA,YAAM,mBAAmB,IAAI,uBAAuB,QAAQ,IAAI,YAAY,MAAM,GAAG;AACrF,UAAG,KAAK,SAAS,iBAAkB,MAAK,SAAS,iBAAiB,gBAAgB;AAElF,uBAAiB,UAAU,CAACC,OAAW;AACnC,YAAIA,GAAE,QAAQ,mBAAmB;AAC7B,gBAAM,UAAU,KAAK,kBAAkB,wBAAwB,gBAAgB,EAAE,KAAK,OAAK,EAAE,cAAcA,GAAE,KAAK,EAAE;AACpH,cAAI,SAAS;AACT,oBAAQ;AAAA,UACZ;AACA;AAAA,QACJ;AAEA,YAAIA,GAAE,QAAQ,iBAAiB;AAC3B,gBAAM,UAAU,KAAK,kBAAkB,wBAAwB,gBAAgB,EAAE,KAAK,OAAK,EAAE,cAAcA,GAAE,KAAK,EAAE;AACpH,cAAI,SAAS;AACT,oBAAQ,YAAY,KAAK,IAAI;AAC7B,gBAAG,KAAK,SAAS,cAAe,MAAK,SAAS,cAAc,SAASA,GAAE,KAAK,UAAU,GAAGA,GAAE,KAAK,WAAW,CAAC;AAC5G,oBAAQ;AACR,gBAAI,QAAQ,eAAe;AACvB,sBAAQ,cAAc,aAAa,KAAK;AAAA,gBACpC,MAAM;AAAA,gBACN,MAAM;AAAA,kBACF,IAAI,QAAQ;AAAA,gBAChB;AAAA,cACJ,CAAC;AACD,sBAAQ,gBAAgB;AAAA,YAC5B;AAAA,UACJ;AACA;AAAA,QACJ;AAEA,YAAIA,GAAE,QAAQ,mBAAmB;AAC7B,gBAAM,UAAU,KAAK,kBAAkB,wBAAwB,gBAAgB,EAAE,KAAK,OAAK,EAAE,cAAcA,GAAE,KAAK,EAAE;AACpH,cAAI,SAAS;AACT,oBAAQ,YAAY;AACpB,gBAAG,KAAK,SAAS,gBAAiB,MAAK,SAAS,gBAAgB,OAAO;AACvE,oBAAQ,cAAc,MAAS;AAAA,UACnC;AACA;AAAA,QACJ;AAEA,YAAGA,GAAE,QAAQ,iBAAiB;AAC1B,eAAK,aAAa,gBAAgB;AAAA,QACtC;AAEA;AAAA,MACJ,CAAC;AAED,uBAAiB,UAAU,CAACA,OAAW;AACnC,YAAGA,GAAE,QAAQ,6BAA4B;AACrC,gBAAM,UAAUA,GAAE;AAClB,gBAAM,UAAU,aAAa,mBAAmB,SAAS,KAAK,eAAe,CAAC;AAC9E,gBAAM,UAAU,KAAK,kBAAkB,kBAAkB,OAAO;AAChE,cAAG,CAAC,SAAQ;AACR,mBAAO,QAAQ,OAAO,IAAI,MAAM,mBAAmB,CAAC;AAAA,UACxD;AACA,cAAG,QAAQ,iDAAkE;AACzE,mBAAO,QAAQ,OAAO,IAAI,MAAM,wBAAwB,CAAC;AAAA,UAC7D;AAEA,cAAG,CAAC,QAAQ,YAAY,cAAa;AACjC,mBAAO,QAAQ,OAAO,IAAI,MAAM,wBAAwB,CAAC;AAAA,UAC7D;AAEA,iBAAO,QAAQ,WAAW,aAAa,QAAQ;AAAA,YAC3C,MAAM;AAAA,YACN,WAAW,QAAQ;AAAA,YACnB;AAAA,YACA,MAAMA,GAAE;AAAA,UACZ,GAAG,GAAI;AAAA,QACX;AAEA,YAAGA,GAAE,QAAQ,kBAAkB;AAC3B,gBAAM,YAAY,QAAQ;AAAA,YACtB,KAAK,iBAAiB,OAAO,EAAE,IAAI,OAAK;AACpC,qBAAO,EAAE,aAAa,QAAmB;AAAA,gBACrC,MAAM;AAAA,gBACN,MAAMA,GAAE;AAAA,cACZ,GAAG,GAAI;AAAA,YACX,CAAC;AAAA,UACL;AACA,iBAAO,IAAI,QAAmB,CAAC,SAAS,WAAW;AAC/C,sBAAU,KAAK,CAAC,MAAM;AAClB,sBAAQ,EAAE,QAAQ,OAAK,CAAC,CAAC;AAAA,YAC7B,CAAC,EAAE,MAAM,MAAM;AAAA,UACnB,CAAC;AAAA,QACL;AAEA,YAAGA,GAAE,QAAQ,cAAc;AACvB,iBAAO;AAAA,YACH,aAAa;AAAA,cACT,GAAG,KAAK,kBAAkB,wBAAwB,gBAAgB,EAAE,IAAI,OAAK,EAAE,SAAS;AAAA,cACxF,GAAG,KAAK,kBAAkB,2BAA2B,gBAAgB,EAAE,IAAI,OAAK,EAAE,SAAS;AAAA,YAC/F;AAAA,UACJ;AAAA,QACJ;AAEA,eAAO,QAAQ,OAAO,IAAI,MAAM,cAAc,CAAC;AAAA,MACnD,CAAC;AAED,WAAK,iBAAiB,IAAI,WAAW,IAAI,gBAAgB;AAAA,IAC7D,CAAC;AAED,SAAK,OAAO,GAAG,cAAc,CAAC,YAAY,WAAW;AACjD,YAAM,mBAAmB,KAAK,iBAAiB,IAAI,WAAW,EAAE;AAChE,UAAI,CAAC,kBAAkB;AACnB;AAAA,MACJ;AAEA,YAAM,WAAW,KAAK,kBAAkB,wBAAwB,gBAAgB;AAChF,iBAAW,WAAW,UAAU;AAC5B,aAAK,kBAAkB,uBAAuB,QAAQ,SAAS;AAAA,MACnE;AAEA,WAAK,iBAAiB,OAAO,WAAW,EAAE;AAC1C,UAAG,KAAK,SAAS,oBAAqB,MAAK,SAAS,oBAAoB,kBAAkB,MAAM;AAAA,IACpG,CAAC;AAED,SAAK,OAAO,GAAG,WAAW,CAACC,UAAS,eAAe;AAC/C,WAAK,oBAAoB,WAAW,IAAIA,QAAO;AAAA,IACnD,CAAC;AAAA,EACL;AAAA,EAEA,oBAAoB,UAAkBA,UAAwB;AAC1D,QAAI,CAAC,KAAK,iBAAiB,IAAI,QAAQ,GAAG;AACtC;AAAA,IACJ;AAEA,UAAM,SAAS,KAAK,iBAAiB,IAAI,QAAQ;AACjD,QAAI,QAAQ;AACR,aAAO,eAAeA,QAAO;AAAA,IACjC;AAAA,EACJ;AAAA,EAEQ,iBAAiB;AACrB,WAAO,KAAK,mBAAmB,KAAK;AAAA,EACxC;AAAA,EAGO,GAAyC,OAAU,UAAyC;AAC/F,SAAK,SAAS,KAAK,IAAI;AAAA,EAC3B;AAAA,EAEO,cAAc;AACjB,WAAO,KAAK,kBAAkB;AAAA,EAClC;AAAA,EAEA,MAAM,mBAAmB;AACrB,UAAM,YAAY,MAAM,KAAK,KAAK,iBAAiB,OAAO,CAAC;AAC3D,eAAW,YAAY,WAAW;AAC9B,eAAS;AAAA,IACb;AAEA,eAAW,YAAY,WAAW;AAC9B,YAAM,KAAK,aAAa,UAAU,KAAK;AAAA,IAC3C;AAAA,EACJ;AAAA,EAEA,MAAM,8BAA8B;AAChC,UAAM,YAAY,MAAM,KAAK,KAAK,iBAAiB,OAAO,CAAC;AAE3D,eAAW,YAAY,WAAW;AAC9B,YAAM,KAAK,aAAa,QAAQ;AAChC,YAAM,IAAI,QAAc,CAAC,YAAY;AACjC,mBAAW,YAAY;AACnB,kBAAQ;AAAA,QACZ,GAAG,MAAO,EAAE;AAAA,MAChB,CAAC;AAAA,IACL;AAAA,EACJ;AAAA,EAEA,MAAM,YAAY,UAAkC,SAA8B;AAC9E,YAAQ,aAAa,QAAQ;AAE7B,SAAK,cAAc,UAAU,SAAS,IAAI;AAAA,EAC9C;AAAA,EAEA,MAAM,aAAa,UAAkC,YAAY,MAAM;AACnE,QAAG,KAAK,SAAS,YAAa,MAAK,SAAS,YAAY,QAAQ;AAChE,aAAS;AAET,QAAI;AAEJ,UAAM,SAAS,aAAa,KAAK;AAAA,MAC7B,MAAM;AAAA,IACV,CAAC;AAED,QAAG,WAAW;AACV,cAAQ,iBAAiB,KAAK,kBAAkB,wBAAwB,QAAQ,EAAE,OAAO,OACrF,EAAE,oDACF,EAAE,iDACF,EAAE,qDAAoE,EAAE,CAAC,OAAO,QAAW;AAE3F,YAAG,eAAe,gDAAmE;AAErF,cAAM,QAAQ,KAAK,kBAAkB,yBAAyB,KAAK,gBAAgB;AACnF,YAAI,CAAC,OAAO;AACR,cAAI,KAAK,SAAS,OAAO;AACrB,iBAAK,SAAS,MAAM,8CAA8C;AAAA,UACtE;AACA,gBAAM,SAAS,aAAa,KAAK;AAAA,YAC7B,MAAM;AAAA,YACN,MAAM;AAAA,cACF,IAAI,eAAe;AAAA,YACvB;AAAA,UACJ,CAAC;AACD,yBAAe,aAAa;AAC5B,yBAAe;AACf;AAAA,QACJ;AAEA,uBAAe,aAAa,KAAK;AAEjC,YAAI,KAAK,SAAS,mBAAmB;AACjC,eAAK,SAAS,kBAAkB,gBAAgB,OAAO,eAAe,aAAc;AAAA,QACxF;AAEA,aAAK,cAAc,OAAO,gBAAgB,IAAI;AAAA,MAClD;AAEA,aAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC1C,cAAM,WAAW,YAAY,YAAY;AACrC,gBAAM,UAAU,KAAK,kBAAkB,2BAA2B,QAAQ,EAAE,CAAC,KAAK;AAClF,cAAI,CAAC,SAAS;AACV,0BAAc,QAAQ;AACtB,kBAAM,SAAS,aAAa,KAAK;AAAA,cAC7B,MAAM;AAAA,YACV,CAAC;AACD,kBAAM,SAAS,WAAW,MAAM,qBAAqB,KAAK;AAC1D,oBAAQ;AACR;AAAA,UACJ;AAAA,QACJ,GAAG,GAAI;AAAA,MACX,CAAC;AAAA,IACL,OAAO;AACH,iBAAU,WAAW,KAAK,kBAAkB,wBAAwB,QAAQ,GAAG;AAC3E,cAAM,SAAS,aAAa,KAAK;AAAA,UAC7B,MAAM;AAAA,UACN,MAAM;AAAA,YACF,IAAI,QAAQ;AAAA,UAChB;AAAA,QACJ,CAAC;AAAA,MACL;AAGA,YAAM,SAAS,aAAa,KAAK;AAAA,QAC7B,MAAM;AAAA,MACV,CAAC;AACD,YAAM,SAAS,WAAW,MAAM,qBAAqB,KAAK;AAAA,IAC9D;AAAA,EACJ;AAAA,EAEA,mBAAmB,SAA8B,SAAoB,MAAe,UAAU,KAAwB;AAClH,QAAG,CAAC,QAAQ,YAAW;AACnB,aAAO,QAAQ,OAAO,IAAI,MAAM,uCAAuC,QAAQ,SAAS,CAAC;AAAA,IAC7F;AAEA,WAAO,QAAQ,WAAW,aAAa,QAAQ;AAAA,MAC3C,MAAM;AAAA,MACN,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,IACJ,GAAG,OAAO;AAAA,EACd;AACJ;;;AGtbA,gBAAe;AACR,IAAM,UAAN,MAAM,SAA0B;AAAA,EAEnB;AAAA,EAEA;AAAA,EAEA,YAAsB,CAAC;AAAA,EAEvB;AAAA,EAEA;AAAA,EAEA;AAAA,EAET;AAAA,EAEA;AAAA,EAEA;AAAA,EAEU,WAIb;AAAA,IACA,SAAS;AAAA,IAAW,SAAS;AAAA,IAAW,eAAe;AAAA,EAC3D;AAAA,EAEA,YAAY,YAAoB,WAAmB,WAAqB,aAAqB,OAAe,SAAiC;AACzI,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,cAAc;AACnB,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,SAAK,eAAe,IAAI,aAAa,CAACC,aAAqB;AACvD,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,YAAI,OAAO,QAAQ,SAAS,YAAY;AACpC,iBAAO,IAAI,MAAM,2CAA2C,CAAC;AAC7D;AAAA,QACJ;AAEA,gBAAQ,OAAOA,UAAS,QAAW,QAAW,CAAC,UAAU;AACrD,cAAI,OAAO;AACP,mBAAO,KAAK;AAAA,UAChB,OAAO;AACH,oBAAQ;AAAA,UACZ;AAAA,QACJ,CAAC;AAAA,MACL,CAAC;AAAA,IACL,GAAG,CAACA,aAAqB;AACrB,WAAK,WAAWA,QAAO;AAAA,IAC3B,GAAG,CAACA,aAAqB;AACrB,aAAO,KAAK,WAAWA,QAAO;AAAA,IAClC,CAAC;AACD,YAAQ,GAAG,WAAW,CAACA,aAAY;AAC/B,WAAK,aAAa,QAAQA,QAAO;AAAA,IACrC,CAAC;AAAA,EACL;AAAA,EAEA,OAAO,UAAwC;AAC3C,UAAM,OAAO,QAAQ;AAErB,QAAI,KAAK,cAAc,UAAa,KAAK,eAAe,UAAa,KAAK,gBAAgB,UAAa,KAAK,SAAS,UAAa,KAAK,WAAW,UAAa,KAAK,cAAc,QAAW;AACzL,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC5D;AAEA,UAAM,YAAY,KAAK,WAAW,MAAM,GAAG,EAAE,IAAI,MAAM;AAEvD,UAAM,cAAc,OAAO,KAAK,YAAY;AAE5C,UAAM,aAAa,OAAO,KAAK,WAAW;AAC1C,UAAM,YAAY,OAAO,KAAK,UAAU;AAExC,UAAM,QAAQ,KAAK;AAEnB,UAAM,UAAU,KAAK,QAAQ,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAEzD,WAAO,IAAI,SAAW,YAAY,WAAW,WAAW,aAAa,OAAO,OAAO;AAAA,EACvF;AAAA,EAEA,aAAa,QAAgB,SAAiB;AAC1C,SAAK,aAAa,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,IAAI,KAAK;AAAA,MACT;AAAA,MACA;AAAA,IACJ,CAAC;AAED,QAAG,KAAK,UAAU,eAAe;AAC7B,WAAK,UAAU,cAAc;AAAA,IACjC;AAAA,EACJ;AAAA,EAEA,aAAa,GAAQ;AACjB,SAAK,aAAa,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,IAAI,KAAK;AAAA,IACb,CAAC;AAAA,EACL;AAAA,EAEA,MAAc,KAAK,IAAY;AAC3B,WAAO,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AAAA,EACzD;AAAA,EAEQ,WAAWA,UAAwB;AACvC,UAAMC,KAAID;AACV,QAAGC,GAAE,QAAQ,YAAY,KAAK,SAAS,SAAS;AAC5C,WAAK,SAAS,QAASA,GAAE,IAAI;AAAA,IACjC;AAAA,EACJ;AAAA,EAEQ,WAAW,SAA2B;AAC1C,UAAM,IAAI;AACV,QAAG,EAAE,QAAQ,YAAY,KAAK,SAAS,SAAS;AAC5C,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,aAAK,SAAS,QAAS,EAAE,MAAM,SAAS,MAAM;AAAA,MAClD,CAAC;AAAA,IACL,WAAU,EAAE,QAAQ,qBAAoB;AACpC,YAAM,YAAY,QAAQ,OAAO,OAAO;AACxC,YAAM,aAAa,QAAQ,SAAS;AAEpC,OAAC,YAAY;AACT,cAAM,KAAK,KAAK,GAAG;AAAA,MACvB,GAAG;AAEH,YAAM,UAAU,QAAQ,OAAO,OAAO;AACtC,YAAM,YAAY,QAAQ,SAAS,UAAU;AAE7C,YAAM,gBAAgB,QAAQ,UAAU,aAAa,KAAK;AAC1D,YAAM,eAAe,UAAU,OAAO,UAAU;AAEhD,YAAM,WAAW,UAAAC,QAAG,KAAK,EAAE;AAC3B,YAAM,aAAc,gBAAgB,gBAAgB,YAAa;AAGjE,UAAI,aAAgH,CAAC;AACrH,UAAI;AACA,cAAM,SAAS,KAAK,OAAO,GAAG;AAE9B,YAAG,QAAQ;AACP,iBAAO,QAAQ,CAAC,UAAU;AACtB,uBAAW,KAAK;AAAA,cAAE,IAAI,MAAM;AAAA,cAAI,MAAM,MAAM;AAAA,cAAM,QAAQ,MAAM;AAAA,cAC5D,QAAQ,KAAK,OAAO,OAAO,MAAM,OAAO,OAAK,EAAE,YAAY,MAAM,EAAE,EAAE;AAAA,cACrE,SAAS,KAAK,OAAO,OAAO,MAAM,OAAO,OAAK,EAAE,YAAY,MAAM,EAAE,EAAE,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,aAAa,CAAC;AAAA,YACnH,CAAC;AAED,iBAAK,OAAO,OAAO,kBAAkB,UAAU,MAAM,EAAE,EAAE,KAAK,YAAU;AACpE,yBAAW,MAAM,EAAE,EAAE,QAAQ,IAAI;AACjC,sBAAQ,IAAI,MAAM;AAAA,YACtB,CAAC,EAAE,MAAM,OAAK;AAAA,YAEd,CAAC;AAAA,UACL,CAAC;AAAA,QACL;AAAA,MACJ,SAAS,GAAG;AAAA,MAEZ;AAEA,aAAO;AAAA,QACH,KAAK,EAAE,KAAK,QAAQ,SAAS,GAAG,YAAY,WAAW,QAAQ,CAAC,EAAE;AAAA,QAClE,QAAQ;AAAA,UAAE,KAAK,QAAQ,YAAY;AAAA,UAC/B,gBAAiB,QAAQ,YAAY,EAAE,WAAW,QAAQ,YAAY,EAAE,YAAa,KAAK,QAAQ,CAAC,IAAI;AAAA,UACvG,QAAQ,QAAQ,YAAY,EAAE,WAAW,OAAO,MAAM,QAAQ,CAAC,IAAI;AAAA,QACvE;AAAA,QACA,MAAM,KAAK,OAAO,GAAG;AAAA,QACrB;AAAA,MACJ;AAAA,IACJ,WAAU,EAAE,QAAQ,kBAAiB;AACjC,YAAM,YAAY;AAElB,YAAM,KAAK,KAAK,IAAI,UAAU,IAAI,GAAG;AAErC,YAAM,SAAS,GAAG,KAAK,MAAM;AAC7B,UAAG,kBAAkB,SAAQ;AACzB,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,iBAAO,KAAK,SAAO;AACf,oBAAQ,GAAG;AAAA,UACf,CAAC,EAAE,MAAM,SAAO;AACZ,mBAAO,GAAG;AAAA,UACd,CAAC;AAAA,QACL,CAAC;AAAA,MACL,OAAO;AACH,eAAO;AAAA,MACX;AAAA,IACJ,WAAU,EAAE,QAAQ,iBAAiB;AACjC,UAAG,KAAK,gBAAgB;AACpB,aAAK,eAAe;AAAA,MACxB;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEO,GAA0C,OAAU,UAA0C;AACjG,SAAK,SAAS,KAAK,IAAI;AAAA,EAC3B;AAAA,EAEO,YAAY,MAAe;AAC9B,SAAK,aAAa,KAAK;AAAA,MACnB,MAAM;AAAA,MACN;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEO,YAAY,MAAe,UAAU,KAAwB;AAChE,WAAO,KAAK,aAAa,QAAQ;AAAA,MAC7B,MAAM;AAAA,MACN;AAAA,IACJ,GAAG,OAAO;AAAA,EACd;AAAA,EAEO,cAAsBC,KAA4B,UAAU,KAA0B;AACzF,WAAO,KAAK,aAAa,QAAQ;AAAA,MAC7B,MAAM;AAAA,MACN,MAAMA,IAAG,SAAS;AAAA,IACtB,GAAG,OAAO;AAAA,EACd;AAAA,EAGO,4BAA4B,SAAiBH,UAAwB;AACxE,QAAI,KAAK,cAAc;AACnB,WAAK,aAAa,KAAK;AAAA,QACnB,MAAM;AAAA,QACN;AAAA,QACA,MAAMA;AAAA,MACV,CAAC;AAAA,IACL;AAAA,EACJ;AAAA,EAEO,4BAA4B,SAAiBA,UAAkB,UAAU,KAAwB;AACpG,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,UAAI,KAAK,cAAc;AACnB,aAAK,aAAa,QAAQ;AAAA,UACtB,MAAM;AAAA,UACN;AAAA,UACA,MAAMA;AAAA,QACV,GAAG,OAAO,EAAE,KAAK,CAAC,aAAa;AAC3B,kBAAQ,QAAQ;AAAA,QACpB,CAAC,EAAE,MAAM,CAAC,UAAU;AAChB,iBAAO,KAAK;AAAA,QAChB,CAAC;AAAA,MACL,OAAO;AACH,eAAO,IAAI,MAAM,kCAAkC,CAAC;AAAA,MACxD;AAAA,IACJ,CAAC;AAAA,EACL;AACJ;;;ACpPO,IAAM,iBAAN,MAAqB;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EACS,YAAoB,KAAK,IAAI;AAAA,EAErC;AAAA,EACA;AAAA,EAER,YAAY,IAAY,OAAqB,WAAqB,aAAqB;AACnF,SAAK,KAAK;AACV,SAAK,QAAQ;AACb,SAAK,YAAY;AACjB,SAAK,cAAc;AACnB,SAAK,SAAS;AACd,SAAK,eAAe,IAAI,aAAa,CAACI,aAAY;AAC9C,aAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC1C,aAAK,MAAM,KAAKA,UAAS,CAAC,UAAU;AAChC,cAAI,OAAO;AACP,mBAAO,KAAK;AAAA,UAChB,OAAO;AACH,oBAAQ;AAAA,UACZ;AAAA,QACJ,CAAC;AAAA,MACL,CAAC;AAAA,IACL,GAAG,CAACA,aAAY;AACZ,UAAI,KAAK,YAAY;AACjB,aAAK,WAAWA,QAAO;AAAA,MAC3B;AAAA,IACJ,GAAG,CAACA,aAAY;AACZ,UAAI,KAAK,YAAY;AACjB,eAAO,KAAK,WAAWA,QAAO;AAAA,MAClC;AACA,aAAO;AAAA,IACX,CAAC;AAED,SAAK,MAAM,GAAG,WAAW,CAACA,aAAY;AAClC,WAAK,aAAa,QAAQA,QAAO;AAAA,IACrC,CAAC;AAGD,SAAK,MAAM,GAAG,QAAQ,MAAM;AACxB,WAAK,aAAa,MAAM,sBAAsB;AAAA,IAClD,CAAC;AACD,SAAK,MAAM,GAAG,SAAS,MAAM;AACzB,WAAK,aAAa,MAAM,qBAAqB;AAAA,IACjD,CAAC;AAAA,EACL;AAAA,EAEA,UAAU,UAAsC;AAC5C,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,UAAU,UAAyC;AAC/C,SAAK,aAAa;AAAA,EACtB;AAAA,EAEO,YAAY,MAAe;AAC9B,SAAK,aAAa,KAAK;AAAA,MACnB,MAAM;AAAA,MACN;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEO,YAAY,MAAe,UAAU,KAAwB;AAChE,WAAO,KAAK,aAAa,QAAQ;AAAA,MAC7B,MAAM;AAAA,MACN;AAAA,IACJ,GAAG,OAAO;AAAA,EACd;AACJ;;;AC9EA,2BAAmB;AAKZ,IAAe,cAAf,MAA2B;AAAA,EAEb;AAAA,EAEA;AAAA,EAED,UAAuC,oBAAI,IAAI;AAAA,EAErD,YAAY,YAAoB,UAAqB;AAC3D,SAAK,aAAa;AAClB,SAAK,WAAW,YAAY,CAAC;AAAA,EACjC;AAAA,EAEmB,WAAsC;AAAA,IACrD,WAAW;AAAA,IACX,WAAW;AAAA,IAEX,kBAAkB;AAAA,IAClB,+BAA+B;AAAA,IAC/B,mBAAmB;AAAA,IACnB,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,iCAAiC;AAAA,IACjC,4BAA4B;AAAA,IAC5B,mCAAmC;AAAA,IACnC,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,IACtB,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,EAC3B;AAAA,EAEU,aAAa,YAAoB,WAAmB,WAAqB,aAAqB,OAAe,SAAuC;AAC1J,QAAI;AACA,YAAM,YAAQ,2BAAK,KAAK,YAAY;AAAA,QAChC,KAAK;AAAA,UACD,aAAa,WAAW,SAAS;AAAA,UACjC,YAAY,UAAU,SAAS;AAAA,UAC/B,YAAY,UAAU,KAAK,GAAG;AAAA,UAC9B,cAAc,YAAY,SAAS;AAAA,UACnC,OAAO;AAAA,UACP,SAAS,QAAQ,KAAK,GAAG;AAAA,UACzB,aAAa;AAAA,QACjB;AAAA,QACA,OAAO;AAAA,QACP,UAAU,KAAK;AAAA,QACf,QAAQ;AAAA,QACR,UAAU;AAAA,MACd,CAAC;AAED,YAAM,SAAS,IAAI,eAAe,WAAW,OAAO,WAAW,WAAW;AAE1E,YAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS;AAC/B,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC7B,CAAC;AAED,YAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS;AAC/B,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC7B,CAAC;AAED,YAAM,GAAG,SAAS,MAAM;AACpB,YAAG,KAAK,SAAS,gBAAiB,MAAK,SAAS,gBAAgB,MAAM;AAEtE,aAAK,kBAAkB,MAAM;AAE7B,aAAK,QAAQ,IAAI,WAAW,MAAM;AAElC,eAAO,UAAU,CAACC,aAAY;AAC1B,eAAK,UAAU,QAAQA,QAAO;AAAA,QAClC,CAAC;AAED,eAAO,UAAU,CAACA,aAAY;AAC1B,iBAAO,KAAK,UAAU,QAAQA,QAAO;AAAA,QACzC,CAAC;AAAA,MACL,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,QAAQ;AACvB,YAAG,KAAK,SAAS,cAAe,MAAK,SAAS,cAAc,QAAQ,GAAG;AAAA,MAC3E,CAAC;AAED,YAAM,GAAG,QAAQ,CAAC,QAAe;AAC7B,YAAG,OAAO,WAAW,WAAW;AAC5B,iBAAO,SAAS;AAChB,eAAK,YAAY,QAAQ,mBAAmB,KAAK,OAAO,EAAE;AAAA,QAC9D;AAAA,MACJ,CAAC;AAAA,IACL,SAAS,OAAO;AACZ,YAAM,IAAI,MAAM,uCAAuC,SAAS,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,IACjI;AAAA,EACJ;AAAA,EAEU,YAAY,QAAwB,QAAsB;AAChE,WAAO,SAAS;AAEhB,WAAO,aAAa,QAAQ;AAAA,MACxB,MAAM;AAAA,MACN;AAAA,IACJ,GAAG,GAAI,EAAE,MAAM,MAAM;AACjB,UAAG,KAAK,SAAS,4BAA6B,MAAK,SAAS,4BAA4B,QAAQ,QAAQ,qCAAqC;AAAA,IACjJ,CAAC,EAAE,QAAQ,MAAM;AACb,UAAI,OAAO,SAAS,OAAO,MAAM,KAAK;AAClC,YAAG,OAAO,MAAM,KAAK,SAAS,GAAG;AAC7B,cAAG,KAAK,SAAS,eAAgB,MAAK,SAAS,eAAe,QAAQ,QAAQ,IAAI;AAAA,QACtF,OAAO;AACH,cAAG,KAAK,SAAS,MAAO,MAAK,SAAS,MAAM,sCAAsC,OAAO,EAAE,EAAE;AAC7F,iBAAO,MAAM,KAAK,SAAS;AAAA,QAC/B;AACA,YAAI;AAAE,kBAAQ,KAAK,CAAC,OAAO,MAAM,GAAG;AAAA,QAAE,QAAQ;AAAA,QAAC;AAAA,MACnD,OAAO;AACH,YAAG,KAAK,SAAS,eAAgB,MAAK,SAAS,eAAe,QAAQ,QAAQ,KAAK;AAAA,MACvF;AACA,WAAK,QAAQ,OAAO,OAAO,EAAE;AAC7B,WAAK,kBAAkB,QAAQ,MAAM;AAAA,IACzC,CAAC;AAAA,EACL;AAAA,EAUQ,UAAU,QAAwBA,UAAoB;AAC1D,QAAGA,SAAQ,SAAS,iBAAiB;AACjC,aAAO,SAAS;AAChB,UAAG,KAAK,SAAS,cAAe,MAAK,SAAS,cAAc,MAAM;AAClE,WAAK,gBAAgB,QAAQA,SAAQ,UAAU,GAAGA,SAAQ,WAAW,CAAC;AAAA,IAC1E;AAEA,QAAIA,SAAQ,SAAS,iBAAiB;AAClC,aAAO,SAAS;AAChB,UAAG,KAAK,SAAS,cAAe,MAAK,SAAS,cAAc,QAAQA,SAAQ,KAAK;AACjF,WAAK,YAAY,QAAQ,oBAAoBA,SAAQ,KAAK;AAAA,IAC9D;AAEA,QAAGA,SAAQ,QAAQ,YAAY,KAAK,SAAS,SAAS;AAClD,WAAK,SAAS,QAAS,QAAQA,SAAQ,IAAI;AAAA,IAC/C;AAAA,EACJ;AAAA,EAIO,GAA8C,OAAU,UAA8C;AACzG,SAAK,SAAS,KAAK,IAAI;AAAA,EAC3B;AAAA,EAEO,4BAA4B,SAAiBA,UAAkB,UAAU,KAAwB;AACpG,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,iBAAW,UAAU,KAAK,QAAQ,OAAO,GAAG;AACxC,cAAM,UAAU,aAAa,mBAAmB,SAAS,OAAO,WAAW;AAC3E,YAAI,OAAO,UAAU,SAAS,OAAO,GAAG;AACpC,iBAAO,aAAa,QAAQ;AAAA,YACxB,MAAM;AAAA,YACN,MAAMA;AAAA,UACV,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM;AACtC;AAAA,QACJ;AAAA,MACJ;AACA,aAAO,IAAI,MAAM,8BAA8B,OAAO,EAAE,CAAC;AAAA,IAC7D,CAAC;AAAA,EACL;AAAA,EAEO,qBAAqB,SAAyBA,UAAkB,UAAU,KAAwB;AACrG,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,cAAQ,aAAa,QAAQ;AAAA,QACzB,MAAM;AAAA,QACN,MAAMA;AAAA,MACV,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM;AACtC;AAAA,IACJ,CAAC;AAAA,EACL;AACJ;;;ACnLA,IAAAC,kBAAqB;AAKd,IAAK,yBAAL,kBAAKC,4BAAL;AACH,EAAAA,gDAAA;AACA,EAAAA,gDAAA;AAFQ,SAAAA;AAAA,GAAA;AAKL,IAAM,kBAAN,cAA8B,YAAY;AAAA,EAE5B;AAAA,EAEA;AAAA,EAEA;AAAA,EAET;AAAA,EAEA,mBAA2C;AAAA,EAE3C;AAAA,EAEA,MAAe;AAAA,EAEvB,YAAY,YAAoB,MAAc,MAAc,YAAoB,MAAe,UAAqB,KAAe;AAC/H,UAAM,YAAY,QAAQ;AAE1B,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,OAAO;AACZ,SAAK,MAAM,OAAO;AAAA,EACtB;AAAA,EAEO,QAAQ;AACX,UAAM,SAAS,IAAI,uBAAO;AAAA,MACtB,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,WAAW;AAAA,MACX,SAAS;AAAA,IACb,CAAC;AAED,SAAK,eAAe,IAAI,aAAa,CAACC,aAAY;AAC9C,UAAG,OAAO,UAAU,GAAG;AACnB,eAAO,OAAO,KAAKA,QAAO;AAAA,MAC9B;AACA,aAAO,QAAQ,OAAO,IAAI,MAAM,sCAAsC,CAAC;AAAA,IAC3E,GAAG,CAACA,aAAY;AACZ,YAAMC,KAAID;AACV,UAAGC,GAAE,QAAQ,kBAAkB;AAC3B,aAAK,gBAAgBA,GAAE,IAAI;AAAA,MAC/B,WAAWA,GAAE,QAAQ,gBAAgB;AACjC,aAAK,cAAcA,GAAE,IAAI;AAAA,MAC7B,WAAUA,GAAE,QAAQ,qBAAqB;AACrC,aAAK,mBAAmBA,GAAE,IAAI;AAAA,MAClC,WAAUA,GAAE,QAAQ,iBAAiB;AACjC,YAAG,KAAK,SAAS,eAAe;AAC5B,eAAK,SAAS,cAAc;AAAA,QAChC;AAAA,MACJ,WAAUA,GAAE,QAAQ,oBAAoB;AACpC,YAAG,KAAK,SAAS,kBAAkB;AAC/B,eAAK,SAAS,iBAAiB;AAAA,QACnC;AAAA,MACJ;AAAA,IACJ,GAAG,CAACD,aAAY;AACZ,aAAO,KAAK,gBAAgBA,QAAO;AAAA,IACvC,CAAC;AAED,gBAAY,MAAM;AACd,UAAG,KAAK,oBAAoB,mBAAkC;AAC1D,aAAK,UAAU;AAAA,MACnB;AAAA,IACJ,GAAG,IAAI;AAEP,WAAO,QAAQ;AAAA,MACX,IAAI,KAAK;AAAA,MACT,KAAK,KAAK;AAAA,MACV,MAAM,KAAK;AAAA,IACf,CAAC,EAAE,KAAK,OAAK;AACT,UAAG,KAAK,SAAS,8BAA+B,MAAK,SAAS,8BAA8B;AAC5F,WAAK,mBAAmB;AAExB,aAAO,GAAG,WAAW,CAACA,aAAY;AAC9B,aAAK,cAAc,QAAQA,QAAO;AAAA,MACtC,CAAC;AACD,aAAO,GAAG,SAAS,CAAC,WAAW;AAC3B,YAAG,KAAK,SAAS,yBAA0B,MAAK,SAAS,yBAAyB,MAAM;AAGxF,YAAG,KAAK,oBAAoB,mBAAkC;AAC1D,eAAK,QAAQ,QAAQ,CAACE,YAAW;AAC7B,iBAAK,YAAYA,SAAQ,0BAA0B;AAAA,UACvD,CAAC;AAAA,QACL;AACA,aAAK,mBAAmB;AAAA,MAC5B,CAAC;AAED,aAAO,GAAG,UAAU,CAAC,WAAW;AAC5B,YAAG,KAAK,SAAS,gCAAiC,MAAK,SAAS,gCAAgC,MAAM;AAEtG,YAAG,UAAU,GAAE;AACX,cAAG,KAAK,oBAAoB,mBAAkC;AAC1D,iBAAK,QAAQ,QAAQ,CAACA,YAAW;AAC7B,mBAAK,YAAYA,SAAQ,0BAA0B;AAAA,YACvD,CAAC;AAAA,UACL;AACA,eAAK,mBAAmB;AAAA,QAC5B,WAAU,UAAU,GAAE;AAClB,eAAK,mBAAmB;AACxB,cAAG,KAAK,SAAS,8BAA+B,MAAK,SAAS,8BAA8B;AAAA,QAChG;AAAA,MACJ,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AAAA,EAEQ,YAAY;AAChB,SAAK,aAAa,QAAQ;AAAA,MACtB,MAAM;AAAA,IACV,GAAG,MAAO,EAAE,EAAE,KAAK,CAAC,MAAM;AACtB,YAAM,WAAW;AAEjB,UAAG,KAAK,SAAS,qBAAqB;AAClC,aAAK,SAAS,oBAAoB,QAAQ;AAAA,MAC9C;AAEA,YAAM,mBAAmB,KAAK,QAAQ,OAAO,EAAE,OAAO,OAAK,EAAE,UAAU,UAAU,EAAE,QAAQ;AAC3F,uBAAiB,QAAQ,CAAC,MAAsB;AAC5C,YAAI,KAAK,IAAI,IAAI,EAAE,YAAY,KAAK,KAAK,KAAM;AAC3C,eAAK,YAAY,GAAG,gCAAgC;AAAA,QACxD;AAAA,MACJ,CAAC;AAGD,YAAM,gBAAgB,KAAK,QAAQ,OAAO,EAAE,OAAO,OAAK,CAAC,SAAS,YAAY,SAAS,EAAE,EAAE,CAAC,EAAE,QAAQ;AACtG,UAAG,cAAc,SAAS,GAAG;AACzB,YAAG,KAAK,SAAS,kBAAkB;AAC/B,eAAK,SAAS,iBAAiB,oCAAoC,cAAc,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,QAChH;AACA,sBAAc,QAAQ,OAAK;AACvB,eAAK,YAAY,GAAG,gCAAgC;AAAA,QACxD,CAAC;AAAA,MACL,OAAO;AACH,YAAG,KAAK,SAAS,oBAAoB;AACjC,eAAK,SAAS,mBAAmB;AAAA,QACrC;AAAA,MACJ;AAAA,IACJ,CAAC,EAAE,MAAM,CAAC,QAAQ;AACd,UAAG,KAAK,SAAS,kBAAkB;AAC/B,aAAK,SAAS,iBAAiB,sBAAsB,GAAG,EAAE;AAAA,MAC9D;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEU,kBAAkB,QAAwB,QAAsB;AACtE,SAAK,cAAc,KAAK;AAAA,MACpB,MAAM;AAAA,MACN,MAAM;AAAA,QACF,IAAI,OAAO;AAAA,QACX;AAAA,MACJ;AAAA,IACJ,CAAC,EAAE,MAAM,MAAM;AACX,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEU,gBAAgB,QAAwB,QAAgB,SAAuB;AACrF,SAAK,cAAc,KAAK;AAAA,MACpB,MAAM;AAAA,MACN,MAAM;AAAA,QACF,IAAI,OAAO;AAAA,QACX;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEU,kBAAkB,QAA8B;AACtD,SAAK,cAAc,KAAK;AAAA,MACpB,MAAM;AAAA,MACN,MAAM;AAAA,QACF,IAAI,OAAO;AAAA,MACf;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEQ,gBAAgBF,UAAiB;AACrC,UAAMC,KAAID;AAEV,QAAG,KAAK,QAAQ,IAAIC,GAAE,SAAS,GAAG;AAC9B,WAAK,cAAc,KAAK;AAAA,QACpB,MAAM;AAAA,QACN,MAAM;AAAA,UACF,IAAIA,GAAE;AAAA,UACN,QAAQ;AAAA,QACZ;AAAA,MACJ,CAAC,EAAE,MAAM,MAAM;AACX,eAAO;AAAA,MACX,CAAC;AACD;AAAA,IACJ;AAEA,SAAK,aAAa,KAAK,YAAYA,GAAE,WAAWA,GAAE,WAAWA,GAAE,aAAaA,GAAE,OAAOA,GAAE,OAAO;AAAA,EAClG;AAAA,EAEQ,cAAcD,UAAkB;AACpC,UAAMC,KAAID;AACV,UAAM,UAAU,KAAK,QAAQ,IAAIC,GAAE,EAAE;AACrC,QAAI,SAAS;AACT,WAAK,YAAY,SAAS,2BAA2BA,GAAE,EAAE,EAAE;AAAA,IAC/D;AAAA,EACJ;AAAA,EAEQ,mBAAmBD,UAAkB;AACzC,UAAMC,KAAID;AACV,UAAM,UAAU,KAAK,QAAQ,IAAIC,GAAE,SAAS;AAC5C,QAAI,KAAK,SAAS,qBAAqB,SAAS;AAC5C,WAAK,SAAS,kBAAkB,OAAO;AAAA,IAC3C;AAAA,EACJ;AAAA,EAEU,UAAU,QAAwBD,UAAgC;AACxE,QAAGA,SAAQ,SAAS,6BAA4B;AAC5C,YAAM,UAAUA,SAAQ;AACxB,YAAM,OAAOA,SAAQ;AAErB,YAAM,UAAU,aAAa,mBAAmB,SAAS,OAAO,WAAW;AAC3E,UAAG,OAAO,UAAU,SAAS,OAAO,GAAG;AACnC,eAAO,OAAO,aAAa,QAAQ;AAAA,UAC/B,MAAM;AAAA,UACN;AAAA,QACJ,GAAG,GAAI;AAAA,MACX,OAAO;AACH,eAAO,KAAK,aAAa,QAAQ;AAAA,UAC7B,MAAM;AAAA,UACN;AAAA,UACA;AAAA,QACJ,GAAG,GAAI;AAAA,MACX;AAAA,IACJ;AAEA,QAAGA,SAAQ,QAAQ,kBAAkB;AACjC,aAAO,KAAK,aAAa,QAAQ;AAAA,QAC7B,MAAM;AAAA,QACN,MAAMA,SAAQ;AAAA,MAClB,GAAG,GAAI;AAAA,IACX;AAEA,QAAGA,SAAQ,QAAQ,YAAY,KAAK,SAAS,SAAS;AAClD,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,aAAK,SAAS,QAAS,QAAQA,SAAQ,MAAM,SAAS,MAAM;AAAA,MAChE,CAAC;AAAA,IACL;AAEA,WAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyBA,SAAQ,IAAI,EAAE,CAAC;AAAA,EAC5E;AAAA,EAEQ,gBAAgBA,UAAgC;AACpD,QAAGA,SAAQ,SAAS,6BAA4B;AAC5C,YAAM,YAAYA,SAAQ;AAC1B,YAAM,OAAOA,SAAQ;AAErB,YAAM,UAAU,KAAK,QAAQ,IAAI,SAAS;AACzC,UAAG,SAAQ;AACP,eAAO,QAAQ,aAAa,QAAQ;AAAA,UAChC,MAAM;AAAA,UACN;AAAA,QACJ,GAAG,GAAI;AAAA,MACX,OAAO;AACH,eAAO,QAAQ,OAAO,IAAI,MAAM,oCAAoC,SAAS,EAAE,CAAC;AAAA,MACpF;AAAA,IACL,WAAUA,SAAQ,QAAQ,qBAAoB;AAC1C,YAAM,YAAYA,SAAQ,KAAK;AAC/B,YAAM,UAAU,KAAK,QAAQ,IAAI,SAAS;AAC1C,UAAI,SAAS;AACT,eAAO,IAAI,QAAiB,CAAC,SAAS,WAAW;AAC7C,kBAAQ,aAAa,QAAQ;AAAA,YACzB,MAAM;AAAA,UACV,GAAG,IAAK,EAAE,KAAK,CAAC,MAAM;AAClB,oBAAQ,CAAC;AAAA,UACb,CAAC,EAAE,MAAM,CAAC,QAAQ;AACd,mBAAO,GAAG;AAAA,UACd,CAAC;AAAA,QACL,CAAC;AAAA,MACL,OAAO;AACH,eAAO,QAAQ,OAAO,IAAI,MAAM,oCAAoC,SAAS,EAAE,CAAC;AAAA,MACpF;AAAA,IACJ,WAAUA,SAAQ,QAAQ,kBAAkB;AACxC,aAAO,QAAQ,IAAI,KAAK,QAAQ,OAAO,EAAE,OAAO,OAAK,EAAE,UAAU,SAAS,EAAE,IAAI,OAAK;AACjF,eAAO,EAAE,aAAa,QAAQ;AAAA,UAC1B,MAAM;AAAA,UACN,MAAMA,SAAQ;AAAA,QAClB,GAAG,GAAI;AAAA,MACX,CAAC,CAAC;AAAA,IACN;AAEA,WAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyBA,SAAQ,IAAI,EAAE,CAAC;AAAA,EAC5E;AAAA,EAEA,eAAqB;AACjB,SAAK,cAAc,KAAK;AAAA,MACpB,MAAM;AAAA,IACV,CAAC;AAAA,EACL;AAEJ;;;AC/SO,IAAM,qBAAN,cAAiC,YAAY;AAAA,EAC/B;AAAA,EACA;AAAA,EAED;AAAA,EACA;AAAA,EAEhB,YAAY,YAAoB,kBAA0B,eAAuB,OAAe,SAAiC,UAAqB;AAClJ,UAAM,YAAY,QAAQ;AAC1B,SAAK,mBAAmB;AACxB,SAAK,gBAAgB;AACrB,SAAK,QAAQ;AACb,SAAK,UAAU;AAAA,EACnB;AAAA,EAEA,IAAI,cAAsB;AACtB,WAAO,KAAK,mBAAmB,KAAK;AAAA,EACxC;AAAA,EAEQ,oBAA8C;AAClD,UAAM,WAAqC,CAAC;AAC5C,aAAS,IAAI,GAAG,IAAI,KAAK,eAAe,KAAK;AACzC,eAAS,CAAC,IAAI,CAAC;AACf,eAAS,IAAI,GAAG,IAAI,KAAK,kBAAkB,KAAK;AAC5C,iBAAS,CAAC,EAAE,KAAK,IAAI,KAAK,mBAAmB,CAAC;AAAA,MAClD;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEO,QAAc;AACjB,UAAM,WAAW,KAAK,kBAAkB;AACxC,eAAW,CAAC,IAAI,SAAS,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACpD,WAAK,aAAa,GAAG,OAAO,EAAE,GAAG,WAAW,KAAK,aAAa,KAAK,OAAO,KAAK,OAAO;AAAA,IAC1F;AAAA,EACJ;AAAA,EAEU,kBAAkB,QAAwB,QAAsB;AACtE,SAAK,QAAQ,OAAO,OAAO,EAAE;AAC7B,SAAK,eAAe,MAAM;AAAA,EAC9B;AAAA,EAEU,gBAAgB,QAA8B;AAAA,EAExD;AAAA,EAEU,kBAAkB,QAA8B;AAAA,EAE1D;AAAA,EAEQ,eAAe,QAA8B;AACjD,SAAK,aAAa,GAAG,OAAO,IAAI,OAAO,WAAW,KAAK,aAAa,KAAK,OAAO,KAAK,OAAO;AAAA,EAChG;AAAA,EAEU,UAAU,QAAwBG,UAAgC;AACxE,QAAGA,SAAQ,SAAS,6BAA4B;AAC5C,YAAM,UAAUA,SAAQ;AACxB,YAAM,OAAOA,SAAQ;AAErB,YAAM,UAAU,aAAa,mBAAmB,SAAS,OAAO,WAAW;AAC3E,UAAG,OAAO,UAAU,SAAS,OAAO,GAAG;AACnC,eAAO,OAAO,aAAa,QAAQ;AAAA,UAC/B,MAAM;AAAA,UACN;AAAA,QACJ,GAAG,GAAI;AAAA,MACX,OAAO;AACH,eAAO,QAAQ,OAAO,IAAI,MAAM,YAAY,OAAO,yBAAyB,OAAO,EAAE,cAAc,OAAO,EAAE,CAAC;AAAA,MACjH;AAAA,IACJ;AAEA,QAAGA,SAAQ,QAAQ,kBAAkB;AACjC,aAAO,QAAQ;AAAA,QACX,KAAK,QAAQ,OAAO,EAAE,IAAI,OAAK;AAC3B,iBAAO,EAAE,aAAa,QAAQ;AAAA,YAC1B,MAAM;AAAA,YACN,MAAMA,SAAQ;AAAA,UAClB,GAAG,GAAI;AAAA,QACX,CAAC;AAAA,MACL;AAAA,IACJ;AAEA,QAAGA,SAAQ,QAAQ,YAAY,KAAK,SAAS,SAAS;AAClD,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,aAAK,SAAS,QAAS,QAAQA,SAAQ,MAAM,SAAS,MAAM;AAAA,MAChE,CAAC;AAAA,IACL;AAEA,WAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyBA,SAAQ,IAAI,EAAE,CAAC;AAAA,EAC5E;AAEJ;","names":["BridgeClientClusterConnectionStatus","result","BridgeClientConnectionStatus","message","m","message","message","m","os","fn","message","message","import_net_ipc","BridgeConnectionStatus","message","m","client","message"]}
|