{"version":3,"file":"index.cjs","names":["syncProtocol","awarenessProtocol","decoding","encoding","time","math","Observable","url","YDoc","#params","#resolveParams"],"sources":["../../src/provider/index.ts"],"sourcesContent":["import * as bc from \"lib0/broadcastchannel\";\nimport * as decoding from \"lib0/decoding\";\nimport * as encoding from \"lib0/encoding\";\nimport * as math from \"lib0/math\";\nimport { Observable } from \"lib0/observable\";\nimport * as time from \"lib0/time\";\nimport * as url from \"lib0/url\";\nimport { nanoid } from \"nanoid\";\nimport * as authProtocol from \"y-protocols/auth\";\nimport * as awarenessProtocol from \"y-protocols/awareness\";\nimport * as syncProtocol from \"y-protocols/sync\";\nimport { Doc as YDoc } from \"yjs\";\n\nexport const messageSync = 0;\nexport const messageQueryAwareness = 3;\nexport const messageAwareness = 1;\nexport const messageAuth = 2;\n\n// Disable BroadcastChannel by default in Cloudflare Workers / Node\nconst DEFAULT_DISABLE_BC = typeof window === \"undefined\";\n\nconst messageHandlers: Array<\n  (\n    encoder: encoding.Encoder,\n    decoder: decoding.Decoder,\n    provider: WebsocketProvider,\n    emitSynced: boolean,\n    messageType: number\n  ) => void\n> = [];\n\nmessageHandlers[messageSync] = (\n  encoder,\n  decoder,\n  provider,\n  emitSynced,\n  _messageType\n) => {\n  encoding.writeVarUint(encoder, messageSync);\n  const syncMessageType = syncProtocol.readSyncMessage(\n    decoder,\n    encoder,\n    provider.doc,\n    provider\n  );\n  if (\n    emitSynced &&\n    syncMessageType === syncProtocol.messageYjsSyncStep2 &&\n    !provider.synced\n  ) {\n    provider.synced = true;\n  }\n};\n\nmessageHandlers[messageQueryAwareness] = (\n  encoder,\n  _decoder,\n  provider,\n  _emitSynced,\n  _messageType\n) => {\n  encoding.writeVarUint(encoder, messageAwareness);\n  encoding.writeVarUint8Array(\n    encoder,\n    awarenessProtocol.encodeAwarenessUpdate(\n      provider.awareness,\n      Array.from(provider.awareness.getStates().keys())\n    )\n  );\n};\n\nmessageHandlers[messageAwareness] = (\n  _encoder,\n  decoder,\n  provider,\n  _emitSynced,\n  _messageType\n) => {\n  awarenessProtocol.applyAwarenessUpdate(\n    provider.awareness,\n    decoding.readVarUint8Array(decoder),\n    provider\n  );\n};\n\nmessageHandlers[messageAuth] = (\n  _encoder,\n  decoder,\n  provider,\n  _emitSynced,\n  _messageType\n) => {\n  authProtocol.readAuthMessage(decoder, provider.doc, (_ydoc, reason) =>\n    permissionDeniedHandler(provider, reason)\n  );\n};\n\nfunction permissionDeniedHandler(provider: WebsocketProvider, reason: string) {\n  console.warn(`Permission denied to access ${provider.url}.\\n${reason}`);\n}\n\nfunction readMessage(\n  provider: WebsocketProvider,\n  buf: Uint8Array,\n  emitSynced: boolean\n): encoding.Encoder {\n  const decoder = decoding.createDecoder(buf);\n  const encoder = encoding.createEncoder();\n  const messageType = decoding.readVarUint(decoder);\n  const messageHandler = provider.messageHandlers[messageType];\n  if (/** @type {any} */ messageHandler) {\n    messageHandler(encoder, decoder, provider, emitSynced, messageType);\n  } else {\n    console.error(\"Unable to compute message\");\n  }\n  return encoder;\n}\n\nfunction setupWS(provider: WebsocketProvider) {\n  if (provider.shouldConnect && provider.ws === null) {\n    if (!provider._WS) {\n      throw new Error(\n        \"No WebSocket implementation available, did you forget to pass options.WebSocketPolyfill?\"\n      );\n    }\n    const websocket = new provider._WS(provider.url);\n    websocket.binaryType = \"arraybuffer\";\n    provider.ws = websocket;\n    provider.wsconnecting = true;\n    provider.wsconnected = false;\n    provider.synced = false;\n\n    websocket.addEventListener(\"message\", (event) => {\n      if (typeof event.data === \"string\") {\n        // Handle custom messages with __YPS: prefix\n        if (event.data.startsWith(\"__YPS:\")) {\n          const customMessage = event.data.slice(6); // Remove __YPS: prefix\n          provider.emit(\"custom-message\", [customMessage]);\n        }\n        return;\n      }\n      provider.wsLastMessageReceived = time.getUnixTime();\n      const encoder = readMessage(provider, new Uint8Array(event.data), true);\n      if (encoding.length(encoder) > 1) {\n        websocket.send(encoding.toUint8Array(encoder));\n      }\n    });\n    websocket.addEventListener(\"error\", (event) => {\n      provider.emit(\"connection-error\", [event, provider]);\n    });\n    websocket.addEventListener(\"close\", (event) => {\n      provider.emit(\"connection-close\", [event, provider]);\n      provider.ws = null;\n      provider.wsconnecting = false;\n      if (provider.wsconnected) {\n        provider.wsconnected = false;\n        provider.synced = false;\n        // update awareness (all users except local left)\n        const removedClients = Array.from(\n          provider.awareness.getStates().keys()\n        ).filter((client) => client !== provider.doc.clientID);\n        awarenessProtocol.removeAwarenessStates(\n          provider.awareness,\n          removedClients,\n          provider\n        );\n        // Clear stale meta for remote clients so their awareness\n        // updates are accepted on reconnect (clock check starts fresh)\n        for (const clientID of removedClients) {\n          provider.awareness.meta.delete(clientID);\n        }\n        provider.emit(\"status\", [\n          {\n            status: \"disconnected\"\n          }\n        ]);\n      } else {\n        provider.wsUnsuccessfulReconnects++;\n      }\n      // Start with no reconnect timeout and increase timeout by\n      // using exponential backoff starting with 100ms\n      setTimeout(\n        () => {\n          if (provider.shouldConnect) {\n            Promise.resolve(provider._reconnectWS()).catch((err) => {\n              console.error(\"Reconnection failed\", err);\n            });\n          }\n        },\n        math.min(\n          math.pow(2, provider.wsUnsuccessfulReconnects) * 100,\n          provider.maxBackoffTime\n        )\n      );\n    });\n    websocket.addEventListener(\"open\", () => {\n      provider.wsLastMessageReceived = time.getUnixTime();\n      provider.wsconnecting = false;\n      provider.wsconnected = true;\n      provider.wsUnsuccessfulReconnects = 0;\n      provider.emit(\"status\", [\n        {\n          status: \"connected\"\n        }\n      ]);\n      // always send sync step 1 when connected\n      const encoder = encoding.createEncoder();\n      encoding.writeVarUint(encoder, messageSync);\n      syncProtocol.writeSyncStep1(encoder, provider.doc);\n      websocket.send(encoding.toUint8Array(encoder));\n      // broadcast local awareness state\n      if (provider.awareness.getLocalState() !== null) {\n        // Re-set local state to bump the awareness clock, ensuring\n        // remote clients accept the update even if they have stale meta\n        provider.awareness.setLocalState(provider.awareness.getLocalState());\n        const encoderAwarenessState = encoding.createEncoder();\n        encoding.writeVarUint(encoderAwarenessState, messageAwareness);\n        encoding.writeVarUint8Array(\n          encoderAwarenessState,\n          awarenessProtocol.encodeAwarenessUpdate(provider.awareness, [\n            provider.doc.clientID\n          ])\n        );\n        websocket.send(encoding.toUint8Array(encoderAwarenessState));\n      }\n    });\n    provider.emit(\"status\", [\n      {\n        status: \"connecting\"\n      }\n    ]);\n  }\n}\n\nfunction broadcastMessage(provider: WebsocketProvider, buf: Uint8Array) {\n  const ws = provider.ws;\n  if (provider.wsconnected && ws && ws.readyState === ws.OPEN) {\n    ws.send(buf);\n  }\n  if (provider.bcconnected) {\n    bc.publish(provider.bcChannel, buf, provider);\n  }\n}\n\ntype AwarenessUpdate = {\n  added: number[];\n  updated: number[];\n  removed: number[];\n};\n\nconst DefaultWebSocket = typeof WebSocket === \"undefined\" ? null : WebSocket;\n\n/**\n * Websocket Provider for Yjs. Creates a websocket connection to sync the shared document.\n * The document name is attached to the provided url. I.e. the following example\n * creates a websocket connection to http://localhost:1234/my-document-name\n *\n * @example\n *   import * as Y from 'yjs'\n *   import { WebsocketProvider } from 'y-websocket'\n *   const doc = new Y.Doc()\n *   const provider = new WebsocketProvider('http://localhost:1234', 'my-document-name', doc)\n *\n * @extends {Observable<string>}\n */\nexport class WebsocketProvider extends Observable<string> {\n  maxBackoffTime: number;\n  bcChannel: string;\n  url: string;\n  roomname: string;\n  doc: YDoc;\n  _WS: typeof WebSocket;\n  awareness: awarenessProtocol.Awareness;\n  wsconnected: boolean;\n  wsconnecting: boolean;\n  bcconnected: boolean;\n  disableBc: boolean;\n  wsUnsuccessfulReconnects: number;\n  messageHandlers: typeof messageHandlers;\n  _synced: boolean;\n  ws: WebSocket | null;\n  wsLastMessageReceived: number;\n  shouldConnect: boolean; // Whether to connect to other peers or not\n  _resyncInterval: ReturnType<typeof setInterval> | number;\n  _bcSubscriber: (message: Uint8Array, origin: unknown) => void;\n  _updateHandler: (update: Uint8Array, origin: unknown) => void;\n  _awarenessUpdateHandler: (update: AwarenessUpdate, origin: unknown) => void;\n  _unloadHandler: () => void;\n\n  constructor(\n    serverUrl: string,\n    roomname: string,\n    doc: YDoc,\n    {\n      connect = true,\n      awareness = new awarenessProtocol.Awareness(doc),\n      params = {},\n      isPrefixedUrl = false,\n      WebSocketPolyfill = DefaultWebSocket, // Optionally provide a WebSocket polyfill\n      resyncInterval = -1, // Request server state every `resyncInterval` milliseconds\n      maxBackoffTime = 2500, // Maximum amount of time to wait before trying to reconnect (we try to reconnect using exponential backoff)\n      disableBc = DEFAULT_DISABLE_BC // Disable cross-tab BroadcastChannel communication\n    }: {\n      connect?: boolean;\n      awareness?: awarenessProtocol.Awareness;\n      params?: { [s: string]: string };\n      isPrefixedUrl?: boolean;\n      WebSocketPolyfill?: typeof WebSocket | null;\n      resyncInterval?: number;\n      maxBackoffTime?: number;\n      disableBc?: boolean;\n    } = {}\n  ) {\n    super();\n    // ensure that url is always ends with /\n    while (serverUrl[serverUrl.length - 1] === \"/\") {\n      serverUrl = serverUrl.slice(0, serverUrl.length - 1);\n    }\n    const encodedParams = url.encodeQueryParams(params);\n    this.maxBackoffTime = maxBackoffTime;\n    this.bcChannel = `${serverUrl}/${roomname}`;\n    this.url = isPrefixedUrl\n      ? serverUrl\n      : `${serverUrl}/${roomname}${encodedParams.length === 0 ? \"\" : `?${encodedParams}`}`;\n    this.roomname = roomname;\n    this.doc = doc;\n    this._WS = WebSocketPolyfill!;\n    this.awareness = awareness;\n    this.wsconnected = false;\n    this.wsconnecting = false;\n    this.bcconnected = false;\n    this.disableBc = disableBc;\n    this.wsUnsuccessfulReconnects = 0;\n    this.messageHandlers = messageHandlers.slice();\n\n    this._synced = false;\n\n    this.ws = null;\n    this.wsLastMessageReceived = 0;\n\n    this.shouldConnect = connect;\n\n    this._resyncInterval = 0;\n    if (resyncInterval > 0) {\n      this._resyncInterval = /** @type {any} */ setInterval(() => {\n        if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n          // resend sync step 1\n          const encoder = encoding.createEncoder();\n          encoding.writeVarUint(encoder, messageSync);\n          syncProtocol.writeSyncStep1(encoder, doc);\n          this.ws.send(encoding.toUint8Array(encoder));\n        }\n      }, resyncInterval);\n    }\n\n    this._bcSubscriber = (data: Uint8Array, origin: unknown) => {\n      if (origin !== this) {\n        const encoder = readMessage(this, new Uint8Array(data), false);\n        if (encoding.length(encoder) > 1) {\n          bc.publish(this.bcChannel, encoding.toUint8Array(encoder), this);\n        }\n      }\n    };\n    /**\n     * Listens to Yjs updates and sends them to remote peers (ws and broadcastchannel)\n     */\n    this._updateHandler = (update: Uint8Array, origin: unknown) => {\n      if (origin !== this) {\n        const encoder = encoding.createEncoder();\n        encoding.writeVarUint(encoder, messageSync);\n        syncProtocol.writeUpdate(encoder, update);\n        broadcastMessage(this, encoding.toUint8Array(encoder));\n      }\n    };\n    this.doc.on(\"update\", this._updateHandler);\n\n    this._awarenessUpdateHandler = (\n      { added, updated, removed }: AwarenessUpdate,\n      _origin: unknown\n    ) => {\n      const changedClients = added.concat(updated).concat(removed);\n      const encoder = encoding.createEncoder();\n      encoding.writeVarUint(encoder, messageAwareness);\n      encoding.writeVarUint8Array(\n        encoder,\n        awarenessProtocol.encodeAwarenessUpdate(awareness, changedClients)\n      );\n      broadcastMessage(this, encoding.toUint8Array(encoder));\n    };\n    this._unloadHandler = () => {\n      awarenessProtocol.removeAwarenessStates(\n        this.awareness,\n        [doc.clientID],\n        \"window unload\"\n      );\n    };\n    if (typeof window !== \"undefined\") {\n      window.addEventListener(\"unload\", this._unloadHandler);\n    } else if (\n      typeof process !== \"undefined\" &&\n      typeof process.on === \"function\"\n    ) {\n      process.on(\"exit\", this._unloadHandler);\n    }\n    // Listen on 'change' (not 'update') so that clock-only awareness\n    // renewals (the 15-second heartbeat) do NOT produce network traffic.\n    // Only actual state changes (cursor moved, name changed, etc.) are sent.\n    // This allows Durable Objects to hibernate when sessions are idle.\n    awareness.on(\"change\", this._awarenessUpdateHandler);\n\n    // Disable the awareness protocol's built-in check interval.\n    // It renews the local clock every 15s (causing wire traffic that defeats\n    // DO hibernation) and removes remote peers after 30s of inactivity.\n    // We handle peer cleanup via WebSocket close events instead.\n    clearInterval(\n      (\n        awareness as unknown as {\n          _checkInterval: ReturnType<typeof setInterval>;\n        }\n      )._checkInterval\n    );\n    if (connect) {\n      this.connect();\n    }\n  }\n\n  /**\n   * @type {boolean}\n   */\n  get synced() {\n    return this._synced;\n  }\n\n  set synced(state) {\n    if (this._synced !== state) {\n      this._synced = state;\n      this.emit(\"synced\", [state]);\n      this.emit(\"sync\", [state]);\n    }\n  }\n\n  destroy() {\n    if (this._resyncInterval !== 0) {\n      clearInterval(this._resyncInterval);\n    }\n    this.disconnect();\n    if (typeof window !== \"undefined\") {\n      window.removeEventListener(\"unload\", this._unloadHandler);\n    } else if (\n      typeof process !== \"undefined\" &&\n      typeof process.off === \"function\"\n    ) {\n      process.off(\"exit\", this._unloadHandler);\n    }\n    this.awareness.off(\"change\", this._awarenessUpdateHandler);\n    this.doc.off(\"update\", this._updateHandler);\n    super.destroy();\n  }\n\n  connectBc() {\n    if (this.disableBc) {\n      return;\n    }\n    if (!this.bcconnected) {\n      bc.subscribe(this.bcChannel, this._bcSubscriber);\n      this.bcconnected = true;\n    }\n    // send sync step1 to bc\n    // write sync step 1\n    const encoderSync = encoding.createEncoder();\n    encoding.writeVarUint(encoderSync, messageSync);\n    syncProtocol.writeSyncStep1(encoderSync, this.doc);\n    bc.publish(this.bcChannel, encoding.toUint8Array(encoderSync), this);\n    // broadcast local state\n    const encoderState = encoding.createEncoder();\n    encoding.writeVarUint(encoderState, messageSync);\n    syncProtocol.writeSyncStep2(encoderState, this.doc);\n    bc.publish(this.bcChannel, encoding.toUint8Array(encoderState), this);\n    // write queryAwareness\n    const encoderAwarenessQuery = encoding.createEncoder();\n    encoding.writeVarUint(encoderAwarenessQuery, messageQueryAwareness);\n    bc.publish(\n      this.bcChannel,\n      encoding.toUint8Array(encoderAwarenessQuery),\n      this\n    );\n    // broadcast local awareness state\n    const encoderAwarenessState = encoding.createEncoder();\n    encoding.writeVarUint(encoderAwarenessState, messageAwareness);\n    encoding.writeVarUint8Array(\n      encoderAwarenessState,\n      awarenessProtocol.encodeAwarenessUpdate(this.awareness, [\n        this.doc.clientID\n      ])\n    );\n    bc.publish(\n      this.bcChannel,\n      encoding.toUint8Array(encoderAwarenessState),\n      this\n    );\n  }\n\n  disconnectBc() {\n    // broadcast message with local awareness state set to null (indicating disconnect)\n    const encoder = encoding.createEncoder();\n    encoding.writeVarUint(encoder, messageAwareness);\n    encoding.writeVarUint8Array(\n      encoder,\n      awarenessProtocol.encodeAwarenessUpdate(\n        this.awareness,\n        [this.doc.clientID],\n        new Map()\n      )\n    );\n    broadcastMessage(this, encoding.toUint8Array(encoder));\n    if (this.bcconnected) {\n      bc.unsubscribe(this.bcChannel, this._bcSubscriber);\n      this.bcconnected = false;\n    }\n  }\n\n  disconnect() {\n    this.shouldConnect = false;\n    this.disconnectBc();\n    if (this.ws !== null) {\n      this.ws.close();\n    }\n  }\n\n  /**\n   * Called by the close handler to re-establish the WebSocket.\n   * Subclasses (e.g. YProvider) override this to refresh dynamic\n   * params before reconnecting.\n   */\n  _reconnectWS() {\n    setupWS(this);\n  }\n\n  connect() {\n    this.shouldConnect = true;\n    if (!this.wsconnected && this.ws === null) {\n      setupWS(this);\n      this.connectBc();\n    }\n  }\n}\n\nfunction assertType(value: unknown, label: string, type: string) {\n  if (typeof value !== type) {\n    throw new Error(\n      `Invalid \"${label}\" parameter provided to YProvider. Expected: ${type}, received: ${value as string}`\n    );\n  }\n}\n\ntype Params = Record<string, string | null | undefined>;\ntype ParamsProvider = Params | (() => Params | Promise<Params>);\ntype BaseProviderOptions = ConstructorParameters<typeof WebsocketProvider>[3];\n\ntype YProviderOptions = Omit<NonNullable<BaseProviderOptions>, \"params\"> & {\n  connectionId?: string;\n  party?: string;\n  prefix?: string;\n  params?: ParamsProvider;\n  protocol?: \"ws\" | \"wss\";\n};\n\nexport default class YProvider extends WebsocketProvider {\n  id: string;\n  #params?: ParamsProvider;\n\n  constructor(\n    host: string,\n    room: string,\n    doc?: YDoc,\n    options: YProviderOptions = {}\n  ) {\n    assertType(host, \"host\", \"string\");\n    assertType(room, \"room\", \"string\");\n\n    // strip the protocol from the beginning of `host` if any\n    host = host.replace(/^(http|https|ws|wss):\\/\\//, \"\");\n\n    // strip trailing slash from host if any\n    if (host.endsWith(\"/\")) {\n      host = host.slice(0, -1);\n    }\n\n    const serverUrl = `${\n      options.protocol ||\n      (host.startsWith(\"localhost:\") ||\n      host.startsWith(\"127.0.0.1:\") ||\n      host.startsWith(\"192.168.\") ||\n      host.startsWith(\"10.\") ||\n      (host.startsWith(\"172.\") &&\n        host.split(\".\")[1] >= \"16\" &&\n        host.split(\".\")[1] <= \"31\")\n        ? \"ws\"\n        : \"wss\")\n    }://${host}${options.prefix || `/parties/${options.party || \"main\"}`}`;\n\n    // use provided id, or generate a random one\n    const id = options.connectionId ?? nanoid(10);\n\n    // don't pass params to WebsocketProvider, we override them in connect()\n    const { params, connect = true, ...rest } = options;\n\n    // don't connect until we've updated the url parameters\n    const baseOptions = {\n      ...rest,\n      isPrefixedUrl: !!options.prefix,\n      connect: false\n    };\n\n    super(serverUrl, room, doc ?? new YDoc(), baseOptions);\n\n    this.id = id;\n    this.#params = params;\n\n    if (connect) {\n      void this.connect();\n    }\n  }\n\n  async #resolveParams() {\n    const nextParams =\n      typeof this.#params === \"function\" ? await this.#params() : this.#params;\n    const urlParams = new URLSearchParams([[\"_pk\", this.id]]);\n    if (nextParams) {\n      for (const [key, value] of Object.entries(nextParams)) {\n        if (value !== null && value !== undefined) {\n          urlParams.append(key, value);\n        }\n      }\n    }\n    const nextUrl = new URL(this.url);\n    nextUrl.search = urlParams.toString();\n    this.url = nextUrl.toString();\n  }\n\n  async connect() {\n    try {\n      await this.#resolveParams();\n      super.connect();\n    } catch (err) {\n      console.error(\"Failed to open connecton to PartyServer\", err);\n      throw err;\n    }\n  }\n\n  async _reconnectWS() {\n    try {\n      await this.#resolveParams();\n    } catch (err) {\n      console.error(\n        \"Failed to refresh params, reconnecting with stale params\",\n        err\n      );\n    }\n    super._reconnectWS();\n  }\n\n  sendMessage(message: string) {\n    this.ws?.send(`__YPS:${message}`);\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,MAAa,cAAc;AAC3B,MAAa,wBAAwB;AACrC,MAAa,mBAAmB;AAChC,MAAa,cAAc;AAG3B,MAAM,qBAAqB,OAAO,WAAW;AAE7C,MAAM,kBAQF,EAAE;AAEN,gBAAA,MACE,SACA,SACA,UACA,YACA,iBACG;AACH,eAAS,aAAa,SAAA,EAAqB;CAC3C,MAAM,kBAAkBA,iBAAa,gBACnC,SACA,SACA,SAAS,KACT,SACD;AACD,KACE,cACA,oBAAoBA,iBAAa,uBACjC,CAAC,SAAS,OAEV,UAAS,SAAS;;AAItB,gBAAA,MACE,SACA,UACA,UACA,aACA,iBACG;AACH,eAAS,aAAa,SAAA,EAA0B;AAChD,eAAS,mBACP,SACAC,sBAAkB,sBAChB,SAAS,WACT,MAAM,KAAK,SAAS,UAAU,WAAW,CAAC,MAAM,CAAC,CAClD,CACF;;AAGH,gBAAA,MACE,UACA,SACA,UACA,aACA,iBACG;AACH,uBAAkB,qBAChB,SAAS,WACTC,cAAS,kBAAkB,QAAQ,EACnC,SACD;;AAGH,gBAAA,MACE,UACA,SACA,UACA,aACA,iBACG;AACH,kBAAa,gBAAgB,SAAS,SAAS,MAAM,OAAO,WAC1D,wBAAwB,UAAU,OAAO,CAC1C;;AAGH,SAAS,wBAAwB,UAA6B,QAAgB;AAC5E,SAAQ,KAAK,+BAA+B,SAAS,IAAI,KAAK,SAAS;;AAGzE,SAAS,YACP,UACA,KACA,YACkB;CAClB,MAAM,UAAUA,cAAS,cAAc,IAAI;CAC3C,MAAM,UAAUC,cAAS,eAAe;CACxC,MAAM,cAAcD,cAAS,YAAY,QAAQ;CACjD,MAAM,iBAAiB,SAAS,gBAAgB;AAChD,KAAuB,eACrB,gBAAe,SAAS,SAAS,UAAU,YAAY,YAAY;KAEnE,SAAQ,MAAM,4BAA4B;AAE5C,QAAO;;AAGT,SAAS,QAAQ,UAA6B;AAC5C,KAAI,SAAS,iBAAiB,SAAS,OAAO,MAAM;AAClD,MAAI,CAAC,SAAS,IACZ,OAAM,IAAI,MACR,2FACD;EAEH,MAAM,YAAY,IAAI,SAAS,IAAI,SAAS,IAAI;AAChD,YAAU,aAAa;AACvB,WAAS,KAAK;AACd,WAAS,eAAe;AACxB,WAAS,cAAc;AACvB,WAAS,SAAS;AAElB,YAAU,iBAAiB,YAAY,UAAU;AAC/C,OAAI,OAAO,MAAM,SAAS,UAAU;AAElC,QAAI,MAAM,KAAK,WAAW,SAAS,EAAE;KACnC,MAAM,gBAAgB,MAAM,KAAK,MAAM,EAAE;AACzC,cAAS,KAAK,kBAAkB,CAAC,cAAc,CAAC;;AAElD;;AAEF,YAAS,wBAAwBE,UAAK,aAAa;GACnD,MAAM,UAAU,YAAY,UAAU,IAAI,WAAW,MAAM,KAAK,EAAE,KAAK;AACvE,OAAID,cAAS,OAAO,QAAQ,GAAG,EAC7B,WAAU,KAAKA,cAAS,aAAa,QAAQ,CAAC;IAEhD;AACF,YAAU,iBAAiB,UAAU,UAAU;AAC7C,YAAS,KAAK,oBAAoB,CAAC,OAAO,SAAS,CAAC;IACpD;AACF,YAAU,iBAAiB,UAAU,UAAU;AAC7C,YAAS,KAAK,oBAAoB,CAAC,OAAO,SAAS,CAAC;AACpD,YAAS,KAAK;AACd,YAAS,eAAe;AACxB,OAAI,SAAS,aAAa;AACxB,aAAS,cAAc;AACvB,aAAS,SAAS;IAElB,MAAM,iBAAiB,MAAM,KAC3B,SAAS,UAAU,WAAW,CAAC,MAAM,CACtC,CAAC,QAAQ,WAAW,WAAW,SAAS,IAAI,SAAS;AACtD,0BAAkB,sBAChB,SAAS,WACT,gBACA,SACD;AAGD,SAAK,MAAM,YAAY,eACrB,UAAS,UAAU,KAAK,OAAO,SAAS;AAE1C,aAAS,KAAK,UAAU,CACtB,EACE,QAAQ,gBACT,CACF,CAAC;SAEF,UAAS;AAIX,oBACQ;AACJ,QAAI,SAAS,cACX,SAAQ,QAAQ,SAAS,cAAc,CAAC,CAAC,OAAO,QAAQ;AACtD,aAAQ,MAAM,uBAAuB,IAAI;MACzC;MAGNE,UAAK,IACHA,UAAK,IAAI,GAAG,SAAS,yBAAyB,GAAG,KACjD,SAAS,eACV,CACF;IACD;AACF,YAAU,iBAAiB,cAAc;AACvC,YAAS,wBAAwBD,UAAK,aAAa;AACnD,YAAS,eAAe;AACxB,YAAS,cAAc;AACvB,YAAS,2BAA2B;AACpC,YAAS,KAAK,UAAU,CACtB,EACE,QAAQ,aACT,CACF,CAAC;GAEF,MAAM,UAAUD,cAAS,eAAe;AACxC,iBAAS,aAAa,SAAA,EAAqB;AAC3C,oBAAa,eAAe,SAAS,SAAS,IAAI;AAClD,aAAU,KAAKA,cAAS,aAAa,QAAQ,CAAC;AAE9C,OAAI,SAAS,UAAU,eAAe,KAAK,MAAM;AAG/C,aAAS,UAAU,cAAc,SAAS,UAAU,eAAe,CAAC;IACpE,MAAM,wBAAwBA,cAAS,eAAe;AACtD,kBAAS,aAAa,uBAAA,EAAwC;AAC9D,kBAAS,mBACP,uBACAF,sBAAkB,sBAAsB,SAAS,WAAW,CAC1D,SAAS,IAAI,SACd,CAAC,CACH;AACD,cAAU,KAAKE,cAAS,aAAa,sBAAsB,CAAC;;IAE9D;AACF,WAAS,KAAK,UAAU,CACtB,EACE,QAAQ,cACT,CACF,CAAC;;;AAIN,SAAS,iBAAiB,UAA6B,KAAiB;CACtE,MAAM,KAAK,SAAS;AACpB,KAAI,SAAS,eAAe,MAAM,GAAG,eAAe,GAAG,KACrD,IAAG,KAAK,IAAI;AAEd,KAAI,SAAS,YACX,uBAAG,QAAQ,SAAS,WAAW,KAAK,SAAS;;AAUjD,MAAM,mBAAmB,OAAO,cAAc,cAAc,OAAO;;;;;;;;;;;;;;AAenE,IAAa,oBAAb,cAAuCG,gBAAAA,WAAmB;CACxD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YACE,WACA,UACA,KACA,EACE,UAAU,MACV,YAAY,IAAIL,sBAAkB,UAAU,IAAI,EAChD,SAAS,EAAE,EACX,gBAAgB,OAChB,oBAAoB,kBACpB,iBAAiB,IACjB,iBAAiB,MACjB,YAAY,uBAUV,EAAE,EACN;AACA,SAAO;AAEP,SAAO,UAAU,UAAU,SAAS,OAAO,IACzC,aAAY,UAAU,MAAM,GAAG,UAAU,SAAS,EAAE;EAEtD,MAAM,gBAAgBM,SAAI,kBAAkB,OAAO;AACnD,OAAK,iBAAiB;AACtB,OAAK,YAAY,GAAG,UAAU,GAAG;AACjC,OAAK,MAAM,gBACP,YACA,GAAG,UAAU,GAAG,WAAW,cAAc,WAAW,IAAI,KAAK,IAAI;AACrE,OAAK,WAAW;AAChB,OAAK,MAAM;AACX,OAAK,MAAM;AACX,OAAK,YAAY;AACjB,OAAK,cAAc;AACnB,OAAK,eAAe;AACpB,OAAK,cAAc;AACnB,OAAK,YAAY;AACjB,OAAK,2BAA2B;AAChC,OAAK,kBAAkB,gBAAgB,OAAO;AAE9C,OAAK,UAAU;AAEf,OAAK,KAAK;AACV,OAAK,wBAAwB;AAE7B,OAAK,gBAAgB;AAErB,OAAK,kBAAkB;AACvB,MAAI,iBAAiB,EACnB,MAAK,kBAAqC,kBAAkB;AAC1D,OAAI,KAAK,MAAM,KAAK,GAAG,eAAe,UAAU,MAAM;IAEpD,MAAM,UAAUJ,cAAS,eAAe;AACxC,kBAAS,aAAa,SAAA,EAAqB;AAC3C,qBAAa,eAAe,SAAS,IAAI;AACzC,SAAK,GAAG,KAAKA,cAAS,aAAa,QAAQ,CAAC;;KAE7C,eAAe;AAGpB,OAAK,iBAAiB,MAAkB,WAAoB;AAC1D,OAAI,WAAW,MAAM;IACnB,MAAM,UAAU,YAAY,MAAM,IAAI,WAAW,KAAK,EAAE,MAAM;AAC9D,QAAIA,cAAS,OAAO,QAAQ,GAAG,EAC7B,uBAAG,QAAQ,KAAK,WAAWA,cAAS,aAAa,QAAQ,EAAE,KAAK;;;;;;AAOtE,OAAK,kBAAkB,QAAoB,WAAoB;AAC7D,OAAI,WAAW,MAAM;IACnB,MAAM,UAAUA,cAAS,eAAe;AACxC,kBAAS,aAAa,SAAA,EAAqB;AAC3C,qBAAa,YAAY,SAAS,OAAO;AACzC,qBAAiB,MAAMA,cAAS,aAAa,QAAQ,CAAC;;;AAG1D,OAAK,IAAI,GAAG,UAAU,KAAK,eAAe;AAE1C,OAAK,2BACH,EAAE,OAAO,SAAS,WAClB,YACG;GACH,MAAM,iBAAiB,MAAM,OAAO,QAAQ,CAAC,OAAO,QAAQ;GAC5D,MAAM,UAAUA,cAAS,eAAe;AACxC,iBAAS,aAAa,SAAA,EAA0B;AAChD,iBAAS,mBACP,SACAF,sBAAkB,sBAAsB,WAAW,eAAe,CACnE;AACD,oBAAiB,MAAME,cAAS,aAAa,QAAQ,CAAC;;AAExD,OAAK,uBAAuB;AAC1B,yBAAkB,sBAChB,KAAK,WACL,CAAC,IAAI,SAAS,EACd,gBACD;;AAEH,MAAI,OAAO,WAAW,YACpB,QAAO,iBAAiB,UAAU,KAAK,eAAe;WAEtD,OAAO,YAAY,eACnB,OAAO,QAAQ,OAAO,WAEtB,SAAQ,GAAG,QAAQ,KAAK,eAAe;AAMzC,YAAU,GAAG,UAAU,KAAK,wBAAwB;AAMpD,gBAEI,UAGA,eACH;AACD,MAAI,QACF,MAAK,SAAS;;;;;CAOlB,IAAI,SAAS;AACX,SAAO,KAAK;;CAGd,IAAI,OAAO,OAAO;AAChB,MAAI,KAAK,YAAY,OAAO;AAC1B,QAAK,UAAU;AACf,QAAK,KAAK,UAAU,CAAC,MAAM,CAAC;AAC5B,QAAK,KAAK,QAAQ,CAAC,MAAM,CAAC;;;CAI9B,UAAU;AACR,MAAI,KAAK,oBAAoB,EAC3B,eAAc,KAAK,gBAAgB;AAErC,OAAK,YAAY;AACjB,MAAI,OAAO,WAAW,YACpB,QAAO,oBAAoB,UAAU,KAAK,eAAe;WAEzD,OAAO,YAAY,eACnB,OAAO,QAAQ,QAAQ,WAEvB,SAAQ,IAAI,QAAQ,KAAK,eAAe;AAE1C,OAAK,UAAU,IAAI,UAAU,KAAK,wBAAwB;AAC1D,OAAK,IAAI,IAAI,UAAU,KAAK,eAAe;AAC3C,QAAM,SAAS;;CAGjB,YAAY;AACV,MAAI,KAAK,UACP;AAEF,MAAI,CAAC,KAAK,aAAa;AACrB,yBAAG,UAAU,KAAK,WAAW,KAAK,cAAc;AAChD,QAAK,cAAc;;EAIrB,MAAM,cAAcA,cAAS,eAAe;AAC5C,gBAAS,aAAa,aAAA,EAAyB;AAC/C,mBAAa,eAAe,aAAa,KAAK,IAAI;AAClD,wBAAG,QAAQ,KAAK,WAAWA,cAAS,aAAa,YAAY,EAAE,KAAK;EAEpE,MAAM,eAAeA,cAAS,eAAe;AAC7C,gBAAS,aAAa,cAAA,EAA0B;AAChD,mBAAa,eAAe,cAAc,KAAK,IAAI;AACnD,wBAAG,QAAQ,KAAK,WAAWA,cAAS,aAAa,aAAa,EAAE,KAAK;EAErE,MAAM,wBAAwBA,cAAS,eAAe;AACtD,gBAAS,aAAa,uBAAA,EAA6C;AACnE,wBAAG,QACD,KAAK,WACLA,cAAS,aAAa,sBAAsB,EAC5C,KACD;EAED,MAAM,wBAAwBA,cAAS,eAAe;AACtD,gBAAS,aAAa,uBAAA,EAAwC;AAC9D,gBAAS,mBACP,uBACAF,sBAAkB,sBAAsB,KAAK,WAAW,CACtD,KAAK,IAAI,SACV,CAAC,CACH;AACD,wBAAG,QACD,KAAK,WACLE,cAAS,aAAa,sBAAsB,EAC5C,KACD;;CAGH,eAAe;EAEb,MAAM,UAAUA,cAAS,eAAe;AACxC,gBAAS,aAAa,SAAA,EAA0B;AAChD,gBAAS,mBACP,SACAF,sBAAkB,sBAChB,KAAK,WACL,CAAC,KAAK,IAAI,SAAS,kBACnB,IAAI,KAAK,CACV,CACF;AACD,mBAAiB,MAAME,cAAS,aAAa,QAAQ,CAAC;AACtD,MAAI,KAAK,aAAa;AACpB,yBAAG,YAAY,KAAK,WAAW,KAAK,cAAc;AAClD,QAAK,cAAc;;;CAIvB,aAAa;AACX,OAAK,gBAAgB;AACrB,OAAK,cAAc;AACnB,MAAI,KAAK,OAAO,KACd,MAAK,GAAG,OAAO;;;;;;;CASnB,eAAe;AACb,UAAQ,KAAK;;CAGf,UAAU;AACR,OAAK,gBAAgB;AACrB,MAAI,CAAC,KAAK,eAAe,KAAK,OAAO,MAAM;AACzC,WAAQ,KAAK;AACb,QAAK,WAAW;;;;AAKtB,SAAS,WAAW,OAAgB,OAAe,MAAc;AAC/D,KAAI,OAAO,UAAU,KACnB,OAAM,IAAI,MACR,YAAY,MAAM,+CAA+C,KAAK,cAAc,QACrF;;AAgBL,IAAqB,YAArB,cAAuC,kBAAkB;CACvD;CACA;CAEA,YACE,MACA,MACA,KACA,UAA4B,EAAE,EAC9B;AACA,aAAW,MAAM,QAAQ,SAAS;AAClC,aAAW,MAAM,QAAQ,SAAS;AAGlC,SAAO,KAAK,QAAQ,6BAA6B,GAAG;AAGpD,MAAI,KAAK,SAAS,IAAI,CACpB,QAAO,KAAK,MAAM,GAAG,GAAG;EAG1B,MAAM,YAAY,GAChB,QAAQ,aACP,KAAK,WAAW,aAAa,IAC9B,KAAK,WAAW,aAAa,IAC7B,KAAK,WAAW,WAAW,IAC3B,KAAK,WAAW,MAAM,IACrB,KAAK,WAAW,OAAO,IACtB,KAAK,MAAM,IAAI,CAAC,MAAM,QACtB,KAAK,MAAM,IAAI,CAAC,MAAM,OACpB,OACA,OACL,KAAK,OAAO,QAAQ,UAAU,YAAY,QAAQ,SAAS;EAG5D,MAAM,KAAK,QAAQ,iBAAA,GAAA,OAAA,QAAuB,GAAG;EAG7C,MAAM,EAAE,QAAQ,UAAU,MAAM,GAAG,SAAS;EAG5C,MAAM,cAAc;GAClB,GAAG;GACH,eAAe,CAAC,CAAC,QAAQ;GACzB,SAAS;GACV;AAED,QAAM,WAAW,MAAM,OAAO,IAAIK,IAAAA,KAAM,EAAE,YAAY;AAEtD,OAAK,KAAK;AACV,QAAA,SAAe;AAEf,MAAI,QACG,MAAK,SAAS;;CAIvB,OAAA,gBAAuB;EACrB,MAAM,aACJ,OAAO,MAAA,WAAiB,aAAa,MAAM,MAAA,QAAc,GAAG,MAAA;EAC9D,MAAM,YAAY,IAAI,gBAAgB,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC;AACzD,MAAI;QACG,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,CACnD,KAAI,UAAU,QAAQ,UAAU,KAAA,EAC9B,WAAU,OAAO,KAAK,MAAM;;EAIlC,MAAM,UAAU,IAAI,IAAI,KAAK,IAAI;AACjC,UAAQ,SAAS,UAAU,UAAU;AACrC,OAAK,MAAM,QAAQ,UAAU;;CAG/B,MAAM,UAAU;AACd,MAAI;AACF,SAAM,MAAA,eAAqB;AAC3B,SAAM,SAAS;WACR,KAAK;AACZ,WAAQ,MAAM,2CAA2C,IAAI;AAC7D,SAAM;;;CAIV,MAAM,eAAe;AACnB,MAAI;AACF,SAAM,MAAA,eAAqB;WACpB,KAAK;AACZ,WAAQ,MACN,4DACA,IACD;;AAEH,QAAM,cAAc;;CAGtB,YAAY,SAAiB;AAC3B,OAAK,IAAI,KAAK,SAAS,UAAU"}