{"version":3,"file":"worker.mjs","names":["#ensureActorRunning","#subscribeSocketToActor","#startPeriodicCacheCleanup","#setupStatePersistence","#enqueueSendStateUpdate","#sendQueues","#sendStateUpdate","#calculateChecksum","#scheduleSnapshotCacheCleanup","#createCallerSnapshot","#persistSnapshot","#setupActorFromRequest","#getValidatedCaller","#storeActorData","#isActorRunning","#getCurrentSnapshot","#matchesEvent","#matchesState","#cleanupSnapshotCache"],"sources":["../src/utils.ts","../src/createActorKitRouter.ts","../src/constants.ts","../src/createMachineServer.ts","../src/fromActorKit.ts"],"sourcesContent":["import { jwtVerify } from \"jose\";\nimport { CallerStringSchema } from \"./schemas\";\nimport { Caller } from \"./types\";\nimport { Actor, SnapshotFrom } from \"xstate\";\nimport { BaseActorKitStateMachine } from \"./types\";\n\n// Define log levels\nexport enum LogLevel {\n  ERROR = 0,\n  WARN = 1,\n  INFO = 2,\n  DEBUG = 3,\n}\n\n// Declare a global variable to control debug level\ndeclare global {\n  var DEBUG_LEVEL: LogLevel | undefined;\n}\n\n// Set the current log level based on the global DEBUG_LEVEL variable\n// Default to INFO if not set\nconst getCurrentLogLevel = (): LogLevel => {\n  return globalThis.DEBUG_LEVEL !== undefined\n    ? globalThis.DEBUG_LEVEL\n    : LogLevel.INFO;\n};\n\n/**\n * Debug logging function\n * @param message The message to log\n * @param level The log level (default: DEBUG)\n * @param data Additional data to log (optional)\n */\nexport function debug(\n  message: string,\n  level: LogLevel = LogLevel.DEBUG,\n  data?: unknown\n) {\n  const currentLogLevel = getCurrentLogLevel();\n  if (level <= currentLogLevel) {\n    const timestamp = new Date().toISOString();\n    const logMessage = `[${timestamp}] ${LogLevel[level]}: ${message}`;\n\n    if (data) {\n      console.log(logMessage, data);\n    } else {\n      console.log(logMessage);\n    }\n\n    // You can extend this to send logs to a service if needed\n    // For example:\n    // if (typeof fetch !== 'undefined') {\n    //   fetch('https://your-logging-service.com', {\n    //     method: 'POST',\n    //     body: JSON.stringify({ message: logMessage, level, data }),\n    //   });\n    // }\n  }\n}\n\n// Convenience methods for different log levels\nexport const logError = (message: string, data?: unknown) =>\n  debug(message, LogLevel.ERROR, data);\nexport const logWarn = (message: string, data?: unknown) =>\n  debug(message, LogLevel.WARN, data);\nexport const logInfo = (message: string, data?: unknown) =>\n  debug(message, LogLevel.INFO, data);\n\nexport const json = <T>(data: T, status = 200) =>\n  Response.json(data, { status });\n\nexport const ok = () => json({ ok: true });\n\nexport const error = (err: string | { message: string }, status = 500) => {\n  console.error(\"Error response\", err);\n  return json(\n    {\n      ok: false,\n      error: typeof err === \"string\" ? err : err.message ?? \"Unknown error\",\n    },\n    status\n  );\n};\n\nexport const notFound = () => error(\"Not found\", 404);\n\n/**\n * Parses query parameters from a URL string.\n * @param url The URL to parse.\n * @returns A URLSearchParams object containing the parsed query parameters.\n */\nexport const parseQueryParams = (url: string) => {\n  const index = url.indexOf(\"?\");\n  const search = index !== -1 ? url.substring(index + 1) : \"\";\n  return new URLSearchParams(search);\n};\n\nexport function assert<T>(\n  expression: T,\n  errorMessage: string\n): asserts expression {\n  if (!expression) {\n    const error = new Error(errorMessage);\n    const stack = error.stack?.split(\"\\n\");\n\n    // Find the line in the stack trace that corresponds to where the assert was called.\n    // This is typically the third line in the stack, but this may vary depending on the JS environment.\n    const assertLine =\n      stack && stack.length >= 3 ? stack[2] : \"unknown location\";\n\n    throw new Error(`${errorMessage} (Assert failed at ${assertLine?.trim()})`);\n  }\n}\n\nexport async function getCallerFromRequest(\n  request: Request,\n  actorType: string,\n  actorId: string,\n  secret: string\n): Promise<Caller> {\n  let accessToken: string;\n  if (request.headers.get(\"Upgrade\") !== \"websocket\") {\n    const authHeader = request.headers.get(\"Authorization\");\n    const stringPart = authHeader?.split(\" \")[1];\n    assert(stringPart, \"Expected authorization header to be set\");\n    accessToken = stringPart;\n  } else {\n    const searchParams = new URLSearchParams(request.url.split(\"?\")[1]);\n    const paramString = searchParams.get(\"accessToken\");\n    assert(paramString, \"expected accessToken when connecting to socket\");\n    accessToken = paramString;\n  }\n\n  return parseAccessTokenForCaller({\n    accessToken,\n    type: actorType,\n    id: actorId,\n    secret,\n  });\n}\n\nexport async function parseAccessTokenForCaller({\n  accessToken,\n  type,\n  id,\n  secret,\n}: {\n  accessToken: string;\n  type: string;\n  id: string;\n  secret: string;\n}): Promise<Caller> {\n  const verified = await jwtVerify(accessToken, new TextEncoder().encode(secret));\n  if (!verified.payload.jti) {\n    throw new Error(\"Expected JTI on accessToken\");\n  }\n  if (verified.payload.jti !== id) {\n    throw new Error(`Expected JTI on accessToken to match actor id: ${id}`);\n  }\n  if (!verified.payload.aud) {\n    throw new Error(\n      `Expected accessToken audience to match actor type: ${type}`\n    );\n  }\n  const audience = Array.isArray(verified.payload.aud)\n    ? verified.payload.aud\n    : [verified.payload.aud];\n  if (!audience.includes(type)) {\n    throw new Error(\n      `Expected accessToken audience to match actor type: ${type}`\n    );\n  }\n  if (!verified.payload.sub) {\n    throw new Error(\"Expected accessToken to have subject\");\n  }\n  return CallerStringSchema.parse(verified.payload.sub);\n}\n\nexport function getSnapshot<TMachine extends BaseActorKitStateMachine>(\n  actor: Actor<TMachine>\n): SnapshotFrom<TMachine> | undefined {\n  return actor.getSnapshot();\n}\n","import { z } from \"zod\";\nimport { AnyEventSchema } from \"./schemas\";\nimport {\n  AnyEvent,\n  Caller,\n  ActorKitEnv,\n  KebabToScreamingSnake,\n  ScreamingSnakeToKebab,\n} from \"./types\";\nimport { getCallerFromRequest } from \"./utils\";\n\nconst SnapshotRequestSearchSchema = z.object({\n  waitForEvent: z.string().optional(),\n  waitForState: z.string().optional(),\n  timeout: z\n    .string()\n    .transform((value) => Number.parseInt(value, 10))\n    .pipe(z.number().int().positive())\n    .optional(),\n  errorOnWaitTimeout: z\n    .enum([\"true\", \"false\"])\n    .transform((value) => value === \"true\")\n    .optional(),\n});\n\ntype ActorKitDurableObjectStub = {\n  spawn(props: {\n    actorType: string;\n    actorId: string;\n    caller: Caller;\n    input: Record<string, unknown>;\n  }): Promise<void> | void;\n  getSnapshot(\n    caller: Caller,\n    options?: {\n      waitForEvent?: unknown;\n      waitForState?: unknown;\n      timeout?: number;\n      errorOnWaitTimeout?: boolean;\n    }\n  ): Promise<{\n    checksum: string;\n    snapshot: unknown;\n  }>;\n  send(event: { caller: Caller; type: string }): void;\n  fetch(request: Request): Promise<Response>;\n};\n\ntype ActorKitNamespace = {\n  idFromName(name: string): unknown;\n  get(id: unknown): ActorKitDurableObjectStub;\n};\n\nexport const createActorKitRouter = <Env extends ActorKitEnv>(\n  routes: Array<ScreamingSnakeToKebab<Extract<keyof Env, string>>>\n) => {\n  type ActorType = ScreamingSnakeToKebab<Extract<keyof Env, string>>;\n\n  // Add a Set to keep track of spawned actors\n  const spawnedActors = new Set<string>();\n\n  function getDurableObjectNamespace<\n    T extends ScreamingSnakeToKebab<Extract<keyof Env, string>>\n  >(\n    env: Env,\n    key: T\n  ): ActorKitNamespace | undefined {\n    const envKey = key.toUpperCase() as KebabToScreamingSnake<T> & keyof Env;\n    const namespace = env[envKey];\n    if (\n      namespace &&\n      typeof namespace === \"object\" &&\n      \"get\" in namespace &&\n      \"idFromName\" in namespace\n    ) {\n      return namespace as unknown as ActorKitNamespace;\n    }\n    return undefined;\n  }\n\n  return async (\n    request: Request,\n    env: Env,\n    _ctx?: unknown\n  ): Promise<Response> => {\n    const url = new URL(request.url);\n    const pathParts = url.pathname.split(\"/\").filter(Boolean);\n    if (pathParts.length !== 3 || pathParts[0] !== \"api\") {\n      return new Response(\"Not Found\", { status: 404 });\n    }\n    const [, actorType, actorId] = pathParts;\n\n    if (!routes.includes(actorType as ActorType)) {\n      return new Response(`Unknown actor type: ${actorType}`, { status: 400 });\n    }\n\n    const durableObjectNamespace = getDurableObjectNamespace<ActorType>(\n      env,\n      actorType as ActorType\n    );\n\n    if (!durableObjectNamespace) {\n      return new Response(\n        `Durable Object namespace not found for actor type: ${actorType}`,\n        { status: 500 }\n      );\n    }\n\n    const durableObjectId = durableObjectNamespace.idFromName(actorId);\n    const durableObjectStub = durableObjectNamespace.get(durableObjectId);\n\n    // Parse the auth header to get the caller token\n    let caller: Caller;\n    try {\n      caller = await getCallerFromRequest(\n        request,\n        actorType,\n        actorId,\n        env.ACTOR_KIT_SECRET\n      );\n    } catch (error: unknown) {\n      const errorMessage =\n        error instanceof Error ? error.message : \"Unknown error\";\n      return new Response(\n        `Error: ${errorMessage}. API requests must specify a valid caller in Bearer token in the Authorization header using fetch method created from 'createActorFetch' or use 'createAccessToken' directly.`,\n        { status: 401 }\n      );\n    }\n\n    // Create a unique key for the actor\n    const actorKey = `${actorType}:${actorId}`;\n\n    // Check if the actor has already been spawned\n    if (!spawnedActors.has(actorKey)) {\n      // If not, spawn it and mark it as spawned\n      await durableObjectStub.spawn({\n        actorType,\n        actorId,\n        caller,\n        input: {},\n      });\n      spawnedActors.add(actorKey);\n    }\n\n    if (request.headers.get(\"Upgrade\") === \"websocket\") {\n      return durableObjectStub.fetch(request);\n    }\n\n    if (request.method === \"GET\") {\n      let searchParams: z.infer<typeof SnapshotRequestSearchSchema>;\n      try {\n        searchParams = SnapshotRequestSearchSchema.parse(\n          Object.fromEntries(new URL(request.url).searchParams)\n        );\n      } catch (error: unknown) {\n        const errorMessage =\n          error instanceof Error ? error.message : \"Invalid search params\";\n        return new Response(JSON.stringify({ error: errorMessage }), {\n          status: 400,\n        });\n      }\n\n      const result = await durableObjectStub.getSnapshot(caller, {\n        waitForEvent: searchParams.waitForEvent\n          ? AnyEventSchema.parse(JSON.parse(searchParams.waitForEvent))\n          : undefined,\n        waitForState: searchParams.waitForState\n          ? JSON.parse(searchParams.waitForState)\n          : undefined,\n        timeout: searchParams.timeout,\n        errorOnWaitTimeout: searchParams.errorOnWaitTimeout,\n      });\n      return new Response(JSON.stringify(result), {\n        headers: { \"Content-Type\": \"application/json\" },\n      });\n    } else if (request.method === \"POST\") {\n      let event: AnyEvent;\n      try {\n        const json = await request.json();\n        event = AnyEventSchema.parse(json);\n      } catch (ex: unknown) {\n        const errorMessage = ex instanceof Error ? ex.message : \"Invalid JSON\";\n        return new Response(JSON.stringify({ error: errorMessage }), {\n          status: 400,\n        });\n      }\n\n      durableObjectStub.send({\n        ...event,\n        caller,\n      });\n      return new Response(JSON.stringify({ success: true }));\n    } else {\n      return new Response(JSON.stringify({ error: \"Method not allowed\" }), {\n        status: 405,\n      });\n    }\n  };\n};\n","import { CallerType } from \"./types\";\n\nexport const HEADERS = {\n  X_CALLER_ID: \"X-Caller-ID\",\n  X_CALLER_TYPE: \"X-Caller-Type\",\n  X_ACTOR_ID: \"X-Actor-ID\",\n  X_ACTOR_TYPE: \"X-Actor-Type\",\n};\n\n/**\n * Defines the types of callers that can interact with the actor system.\n * Each type represents a different source of events with varying levels of trust and permissions.\n * Note: SYSTEM events are handled internally by Actor Kit and are not defined by the user.\n */\nexport const CallerTypes: Record<CallerType, CallerType> = {\n  client: \"client\",\n  system: \"system\", // Handled internally by Actor Kit\n  service: \"service\",\n};\n\nexport const PERSISTED_SNAPSHOT_KEY = \"persistedSnapshot\";\n","import { DurableObject } from \"cloudflare:workers\";\nimport { compare } from \"fast-json-patch\";\nimport {\n  Actor,\n  AnyEventObject,\n  createActor,\n  EventFromLogic,\n  InputFrom,\n  matchesState,\n  SnapshotFrom,\n  StateValueFrom,\n  Subscription,\n} from \"xstate\";\nimport { xstateMigrate } from \"xstate-migrate\";\nimport { z } from \"zod\";\nimport { PERSISTED_SNAPSHOT_KEY } from \"./constants\";\nimport { CallerSchema } from \"./schemas\";\nimport type {\n  ActorKitInputProps,\n  ActorServer,\n  AnyActorKitStateMachine,\n  Caller,\n  CallerSnapshotFrom,\n  ClientEventFrom,\n  EnvFromMachine,\n  MachineServerOptions,\n  ServiceEventFrom,\n} from \"./types\";\nimport { assert, getCallerFromRequest } from \"./utils\";\n\nconst StorageSchema = z.object({\n  actorType: z.string(),\n  actorId: z.string(),\n  initialCaller: CallerSchema,\n  input: z.record(z.unknown()),\n});\n\nconst WebSocketAttachmentSchema = z.object({\n  caller: CallerSchema,\n  lastSentChecksum: z.string().optional(),\n});\n\ntype WebSocketAttachment = z.infer<typeof WebSocketAttachmentSchema>;\n\ntype ActorKitWebSocket = WebSocket & {\n  serializeAttachment(value: WebSocketAttachment): void;\n  deserializeAttachment(): unknown;\n};\n\ntype WebSocketResponseInit = ResponseInit & {\n  webSocket: WebSocket;\n};\n\ntype ActorKitSnapshotView<TMachine extends AnyActorKitStateMachine> = {\n  value: CallerSnapshotFrom<TMachine>[\"value\"];\n  context: {\n    public: CallerSnapshotFrom<TMachine>[\"public\"];\n    private: Record<string, CallerSnapshotFrom<TMachine>[\"private\"]>;\n  };\n};\n\nconst InputSearchSchema = z.object({\n  input: z.string().optional(),\n});\n\nconst ParsedMessageSchema = z.string().transform((value, context) => {\n  try {\n    return JSON.parse(value) as unknown;\n  } catch {\n    context.addIssue({\n      code: z.ZodIssueCode.custom,\n      message: \"Expected valid JSON payload\",\n    });\n    return z.NEVER;\n  }\n});\n\nfunction getErrorMessage(error: unknown): string {\n  return error instanceof Error ? error.message : \"Unknown error\";\n}\n\nfunction parseStoredJson<T>(value: unknown, fallbackSchema: z.ZodType<T>): T {\n  const parsedString = z.string().parse(value);\n  return fallbackSchema.parse(JSON.parse(parsedString));\n}\n\nexport const createMachineServer = <\n  TClientEvent extends AnyEventObject,\n  TServiceEvent extends AnyEventObject,\n  TInputSchema extends z.ZodObject<z.ZodRawShape>,\n  TMachine extends AnyActorKitStateMachine\n>({\n  machine,\n  schemas,\n  options,\n}: {\n  machine: TMachine;\n  schemas: {\n    clientEvent: z.ZodSchema<TClientEvent>;\n    serviceEvent: z.ZodSchema<TServiceEvent>;\n    inputProps: TInputSchema;\n  };\n  options?: MachineServerOptions;\n}): new (\n  state: DurableObjectState,\n  env: EnvFromMachine<TMachine>\n) => ActorServer<TMachine> =>\n  class MachineServerImpl extends DurableObject implements ActorServer<TMachine> {\n    actor: Actor<TMachine> | undefined;\n    actorType: string | undefined;\n    actorId: string | undefined;\n    input: Record<string, unknown> | undefined;\n    initialCaller: Caller | undefined;\n    lastPersistedSnapshot: SnapshotFrom<TMachine> | null = null;\n    snapshotCache = new Map<\n      string,\n      { snapshot: SnapshotFrom<TMachine>; timestamp: number }\n    >();\n    state: DurableObjectState;\n    storage: DurableObjectStorage;\n    attachments = new Map<WebSocket, WebSocketAttachment>();\n    subscriptions = new Map<WebSocket, Subscription>();\n    #sendQueues = new Map<WebSocket, Promise<void>>();\n    env: EnvFromMachine<TMachine>;\n    currentChecksum: string | null = null;\n\n    constructor(state: DurableObjectState, env: EnvFromMachine<TMachine>) {\n      super(state, env);\n      this.state = state;\n      this.storage = state.storage;\n      this.env = env;\n\n      this.state.blockConcurrencyWhile(async () => {\n        const [actorType, actorId, initialCallerString, inputString] =\n          await Promise.all([\n            this.storage.get(\"actorType\"),\n            this.storage.get(\"actorId\"),\n            this.storage.get(\"initialCaller\"),\n            this.storage.get(\"input\"),\n          ]);\n\n        if (actorType && actorId && initialCallerString && inputString) {\n          try {\n            const parsedData = StorageSchema.parse({\n              actorType,\n              actorId,\n              initialCaller: parseStoredJson(initialCallerString, CallerSchema),\n              input: parseStoredJson(inputString, z.record(z.unknown())),\n            });\n\n            this.actorType = parsedData.actorType;\n            this.actorId = parsedData.actorId;\n            this.initialCaller = parsedData.initialCaller;\n            this.input = parsedData.input;\n\n            if (options?.persisted) {\n              const persistedSnapshot = await this.loadPersistedSnapshot();\n              if (persistedSnapshot) {\n                this.restorePersistedActor(persistedSnapshot);\n              } else {\n                this.#ensureActorRunning();\n              }\n            } else {\n              this.#ensureActorRunning();\n            }\n          } catch {\n            // Ignore corrupt startup state and wait for a fresh spawn.\n          }\n        }\n\n        for (const socket of this.state.getWebSockets()) {\n          this.#subscribeSocketToActor(socket);\n        }\n      });\n\n      this.#startPeriodicCacheCleanup();\n    }\n\n    #ensureActorRunning() {\n      assert(this.actorId, \"actorId is not set\");\n      assert(this.actorType, \"actorType is not set\");\n      assert(this.input, \"input is not set\");\n      assert(this.initialCaller, \"initialCaller is not set\");\n\n      if (!this.actor) {\n        const input = {\n          id: this.actorId,\n          caller: this.initialCaller,\n          env: this.env,\n          storage: this.storage,\n          ...this.input,\n        } satisfies ActorKitInputProps;\n\n        this.actor = createActor(machine, {\n          input: input as InputFrom<TMachine>,\n        });\n\n        if (options?.persisted) {\n          this.#setupStatePersistence(this.actor);\n        }\n\n        this.actor.start();\n      }\n\n      return this.actor;\n    }\n\n    #subscribeSocketToActor(ws: WebSocket) {\n      try {\n        const socket = ws as ActorKitWebSocket;\n        const attachment = WebSocketAttachmentSchema.parse(\n          socket.deserializeAttachment()\n        );\n        this.attachments.set(socket, attachment);\n        this.#enqueueSendStateUpdate(socket);\n\n        const subscription = this.actor?.subscribe(() => {\n          this.#enqueueSendStateUpdate(socket);\n        });\n\n        if (subscription) {\n          this.subscriptions.set(socket, subscription);\n        }\n      } catch {\n        // Ignore malformed socket state.\n      }\n    }\n\n    #enqueueSendStateUpdate(ws: ActorKitWebSocket) {\n      const prev = this.#sendQueues.get(ws);\n      const sendTask = prev\n        ? prev.then(() => this.#sendStateUpdate(ws))\n        : this.#sendStateUpdate(ws);\n      const next = sendTask.catch(() => {\n        // Errors in send are non-fatal; the next update will retry.\n      });\n      this.#sendQueues.set(ws, next);\n    }\n\n    async #sendStateUpdate(ws: ActorKitWebSocket) {\n      assert(this.actor, \"actor is not running\");\n      const attachment = this.attachments.get(ws);\n      assert(attachment, \"Attachment missing for WebSocket\");\n\n      const fullSnapshot = this.actor.getSnapshot();\n      const currentChecksum = await this.#calculateChecksum(fullSnapshot);\n\n      this.snapshotCache.set(currentChecksum, {\n        snapshot: fullSnapshot,\n        timestamp: Date.now(),\n      });\n      this.#scheduleSnapshotCacheCleanup(currentChecksum);\n      this.currentChecksum = currentChecksum;\n\n      if (attachment.lastSentChecksum === currentChecksum) {\n        return;\n      }\n\n      const nextSnapshot = this.#createCallerSnapshot(\n        fullSnapshot,\n        attachment.caller.id\n      );\n\n      let lastSnapshot: Partial<typeof nextSnapshot> = {};\n      if (attachment.lastSentChecksum) {\n        const cachedSnapshot = this.snapshotCache.get(attachment.lastSentChecksum);\n        if (cachedSnapshot) {\n          lastSnapshot = this.#createCallerSnapshot(\n            cachedSnapshot.snapshot,\n            attachment.caller.id\n          );\n        }\n      }\n\n      const operations = compare(lastSnapshot, nextSnapshot);\n      if (operations.length === 0) {\n        return;\n      }\n\n      ws.send(JSON.stringify({ operations, checksum: currentChecksum }));\n      attachment.lastSentChecksum = currentChecksum;\n      ws.serializeAttachment(attachment);\n    }\n\n    #setupStatePersistence(actor: Actor<TMachine>) {\n      actor.subscribe(() => {\n        const fullSnapshot = actor.getSnapshot();\n        this.#persistSnapshot(fullSnapshot).catch(() => {\n          // Ignore persistence errors.\n        });\n      });\n    }\n\n    async #persistSnapshot(snapshot: SnapshotFrom<TMachine>) {\n      if (\n        this.lastPersistedSnapshot &&\n        compare(this.lastPersistedSnapshot, snapshot).length === 0\n      ) {\n        return;\n      }\n\n      await this.storage.put(PERSISTED_SNAPSHOT_KEY, JSON.stringify(snapshot));\n      this.lastPersistedSnapshot = snapshot;\n    }\n\n    async #setupActorFromRequest(request: Request): Promise<Response | null> {\n      const url = new URL(request.url);\n      const searchParams = InputSearchSchema.parse(\n        Object.fromEntries(url.searchParams)\n      );\n      const pathParts = url.pathname.split(\"/\").filter(Boolean);\n      const [, actorType, actorId] = pathParts;\n\n      if (!actorType || !actorId) {\n        return new Response(\"Invalid actor path\", { status: 400 });\n      }\n\n      const hasRequiredFields = Object.values(schemas.inputProps.shape).some(\n        (field) => !field.isOptional()\n      );\n\n      if (hasRequiredFields && !searchParams.input) {\n        return new Response(\"Input parameters required for initial actor setup\", {\n          status: 400,\n        });\n      }\n\n      let input: Record<string, unknown> = {};\n      if (searchParams.input) {\n        try {\n          input = schemas.inputProps.parse(JSON.parse(searchParams.input));\n        } catch (error: unknown) {\n          return new Response(`Invalid input: ${getErrorMessage(error)}`, {\n            status: 400,\n          });\n        }\n      }\n\n      const caller = await this.#getValidatedCaller(request, actorType, actorId);\n      if (!caller) {\n        return new Response(\"Unauthorized\", { status: 401 });\n      }\n\n      await this.#storeActorData(actorType, actorId, caller, input);\n      this.actorType = actorType;\n      this.actorId = actorId;\n      this.initialCaller = caller;\n      this.input = input;\n\n      return null;\n    }\n\n    async #getValidatedCaller(\n      request: Request,\n      actorType: string,\n      actorId: string\n    ): Promise<Caller | null> {\n      try {\n        return await getCallerFromRequest(\n          request,\n          actorType,\n          actorId,\n          this.env.ACTOR_KIT_SECRET\n        );\n      } catch {\n        return null;\n      }\n    }\n\n    async #storeActorData(\n      actorType: string,\n      actorId: string,\n      caller: Caller,\n      input: Record<string, unknown>\n    ) {\n      await Promise.all([\n        this.storage.put(\"actorType\", actorType),\n        this.storage.put(\"actorId\", actorId),\n        this.storage.put(\"initialCaller\", JSON.stringify(caller)),\n        this.storage.put(\"input\", JSON.stringify(input)),\n      ]);\n    }\n\n    #isActorRunning() {\n      return Boolean(this.actorType);\n    }\n\n    async fetch(request: Request): Promise<Response> {\n      const url = new URL(request.url);\n      const clientChecksum = url.searchParams.get(\"checksum\");\n\n      if (!this.#isActorRunning()) {\n        const setupError = await this.#setupActorFromRequest(request);\n        if (setupError) {\n          return setupError;\n        }\n      }\n\n      this.#ensureActorRunning();\n      assert(this.actorType, \"actorType is not set\");\n      assert(this.actorId, \"actorId is not set\");\n\n      const webSocketPair = new WebSocketPair();\n      const client = webSocketPair[0];\n      const server = webSocketPair[1] as ActorKitWebSocket;\n\n      const caller = await this.#getValidatedCaller(\n        request,\n        this.actorType,\n        this.actorId\n      );\n      if (!caller) {\n        return new Response(\"Unauthorized\", { status: 401 });\n      }\n\n      this.state.acceptWebSocket(server);\n      server.serializeAttachment({\n        caller,\n        lastSentChecksum: clientChecksum ?? undefined,\n      });\n      this.#subscribeSocketToActor(server);\n\n      return new Response(null, {\n        status: 101,\n        webSocket: client,\n      } as WebSocketResponseInit);\n    }\n\n    async webSocketMessage(ws: WebSocket, message: ArrayBuffer | string) {\n      const attachment = this.attachments.get(ws);\n      assert(attachment, \"Attachment missing for WebSocket\");\n\n      const messageString =\n        typeof message === \"string\"\n          ? message\n          : new TextDecoder().decode(message);\n      const parsedMessage = ParsedMessageSchema.parse(messageString);\n\n      if (attachment.caller.type === \"client\") {\n        const clientEvent = schemas.clientEvent.parse(parsedMessage);\n        this.send({\n          ...clientEvent,\n          caller: attachment.caller,\n        } as ClientEventFrom<TMachine>);\n        return;\n      }\n\n      if (attachment.caller.type === \"service\") {\n        const serviceEvent = schemas.serviceEvent.parse(parsedMessage);\n        this.send({\n          ...serviceEvent,\n          caller: attachment.caller,\n        } as ServiceEventFrom<TMachine>);\n        return;\n      }\n\n      throw new Error(`Unknown caller type: ${attachment.caller.type}`);\n    }\n\n    async webSocketError(_ws: WebSocket, _error: Error) {\n      // No-op; the runtime closes the socket for us.\n    }\n\n    async webSocketClose(\n      ws: WebSocket,\n      code: number,\n      _reason: string,\n      _wasClean: boolean\n    ) {\n      ws.close(code, \"Durable Object is closing WebSocket\");\n      const subscription = this.subscriptions.get(ws);\n      if (subscription) {\n        subscription.unsubscribe();\n        this.subscriptions.delete(ws);\n      }\n      this.attachments.delete(ws);\n      this.#sendQueues.delete(ws);\n    }\n\n    send(event: ClientEventFrom<TMachine> | ServiceEventFrom<TMachine>) {\n      assert(this.actor, \"Actor is not running\");\n      this.actor.send({\n        ...event,\n        env: this.env,\n        storage: this.storage,\n      });\n    }\n\n    async getSnapshot(\n      caller: Caller,\n      options?: {\n        waitForEvent?: ClientEventFrom<TMachine>;\n        waitForState?: StateValueFrom<TMachine>;\n        timeout?: number;\n        errorOnWaitTimeout?: boolean;\n      }\n    ): Promise<{\n      checksum: string;\n      snapshot: CallerSnapshotFrom<TMachine>;\n    }> {\n      this.#ensureActorRunning();\n\n      if (!options?.waitForEvent && !options?.waitForState) {\n        return await this.#getCurrentSnapshot(caller);\n      }\n\n      const timeoutPromise = new Promise<{\n        checksum: string;\n        snapshot: CallerSnapshotFrom<TMachine>;\n      }>((resolve, reject) => {\n        setTimeout(async () => {\n          if (options.errorOnWaitTimeout !== false) {\n            reject(new Error(\"Timeout waiting for event or state\"));\n          } else {\n            resolve(await this.#getCurrentSnapshot(caller));\n          }\n        }, options.timeout ?? 5000);\n      });\n\n      const waitPromise = new Promise<{\n        checksum: string;\n        snapshot: CallerSnapshotFrom<TMachine>;\n      }>((resolve) => {\n        const subscription = this.actor?.subscribe(async (snapshot) => {\n          if (\n            (options.waitForEvent &&\n              this.#matchesEvent(snapshot, options.waitForEvent)) ||\n            (options.waitForState &&\n              this.#matchesState(snapshot, options.waitForState))\n          ) {\n            subscription?.unsubscribe();\n            resolve(await this.#getCurrentSnapshot(caller));\n          }\n        });\n      });\n\n      return Promise.race([waitPromise, timeoutPromise]);\n    }\n\n    async #getCurrentSnapshot(caller: Caller) {\n      const fullSnapshot = this.actor?.getSnapshot();\n      assert(fullSnapshot, \"Actor snapshot is not available\");\n      return {\n        snapshot: this.#createCallerSnapshot(fullSnapshot, caller.id),\n        checksum: await this.#calculateChecksum(fullSnapshot),\n      };\n    }\n\n    #matchesEvent(\n      _snapshot: SnapshotFrom<TMachine>,\n      _event: ClientEventFrom<TMachine>\n    ) {\n      return true;\n    }\n\n    #matchesState(\n      snapshot: SnapshotFrom<TMachine>,\n      stateValue: StateValueFrom<TMachine>\n    ) {\n      return matchesState(stateValue, snapshot);\n    }\n\n    async #calculateChecksum(snapshot: SnapshotFrom<TMachine>) {\n      const str = JSON.stringify(snapshot);\n      const buffer = new TextEncoder().encode(str);\n      const hash = await crypto.subtle.digest(\"SHA-256\", buffer);\n      const array = new Uint8Array(hash);\n      return Array.from(array, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n    }\n\n    #createCallerSnapshot(\n      fullSnapshot: SnapshotFrom<TMachine>,\n      callerId: string\n    ): CallerSnapshotFrom<TMachine> {\n      const snapshot = fullSnapshot as unknown as ActorKitSnapshotView<TMachine>;\n      assert(snapshot.value, \"expected value\");\n      assert(snapshot.context.public, \"expected public key in context\");\n      assert(snapshot.context.private, \"expected private key in context\");\n      return {\n        public: snapshot.context.public,\n        private:\n          snapshot.context.private[callerId] ??\n          ({} as CallerSnapshotFrom<TMachine>[\"private\"]),\n        value: snapshot.value,\n      };\n    }\n\n    async spawn(props: {\n      actorType: string;\n      actorId: string;\n      caller: Caller;\n      input: Record<string, unknown>;\n    }) {\n      if (this.actorType || this.actorId || this.initialCaller) {\n        return;\n      }\n\n      await this.#storeActorData(\n        props.actorType,\n        props.actorId,\n        props.caller,\n        props.input\n      );\n      this.actorType = props.actorType;\n      this.actorId = props.actorId;\n      this.initialCaller = props.caller;\n      this.input = props.input;\n      this.#ensureActorRunning();\n    }\n\n    #scheduleSnapshotCacheCleanup(checksum: string) {\n      setTimeout(() => {\n        this.#cleanupSnapshotCache(checksum);\n      }, 300000);\n    }\n\n    #startPeriodicCacheCleanup() {\n      setInterval(() => {\n        const now = Date.now();\n        for (const [checksum, { timestamp }] of this.snapshotCache.entries()) {\n          if (now - timestamp > 300000) {\n            this.snapshotCache.delete(checksum);\n          }\n        }\n      }, 300000);\n    }\n\n    #cleanupSnapshotCache(checksum: string) {\n      if (checksum === this.currentChecksum) {\n        return;\n      }\n\n      const cachedData = this.snapshotCache.get(checksum);\n      if (cachedData && Date.now() - cachedData.timestamp > 300000) {\n        this.snapshotCache.delete(checksum);\n      }\n    }\n\n    async loadPersistedSnapshot(): Promise<SnapshotFrom<TMachine> | null> {\n      const snapshotString = await this.storage.get(PERSISTED_SNAPSHOT_KEY);\n      return snapshotString\n        ? (JSON.parse(z.string().parse(snapshotString)) as SnapshotFrom<TMachine>)\n        : null;\n    }\n\n    restorePersistedActor(persistedSnapshot: SnapshotFrom<TMachine>) {\n      assert(this.actorId, \"actorId is not set\");\n      assert(this.actorType, \"actorType is not set\");\n      assert(this.initialCaller, \"initialCaller is not set\");\n      assert(this.input, \"input is not set\");\n\n      const input = {\n        id: this.actorId,\n        caller: this.initialCaller,\n        storage: this.storage,\n        env: this.env,\n        ...this.input,\n      } as InputFrom<TMachine>;\n\n      const migrations = xstateMigrate.generateMigrations(\n        machine,\n        persistedSnapshot,\n        input\n      );\n      const restoredSnapshot = xstateMigrate.applyMigrations(\n        persistedSnapshot,\n        migrations\n      );\n\n      this.actor = createActor(machine, {\n        snapshot: restoredSnapshot,\n        input,\n      });\n\n      if (options?.persisted) {\n        this.#setupStatePersistence(this.actor);\n      }\n\n      this.actor.start();\n      this.actor.send({\n        type: \"RESUME\",\n        caller: { id: this.actorId, type: \"system\" },\n        env: this.env,\n        storage: this.storage,\n      } as EventFromLogic<TMachine>);\n\n      this.lastPersistedSnapshot = restoredSnapshot as SnapshotFrom<TMachine>;\n    }\n  };\n","/**\n * fromActorKit — XState callback actor for DO-to-DO communication.\n *\n * Creates an XState `fromCallback` actor that connects a parent actor-kit\n * Durable Object to a remote child actor-kit DO via WebSocket. The callback:\n *\n * 1. Spawns the remote DO (idempotent)\n * 2. Creates a JWT for the remote actor\n * 3. Opens a WebSocket via stub.fetch() with Upgrade header\n * 4. Receives JSON Patch snapshot updates → emits {TYPE}_UPDATED to parent\n * 5. Forwards events from parent → remote DO (validated via Zod schema)\n * 6. Queues events sent before WebSocket is ready\n * 7. Cleans up WebSocket on actor stop\n *\n * @example\n * ```ts\n * const sessionMachine = setup({\n *   actors: {\n *     zone: fromActorKit<ZoneMachine>(\"zone\"),\n *   },\n * }).createMachine({\n *   invoke: {\n *     id: \"zone\",\n *     src: \"zone\",\n *     input: ({ context }) => ({\n *       server: context.env.ZONE,\n *       actorId: context.public.zoneId,\n *       actorInput: {},\n *       caller: { id: context.public.playerId, type: \"service\" as const },\n *       signingKey: context.env.ACTOR_KIT_SECRET,\n *       eventSchema: ZoneServiceEventSchema,\n *     }),\n *   },\n *   on: { ZONE_UPDATED: { actions: \"syncZoneSnapshot\" } },\n * });\n * ```\n *\n * @module\n */\nimport { applyPatch } from \"fast-json-patch\";\nimport type { Operation } from \"fast-json-patch\";\nimport { produce } from \"immer\";\nimport type { CallbackLogicFunction } from \"xstate\";\nimport { fromCallback } from \"xstate\";\nimport type { z } from \"zod\";\nimport { createAccessToken } from \"./createAccessToken\";\nimport { EmittedEventSchema } from \"./schemas\";\nimport type {\n  AnyActorKitStateMachine,\n  Caller,\n  CallerSnapshotFrom,\n} from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Convert kebab-case to SCREAMING_SNAKE: `\"my-actor\"` → `\"MY_ACTOR\"` */\ntype KebabToScreamingSnake<S extends string> = string extends S\n  ? string\n  : S extends `${infer Head}-${infer Tail}`\n    ? `${Uppercase<Head>}_${KebabToScreamingSnake<Tail>}`\n    : Uppercase<S>;\n\n/** Events emitted back to the parent machine. */\nexport type FromActorKitEmitted<\n  TActorType extends string,\n  TMachine extends AnyActorKitStateMachine,\n> =\n  | {\n      type: `${KebabToScreamingSnake<TActorType>}_UPDATED`;\n      actorType: TActorType;\n      actorId: string;\n      snapshot: CallerSnapshotFrom<TMachine>;\n      operations: Operation[];\n    }\n  | {\n      type: `${KebabToScreamingSnake<TActorType>}_ERROR`;\n      actorType: TActorType;\n      actorId: string;\n      error: Error;\n    };\n\n/**\n * Minimal interface for a DO namespace — compatible with both\n * `DurableObjectNamespace` (untyped) and `DurableObjectNamespace<T>` (RPC-typed).\n */\nexport interface ActorKitNamespaceLike {\n  idFromName(name: string): unknown;\n  get(id: unknown): {\n    fetch(request: Request): Promise<Response>;\n    spawn?(props: {\n      actorType: string;\n      actorId: string;\n      caller: Caller;\n      input: Record<string, unknown>;\n    }): Promise<void> | void;\n    [key: string]: unknown;\n  };\n}\n\n/** Input the parent must provide when invoking the callback actor. */\nexport interface FromActorKitInput<\n  TEventSchema extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n  /** DO namespace binding for the remote actor (e.g. `env.ZONE`). */\n  server: ActorKitNamespaceLike;\n  /** ID of the remote actor instance. */\n  actorId: string;\n  /** Input props forwarded to the remote actor on spawn. */\n  actorInput: Record<string, unknown>;\n  /** Caller identity used for JWT signing. */\n  caller: Caller;\n  /** Secret key used to sign the JWT. */\n  signingKey: string;\n  /** Zod schema that validates events before forwarding to the remote DO. */\n  eventSchema: TEventSchema;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction toScreamingSnake(s: string): string {\n  return s.replace(/-/g, \"_\").toUpperCase();\n}\n\n// ---------------------------------------------------------------------------\n// Main export\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an XState callback actor that bridges a parent actor-kit DO\n * to a remote child actor-kit DO via WebSocket.\n *\n * @param actorType — kebab-case actor type name (e.g. `\"zone\"`)\n */\nexport function fromActorKit<\n  TMachine extends AnyActorKitStateMachine,\n  TActorType extends string = string,\n>(actorType: TActorType) {\n  type TEmitted = FromActorKitEmitted<TActorType, TMachine>;\n\n  const TYPE = toScreamingSnake(actorType);\n\n  function emitUpdated(\n    emitActorType: TActorType,\n    actorId: string,\n    snapshot: CallerSnapshotFrom<TMachine>,\n    operations: Operation[],\n  ): TEmitted {\n    return {\n      type: `${TYPE}_UPDATED`,\n      actorType: emitActorType,\n      actorId,\n      snapshot,\n      operations,\n    } as TEmitted;\n  }\n\n  function emitError(\n    emitActorType: TActorType,\n    actorId: string,\n    error: Error,\n  ): TEmitted {\n    return {\n      type: `${TYPE}_ERROR`,\n      actorType: emitActorType,\n      actorId,\n      error,\n    } as TEmitted;\n  }\n\n  const callback: CallbackLogicFunction<\n    Record<string, unknown> & { type: string }, // events parent can send\n    TEmitted, // events sent back to parent\n    FromActorKitInput // input\n  > = ({ sendBack, receive, input }) => {\n    let ws: WebSocket | null = null;\n    const pendingEvents: string[] = [];\n\n    // Async setup — spawn, auth, connect\n    (async () => {\n      try {\n        const id = input.server.idFromName(input.actorId);\n        const stub = input.server.get(id);\n\n        // 1. Spawn remote actor (idempotent) via RPC\n        if (stub.spawn) {\n          await Promise.resolve(\n            stub.spawn({\n              actorType,\n              actorId: input.actorId,\n              caller: input.caller,\n              input: input.actorInput,\n            })\n          );\n        }\n\n        // 2. Create JWT\n        const accessToken = await createAccessToken({\n          signingKey: input.signingKey,\n          actorId: input.actorId,\n          actorType,\n          callerId: input.caller.id,\n          callerType: input.caller.type,\n        });\n\n        // 3. Open WebSocket via fetch upgrade\n        const response = await stub.fetch(\n          new Request(\n            `https://internal/api/${actorType}/${input.actorId}/?accessToken=${accessToken}`,\n            { headers: { Upgrade: \"websocket\" } }\n          )\n        );\n\n        const webSocket = response.webSocket;\n        if (!webSocket) {\n          throw new Error(\n            `WebSocket upgrade failed for ${actorType}/${input.actorId}`\n          );\n        }\n\n        webSocket.accept();\n        ws = webSocket;\n\n        // 4. Track snapshot via patches\n        let currentSnapshot: CallerSnapshotFrom<TMachine> | undefined;\n\n        ws.addEventListener(\"message\", (event: MessageEvent) => {\n          try {\n            const raw =\n              typeof event.data === \"string\"\n                ? event.data\n                : new TextDecoder().decode(event.data);\n            const data = EmittedEventSchema.parse(JSON.parse(raw));\n\n            currentSnapshot = produce(\n              currentSnapshot ?? ({} as CallerSnapshotFrom<TMachine>),\n              (draft) => {\n                applyPatch(draft, data.operations);\n              }\n            );\n\n            sendBack(emitUpdated(actorType, input.actorId, currentSnapshot, data.operations));\n          } catch (err) {\n            console.error(\n              `[fromActorKit:${actorType}] message error:`,\n              err\n            );\n          }\n        });\n\n        ws.addEventListener(\"error\", () => {\n          sendBack(emitError(actorType, input.actorId, new Error(`WebSocket error for ${actorType}/${input.actorId}`)));\n        });\n\n        // Handle normal close (e.g., child DO eviction/restart)\n        ws.addEventListener(\"close\", (event: CloseEvent) => {\n          ws = null;\n          sendBack(emitError(\n            actorType,\n            input.actorId,\n            new Error(`WebSocket closed for ${actorType}/${input.actorId}: code=${event.code} reason=${event.reason}`)\n          ));\n        });\n\n        // 5. Flush queued events\n        while (pendingEvents.length > 0) {\n          ws.send(pendingEvents.shift()!);\n        }\n      } catch (err) {\n        console.error(`[fromActorKit:${actorType}] setup error:`, err);\n        sendBack(emitError(\n          actorType,\n          input.actorId,\n          err instanceof Error\n            ? err\n            : new Error(`Setup failed for ${actorType}/${input.actorId}`)\n        ));\n      }\n    })();\n\n    // 6. Forward validated events from parent → remote DO\n    receive((event) => {\n      const result = input.eventSchema.safeParse(event);\n      if (!result.success) return; // not meant for this actor\n\n      const serialized = JSON.stringify(result.data);\n      if (ws) {\n        ws.send(serialized);\n      } else {\n        pendingEvents.push(serialized);\n      }\n    });\n\n    // 7. Cleanup\n    return () => {\n      if (ws) {\n        try {\n          ws.close(1000, \"Actor stopped\");\n        } catch {\n          // ignore\n        }\n        ws = null;\n      }\n    };\n  };\n\n  return fromCallback(callback);\n}\n"],"mappings":";;;;;;;;;;AAiGA,SAAgB,OACd,YACA,cACoB;AACpB,KAAI,CAAC,YAAY;EAEf,MAAM,QADQ,IAAI,MAAM,aAAa,CACjB,OAAO,MAAM,KAAK;EAItC,MAAM,aACJ,SAAS,MAAM,UAAU,IAAI,MAAM,KAAK;AAE1C,QAAM,IAAI,MAAM,GAAG,aAAa,qBAAqB,YAAY,MAAM,CAAC,GAAG;;;AAI/E,eAAsB,qBACpB,SACA,WACA,SACA,QACiB;CACjB,IAAI;AACJ,KAAI,QAAQ,QAAQ,IAAI,UAAU,KAAK,aAAa;EAElD,MAAM,aADa,QAAQ,QAAQ,IAAI,gBAAgB,EACxB,MAAM,IAAI,CAAC;AAC1C,SAAO,YAAY,0CAA0C;AAC7D,gBAAc;QACT;EAEL,MAAM,cADe,IAAI,gBAAgB,QAAQ,IAAI,MAAM,IAAI,CAAC,GAAG,CAClC,IAAI,cAAc;AACnD,SAAO,aAAa,iDAAiD;AACrE,gBAAc;;AAGhB,QAAO,0BAA0B;EAC/B;EACA,MAAM;EACN,IAAI;EACJ;EACD,CAAC;;AAGJ,eAAsB,0BAA0B,EAC9C,aACA,MACA,IACA,UAMkB;CAClB,MAAM,WAAW,MAAM,UAAU,aAAa,IAAI,aAAa,CAAC,OAAO,OAAO,CAAC;AAC/E,KAAI,CAAC,SAAS,QAAQ,IACpB,OAAM,IAAI,MAAM,8BAA8B;AAEhD,KAAI,SAAS,QAAQ,QAAQ,GAC3B,OAAM,IAAI,MAAM,kDAAkD,KAAK;AAEzE,KAAI,CAAC,SAAS,QAAQ,IACpB,OAAM,IAAI,MACR,sDAAsD,OACvD;AAKH,KAAI,EAHa,MAAM,QAAQ,SAAS,QAAQ,IAAI,GAChD,SAAS,QAAQ,MACjB,CAAC,SAAS,QAAQ,IAAI,EACZ,SAAS,KAAK,CAC1B,OAAM,IAAI,MACR,sDAAsD,OACvD;AAEH,KAAI,CAAC,SAAS,QAAQ,IACpB,OAAM,IAAI,MAAM,uCAAuC;AAEzD,QAAO,mBAAmB,MAAM,SAAS,QAAQ,IAAI;;;;ACpKvD,MAAM,8BAA8B,EAAE,OAAO;CAC3C,cAAc,EAAE,QAAQ,CAAC,UAAU;CACnC,cAAc,EAAE,QAAQ,CAAC,UAAU;CACnC,SAAS,EACN,QAAQ,CACR,WAAW,UAAU,OAAO,SAAS,OAAO,GAAG,CAAC,CAChD,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CACjC,UAAU;CACb,oBAAoB,EACjB,KAAK,CAAC,QAAQ,QAAQ,CAAC,CACvB,WAAW,UAAU,UAAU,OAAO,CACtC,UAAU;CACd,CAAC;AA8BF,MAAa,wBACX,WACG;CAIH,MAAM,gCAAgB,IAAI,KAAa;CAEvC,SAAS,0BAGP,KACA,KAC+B;EAE/B,MAAM,YAAY,IADH,IAAI,aAAa;AAEhC,MACE,aACA,OAAO,cAAc,YACrB,SAAS,aACT,gBAAgB,UAEhB,QAAO;;AAKX,QAAO,OACL,SACA,KACA,SACsB;EAEtB,MAAM,YADM,IAAI,IAAI,QAAQ,IAAI,CACV,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ;AACzD,MAAI,UAAU,WAAW,KAAK,UAAU,OAAO,MAC7C,QAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,KAAK,CAAC;EAEnD,MAAM,GAAG,WAAW,WAAW;AAE/B,MAAI,CAAC,OAAO,SAAS,UAAuB,CAC1C,QAAO,IAAI,SAAS,uBAAuB,aAAa,EAAE,QAAQ,KAAK,CAAC;EAG1E,MAAM,yBAAyB,0BAC7B,KACA,UACD;AAED,MAAI,CAAC,uBACH,QAAO,IAAI,SACT,sDAAsD,aACtD,EAAE,QAAQ,KAAK,CAChB;EAGH,MAAM,kBAAkB,uBAAuB,WAAW,QAAQ;EAClE,MAAM,oBAAoB,uBAAuB,IAAI,gBAAgB;EAGrE,IAAI;AACJ,MAAI;AACF,YAAS,MAAM,qBACb,SACA,WACA,SACA,IAAI,iBACL;WACM,OAAgB;GACvB,MAAM,eACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,UAAO,IAAI,SACT,UAAU,aAAa,iLACvB,EAAE,QAAQ,KAAK,CAChB;;EAIH,MAAM,WAAW,GAAG,UAAU,GAAG;AAGjC,MAAI,CAAC,cAAc,IAAI,SAAS,EAAE;AAEhC,SAAM,kBAAkB,MAAM;IAC5B;IACA;IACA;IACA,OAAO,EAAE;IACV,CAAC;AACF,iBAAc,IAAI,SAAS;;AAG7B,MAAI,QAAQ,QAAQ,IAAI,UAAU,KAAK,YACrC,QAAO,kBAAkB,MAAM,QAAQ;AAGzC,MAAI,QAAQ,WAAW,OAAO;GAC5B,IAAI;AACJ,OAAI;AACF,mBAAe,4BAA4B,MACzC,OAAO,YAAY,IAAI,IAAI,QAAQ,IAAI,CAAC,aAAa,CACtD;YACM,OAAgB;IACvB,MAAM,eACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,WAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,cAAc,CAAC,EAAE,EAC3D,QAAQ,KACT,CAAC;;GAGJ,MAAM,SAAS,MAAM,kBAAkB,YAAY,QAAQ;IACzD,cAAc,aAAa,eACvB,eAAe,MAAM,KAAK,MAAM,aAAa,aAAa,CAAC,GAC3D,KAAA;IACJ,cAAc,aAAa,eACvB,KAAK,MAAM,aAAa,aAAa,GACrC,KAAA;IACJ,SAAS,aAAa;IACtB,oBAAoB,aAAa;IAClC,CAAC;AACF,UAAO,IAAI,SAAS,KAAK,UAAU,OAAO,EAAE,EAC1C,SAAS,EAAE,gBAAgB,oBAAoB,EAChD,CAAC;aACO,QAAQ,WAAW,QAAQ;GACpC,IAAI;AACJ,OAAI;IACF,MAAM,OAAO,MAAM,QAAQ,MAAM;AACjC,YAAQ,eAAe,MAAM,KAAK;YAC3B,IAAa;IACpB,MAAM,eAAe,cAAc,QAAQ,GAAG,UAAU;AACxD,WAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,cAAc,CAAC,EAAE,EAC3D,QAAQ,KACT,CAAC;;AAGJ,qBAAkB,KAAK;IACrB,GAAG;IACH;IACD,CAAC;AACF,UAAO,IAAI,SAAS,KAAK,UAAU,EAAE,SAAS,MAAM,CAAC,CAAC;QAEtD,QAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,sBAAsB,CAAC,EAAE,EACnE,QAAQ,KACT,CAAC;;;;;AC/KR,MAAa,yBAAyB;;;ACUtC,MAAM,gBAAgB,EAAE,OAAO;CAC7B,WAAW,EAAE,QAAQ;CACrB,SAAS,EAAE,QAAQ;CACnB,eAAe;CACf,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC;CAC7B,CAAC;AAEF,MAAM,4BAA4B,EAAE,OAAO;CACzC,QAAQ;CACR,kBAAkB,EAAE,QAAQ,CAAC,UAAU;CACxC,CAAC;AAqBF,MAAM,oBAAoB,EAAE,OAAO,EACjC,OAAO,EAAE,QAAQ,CAAC,UAAU,EAC7B,CAAC;AAEF,MAAM,sBAAsB,EAAE,QAAQ,CAAC,WAAW,OAAO,YAAY;AACnE,KAAI;AACF,SAAO,KAAK,MAAM,MAAM;SAClB;AACN,UAAQ,SAAS;GACf,MAAM,EAAE,aAAa;GACrB,SAAS;GACV,CAAC;AACF,SAAO,EAAE;;EAEX;AAEF,SAAS,gBAAgB,OAAwB;AAC/C,QAAO,iBAAiB,QAAQ,MAAM,UAAU;;AAGlD,SAAS,gBAAmB,OAAgB,gBAAiC;CAC3E,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,MAAM;AAC5C,QAAO,eAAe,MAAM,KAAK,MAAM,aAAa,CAAC;;AAGvD,MAAa,uBAKX,EACA,SACA,SACA,cAaA,MAAM,0BAA0B,cAA+C;CAC7E;CACA;CACA;CACA;CACA;CACA,wBAAuD;CACvD,gCAAgB,IAAI,KAGjB;CACH;CACA;CACA,8BAAc,IAAI,KAAqC;CACvD,gCAAgB,IAAI,KAA8B;CAClD,8BAAc,IAAI,KAA+B;CACjD;CACA,kBAAiC;CAEjC,YAAY,OAA2B,KAA+B;AACpE,QAAM,OAAO,IAAI;AACjB,OAAK,QAAQ;AACb,OAAK,UAAU,MAAM;AACrB,OAAK,MAAM;AAEX,OAAK,MAAM,sBAAsB,YAAY;GAC3C,MAAM,CAAC,WAAW,SAAS,qBAAqB,eAC9C,MAAM,QAAQ,IAAI;IAChB,KAAK,QAAQ,IAAI,YAAY;IAC7B,KAAK,QAAQ,IAAI,UAAU;IAC3B,KAAK,QAAQ,IAAI,gBAAgB;IACjC,KAAK,QAAQ,IAAI,QAAQ;IAC1B,CAAC;AAEJ,OAAI,aAAa,WAAW,uBAAuB,YACjD,KAAI;IACF,MAAM,aAAa,cAAc,MAAM;KACrC;KACA;KACA,eAAe,gBAAgB,qBAAqB,aAAa;KACjE,OAAO,gBAAgB,aAAa,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;KAC3D,CAAC;AAEF,SAAK,YAAY,WAAW;AAC5B,SAAK,UAAU,WAAW;AAC1B,SAAK,gBAAgB,WAAW;AAChC,SAAK,QAAQ,WAAW;AAExB,QAAI,SAAS,WAAW;KACtB,MAAM,oBAAoB,MAAM,KAAK,uBAAuB;AAC5D,SAAI,kBACF,MAAK,sBAAsB,kBAAkB;SAE7C,OAAA,oBAA0B;UAG5B,OAAA,oBAA0B;WAEtB;AAKV,QAAK,MAAM,UAAU,KAAK,MAAM,eAAe,CAC7C,OAAA,uBAA6B,OAAO;IAEtC;AAEF,QAAA,2BAAiC;;CAGnC,sBAAsB;AACpB,SAAO,KAAK,SAAS,qBAAqB;AAC1C,SAAO,KAAK,WAAW,uBAAuB;AAC9C,SAAO,KAAK,OAAO,mBAAmB;AACtC,SAAO,KAAK,eAAe,2BAA2B;AAEtD,MAAI,CAAC,KAAK,OAAO;AASf,QAAK,QAAQ,YAAY,SAAS,EAChC,OATY;IACZ,IAAI,KAAK;IACT,QAAQ,KAAK;IACb,KAAK,KAAK;IACV,SAAS,KAAK;IACd,GAAG,KAAK;IACT,EAIA,CAAC;AAEF,OAAI,SAAS,UACX,OAAA,sBAA4B,KAAK,MAAM;AAGzC,QAAK,MAAM,OAAO;;AAGpB,SAAO,KAAK;;CAGd,wBAAwB,IAAe;AACrC,MAAI;GACF,MAAM,SAAS;GACf,MAAM,aAAa,0BAA0B,MAC3C,OAAO,uBAAuB,CAC/B;AACD,QAAK,YAAY,IAAI,QAAQ,WAAW;AACxC,SAAA,uBAA6B,OAAO;GAEpC,MAAM,eAAe,KAAK,OAAO,gBAAgB;AAC/C,UAAA,uBAA6B,OAAO;KACpC;AAEF,OAAI,aACF,MAAK,cAAc,IAAI,QAAQ,aAAa;UAExC;;CAKV,wBAAwB,IAAuB;EAC7C,MAAM,OAAO,MAAA,WAAiB,IAAI,GAAG;EAIrC,MAAM,QAHW,OACb,KAAK,WAAW,MAAA,gBAAsB,GAAG,CAAC,GAC1C,MAAA,gBAAsB,GAAG,EACP,YAAY,GAEhC;AACF,QAAA,WAAiB,IAAI,IAAI,KAAK;;CAGhC,OAAA,gBAAuB,IAAuB;AAC5C,SAAO,KAAK,OAAO,uBAAuB;EAC1C,MAAM,aAAa,KAAK,YAAY,IAAI,GAAG;AAC3C,SAAO,YAAY,mCAAmC;EAEtD,MAAM,eAAe,KAAK,MAAM,aAAa;EAC7C,MAAM,kBAAkB,MAAM,MAAA,kBAAwB,aAAa;AAEnE,OAAK,cAAc,IAAI,iBAAiB;GACtC,UAAU;GACV,WAAW,KAAK,KAAK;GACtB,CAAC;AACF,QAAA,6BAAmC,gBAAgB;AACnD,OAAK,kBAAkB;AAEvB,MAAI,WAAW,qBAAqB,gBAClC;EAGF,MAAM,eAAe,MAAA,qBACnB,cACA,WAAW,OAAO,GACnB;EAED,IAAI,eAA6C,EAAE;AACnD,MAAI,WAAW,kBAAkB;GAC/B,MAAM,iBAAiB,KAAK,cAAc,IAAI,WAAW,iBAAiB;AAC1E,OAAI,eACF,gBAAe,MAAA,qBACb,eAAe,UACf,WAAW,OAAO,GACnB;;EAIL,MAAM,aAAa,QAAQ,cAAc,aAAa;AACtD,MAAI,WAAW,WAAW,EACxB;AAGF,KAAG,KAAK,KAAK,UAAU;GAAE;GAAY,UAAU;GAAiB,CAAC,CAAC;AAClE,aAAW,mBAAmB;AAC9B,KAAG,oBAAoB,WAAW;;CAGpC,uBAAuB,OAAwB;AAC7C,QAAM,gBAAgB;GACpB,MAAM,eAAe,MAAM,aAAa;AACxC,SAAA,gBAAsB,aAAa,CAAC,YAAY,GAE9C;IACF;;CAGJ,OAAA,gBAAuB,UAAkC;AACvD,MACE,KAAK,yBACL,QAAQ,KAAK,uBAAuB,SAAS,CAAC,WAAW,EAEzD;AAGF,QAAM,KAAK,QAAQ,IAAI,wBAAwB,KAAK,UAAU,SAAS,CAAC;AACxE,OAAK,wBAAwB;;CAG/B,OAAA,sBAA6B,SAA4C;EACvE,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;EAChC,MAAM,eAAe,kBAAkB,MACrC,OAAO,YAAY,IAAI,aAAa,CACrC;EAED,MAAM,GAAG,WAAW,WADF,IAAI,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ;AAGzD,MAAI,CAAC,aAAa,CAAC,QACjB,QAAO,IAAI,SAAS,sBAAsB,EAAE,QAAQ,KAAK,CAAC;AAO5D,MAJ0B,OAAO,OAAO,QAAQ,WAAW,MAAM,CAAC,MAC/D,UAAU,CAAC,MAAM,YAAY,CAC/B,IAEwB,CAAC,aAAa,MACrC,QAAO,IAAI,SAAS,qDAAqD,EACvE,QAAQ,KACT,CAAC;EAGJ,IAAI,QAAiC,EAAE;AACvC,MAAI,aAAa,MACf,KAAI;AACF,WAAQ,QAAQ,WAAW,MAAM,KAAK,MAAM,aAAa,MAAM,CAAC;WACzD,OAAgB;AACvB,UAAO,IAAI,SAAS,kBAAkB,gBAAgB,MAAM,IAAI,EAC9D,QAAQ,KACT,CAAC;;EAIN,MAAM,SAAS,MAAM,MAAA,mBAAyB,SAAS,WAAW,QAAQ;AAC1E,MAAI,CAAC,OACH,QAAO,IAAI,SAAS,gBAAgB,EAAE,QAAQ,KAAK,CAAC;AAGtD,QAAM,MAAA,eAAqB,WAAW,SAAS,QAAQ,MAAM;AAC7D,OAAK,YAAY;AACjB,OAAK,UAAU;AACf,OAAK,gBAAgB;AACrB,OAAK,QAAQ;AAEb,SAAO;;CAGT,OAAA,mBACE,SACA,WACA,SACwB;AACxB,MAAI;AACF,UAAO,MAAM,qBACX,SACA,WACA,SACA,KAAK,IAAI,iBACV;UACK;AACN,UAAO;;;CAIX,OAAA,eACE,WACA,SACA,QACA,OACA;AACA,QAAM,QAAQ,IAAI;GAChB,KAAK,QAAQ,IAAI,aAAa,UAAU;GACxC,KAAK,QAAQ,IAAI,WAAW,QAAQ;GACpC,KAAK,QAAQ,IAAI,iBAAiB,KAAK,UAAU,OAAO,CAAC;GACzD,KAAK,QAAQ,IAAI,SAAS,KAAK,UAAU,MAAM,CAAC;GACjD,CAAC;;CAGJ,kBAAkB;AAChB,SAAO,QAAQ,KAAK,UAAU;;CAGhC,MAAM,MAAM,SAAqC;EAE/C,MAAM,iBADM,IAAI,IAAI,QAAQ,IAAI,CACL,aAAa,IAAI,WAAW;AAEvD,MAAI,CAAC,MAAA,gBAAsB,EAAE;GAC3B,MAAM,aAAa,MAAM,MAAA,sBAA4B,QAAQ;AAC7D,OAAI,WACF,QAAO;;AAIX,QAAA,oBAA0B;AAC1B,SAAO,KAAK,WAAW,uBAAuB;AAC9C,SAAO,KAAK,SAAS,qBAAqB;EAE1C,MAAM,gBAAgB,IAAI,eAAe;EACzC,MAAM,SAAS,cAAc;EAC7B,MAAM,SAAS,cAAc;EAE7B,MAAM,SAAS,MAAM,MAAA,mBACnB,SACA,KAAK,WACL,KAAK,QACN;AACD,MAAI,CAAC,OACH,QAAO,IAAI,SAAS,gBAAgB,EAAE,QAAQ,KAAK,CAAC;AAGtD,OAAK,MAAM,gBAAgB,OAAO;AAClC,SAAO,oBAAoB;GACzB;GACA,kBAAkB,kBAAkB,KAAA;GACrC,CAAC;AACF,QAAA,uBAA6B,OAAO;AAEpC,SAAO,IAAI,SAAS,MAAM;GACxB,QAAQ;GACR,WAAW;GACZ,CAA0B;;CAG7B,MAAM,iBAAiB,IAAe,SAA+B;EACnE,MAAM,aAAa,KAAK,YAAY,IAAI,GAAG;AAC3C,SAAO,YAAY,mCAAmC;EAEtD,MAAM,gBACJ,OAAO,YAAY,WACf,UACA,IAAI,aAAa,CAAC,OAAO,QAAQ;EACvC,MAAM,gBAAgB,oBAAoB,MAAM,cAAc;AAE9D,MAAI,WAAW,OAAO,SAAS,UAAU;GACvC,MAAM,cAAc,QAAQ,YAAY,MAAM,cAAc;AAC5D,QAAK,KAAK;IACR,GAAG;IACH,QAAQ,WAAW;IACpB,CAA8B;AAC/B;;AAGF,MAAI,WAAW,OAAO,SAAS,WAAW;GACxC,MAAM,eAAe,QAAQ,aAAa,MAAM,cAAc;AAC9D,QAAK,KAAK;IACR,GAAG;IACH,QAAQ,WAAW;IACpB,CAA+B;AAChC;;AAGF,QAAM,IAAI,MAAM,wBAAwB,WAAW,OAAO,OAAO;;CAGnE,MAAM,eAAe,KAAgB,QAAe;CAIpD,MAAM,eACJ,IACA,MACA,SACA,WACA;AACA,KAAG,MAAM,MAAM,sCAAsC;EACrD,MAAM,eAAe,KAAK,cAAc,IAAI,GAAG;AAC/C,MAAI,cAAc;AAChB,gBAAa,aAAa;AAC1B,QAAK,cAAc,OAAO,GAAG;;AAE/B,OAAK,YAAY,OAAO,GAAG;AAC3B,QAAA,WAAiB,OAAO,GAAG;;CAG7B,KAAK,OAA+D;AAClE,SAAO,KAAK,OAAO,uBAAuB;AAC1C,OAAK,MAAM,KAAK;GACd,GAAG;GACH,KAAK,KAAK;GACV,SAAS,KAAK;GACf,CAAC;;CAGJ,MAAM,YACJ,QACA,SASC;AACD,QAAA,oBAA0B;AAE1B,MAAI,CAAC,SAAS,gBAAgB,CAAC,SAAS,aACtC,QAAO,MAAM,MAAA,mBAAyB,OAAO;EAG/C,MAAM,iBAAiB,IAAI,SAGvB,SAAS,WAAW;AACtB,cAAW,YAAY;AACrB,QAAI,QAAQ,uBAAuB,MACjC,wBAAO,IAAI,MAAM,qCAAqC,CAAC;QAEvD,SAAQ,MAAM,MAAA,mBAAyB,OAAO,CAAC;MAEhD,QAAQ,WAAW,IAAK;IAC3B;EAEF,MAAM,cAAc,IAAI,SAGpB,YAAY;GACd,MAAM,eAAe,KAAK,OAAO,UAAU,OAAO,aAAa;AAC7D,QACG,QAAQ,gBACP,MAAA,aAAmB,UAAU,QAAQ,aAAa,IACnD,QAAQ,gBACP,MAAA,aAAmB,UAAU,QAAQ,aAAa,EACpD;AACA,mBAAc,aAAa;AAC3B,aAAQ,MAAM,MAAA,mBAAyB,OAAO,CAAC;;KAEjD;IACF;AAEF,SAAO,QAAQ,KAAK,CAAC,aAAa,eAAe,CAAC;;CAGpD,OAAA,mBAA0B,QAAgB;EACxC,MAAM,eAAe,KAAK,OAAO,aAAa;AAC9C,SAAO,cAAc,kCAAkC;AACvD,SAAO;GACL,UAAU,MAAA,qBAA2B,cAAc,OAAO,GAAG;GAC7D,UAAU,MAAM,MAAA,kBAAwB,aAAa;GACtD;;CAGH,cACE,WACA,QACA;AACA,SAAO;;CAGT,cACE,UACA,YACA;AACA,SAAO,aAAa,YAAY,SAAS;;CAG3C,OAAA,kBAAyB,UAAkC;EACzD,MAAM,MAAM,KAAK,UAAU,SAAS;EACpC,MAAM,SAAS,IAAI,aAAa,CAAC,OAAO,IAAI;EAC5C,MAAM,OAAO,MAAM,OAAO,OAAO,OAAO,WAAW,OAAO;EAC1D,MAAM,QAAQ,IAAI,WAAW,KAAK;AAClC,SAAO,MAAM,KAAK,QAAQ,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG;;CAG3E,sBACE,cACA,UAC8B;EAC9B,MAAM,WAAW;AACjB,SAAO,SAAS,OAAO,iBAAiB;AACxC,SAAO,SAAS,QAAQ,QAAQ,iCAAiC;AACjE,SAAO,SAAS,QAAQ,SAAS,kCAAkC;AACnE,SAAO;GACL,QAAQ,SAAS,QAAQ;GACzB,SACE,SAAS,QAAQ,QAAQ,aACxB,EAAE;GACL,OAAO,SAAS;GACjB;;CAGH,MAAM,MAAM,OAKT;AACD,MAAI,KAAK,aAAa,KAAK,WAAW,KAAK,cACzC;AAGF,QAAM,MAAA,eACJ,MAAM,WACN,MAAM,SACN,MAAM,QACN,MAAM,MACP;AACD,OAAK,YAAY,MAAM;AACvB,OAAK,UAAU,MAAM;AACrB,OAAK,gBAAgB,MAAM;AAC3B,OAAK,QAAQ,MAAM;AACnB,QAAA,oBAA0B;;CAG5B,8BAA8B,UAAkB;AAC9C,mBAAiB;AACf,SAAA,qBAA2B,SAAS;KACnC,IAAO;;CAGZ,6BAA6B;AAC3B,oBAAkB;GAChB,MAAM,MAAM,KAAK,KAAK;AACtB,QAAK,MAAM,CAAC,UAAU,EAAE,gBAAgB,KAAK,cAAc,SAAS,CAClE,KAAI,MAAM,YAAY,IACpB,MAAK,cAAc,OAAO,SAAS;KAGtC,IAAO;;CAGZ,sBAAsB,UAAkB;AACtC,MAAI,aAAa,KAAK,gBACpB;EAGF,MAAM,aAAa,KAAK,cAAc,IAAI,SAAS;AACnD,MAAI,cAAc,KAAK,KAAK,GAAG,WAAW,YAAY,IACpD,MAAK,cAAc,OAAO,SAAS;;CAIvC,MAAM,wBAAgE;EACpE,MAAM,iBAAiB,MAAM,KAAK,QAAQ,IAAI,uBAAuB;AACrE,SAAO,iBACF,KAAK,MAAM,EAAE,QAAQ,CAAC,MAAM,eAAe,CAAC,GAC7C;;CAGN,sBAAsB,mBAA2C;AAC/D,SAAO,KAAK,SAAS,qBAAqB;AAC1C,SAAO,KAAK,WAAW,uBAAuB;AAC9C,SAAO,KAAK,eAAe,2BAA2B;AACtD,SAAO,KAAK,OAAO,mBAAmB;EAEtC,MAAM,QAAQ;GACZ,IAAI,KAAK;GACT,QAAQ,KAAK;GACb,SAAS,KAAK;GACd,KAAK,KAAK;GACV,GAAG,KAAK;GACT;EAED,MAAM,aAAa,cAAc,mBAC/B,SACA,mBACA,MACD;EACD,MAAM,mBAAmB,cAAc,gBACrC,mBACA,WACD;AAED,OAAK,QAAQ,YAAY,SAAS;GAChC,UAAU;GACV;GACD,CAAC;AAEF,MAAI,SAAS,UACX,OAAA,sBAA4B,KAAK,MAAM;AAGzC,OAAK,MAAM,OAAO;AAClB,OAAK,MAAM,KAAK;GACd,MAAM;GACN,QAAQ;IAAE,IAAI,KAAK;IAAS,MAAM;IAAU;GAC5C,KAAK,KAAK;GACV,SAAS,KAAK;GACf,CAA6B;AAE9B,OAAK,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnjBnC,SAAS,iBAAiB,GAAmB;AAC3C,QAAO,EAAE,QAAQ,MAAM,IAAI,CAAC,aAAa;;;;;;;;AAa3C,SAAgB,aAGd,WAAuB;CAGvB,MAAM,OAAO,iBAAiB,UAAU;CAExC,SAAS,YACP,eACA,SACA,UACA,YACU;AACV,SAAO;GACL,MAAM,GAAG,KAAK;GACd,WAAW;GACX;GACA;GACA;GACD;;CAGH,SAAS,UACP,eACA,SACA,OACU;AACV,SAAO;GACL,MAAM,GAAG,KAAK;GACd,WAAW;GACX;GACA;GACD;;CAGH,MAAM,YAID,EAAE,UAAU,SAAS,YAAY;EACpC,IAAI,KAAuB;EAC3B,MAAM,gBAA0B,EAAE;AAGlC,GAAC,YAAY;AACX,OAAI;IACF,MAAM,KAAK,MAAM,OAAO,WAAW,MAAM,QAAQ;IACjD,MAAM,OAAO,MAAM,OAAO,IAAI,GAAG;AAGjC,QAAI,KAAK,MACP,OAAM,QAAQ,QACZ,KAAK,MAAM;KACT;KACA,SAAS,MAAM;KACf,QAAQ,MAAM;KACd,OAAO,MAAM;KACd,CAAC,CACH;IAIH,MAAM,cAAc,MAAM,kBAAkB;KAC1C,YAAY,MAAM;KAClB,SAAS,MAAM;KACf;KACA,UAAU,MAAM,OAAO;KACvB,YAAY,MAAM,OAAO;KAC1B,CAAC;IAUF,MAAM,aAPW,MAAM,KAAK,MAC1B,IAAI,QACF,wBAAwB,UAAU,GAAG,MAAM,QAAQ,gBAAgB,eACnE,EAAE,SAAS,EAAE,SAAS,aAAa,EAAE,CACtC,CACF,EAE0B;AAC3B,QAAI,CAAC,UACH,OAAM,IAAI,MACR,gCAAgC,UAAU,GAAG,MAAM,UACpD;AAGH,cAAU,QAAQ;AAClB,SAAK;IAGL,IAAI;AAEJ,OAAG,iBAAiB,YAAY,UAAwB;AACtD,SAAI;MACF,MAAM,MACJ,OAAO,MAAM,SAAS,WAClB,MAAM,OACN,IAAI,aAAa,CAAC,OAAO,MAAM,KAAK;MAC1C,MAAM,OAAO,mBAAmB,MAAM,KAAK,MAAM,IAAI,CAAC;AAEtD,wBAAkB,QAChB,mBAAoB,EAAE,GACrB,UAAU;AACT,kBAAW,OAAO,KAAK,WAAW;QAErC;AAED,eAAS,YAAY,WAAW,MAAM,SAAS,iBAAiB,KAAK,WAAW,CAAC;cAC1E,KAAK;AACZ,cAAQ,MACN,iBAAiB,UAAU,mBAC3B,IACD;;MAEH;AAEF,OAAG,iBAAiB,eAAe;AACjC,cAAS,UAAU,WAAW,MAAM,yBAAS,IAAI,MAAM,uBAAuB,UAAU,GAAG,MAAM,UAAU,CAAC,CAAC;MAC7G;AAGF,OAAG,iBAAiB,UAAU,UAAsB;AAClD,UAAK;AACL,cAAS,UACP,WACA,MAAM,yBACN,IAAI,MAAM,wBAAwB,UAAU,GAAG,MAAM,QAAQ,SAAS,MAAM,KAAK,UAAU,MAAM,SAAS,CAC3G,CAAC;MACF;AAGF,WAAO,cAAc,SAAS,EAC5B,IAAG,KAAK,cAAc,OAAO,CAAE;YAE1B,KAAK;AACZ,YAAQ,MAAM,iBAAiB,UAAU,iBAAiB,IAAI;AAC9D,aAAS,UACP,WACA,MAAM,SACN,eAAe,QACX,sBACA,IAAI,MAAM,oBAAoB,UAAU,GAAG,MAAM,UAAU,CAChE,CAAC;;MAEF;AAGJ,WAAS,UAAU;GACjB,MAAM,SAAS,MAAM,YAAY,UAAU,MAAM;AACjD,OAAI,CAAC,OAAO,QAAS;GAErB,MAAM,aAAa,KAAK,UAAU,OAAO,KAAK;AAC9C,OAAI,GACF,IAAG,KAAK,WAAW;OAEnB,eAAc,KAAK,WAAW;IAEhC;AAGF,eAAa;AACX,OAAI,IAAI;AACN,QAAI;AACF,QAAG,MAAM,KAAM,gBAAgB;YACzB;AAGR,SAAK;;;;AAKX,QAAO,aAAa,SAAS"}