{"version":3,"file":"firebase-data-connect.js","sources":["../util/src/errors.ts","../util/src/url.ts","../component/src/component.ts","../logger/src/logger.ts","../data-connect/src/core/version.ts","../data-connect/src/core/error.ts","../data-connect/src/cache/EntityDataObject.ts","../data-connect/src/cache/InMemoryCacheProvider.ts","../data-connect/src/cache/EntityNode.ts","../data-connect/src/cache/ResultTree.ts","../data-connect/src/cache/ImpactedQueryRefsAccumulator.ts","../data-connect/src/cache/ResultTreeProcessor.ts","../data-connect/src/cache/Cache.ts","../util/src/sha256.ts","../data-connect/src/core/AppCheckTokenProvider.ts","../data-connect/src/logger.ts","../data-connect/src/core/FirebaseAuthProvider.ts","../data-connect/src/api/Reference.ts","../data-connect/src/cache/cacheUtils.ts","../data-connect/src/util/encoder.ts","../data-connect/src/core/query/QueryManager.ts","../data-connect/src/network/transport.ts","../data-connect/src/network/rest/fetch.ts","../data-connect/src/util/url.ts","../data-connect/src/network/rest/restTransport.ts","../data-connect/src/network/stream/streamTransport.ts","../data-connect/src/network/stream/websocket.ts","../data-connect/src/network/manager.ts","../data-connect/src/api/Mutation.ts","../data-connect/src/api/DataConnect.ts","../data-connect/src/core/query/queryOptions.ts","../data-connect/src/api/query.ts","../data-connect/src/util/validateArgs.ts","../data-connect/src/core/query/subscribe.ts","../data-connect/src/register.ts","../data-connect/src/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n *   // TypeScript string literals for type-safe codes\n *   type Err =\n *     'unknown' |\n *     'object-not-found'\n *     ;\n *\n *   // Closure enum for type-safe error codes\n *   // at-enum {string}\n *   var Err = {\n *     UNKNOWN: 'unknown',\n *     OBJECT_NOT_FOUND: 'object-not-found',\n *   }\n *\n *   let errors: Map<Err, string> = {\n *     'generic-error': \"Unknown error\",\n *     'file-not-found': \"Could not find file: {$file}\",\n *   };\n *\n *   // Type-safe function - must pass a valid error code as param.\n *   let error = new ErrorFactory<Err>('service', 'Service', errors);\n *\n *   ...\n *   throw error.create(Err.GENERIC);\n *   ...\n *   throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n *   ...\n *   // Service: Could not file file: foo.txt (service/file-not-found).\n *\n *   catch (e) {\n *     assert(e.message === \"Could not find file: foo.txt.\");\n *     if ((e as FirebaseError)?.code === 'service/file-not-found') {\n *       console.log(\"Could not read file: \" + e['file']);\n *     }\n *   }\n */\n\nexport type ErrorMap<ErrorCode extends string> = {\n  readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n  toString(): string;\n}\n\nexport interface ErrorData {\n  [key: string]: unknown;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n  /** The custom name for all FirebaseErrors. */\n  readonly name: string = ERROR_NAME;\n\n  constructor(\n    /** The error code for this error. */\n    readonly code: string,\n    message: string,\n    /** Custom data for this error. */\n    public customData?: Record<string, unknown>\n  ) {\n    super(message);\n\n    // Fix For ES5\n    // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n    // TODO(dlarocque): Replace this with `new.target`: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget\n    //                   which we can now use since we no longer target ES5.\n    Object.setPrototypeOf(this, FirebaseError.prototype);\n\n    // Maintains proper stack trace for where our error was thrown.\n    // Only available on V8.\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, ErrorFactory.prototype.create);\n    }\n  }\n}\n\nexport class ErrorFactory<\n  ErrorCode extends string,\n  ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n  constructor(\n    private readonly service: string,\n    private readonly serviceName: string,\n    private readonly errors: ErrorMap<ErrorCode>\n  ) {}\n\n  create<K extends ErrorCode>(\n    code: K,\n    ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n  ): FirebaseError {\n    const customData = (data[0] as ErrorData) || {};\n    const fullCode = `${this.service}/${code}`;\n    const template = this.errors[code];\n\n    const message = template ? replaceTemplate(template, customData) : 'Error';\n    // Service Name: Error message (service/code).\n    const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n    const error = new FirebaseError(fullCode, fullMessage, customData);\n\n    return error;\n  }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n  try {\n    let ptr = 0;\n    let result = '';\n    while (ptr < template.length) {\n      const start = template.indexOf('{$', ptr);\n      if (start === -1) {\n        result += template.substring(ptr);\n        break;\n      }\n      const end = template.indexOf('}', start + 2);\n      if (end === -1) {\n        result += template.substring(ptr);\n        break;\n      }\n      const key = template.substring(start + 2, end);\n      const value = data[key];\n      result +=\n        template.substring(ptr, start) +\n        (value != null ? String(value) : `<${key}?>`);\n      ptr = end + 1;\n    }\n    return result;\n  } catch (e) {\n    // Should never happen, but fallback just in case\n    return template;\n  }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Checks whether host is a cloud workstation or not.\n * @public\n */\nexport function isCloudWorkstation(url: string): boolean {\n  // `isCloudWorkstation` is called without protocol in certain connect*Emulator functions\n  // In HTTP request builders, it's called with the protocol.\n  // If called with protocol prefix, it's a valid URL, so we extract the hostname\n  // If called without, we assume the string is the hostname.\n  try {\n    const host =\n      url.startsWith('http://') || url.startsWith('https://')\n        ? new URL(url).hostname\n        : url;\n    return host.endsWith('.cloudworkstations.dev');\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Makes a fetch request to the given server.\n * Mostly used for forwarding cookies in Firebase Studio.\n * @public\n */\nexport async function pingServer(endpoint: string): Promise<boolean> {\n  const result = await fetch(endpoint, {\n    credentials: 'include'\n  });\n  return result.ok;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n  InstantiationMode,\n  InstanceFactory,\n  ComponentType,\n  Dictionary,\n  Name,\n  onInstanceCreatedCallback\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component<T extends Name = Name> {\n  multipleInstances = false;\n  /**\n   * Properties to be added to the service namespace\n   */\n  serviceProps: Dictionary = {};\n\n  instantiationMode = InstantiationMode.LAZY;\n\n  onInstanceCreated: onInstanceCreatedCallback<T> | null = null;\n\n  /**\n   *\n   * @param name The public service name, e.g. app, auth, firestore, database\n   * @param instanceFactory Service factory responsible for creating the public interface\n   * @param type whether the service provided by the component is public or private\n   */\n  constructor(\n    readonly name: T,\n    readonly instanceFactory: InstanceFactory<T>,\n    readonly type: ComponentType\n  ) {}\n\n  setInstantiationMode(mode: InstantiationMode): this {\n    this.instantiationMode = mode;\n    return this;\n  }\n\n  setMultipleInstances(multipleInstances: boolean): this {\n    this.multipleInstances = multipleInstances;\n    return this;\n  }\n\n  setServiceProps(props: Dictionary): this {\n    this.serviceProps = props;\n    return this;\n  }\n\n  setInstanceCreatedCallback(callback: onInstanceCreatedCallback<T>): this {\n    this.onInstanceCreated = callback;\n    return this;\n  }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type LogLevelString =\n  | 'debug'\n  | 'verbose'\n  | 'info'\n  | 'warn'\n  | 'error'\n  | 'silent';\n\nexport interface LogOptions {\n  level: LogLevelString;\n}\n\nexport type LogCallback = (callbackParams: LogCallbackParams) => void;\n\nexport interface LogCallbackParams {\n  level: LogLevelString;\n  message: string;\n  args: unknown[];\n  type: string;\n}\n\n/**\n * A container for all of the Logger instances\n */\nexport const instances: Logger[] = [];\n\n/**\n * The JS SDK supports 5 log levels and also allows a user the ability to\n * silence the logs altogether.\n *\n * The order is a follows:\n * DEBUG < VERBOSE < INFO < WARN < ERROR\n *\n * All of the log types above the current log level will be captured (i.e. if\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\n * `VERBOSE` logs will not)\n */\nexport enum LogLevel {\n  DEBUG,\n  VERBOSE,\n  INFO,\n  WARN,\n  ERROR,\n  SILENT\n}\n\nconst levelStringToEnum: { [key in LogLevelString]: LogLevel } = {\n  'debug': LogLevel.DEBUG,\n  'verbose': LogLevel.VERBOSE,\n  'info': LogLevel.INFO,\n  'warn': LogLevel.WARN,\n  'error': LogLevel.ERROR,\n  'silent': LogLevel.SILENT\n};\n\n/**\n * The default log level\n */\nconst defaultLogLevel: LogLevel = LogLevel.INFO;\n\n/**\n * We allow users the ability to pass their own log handler. We will pass the\n * type of log, the current log level, and any other arguments passed (i.e. the\n * messages that the user wants to log) to this function.\n */\nexport type LogHandler = (\n  loggerInstance: Logger,\n  logType: LogLevel,\n  ...args: unknown[]\n) => void;\n\n/**\n * By default, `console.debug` is not displayed in the developer console (in\n * chrome). To avoid forcing users to have to opt-in to these logs twice\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\n * logs to the `console.log` function.\n */\nconst ConsoleMethod = {\n  [LogLevel.DEBUG]: 'log',\n  [LogLevel.VERBOSE]: 'log',\n  [LogLevel.INFO]: 'info',\n  [LogLevel.WARN]: 'warn',\n  [LogLevel.ERROR]: 'error'\n};\n\n/**\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\n * messages on to their corresponding console counterparts (if the log method\n * is supported by the current log level)\n */\nconst defaultLogHandler: LogHandler = (instance, logType, ...args): void => {\n  if (logType < instance.logLevel) {\n    return;\n  }\n  const now = new Date().toISOString();\n  const method = ConsoleMethod[logType as keyof typeof ConsoleMethod];\n  if (method) {\n    console[method as 'log' | 'info' | 'warn' | 'error'](\n      `[${now}]  ${instance.name}:`,\n      ...args\n    );\n  } else {\n    throw new Error(\n      `Attempted to log a message with an invalid logType (value: ${logType})`\n    );\n  }\n};\n\nexport class Logger {\n  /**\n   * Gives you an instance of a Logger to capture messages according to\n   * Firebase's logging scheme.\n   *\n   * @param name The name that the logs will be associated with\n   */\n  constructor(public name: string) {\n    /**\n     * Capture the current instance for later use\n     */\n    instances.push(this);\n  }\n\n  /**\n   * The log level of the given Logger instance.\n   */\n  private _logLevel = defaultLogLevel;\n\n  get logLevel(): LogLevel {\n    return this._logLevel;\n  }\n\n  set logLevel(val: LogLevel) {\n    if (!(val in LogLevel)) {\n      throw new TypeError(`Invalid value \"${val}\" assigned to \\`logLevel\\``);\n    }\n    this._logLevel = val;\n  }\n\n  // Workaround for setter/getter having to be the same type.\n  setLogLevel(val: LogLevel | LogLevelString): void {\n    this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;\n  }\n\n  /**\n   * The main (internal) log handler for the Logger instance.\n   * Can be set to a new function in internal package code but not by user.\n   */\n  private _logHandler: LogHandler = defaultLogHandler;\n  get logHandler(): LogHandler {\n    return this._logHandler;\n  }\n  set logHandler(val: LogHandler) {\n    if (typeof val !== 'function') {\n      throw new TypeError('Value assigned to `logHandler` must be a function');\n    }\n    this._logHandler = val;\n  }\n\n  /**\n   * The optional, additional, user-defined log handler for the Logger instance.\n   */\n  private _userLogHandler: LogHandler | null = null;\n  get userLogHandler(): LogHandler | null {\n    return this._userLogHandler;\n  }\n  set userLogHandler(val: LogHandler | null) {\n    this._userLogHandler = val;\n  }\n\n  /**\n   * The functions below are all based on the `console` interface\n   */\n\n  debug(...args: unknown[]): void {\n    this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);\n    this._logHandler(this, LogLevel.DEBUG, ...args);\n  }\n  log(...args: unknown[]): void {\n    this._userLogHandler &&\n      this._userLogHandler(this, LogLevel.VERBOSE, ...args);\n    this._logHandler(this, LogLevel.VERBOSE, ...args);\n  }\n  info(...args: unknown[]): void {\n    this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);\n    this._logHandler(this, LogLevel.INFO, ...args);\n  }\n  warn(...args: unknown[]): void {\n    this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);\n    this._logHandler(this, LogLevel.WARN, ...args);\n  }\n  error(...args: unknown[]): void {\n    this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);\n    this._logHandler(this, LogLevel.ERROR, ...args);\n  }\n}\n\nexport function setLogLevel(level: LogLevelString | LogLevel): void {\n  instances.forEach(inst => {\n    inst.setLogLevel(level);\n  });\n}\n\nexport function setUserLogHandler(\n  logCallback: LogCallback | null,\n  options?: LogOptions\n): void {\n  for (const instance of instances) {\n    let customLogLevel: LogLevel | null = null;\n    if (options && options.level) {\n      customLogLevel = levelStringToEnum[options.level];\n    }\n    if (logCallback === null) {\n      instance.userLogHandler = null;\n    } else {\n      instance.userLogHandler = (\n        instance: Logger,\n        level: LogLevel,\n        ...args: unknown[]\n      ) => {\n        const message = args\n          .map(arg => {\n            if (arg == null) {\n              return null;\n            } else if (typeof arg === 'string') {\n              return arg;\n            } else if (typeof arg === 'number' || typeof arg === 'boolean') {\n              return arg.toString();\n            } else if (arg instanceof Error) {\n              return arg.message;\n            } else {\n              try {\n                return JSON.stringify(arg);\n              } catch (ignored) {\n                return null;\n              }\n            }\n          })\n          .filter(arg => arg)\n          .join(' ');\n        if (level >= (customLogLevel ?? instance.logLevel)) {\n          logCallback({\n            level: LogLevel[level].toLowerCase() as LogLevelString,\n            message,\n            args,\n            type: instance.name\n          });\n        }\n      };\n    }\n  }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** The semver (www.semver.org) version of the SDK. */\nexport let SDK_VERSION = '';\n\n/**\n * SDK_VERSION should be set before any database instance is created\n * @internal\n */\nexport function setSDKVersion(version: string): void {\n  SDK_VERSION = version;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\n\nexport type DataConnectErrorCode =\n  | 'other'\n  | 'already-initialized'\n  | 'not-initialized'\n  | 'not-supported'\n  | 'invalid-argument'\n  | 'partial-error'\n  | 'unauthorized';\n\nexport type Code = DataConnectErrorCode;\n\nexport const Code = {\n  OTHER: 'other' as DataConnectErrorCode,\n  ALREADY_INITIALIZED: 'already-initialized' as DataConnectErrorCode,\n  NOT_INITIALIZED: 'not-initialized' as DataConnectErrorCode,\n  NOT_SUPPORTED: 'not-supported' as DataConnectErrorCode,\n  INVALID_ARGUMENT: 'invalid-argument' as DataConnectErrorCode,\n  PARTIAL_ERROR: 'partial-error' as DataConnectErrorCode,\n  UNAUTHORIZED: 'unauthorized' as DataConnectErrorCode\n};\n\n/** An error returned by a DataConnect operation. */\nexport class DataConnectError extends FirebaseError {\n  /** @internal */\n  readonly name: string = 'DataConnectError';\n\n  constructor(code: Code, message: string) {\n    super(code, message);\n\n    // Ensure the instanceof operator works as expected on subclasses of Error.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#custom_error_types\n    // and https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget\n    Object.setPrototypeOf(this, DataConnectError.prototype);\n  }\n\n  /** @internal */\n  toString(): string {\n    return `${this.name}[code=${this.code}]: ${this.message}`;\n  }\n}\n\n/** An error returned by a DataConnect operation. */\nexport class DataConnectOperationError extends DataConnectError {\n  /** @internal */\n  readonly name: string = 'DataConnectOperationError';\n\n  /** The response received from the backend. */\n  readonly response: DataConnectOperationFailureResponse;\n\n  /** @hideconstructor */\n  constructor(message: string, response: DataConnectOperationFailureResponse) {\n    super(Code.PARTIAL_ERROR, message);\n    this.response = response;\n  }\n}\n\nexport interface DataConnectOperationFailureResponse {\n  // The \"data\" provided by the backend in the response message.\n  //\n  // Will be `undefined` if no \"data\" was provided in the response message.\n  // Otherwise, will be `null` if `null` was explicitly specified as the \"data\"\n  // in the response message. Otherwise, will be the value of the \"data\"\n  // specified as the \"data\" in the response message\n  readonly data?: Record<string, unknown> | null;\n\n  // The list of errors provided by the backend in the response message.\n  readonly errors: DataConnectOperationFailureResponseErrorInfo[];\n}\n\n// Information about the error, as provided in the response from the backend.\n// See https://spec.graphql.org/draft/#sec-Errors\nexport interface DataConnectOperationFailureResponseErrorInfo {\n  // The error message.\n  readonly message: string;\n\n  // The path of the field in the response data to which this error relates.\n  // String values in this array refer to field names. Numeric values in this\n  // array always satisfy `Number.isInteger()` and refer to the index in an\n  // array.\n  readonly path: Array<string | number>;\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type FDCScalarValue =\n  | string\n  | number\n  | boolean\n  | undefined\n  | null\n  | Record<string, unknown>\n  | FDCScalarValue[];\n\nexport interface EntityDataObjectJson {\n  map: {\n    [key: string]: FDCScalarValue;\n  };\n  referencedFrom: string[];\n  globalID: string;\n}\n\nexport class EntityDataObject {\n  getServerValue(key: string): unknown {\n    return this.serverValues[key];\n  }\n  private serverValues: { [key: string]: FDCScalarValue } = {};\n  private referencedFrom = new Set<string>();\n  constructor(public readonly globalID: string) {}\n  getServerValues(): { [key: string]: FDCScalarValue } {\n    return this.serverValues;\n  }\n  toJSON(): EntityDataObjectJson {\n    return {\n      globalID: this.globalID,\n      map: this.serverValues,\n      referencedFrom: Array.from(this.referencedFrom)\n    };\n  }\n  static fromJSON(json: EntityDataObjectJson): EntityDataObject {\n    const edo = new EntityDataObject(json.globalID);\n    edo.serverValues = json.map;\n    edo.referencedFrom = new Set(json.referencedFrom);\n    return edo;\n  }\n\n  updateServerValue(\n    key: string,\n    value: FDCScalarValue,\n    requestedFrom: string\n  ): string[] {\n    this.serverValues[key] = value;\n    this.referencedFrom.add(requestedFrom);\n    return Array.from(this.referencedFrom);\n  }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { InternalCacheProvider } from './CacheProvider';\nimport { EntityDataObject } from './EntityDataObject';\nimport { ResultTree } from './ResultTree';\n\nexport class InMemoryCacheProvider implements InternalCacheProvider {\n  private edos = new Map<string, EntityDataObject>();\n  private resultTrees = new Map<string, ResultTree>();\n  constructor(private _keyId: string) {}\n\n  async setResultTree(queryId: string, rt: ResultTree): Promise<void> {\n    this.resultTrees.set(queryId, rt);\n  }\n  async getResultTree(queryId: string): Promise<ResultTree | undefined> {\n    return this.resultTrees.get(queryId);\n  }\n  async updateEntityData(entityData: EntityDataObject): Promise<void> {\n    this.edos.set(entityData.globalID, entityData);\n  }\n  async getEntityData(globalId: string): Promise<EntityDataObject> {\n    if (!this.edos.has(globalId)) {\n      this.edos.set(globalId, new EntityDataObject(globalId));\n    }\n    // Because of the above, we can guarantee that there will be an EDO at the globalId.\n    return this.edos.get(globalId)!;\n  }\n  close(): Promise<void> {\n    // No-op\n    return Promise.resolve();\n  }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Code, DataConnectError } from '../core/error';\n\nimport { InternalCacheProvider } from './CacheProvider';\nimport {\n  EntityDataObject,\n  EntityDataObjectJson,\n  FDCScalarValue\n} from './EntityDataObject';\nimport { ImpactedQueryRefsAccumulator } from './ImpactedQueryRefsAccumulator';\n\nexport const GLOBAL_ID_KEY = '_id';\nexport const OBJECT_LISTS_KEY = '_objectLists';\nexport const REFERENCES_KEY = '_references';\nexport const SCALARS_KEY = '_scalars';\nexport const ENTITY_DATA_KEYS_KEY = '_entity_data_keys';\nexport class EntityNode {\n  entityData?: EntityDataObject;\n  scalars: Record<string, FDCScalarValue> = {};\n  references: { [key: string]: EntityNode } = {};\n  objectLists: {\n    [key: string]: EntityNode[];\n  } = {};\n  globalId?: string;\n  entityDataKeys: Set<string> = new Set();\n\n  async loadData(\n    queryId: string,\n    values: FDCScalarValue,\n    entityIds: Record<string, unknown> | undefined,\n    acc: ImpactedQueryRefsAccumulator,\n    cacheProvider: InternalCacheProvider\n  ): Promise<void> {\n    if (values === undefined) {\n      return;\n    }\n    if (typeof values !== 'object' || Array.isArray(values)) {\n      throw new DataConnectError(\n        Code.INVALID_ARGUMENT,\n        'EntityNode initialized with non-object value'\n      );\n    }\n    if (values === null) {\n      return;\n    }\n\n    if (\n      typeof values === 'object' &&\n      entityIds &&\n      entityIds[GLOBAL_ID_KEY] &&\n      typeof entityIds[GLOBAL_ID_KEY] === 'string'\n    ) {\n      this.globalId = entityIds[GLOBAL_ID_KEY];\n      this.entityData = await cacheProvider.getEntityData(this.globalId);\n    }\n    for (const key in values) {\n      if (values.hasOwnProperty(key)) {\n        if (typeof values[key] === 'object') {\n          if (Array.isArray(values[key])) {\n            const ids: Record<string, unknown> | undefined =\n              entityIds && (entityIds[key] as Record<string, unknown>);\n            const objArray: EntityNode[] = [];\n            const scalarArray: Array<NonNullable<FDCScalarValue>> = [];\n            for (const [index, value] of values[key].entries()) {\n              if (typeof value === 'object') {\n                if (Array.isArray(value)) {\n                  // Note: we don't support sparse arrays.\n                } else {\n                  const entityNode = new EntityNode();\n                  await entityNode.loadData(\n                    queryId,\n                    value,\n                    ids && (ids[index] as Record<string, unknown>),\n                    acc,\n                    cacheProvider\n                  );\n                  objArray.push(entityNode);\n                }\n              } else {\n                scalarArray.push(value);\n              }\n            }\n            if (scalarArray.length > 0 && objArray.length > 0) {\n              this.scalars[key] = values[key];\n            } else if (scalarArray.length > 0) {\n              if (this.entityData) {\n                const impactedRefs = this.entityData.updateServerValue(\n                  key,\n                  scalarArray,\n                  queryId\n                );\n                this.entityDataKeys.add(key);\n                acc.add(impactedRefs);\n              } else {\n                this.scalars[key] = scalarArray;\n              }\n            } else if (objArray.length > 0) {\n              this.objectLists[key] = objArray;\n            } else {\n              this.scalars[key] = [];\n            }\n          } else {\n            if (values[key] === null) {\n              this.scalars[key] = null;\n              continue;\n            }\n            const entityNode = new EntityNode();\n            // TODO: Load Data might need to be pushed into ResultTreeProcessor instead.\n            await entityNode.loadData(\n              queryId,\n              (values as Record<string, FDCScalarValue>)[key],\n              entityIds && (entityIds[key] as Record<string, unknown>),\n              acc,\n              cacheProvider\n            );\n            this.references[key] = entityNode;\n          }\n        } else {\n          if (this.entityData) {\n            const impactedRefs = this.entityData.updateServerValue(\n              key,\n              values[key] as FDCScalarValue,\n              queryId\n            );\n            this.entityDataKeys.add(key);\n            acc.add(impactedRefs);\n          } else {\n            this.scalars[key] = values[key] as FDCScalarValue;\n          }\n        }\n      }\n    }\n    if (this.entityData) {\n      await cacheProvider.updateEntityData(this.entityData);\n    }\n  }\n\n  toJSON(mode: EncodingMode): Record<string, unknown> {\n    const resultObject: Record<string, unknown> = {};\n    if (mode === EncodingMode.hydrated) {\n      if (this.entityData) {\n        for (const key of this.entityDataKeys) {\n          resultObject[key] = this.entityData.getServerValue(key);\n        }\n      }\n\n      if (this.scalars) {\n        Object.assign(resultObject, this.scalars);\n      }\n      if (this.references) {\n        for (const key in this.references) {\n          if (this.references.hasOwnProperty(key)) {\n            resultObject[key] = this.references[key].toJSON(mode);\n          }\n        }\n      }\n      if (this.objectLists) {\n        for (const key in this.objectLists) {\n          if (this.objectLists.hasOwnProperty(key)) {\n            resultObject[key] = this.objectLists[key].map(obj =>\n              obj.toJSON(mode)\n            );\n          }\n        }\n      }\n      return resultObject;\n    } else {\n      // Get JSON representation of dehydrated list\n      if (this.entityData) {\n        resultObject[GLOBAL_ID_KEY] = this.entityData.globalID;\n      }\n\n      resultObject[ENTITY_DATA_KEYS_KEY] = Array.from(this.entityDataKeys);\n\n      if (this.scalars) {\n        resultObject[SCALARS_KEY] = this.scalars;\n      }\n\n      if (this.references) {\n        const references = {} as Record<string, unknown>;\n        for (const key in this.references) {\n          if (this.references.hasOwnProperty(key)) {\n            references[key] = this.references[key].toJSON(mode);\n          }\n        }\n        resultObject[REFERENCES_KEY] = references;\n      }\n      if (this.objectLists) {\n        const objectLists = {} as Record<string, unknown>;\n        for (const key in this.objectLists) {\n          if (this.objectLists.hasOwnProperty(key)) {\n            objectLists[key] = this.objectLists[key].map(obj =>\n              obj.toJSON(mode)\n            );\n          }\n        }\n        resultObject[OBJECT_LISTS_KEY] = objectLists;\n      }\n    }\n\n    return resultObject;\n  }\n\n  static fromJson(obj: DehydratedStubDataObject): EntityNode {\n    const sdo = new EntityNode();\n    if (obj.backingData) {\n      sdo.entityData = EntityDataObject.fromJSON(obj.backingData);\n    }\n    sdo.globalId = obj.globalID;\n    sdo.scalars = obj.scalars;\n    if (obj.references) {\n      const references: Record<string, unknown> = {};\n      for (const key in obj.references) {\n        if (obj.references.hasOwnProperty(key)) {\n          references[key] = EntityNode.fromJson(obj.references[key]);\n        }\n      }\n      sdo.references = references as typeof sdo.references;\n    }\n    if (obj.objectLists) {\n      const objectLists: Record<string, unknown> = {};\n      for (const key in obj.objectLists) {\n        if (obj.objectLists.hasOwnProperty(key)) {\n          objectLists[key] = obj.objectLists[key].map(obj =>\n            EntityNode.fromJson(obj)\n          );\n        }\n      }\n      sdo.objectLists = objectLists as typeof sdo.objectLists;\n    }\n    return sdo;\n  }\n}\n\nexport interface DehydratedStubDataObject {\n  backingData?: EntityDataObjectJson;\n  globalID?: string;\n  scalars: { [key: string]: FDCScalarValue };\n  references: { [key: string]: DehydratedStubDataObject };\n  objectLists: {\n    [key: string]: DehydratedStubDataObject[];\n  };\n}\n\n// Helpful for storing in persistent cache, which is not available yet.\nexport enum EncodingMode {\n  hydrated,\n  dehydrated\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EntityNode, DehydratedStubDataObject } from './EntityNode';\n\nexport class ResultTree {\n  /**\n   * Create a {@link ResultTree} from a dehydrated JSON object.\n   * @param value The dehydrated JSON object.\n   * @returns The {@link ResultTree}.\n   */\n  static fromJson(value: DehydratedResultTreeJson): ResultTree {\n    return new ResultTree(\n      EntityNode.fromJson(value.rootStub),\n      value.maxAge,\n      value.cachedAt,\n      value.lastAccessed\n    );\n  }\n  constructor(\n    private rootStub: EntityNode,\n    private maxAge: number = 0,\n    public readonly cachedAt: Date,\n    private _lastAccessed: Date\n  ) {}\n  isStale(): boolean {\n    return (\n      Date.now() - new Date(this.cachedAt.getTime()).getTime() >\n      this.maxAge * 1000\n    );\n  }\n  updateMaxAge(maxAgeInSeconds: number): void {\n    this.maxAge = maxAgeInSeconds;\n  }\n  updateAccessed(): void {\n    this._lastAccessed = new Date();\n  }\n  get lastAccessed(): Date {\n    return this._lastAccessed;\n  }\n  getRootStub(): EntityNode {\n    return this.rootStub;\n  }\n}\n\ninterface DehydratedResultTreeJson {\n  rootStub: DehydratedStubDataObject;\n  maxAge: number;\n  cachedAt: Date;\n  lastAccessed: Date;\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class ImpactedQueryRefsAccumulator {\n  impacted = new Set<string>();\n  constructor(private queryId: string) {}\n  add(impacted: string[]): void {\n    impacted\n      .filter(ref => ref !== this.queryId)\n      .forEach(ref => this.impacted.add(ref));\n  }\n  consumeEvents(): string[] {\n    const events = Array.from(this.impacted);\n    this.impacted.clear();\n    return events;\n  }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { InternalCacheProvider } from './CacheProvider';\nimport { EncodingMode, EntityNode } from './EntityNode';\nimport { ImpactedQueryRefsAccumulator } from './ImpactedQueryRefsAccumulator';\n\ninterface DehydratedResults {\n  entityNode: EntityNode;\n  impacted: string[];\n}\n\nexport class ResultTreeProcessor {\n  /**\n   * Hydrate the EntityNode into a JSON object so that it can be returned to the user.\n   * @param rootStubObject\n   * @returns {string}\n   */\n  hydrateResults(rootStubObject: EntityNode): Record<string, unknown> {\n    return rootStubObject.toJSON(EncodingMode.hydrated);\n  }\n  /**\n   * Dehydrate results so that they can be stored in the cache.\n   * @param json\n   * @param entityIds\n   * @param cacheProvider\n   * @param queryId\n   * @returns {Promise<DehydratedResults>}\n   */\n  async dehydrateResults(\n    json: Record<string, unknown>,\n    entityIds: Record<string, unknown>,\n    cacheProvider: InternalCacheProvider,\n    queryId: string\n  ): Promise<DehydratedResults> {\n    const acc = new ImpactedQueryRefsAccumulator(queryId);\n    const entityNode = new EntityNode();\n    await entityNode.loadData(queryId, json, entityIds, acc, cacheProvider);\n    return {\n      entityNode,\n      impacted: acc.consumeEvents()\n    };\n  }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { generateSHA256Hash } from '@firebase/util';\n\nimport {\n  CacheProvider,\n  CacheSettings,\n  type ConnectorConfig\n} from '../api/DataConnect';\nimport { Code, DataConnectError } from '../core/error';\nimport { type AuthTokenProvider } from '../core/FirebaseAuthProvider';\n\nimport { InternalCacheProvider } from './CacheProvider';\nimport { InMemoryCacheProvider } from './InMemoryCacheProvider';\nimport { ResultTree } from './ResultTree';\nimport { ResultTreeProcessor } from './ResultTreeProcessor';\n\nexport const Memory = 'memory';\n\nexport type DataConnectStorage = typeof Memory;\n\n/**\n * ServerValues\n */\nexport interface ServerValues extends Record<string, unknown> {\n  maxAge?: number;\n}\n\nexport class DataConnectCache {\n  private cacheProvider: InternalCacheProvider | null = null;\n  private uid: string | null = null;\n  constructor(\n    private authProvider: AuthTokenProvider,\n    private projectId: string,\n    private connectorConfig: ConnectorConfig,\n    private host: string,\n    public cacheSettings: CacheSettings\n  ) {\n    this.authProvider.addTokenChangeListener(async _ => {\n      const newUid = this.authProvider.getAuth().getUid();\n      // We should only close if the token changes and so does the new UID\n      if (this.uid !== newUid) {\n        this.cacheProvider?.close();\n        this.uid = newUid;\n        const identifier = await this.getIdentifier(this.uid);\n        this.cacheProvider = this.initializeNewProviders(identifier);\n      }\n    });\n  }\n\n  async initialize(): Promise<void> {\n    if (!this.cacheProvider) {\n      const identifier = await this.getIdentifier(this.uid);\n      this.cacheProvider = this.initializeNewProviders(identifier);\n    }\n  }\n\n  async getIdentifier(uid: string | null): Promise<string> {\n    const identifier = `${\n      'memory' // TODO: replace this with indexeddb when persistence is available.\n    }-${this.projectId}-${this.connectorConfig.service}-${\n      this.connectorConfig.connector\n    }-${this.connectorConfig.location}-${uid}-${this.host}`;\n    const sha256 = await generateSHA256Hash(identifier);\n    return sha256;\n  }\n\n  initializeNewProviders(identifier: string): InternalCacheProvider {\n    return this.cacheSettings.cacheProvider.initialize(identifier);\n  }\n\n  async containsResultTree(queryId: string): Promise<boolean> {\n    await this.initialize();\n    const resultTree = await this.cacheProvider!.getResultTree(queryId);\n    return resultTree !== undefined;\n  }\n  async getResultTree(queryId: string): Promise<ResultTree | undefined> {\n    await this.initialize();\n    return this.cacheProvider!.getResultTree(queryId);\n  }\n  async getResultJSON(queryId: string): Promise<Record<string, unknown>> {\n    await this.initialize();\n    const processor = new ResultTreeProcessor();\n    const cacheProvider = this.cacheProvider;\n    const resultTree = await cacheProvider!.getResultTree(queryId);\n    if (!resultTree) {\n      throw new DataConnectError(\n        Code.INVALID_ARGUMENT,\n        `${queryId} not found in cache. Call \"update()\" first.`\n      );\n    }\n    return processor.hydrateResults(resultTree.getRootStub());\n  }\n  async update(\n    queryId: string,\n    serverValues: ServerValues,\n    entityIds: Record<string, unknown>\n  ): Promise<string[]> {\n    await this.initialize();\n    const processor = new ResultTreeProcessor();\n    const cacheProvider = this.cacheProvider;\n    const { entityNode: stubDataObject, impacted } =\n      await processor.dehydrateResults(\n        serverValues,\n        entityIds,\n        cacheProvider!,\n        queryId\n      );\n    const now = new Date();\n    await cacheProvider!.setResultTree(\n      queryId,\n      new ResultTree(\n        stubDataObject,\n        serverValues.maxAge || this.cacheSettings.maxAgeSeconds,\n        now,\n        now\n      )\n    );\n    return impacted;\n  }\n}\n\nexport class MemoryStub implements CacheProvider<'MEMORY'> {\n  type: 'MEMORY' = 'MEMORY';\n  /**\n   * @internal\n   */\n  initialize(cacheId: string): InMemoryCacheProvider {\n    return new InMemoryCacheProvider(cacheId);\n  }\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @public\n * Generates a SHA-256 hash for the given input string.\n *\n * @param input The string to hash.\n * @returns A promise that resolves to the SHA-256 hash as a hex string.\n */\nexport async function generateSHA256Hash(input: string): Promise<string> {\n  const textEncoder = new TextEncoder();\n  const data = textEncoder.encode(input);\n  const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n\n  // Convert ArrayBuffer to hex string\n  const hashArray = Array.from(new Uint8Array(hashBuffer));\n  const hexHash = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n  return hexHash;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, _isFirebaseServerApp } from '@firebase/app';\nimport {\n  AppCheckInternalComponentName,\n  AppCheckTokenListener,\n  AppCheckTokenResult,\n  FirebaseAppCheckInternal\n} from '@firebase/app-check-interop-types';\nimport { Provider } from '@firebase/component';\n\n/**\n * @internal\n * Abstraction around AppCheck's token fetching capabilities.\n */\nexport class AppCheckTokenProvider {\n  private appCheck?: FirebaseAppCheckInternal | null;\n  private serverAppAppCheckToken?: string;\n  constructor(\n    app: FirebaseApp,\n    private appCheckProvider?: Provider<AppCheckInternalComponentName>\n  ) {\n    if (_isFirebaseServerApp(app) && app.settings.appCheckToken) {\n      this.serverAppAppCheckToken = app.settings.appCheckToken;\n    }\n    this.appCheck = appCheckProvider?.getImmediate({ optional: true });\n    if (!this.appCheck) {\n      void appCheckProvider\n        ?.get()\n        .then(appCheck => (this.appCheck = appCheck))\n        .catch();\n    }\n  }\n\n  getToken(): Promise<AppCheckTokenResult | null> {\n    if (this.serverAppAppCheckToken) {\n      return Promise.resolve({ token: this.serverAppAppCheckToken });\n    }\n\n    if (!this.appCheck) {\n      return new Promise<AppCheckTokenResult | null>((resolve, reject) => {\n        // Support delayed initialization of FirebaseAppCheck. This allows our\n        // customers to initialize the RTDB SDK before initializing Firebase\n        // AppCheck and ensures that all requests are authenticated if a token\n        // becomes available before the timoeout below expires.\n        setTimeout(() => {\n          if (this.appCheck) {\n            this.getToken().then(resolve, reject);\n          } else {\n            resolve(null);\n          }\n        }, 0);\n      });\n    }\n    return this.appCheck.getToken();\n  }\n\n  addTokenChangeListener(listener: AppCheckTokenListener): void {\n    void this.appCheckProvider\n      ?.get()\n      .then(appCheck => appCheck.addTokenListener(listener));\n  }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Logger, LogLevelString } from '@firebase/logger';\n\nimport { SDK_VERSION } from './core/version';\n\nconst logger = new Logger('@firebase/data-connect');\nexport function setLogLevel(logLevel: LogLevelString): void {\n  logger.setLogLevel(logLevel);\n}\nexport function logDebug(msg: string): void {\n  logger.debug(`DataConnect (${SDK_VERSION}): ${msg}`);\n}\n\nexport function logError(msg: string): void {\n  logger.error(`DataConnect (${SDK_VERSION}): ${msg}`);\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseOptions } from '@firebase/app-types';\nimport {\n  FirebaseAuthInternal,\n  FirebaseAuthInternalName,\n  FirebaseAuthTokenData\n} from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\n\nimport { logDebug, logError } from '../logger';\n\n// @internal\nexport interface AuthTokenProvider {\n  getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData | null>;\n  addTokenChangeListener(listener: AuthTokenListener): void;\n  getAuth(): FirebaseAuthInternal;\n}\nexport type AuthTokenListener = (token: string | null) => void;\n\n// @internal\nexport class FirebaseAuthProvider implements AuthTokenProvider {\n  private _auth: FirebaseAuthInternal;\n  constructor(\n    private _appName: string,\n    private _options: FirebaseOptions,\n    private _authProvider: Provider<FirebaseAuthInternalName>\n  ) {\n    this._auth = _authProvider.getImmediate({ optional: true })!;\n    if (!this._auth) {\n      _authProvider.onInit(auth => (this._auth = auth));\n    }\n  }\n  getAuth(): FirebaseAuthInternal {\n    return this._auth;\n  }\n  getToken(forceRefresh: boolean): Promise<FirebaseAuthTokenData | null> {\n    if (!this._auth) {\n      return new Promise((resolve, reject) => {\n        setTimeout(() => {\n          if (this._auth) {\n            this.getToken(forceRefresh).then(resolve, reject);\n          } else {\n            resolve(null);\n          }\n        }, 0);\n      });\n    }\n    return this._auth.getToken(forceRefresh).catch(error => {\n      if (error && error.code === 'auth/token-not-initialized') {\n        logDebug(\n          'Got auth/token-not-initialized error.  Treating as null token.'\n        );\n        return null;\n      } else {\n        logError(\n          'Error received when attempting to retrieve token: ' +\n            JSON.stringify(error)\n        );\n        return Promise.reject(error);\n      }\n    });\n  }\n  addTokenChangeListener(listener: AuthTokenListener): void {\n    this._auth?.addAuthTokenListener(listener);\n  }\n  removeTokenChangeListener(listener: (token: string | null) => void): void {\n    this._authProvider\n      .get()\n      .then(auth => auth.removeAuthTokenListener(listener))\n      .catch(err => logError(err));\n  }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Extensions } from '../network';\n\nimport { DataConnect, DataConnectOptions } from './DataConnect';\nexport const QUERY_STR = 'query';\nexport const MUTATION_STR = 'mutation';\nexport type ReferenceType = typeof QUERY_STR | typeof MUTATION_STR;\n\nexport const SOURCE_SERVER = 'SERVER';\nexport const SOURCE_CACHE = 'CACHE';\nexport type DataSource = typeof SOURCE_CACHE | typeof SOURCE_SERVER;\n\nexport interface OpResult<Data> {\n  data: Data;\n  source: DataSource;\n  fetchTime: string;\n  extensions?: Extensions;\n}\n\nexport interface OperationRef<_Data, Variables> {\n  name: string;\n  variables: Variables;\n  refType: ReferenceType;\n  dataConnect: DataConnect;\n}\n\nexport interface DataConnectResult<Data, Variables> extends OpResult<Data> {\n  ref: OperationRef<Data, Variables>;\n  // future metadata\n}\n\n/**\n * Serialized RefInfo as a result of `QueryResult.toJSON().refInfo`\n */\nexport interface RefInfo<Variables> {\n  name: string;\n  variables: Variables;\n  connectorConfig: DataConnectOptions;\n}\n/**\n * Serialized Ref as a result of `QueryResult.toJSON()`\n */\nexport interface SerializedRef<Data, Variables> extends OpResult<Data> {\n  refInfo: RefInfo<Variables>;\n}\n","/**\n * @license\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { OpResult } from '../api/Reference';\nimport { DataConnectExtension } from '../network';\nexport function parseEntityIds<T>(\n  result: OpResult<T>\n): Record<string, unknown> {\n  // Iterate through extensions.dataConnect\n  const dataConnectExtensions = result.extensions?.dataConnect;\n  const dataCopy = Object.assign(result);\n  if (!dataConnectExtensions) {\n    return dataCopy;\n  }\n  const ret: Record<string, unknown> = {};\n  for (const extension of dataConnectExtensions) {\n    const { path } = extension;\n    populatePath(path, ret, extension);\n  }\n  return ret;\n}\n\n// mutates the object to update the path\nexport function populatePath(\n  path: Array<string | number>,\n  toUpdate: Record<string | number, unknown>,\n  extension: DataConnectExtension\n): void {\n  let curObj: Record<string | number, unknown> = toUpdate;\n  for (const slice of path) {\n    if (typeof curObj[slice] !== 'object') {\n      curObj[slice] = {};\n    }\n    curObj = curObj[slice] as Record<string, unknown>;\n  }\n\n  if ('entityId' in extension && extension.entityId) {\n    curObj['_id'] = extension.entityId;\n  } else if ('entityIds' in extension) {\n    const entityArr = extension.entityIds;\n    for (let i = 0; i < entityArr.length; i++) {\n      const entityId = entityArr[i];\n      if (typeof curObj[i] === 'undefined') {\n        curObj[i] = {};\n      }\n      (curObj[i] as Record<string, unknown>)._id = entityId;\n    }\n  }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type HmacImpl = (obj: Record<string, unknown>) => string;\nexport let encoderImpl: HmacImpl;\nexport type DecodeHmacImpl = (s: string) => Record<string, unknown>;\nexport let decoderImpl: DecodeHmacImpl;\nexport function setEncoder(encoder: HmacImpl): void {\n  encoderImpl = encoder;\n}\nexport function setDecoder(decoder: DecodeHmacImpl): void {\n  decoderImpl = decoder;\n}\nfunction sortKeysForObj(o: Record<string, unknown>): Record<string, unknown> {\n  return Object.keys(o)\n    .sort()\n    .reduce((accumulator, currentKey) => {\n      accumulator[currentKey] = o[currentKey];\n      return accumulator;\n    }, {} as Record<string, unknown>);\n}\nsetEncoder((o: Record<string, unknown>) => JSON.stringify(sortKeysForObj(o)));\nsetDecoder(s => sortKeysForObj(JSON.parse(s)));\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { type DataConnect } from '../../api/DataConnect';\nimport { QueryRef, QueryResult } from '../../api/query';\nimport {\n  QUERY_STR,\n  SerializedRef,\n  SOURCE_SERVER,\n  DataSource,\n  SOURCE_CACHE\n} from '../../api/Reference';\nimport { DataConnectSubscription } from '../../api.browser';\nimport { DataConnectCache, ServerValues } from '../../cache/Cache';\nimport { parseEntityIds } from '../../cache/cacheUtils';\nimport { EncodingMode } from '../../cache/EntityNode';\nimport {\n  DataConnectTransportInterface,\n  Extensions,\n  DataConnectExtensionWithMaxAge,\n  ExtensionsWithMaxAge,\n  SubscribeObserver,\n  DataConnectResponse\n} from '../../network';\nimport { decoderImpl, encoderImpl } from '../../util/encoder';\nimport {\n  Code,\n  DataConnectError,\n  DataConnectOperationError,\n  DataConnectOperationFailureResponse\n} from '../error';\n\nimport {\n  OnCompleteSubscription,\n  OnErrorSubscription,\n  OnResultSubscription\n} from './subscribe';\n\nexport function getRefSerializer<Data, Variables>(\n  queryRef: QueryRef<Data, Variables>,\n  data: Data,\n  source: DataSource,\n  fetchTime: string\n) {\n  return function toJSON(): SerializedRef<Data, Variables> {\n    return {\n      data,\n      refInfo: {\n        name: queryRef.name,\n        variables: queryRef.variables,\n        connectorConfig: {\n          projectId: queryRef.dataConnect.app.options.projectId!,\n          ...queryRef.dataConnect.getSettings()\n        }\n      },\n      fetchTime,\n      source\n    };\n  };\n}\n\nexport class QueryManager {\n  async preferCacheResults<Data, Variables>(\n    queryRef: QueryRef<Data, Variables>,\n    allowStale = false\n  ): Promise<QueryResult<Data, Variables>> {\n    let cacheResult: QueryResult<Data, Variables> | undefined;\n    try {\n      cacheResult = await this.fetchCacheResults(queryRef, allowStale);\n    } catch (e) {\n      // Ignore the error and try to fetch from the server.\n    }\n    if (cacheResult) {\n      return cacheResult;\n    }\n    return this.fetchServerResults(queryRef);\n  }\n  private callbacks = new Map<\n    string,\n    Array<DataConnectSubscription<unknown, unknown>>\n  >();\n  /**\n   * Map of serialized query keys to most recent Query Result. Used as a simple fallback cache\n   * for subsciptions if caching is not enabled.\n   */\n  private subscriptionCache = new Map<string, QueryResult<unknown, unknown>>();\n  constructor(\n    private transport: DataConnectTransportInterface,\n    private dc: DataConnect,\n    private cache?: DataConnectCache\n  ) {}\n  private queue: Array<Promise<unknown>> = [];\n  async waitForQueuedWrites(): Promise<void> {\n    for (const promise of this.queue) {\n      await promise;\n    }\n    this.queue = [];\n  }\n\n  updateSSR<Data, Variables>(updatedData: QueryResult<Data, Variables>): void {\n    this.queue.push(\n      this.updateCache(updatedData).then(async result =>\n        this.publishCacheResultsToSubscribers(result, updatedData.fetchTime)\n      )\n    );\n  }\n\n  async updateCache<Data, Variables>(\n    result: QueryResult<Data, Variables>,\n    extensions?: DataConnectExtensionWithMaxAge[]\n  ): Promise<string[]> {\n    await this.waitForQueuedWrites();\n    if (this.cache) {\n      const entityIds = parseEntityIds(result);\n      const updatedMaxAge = getMaxAgeFromExtensions(extensions);\n      if (updatedMaxAge !== undefined) {\n        this.cache.cacheSettings.maxAgeSeconds = updatedMaxAge;\n      }\n      return this.cache.update(\n        encoderImpl({\n          name: result.ref.name,\n          variables: result.ref.variables,\n          refType: QUERY_STR\n        }),\n        result.data as ServerValues,\n        entityIds\n      );\n    } else {\n      const key = encoderImpl({\n        name: result.ref.name,\n        variables: result.ref.variables,\n        refType: QUERY_STR\n      });\n      this.subscriptionCache.set(key, result);\n      return [key];\n    }\n  }\n\n  addSubscription<Data, Variables>(\n    queryRef: QueryRef<Data, Variables>,\n    onResultCallback: OnResultSubscription<Data, Variables>,\n    onCompleteCallback?: OnCompleteSubscription,\n    onErrorCallback?: OnErrorSubscription,\n    initialCache?: QueryResult<Data, Variables>\n  ): () => void {\n    const key = encoderImpl({\n      name: queryRef.name,\n      variables: queryRef.variables,\n      refType: QUERY_STR\n    });\n\n    const unsubscribe = (): void => {\n      if (this.callbacks.has(key)) {\n        const callbackList = this.callbacks.get(key)!;\n        const newList = callbackList.filter(\n          callback => callback !== subscription\n        );\n        this.callbacks.set(key, newList);\n\n        if (newList.length === 0) {\n          this.callbacks.delete(key);\n          this.transport.invokeUnsubscribe(queryRef.name, queryRef.variables);\n        }\n        onCompleteCallback?.();\n      }\n    };\n    const subscription: DataConnectSubscription<Data, Variables> = {\n      userCallback: onResultCallback,\n      errCallback: onErrorCallback,\n      unsubscribe\n    };\n\n    if (initialCache) {\n      this.updateSSR(initialCache);\n    }\n\n    const promise = this.preferCacheResults(queryRef, /*allowStale=*/ true);\n    // We want to ignore the error and let subscriptions handle it\n    promise.then(undefined, err => {});\n\n    if (this.callbacks.has(key)) {\n      this.callbacks\n        .get(key)!\n        .push(subscription as DataConnectSubscription<unknown, unknown>);\n    } else {\n      this.callbacks.set(key, [\n        subscription as DataConnectSubscription<unknown, unknown>\n      ]);\n\n      // only invoke subscription if we don't already have an active subscription\n      this.transport.invokeSubscribe<Data, Variables>(\n        this.makeSubscribeObserver(queryRef),\n        queryRef.name,\n        queryRef.variables\n      );\n    }\n\n    return unsubscribe;\n  }\n\n  async fetchServerResults<Data, Variables>(\n    queryRef: QueryRef<Data, Variables>\n  ): Promise<QueryResult<Data, Variables>> {\n    await this.waitForQueuedWrites();\n    const key = encoderImpl({\n      name: queryRef.name,\n      variables: queryRef.variables,\n      refType: QUERY_STR\n    });\n    try {\n      const result = await this.transport.invokeQuery<Data, Variables>(\n        queryRef.name,\n        queryRef.variables\n      );\n      const fetchTime = Date.now().toString();\n      const originalExtensions = result.extensions;\n      const queryResult: QueryResult<Data, Variables> = {\n        ...result,\n        ref: queryRef,\n        source: SOURCE_SERVER,\n        fetchTime,\n        data: result.data,\n        extensions: getDataConnectExtensionsWithoutMaxAge(originalExtensions),\n        toJSON: getRefSerializer(\n          queryRef,\n          result.data,\n          SOURCE_SERVER,\n          fetchTime\n        )\n      };\n      const updatedKeys = await this.updateCache(\n        queryResult,\n        originalExtensions?.dataConnect\n      );\n      this.publishDataToSubscribers(key, queryResult);\n      if (this.cache) {\n        await this.publishCacheResultsToSubscribers(updatedKeys, fetchTime);\n      } else {\n        this.subscriptionCache.set(key, queryResult);\n      }\n      return queryResult;\n    } catch (e) {\n      this.publishErrorToSubscribers(key, e);\n      throw e;\n    }\n  }\n\n  async fetchCacheResults<Data, Variables>(\n    queryRef: QueryRef<Data, Variables>,\n    allowStale = false\n  ): Promise<QueryResult<Data, Variables>> {\n    await this.waitForQueuedWrites();\n    let result: QueryResult<Data, Variables> | undefined | null;\n    if (!this.cache) {\n      result = await this.getFromSubscriberCache(queryRef);\n    } else {\n      result = await this.getFromResultTreeCache(queryRef, allowStale);\n    }\n    if (!result) {\n      throw new DataConnectError(\n        Code.OTHER,\n        'No cache entry found for query: ' + queryRef.name\n      );\n    }\n    const fetchTime = Date.now().toString();\n    const queryResult: QueryResult<Data, Variables> = {\n      ...result,\n      ref: queryRef,\n      source: SOURCE_CACHE,\n      fetchTime,\n      data: result.data,\n      extensions: result.extensions,\n      toJSON: getRefSerializer(queryRef, result.data, SOURCE_CACHE, fetchTime)\n    };\n    if (this.cache) {\n      const key = encoderImpl({\n        name: queryRef.name,\n        variables: queryRef.variables,\n        refType: QUERY_STR\n      });\n      await this.publishCacheResultsToSubscribers([key], fetchTime);\n    } else {\n      const key = encoderImpl({\n        name: queryRef.name,\n        variables: queryRef.variables,\n        refType: QUERY_STR\n      });\n      this.subscriptionCache.set(key, queryResult);\n      this.publishDataToSubscribers(key, queryResult);\n    }\n\n    return queryResult;\n  }\n\n  publishErrorToSubscribers(key: string, err: unknown): void {\n    this.callbacks.get(key)?.forEach(subscription => {\n      if (subscription.errCallback) {\n        subscription.errCallback(err as DataConnectError);\n      }\n    });\n  }\n\n  async getFromResultTreeCache<Data, Variables>(\n    queryRef: QueryRef<Data, Variables>,\n    allowStale = false\n  ): Promise<QueryResult<Data, Variables> | null> {\n    const key = encoderImpl({\n      name: queryRef.name,\n      variables: queryRef.variables,\n      refType: QUERY_STR\n    });\n    if (!this.cache || !(await this.cache.containsResultTree(key))) {\n      return null;\n    }\n    const cacheResult: Data = (await this.cache!.getResultJSON(key)) as Data;\n    const resultTree = await this.cache!.getResultTree(key);\n    if (!allowStale && resultTree!.isStale()) {\n      return null;\n    }\n    const result: QueryResult<Data, Variables> = {\n      source: SOURCE_CACHE,\n      ref: queryRef,\n      data: cacheResult,\n      toJSON: getRefSerializer(\n        queryRef,\n        cacheResult,\n        SOURCE_CACHE,\n        resultTree!.cachedAt.toString()\n      ),\n      fetchTime: resultTree!.cachedAt.toString()\n    };\n    (await this.cache!.getResultTree(key))!.updateAccessed();\n    return result;\n  }\n  async getFromSubscriberCache<Data, Variables>(\n    queryRef: QueryRef<Data, Variables>\n  ): Promise<QueryResult<Data, Variables> | undefined> {\n    const key = encoderImpl({\n      name: queryRef.name,\n      variables: queryRef.variables,\n      refType: QUERY_STR\n    });\n    if (!this.subscriptionCache.has(key)) {\n      return;\n    }\n    const result = this.subscriptionCache.get(key);\n    result!.source = SOURCE_CACHE;\n    result!.toJSON = getRefSerializer(\n      result!.ref,\n      result!.data,\n      SOURCE_CACHE,\n      result!.fetchTime\n    );\n    return result as QueryResult<Data, Variables>;\n  }\n\n  /** Call the registered onNext callbacks for the given key */\n  publishDataToSubscribers(\n    key: string,\n    queryResult: QueryResult<unknown, unknown>\n  ): void {\n    if (!this.callbacks.has(key)) {\n      return;\n    }\n    const subscribers = this.callbacks.get(key);\n    subscribers!.forEach(callback => {\n      callback.userCallback(queryResult);\n    });\n  }\n  async publishCacheResultsToSubscribers(\n    impactedQueries: string[],\n    fetchTime: string\n  ): Promise<void> {\n    if (!this.cache) {\n      return;\n    }\n    for (const query of impactedQueries) {\n      const callbacks = this.callbacks.get(query);\n      if (!callbacks) {\n        continue;\n      }\n      const newJson = (await this.cache.getResultTree(query))!\n        .getRootStub()\n        .toJSON(EncodingMode.hydrated);\n      const { name, variables } = decoderImpl(query) as unknown as QueryRef<\n        unknown,\n        unknown\n      >;\n      const queryRef: QueryRef<unknown, unknown> = {\n        dataConnect: this.dc,\n        refType: QUERY_STR,\n        name,\n        variables\n      };\n      this.publishDataToSubscribers(query, {\n        data: newJson,\n        fetchTime,\n        ref: queryRef,\n        source: SOURCE_CACHE,\n        toJSON: getRefSerializer(queryRef, newJson, SOURCE_CACHE, fetchTime)\n      });\n    }\n  }\n  enableEmulator(host: string, port: number): void {\n    this.transport.useEmulator(host, port);\n  }\n\n  /**\n   * Create a new {@link SubscribeObserver} for the given QueryRef. This will be passed to\n   * {@link DataConnectTransportInterface.invokeSubscribe | invokeSubscribe()} to notify the query\n   * layer of data update notifications or if the stream disconnected.\n   */\n  private makeSubscribeObserver<Data, Variables>(\n    queryRef: QueryRef<Data, Variables>\n  ): SubscribeObserver<Data> {\n    const key = encoderImpl({\n      name: queryRef.name,\n      variables: queryRef.variables,\n      refType: QUERY_STR\n    });\n    return {\n      onData: async response => {\n        await this.handleStreamNotification(key, response, queryRef);\n      },\n      onDisconnect: (code, reason) => {\n        this.handleStreamDisconnect(key, code, reason);\n      },\n      onError: error => {\n        this.publishErrorToSubscribers(key, error);\n      }\n    };\n  }\n\n  /**\n   * Handle a data update notification from the stream. Notify subscribers of results/errors, and\n   * update the cache.\n   */\n  private async handleStreamNotification<Data, Variables>(\n    key: string,\n    response: DataConnectResponse<Data>,\n    queryRef: QueryRef<Data, Variables>\n  ): Promise<void> {\n    if (response.errors && response.errors.length > 0) {\n      const stringified = JSON.stringify(\n        response.errors.map(e => {\n          if (e && typeof e === 'object') {\n            return {\n              message: (e as unknown as { message: string }).message,\n              code: (e as unknown as { code?: unknown }).code\n            };\n          }\n          return e;\n        })\n      );\n      const failureResponse: DataConnectOperationFailureResponse = {\n        errors: response.errors as [],\n        data: response.data as Record<string, unknown>\n      };\n      const error = new DataConnectOperationError(\n        'DataConnect error received from subscribe notification: ' +\n          stringified,\n        failureResponse\n      );\n      this.publishErrorToSubscribers(key, error);\n      return;\n    }\n\n    const fetchTime = Date.now().toString();\n    const queryResult: QueryResult<Data, Variables> = {\n      ref: queryRef,\n      source: SOURCE_SERVER,\n      fetchTime,\n      data: response.data,\n      extensions: getDataConnectExtensionsWithoutMaxAge(response.extensions),\n      toJSON: getRefSerializer(\n        queryRef,\n        response.data,\n        SOURCE_SERVER,\n        fetchTime\n      )\n    };\n    const updatedKeys = await this.updateCache(\n      queryResult,\n      response.extensions?.dataConnect\n    );\n    this.publishDataToSubscribers(key, queryResult);\n    if (this.cache) {\n      await this.publishCacheResultsToSubscribers(updatedKeys, fetchTime);\n    }\n  }\n\n  /**\n   * Handle a disconnect from the stream. Unsubscribe all callbacks for the given key.\n   */\n  private handleStreamDisconnect(\n    key: string,\n    code: string,\n    reason: string\n  ): void {\n    const error = new DataConnectError(code as Code, reason);\n    this.publishErrorToSubscribers(key, error);\n\n    const callbacks = this.callbacks.get(key);\n    if (callbacks) {\n      [...callbacks].forEach(cb => cb.unsubscribe());\n    }\n    return;\n  }\n}\n\nexport function getMaxAgeFromExtensions(\n  extensions: DataConnectExtensionWithMaxAge[] | undefined\n): number | undefined {\n  if (!extensions) {\n    return;\n  }\n  for (const extension of extensions) {\n    if (\n      'maxAge' in extension &&\n      extension.maxAge !== undefined &&\n      extension.maxAge !== null\n    ) {\n      if (extension.maxAge.endsWith('s')) {\n        return Number(\n          extension.maxAge.substring(0, extension.maxAge.length - 1)\n        );\n      }\n    }\n  }\n}\nfunction getDataConnectExtensionsWithoutMaxAge(\n  extensions: ExtensionsWithMaxAge\n): Extensions | undefined {\n  return {\n    dataConnect: extensions.dataConnect?.filter(\n      extension => 'entityId' in extension || 'entityIds' in extension\n    )\n  };\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DataConnectOptions, TransportOptions } from '../api/DataConnect';\nimport { AppCheckTokenProvider } from '../core/AppCheckTokenProvider';\nimport { Code, DataConnectError } from '../core/error';\nimport { AuthTokenProvider } from '../core/FirebaseAuthProvider';\nimport { SDK_VERSION } from '../core/version';\nimport { logDebug } from '../logger';\n\n/**\n * enum representing different flavors of the SDK used by developers\n * use the CallerSdkType for type-checking, and the CallerSdkTypeEnum for value-checking/assigning\n */\nexport type CallerSdkType =\n  | 'Base' // Core JS SDK\n  | 'Generated' // Generated JS SDK\n  | 'TanstackReactCore' // Tanstack non-generated React SDK\n  | 'GeneratedReact' // Generated React SDK\n  | 'TanstackAngularCore' // Tanstack non-generated Angular SDK\n  | 'GeneratedAngular'; // Generated Angular SDK\nexport const CallerSdkTypeEnum = {\n  Base: 'Base', // Core JS SDK\n  Generated: 'Generated', // Generated JS SDK\n  TanstackReactCore: 'TanstackReactCore', // Tanstack non-generated React SDK\n  GeneratedReact: 'GeneratedReact', // Tanstack non-generated Angular SDK\n  TanstackAngularCore: 'TanstackAngularCore', // Tanstack non-generated Angular SDK\n  GeneratedAngular: 'GeneratedAngular' // Generated Angular SDK\n} as const;\n\nexport interface DataConnectEntityArray {\n  entityIds: string[];\n}\n\nexport interface DataConnectSingleEntity {\n  entityId: string;\n}\n\nexport type DataConnectExtension = {\n  path: Array<string | number>;\n} & (DataConnectEntityArray | DataConnectSingleEntity);\n\n/** @internal */\nexport interface DataConnectMaxAge {\n  maxAge: string;\n}\n\n/** @internal */\nexport type DataConnectExtensionWithMaxAge = {\n  path: Array<string | number>;\n} & (DataConnectEntityArray | DataConnectSingleEntity | DataConnectMaxAge);\n\nexport interface Extensions {\n  dataConnect?: DataConnectExtension[];\n}\n\n/** @internal */\nexport interface ExtensionsWithMaxAge {\n  dataConnect?: DataConnectExtensionWithMaxAge[];\n}\n\n/** @internal */\nexport interface DataConnectResponse<T> {\n  data: T;\n  errors: Error[];\n  extensions: Extensions;\n}\n\n/** @internal */\nexport interface DataConnectResponseWithMaxAge<T> {\n  data: T;\n  errors: Error[];\n  extensions: ExtensionsWithMaxAge;\n}\n\n/**\n * Observer defined by the Query Layer for receiving notifications from the Transport Layer.\n * @internal\n */\nexport interface SubscribeObserver<Data> {\n  onData(response: DataConnectResponse<Data>): Promise<void> | void;\n  onDisconnect(code: string, reason: string): void;\n  onError(error: Error): void;\n}\n\n/**\n * Interface defining the external API of the transport layer.\n * @internal\n */\nexport interface DataConnectTransportInterface {\n  /**\n   * Invoke a query execution request.\n   * @param queryName The name of the query to execute.\n   * @param body The variables associated with the query.\n   * @returns A promise resolving to the DataConnectResponse.\n   */\n  invokeQuery<Data, Variables>(\n    queryName: string,\n    body?: Variables\n  ): Promise<DataConnectResponseWithMaxAge<Data>>;\n\n  /**\n   * Invoke a mutation execution request.\n   * @param queryName The name of the mutation to execute.\n   * @param body The variables associated with the mutation.\n   * @returns A promise resolving to the DataConnectResponse.\n   */\n  invokeMutation<Data, Variables>(\n    queryName: string,\n    body?: Variables\n  ): Promise<DataConnectResponse<Data>>;\n\n  /**\n   * Subscribes to a query to receive push notifications of updates.\n   * @param observer the observer passed to the transport layer to notify the query layer of events.\n   * @param queryName The name of the query to subscribe to.\n   * @param body The variables associated with the subscription.\n   */\n  invokeSubscribe<Data, Variables>(\n    observer: SubscribeObserver<Data>,\n    queryName: string,\n    body?: Variables\n  ): void;\n\n  /**\n   * Unsubscribes from an active subscription.\n   * @param queryName The name of the query to unsubscribe from.\n   * @param body The variables associated with the subscription.\n   */\n  invokeUnsubscribe<Variables>(queryName: string, body?: Variables): void;\n\n  /**\n   * Configures the transport to use a local Data Connect emulator.\n   * @param host The host address of the emulator (e.g., '127.0.0.1').\n   * @param port The port number the emulator is listening on.\n   * @param sslEnabled Whether to use SSL (HTTPS/WSS) for the emulator connection.\n   */\n  useEmulator(host: string, port?: number, sslEnabled?: boolean): void;\n\n  /**\n   * Callback invoked when the Firebase Auth token is refreshed or changed. Note that this callback\n   * is called immediately asynchronously when the Auth Provider is initialized to provide\n   * the initial auth state.\n   * @param token The new access token or null if signed out.\n   */\n  onAuthTokenChanged: (token: string | null) => void;\n\n  /**\n   * Internal method to set the SDK type for metrics and logging purposes.\n   * @param callerSdkType The type of SDK making the call (e.g., generated vs base).\n   */\n  _setCallerSdkType(callerSdkType: CallerSdkType): void;\n}\n\n/**\n * Type signature of a transport class constructor.\n * @internal\n */\nexport type TransportClass = new (\n  options: DataConnectOptions,\n  apiKey?: string,\n  appId?: string,\n  authProvider?: AuthTokenProvider,\n  appCheckProvider?: AppCheckTokenProvider,\n  transportOptions?: TransportOptions,\n  _isUsingGen?: boolean,\n  _callerSdkType?: CallerSdkType\n) => DataConnectTransportInterface;\n\n/**\n * Constructs the value for the X-Goog-Api-Client header\n * @internal\n */\nexport function getGoogApiClientValue(\n  isUsingGen: boolean,\n  callerSdkType: CallerSdkType\n): string {\n  let str = 'gl-js/ fire/' + SDK_VERSION;\n  if (\n    callerSdkType !== CallerSdkTypeEnum.Base &&\n    callerSdkType !== CallerSdkTypeEnum.Generated\n  ) {\n    str += ' js/' + callerSdkType.toLowerCase();\n  } else if (isUsingGen || callerSdkType === CallerSdkTypeEnum.Generated) {\n    str += ' js/gen';\n  }\n  return str;\n}\n\n/**\n * The base class for all DataConnectTransportInterface implementations. Handles common logic such as\n * URL construction, auth token management, and emulator usage. Concrete transport implementations\n * should extend this class and implement the abstract {@link DataConnectTransportInterface} methods.\n * @internal\n */\nexport abstract class AbstractDataConnectTransport\n  implements DataConnectTransportInterface\n{\n  protected _host = '';\n  protected _port: number | undefined;\n  protected _location = 'l';\n  protected _connectorName = '';\n  /** The resource path for requests from this Data Connect instance. */\n  protected _connectorResourcePath: string;\n  protected _secure = true;\n  protected _project = 'p';\n  protected _serviceName: string;\n  protected _authToken: string | null = null;\n  protected _appCheckToken: string | null | undefined = null;\n  protected _lastToken: string | null = null;\n  protected _isUsingEmulator = false;\n\n  constructor(\n    options: DataConnectOptions,\n    protected apiKey?: string | undefined,\n    protected appId?: string | null,\n    protected authProvider?: AuthTokenProvider | undefined,\n    protected appCheckProvider?: AppCheckTokenProvider | undefined,\n    transportOptions?: TransportOptions | undefined,\n    protected _isUsingGen = false,\n    protected _callerSdkType: CallerSdkType = CallerSdkTypeEnum.Base\n  ) {\n    if (transportOptions) {\n      if (typeof transportOptions.port === 'number') {\n        this._port = transportOptions.port;\n      }\n      if (typeof transportOptions.sslEnabled !== 'undefined') {\n        this._secure = transportOptions.sslEnabled;\n      }\n      this._host = transportOptions.host;\n    }\n    const { location, projectId: project, connector, service } = options;\n    if (location) {\n      this._location = location;\n    }\n    if (project) {\n      this._project = project;\n    }\n    this._serviceName = service;\n    if (!connector) {\n      throw new DataConnectError(\n        Code.INVALID_ARGUMENT,\n        'Connector Name required!'\n      );\n    }\n    this._connectorName = connector;\n    this._connectorResourcePath = `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`;\n    this.authProvider?.addTokenChangeListener(token => {\n      logDebug(`New Token Available: ${token}`);\n      this.onAuthTokenChanged(token);\n    });\n    this.appCheckProvider?.addTokenChangeListener(result => {\n      const { token } = result;\n      logDebug(`New App Check Token Available: ${token}`);\n      this._appCheckToken = token;\n    });\n  }\n\n  /** Get the endpoint URL this transport should use to communicate with the backend. */\n  abstract get endpointUrl(): string;\n\n  useEmulator(host: string, port?: number, isSecure?: boolean): void {\n    this._host = host;\n    this._isUsingEmulator = true;\n    if (typeof port === 'number') {\n      this._port = port;\n    }\n    if (typeof isSecure !== 'undefined') {\n      this._secure = isSecure;\n    }\n  }\n\n  async getWithAuth(forceToken = false): Promise<string | null> {\n    let starterPromise: Promise<string | null> = new Promise(resolve =>\n      resolve(this._authToken)\n    );\n    if (this.appCheckProvider) {\n      const appCheckToken = await this.appCheckProvider.getToken();\n      if (appCheckToken) {\n        this._appCheckToken = appCheckToken.token;\n      }\n    }\n    if (this.authProvider) {\n      starterPromise = this.authProvider\n        .getToken(/*forceToken=*/ forceToken)\n        .then(data => {\n          if (!data) {\n            return null;\n          }\n          this._authToken = data.accessToken;\n          return this._authToken;\n        });\n    } else {\n      starterPromise = new Promise(resolve => resolve(''));\n    }\n    return starterPromise;\n  }\n\n  async withRetry<T>(\n    promiseFactory: () => Promise<DataConnectResponse<T>>,\n    retry = false\n  ): Promise<DataConnectResponse<T>> {\n    let isNewToken = false;\n    return this.getWithAuth(retry)\n      .then(res => {\n        isNewToken = this._lastToken !== res;\n        this._lastToken = res;\n        return res;\n      })\n      .then(promiseFactory)\n      .catch(err => {\n        // Only retry if the result is unauthorized and the last token isn't the same as the new one.\n        if (\n          'code' in err &&\n          err.code === Code.UNAUTHORIZED &&\n          !retry &&\n          isNewToken\n        ) {\n          logDebug('Retrying due to unauthorized');\n          return this.withRetry(promiseFactory, true);\n        }\n        throw err;\n      });\n  }\n\n  _setLastToken(lastToken: string | null): void {\n    this._lastToken = lastToken;\n  }\n\n  abstract invokeQuery<Data, Variables>(\n    queryName: string,\n    body?: Variables\n  ): Promise<DataConnectResponseWithMaxAge<Data>>;\n\n  abstract invokeMutation<Data, Variables>(\n    queryName: string,\n    body?: Variables\n  ): Promise<DataConnectResponse<Data>>;\n\n  abstract invokeSubscribe<Data, Variables>(\n    observer: SubscribeObserver<Data>,\n    queryName: string,\n    body?: Variables\n  ): void;\n\n  abstract invokeUnsubscribe<Variables>(\n    queryName: string,\n    variables: Variables\n  ): void;\n\n  abstract onAuthTokenChanged(newToken: string | null): void;\n\n  _setCallerSdkType(callerSdkType: CallerSdkType): void {\n    this._callerSdkType = callerSdkType;\n  }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { isCloudWorkstation } from '@firebase/util';\n\nimport {\n  CallerSdkType,\n  CallerSdkTypeEnum,\n  DataConnectResponse,\n  Extensions\n} from '..';\nimport {\n  Code,\n  DataConnectError,\n  DataConnectOperationError,\n  DataConnectOperationFailureResponse\n} from '../../core/error';\nimport { SDK_VERSION } from '../../core/version';\nimport { logError } from '../../logger';\n\n/** The fetch implementation to be used by the {@link RESTTransport}. */\nlet connectFetch: typeof fetch | null = globalThis.fetch;\n\n/**\n * This function is ONLY used for testing and for ensuring compatability in environments which may\n * be using a poyfill and/or bundlers. It should not be called by users of the Firebase JS SDK.\n * @internal\n */\nexport function initializeFetch(fetchImpl: typeof fetch): void {\n  connectFetch = fetchImpl;\n}\n\nfunction getGoogApiClientValue(\n  _isUsingGen: boolean,\n  _callerSdkType: CallerSdkType\n): string {\n  let str = 'gl-js/ fire/' + SDK_VERSION;\n  if (\n    _callerSdkType !== CallerSdkTypeEnum.Base &&\n    _callerSdkType !== CallerSdkTypeEnum.Generated\n  ) {\n    str += ' js/' + _callerSdkType.toLowerCase();\n  } else if (_isUsingGen || _callerSdkType === CallerSdkTypeEnum.Generated) {\n    str += ' js/gen';\n  }\n  return str;\n}\nexport interface DataConnectFetchBody<Variables> {\n  name: string;\n  operationName: string;\n  variables: Variables;\n}\nexport async function dcFetch<Data, Variables>(\n  url: string,\n  body: DataConnectFetchBody<Variables>,\n  { signal }: AbortController,\n  appId: string | null | undefined,\n  accessToken: string | null,\n  appCheckToken: string | null | undefined,\n  _isUsingGen: boolean,\n  _callerSdkType: CallerSdkType,\n  _isUsingEmulator: boolean\n): Promise<DataConnectResponse<Data>> {\n  if (!connectFetch) {\n    throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');\n  }\n  const headers: HeadersInit = {\n    'Content-Type': 'application/json',\n    'X-Goog-Api-Client': getGoogApiClientValue(_isUsingGen, _callerSdkType),\n    'X-Client-Version': `web/${SDK_VERSION}`\n  };\n  if (accessToken) {\n    headers['X-Firebase-Auth-Token'] = accessToken;\n  }\n  if (appId) {\n    headers['x-firebase-gmpid'] = appId;\n  }\n  if (appCheckToken) {\n    headers['X-Firebase-AppCheck'] = appCheckToken;\n  }\n  const bodyStr = JSON.stringify(body);\n  const fetchOptions: RequestInit = {\n    body: bodyStr,\n    method: 'POST',\n    headers,\n    signal\n  };\n  if (isCloudWorkstation(url) && _isUsingEmulator) {\n    fetchOptions.credentials = 'include';\n  }\n\n  let response: Response;\n  try {\n    response = await connectFetch(url, fetchOptions);\n  } catch (err) {\n    const message =\n      err && typeof err === 'object' && 'message' in err\n        ? (err as unknown as Record<string, unknown>)['message']\n        : String(err);\n    throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + message);\n  }\n  let jsonResponse: JsonResponse<Data>;\n  try {\n    jsonResponse = await response.json();\n  } catch (e) {\n    const message =\n      e && typeof e === 'object' && 'message' in e\n        ? (e as unknown as Record<string, unknown>)['message']\n        : String(e);\n    throw new DataConnectError(\n      Code.OTHER,\n      'Failed to parse JSON response: ' + message\n    );\n  }\n  const message = getErrorMessage(jsonResponse);\n  if (response.status >= 400) {\n    logError('Error while performing request: ' + JSON.stringify(jsonResponse));\n    if (response.status === 401) {\n      throw new DataConnectError(Code.UNAUTHORIZED, message);\n    }\n    throw new DataConnectError(Code.OTHER, message);\n  }\n  if (jsonResponse.errors && jsonResponse.errors.length) {\n    const stringified = JSON.stringify(jsonResponse.errors);\n    const failureResponse: DataConnectOperationFailureResponse = {\n      errors: jsonResponse.errors,\n      data: jsonResponse.data as Record<string, unknown>\n    };\n    throw new DataConnectOperationError(\n      'DataConnect error while performing request: ' + stringified,\n      failureResponse\n    );\n  }\n  if (!jsonResponse.extensions) {\n    jsonResponse.extensions = {\n      dataConnect: []\n    };\n  }\n  return jsonResponse as DataConnectResponse<Data>;\n}\ninterface JsonResponse<Data> {\n  message?: string;\n  errors: [];\n  data: Record<string, unknown> | Data | null;\n  extensions?: Extensions;\n}\nfunction getErrorMessage(obj: JsonResponse<unknown>): string {\n  if ('message' in obj && obj.message) {\n    return obj.message;\n  }\n  return JSON.stringify(obj);\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DataConnectOptions, TransportOptions } from '../api/DataConnect';\nimport { Code, DataConnectError } from '../core/error';\nimport { logError } from '../logger';\n\nexport const PROD_HOST = 'firebasedataconnect.googleapis.com';\nexport const WEBSOCKET_PATH =\n  'ws/google.firebase.dataconnect.v1.ConnectorStreamService';\n\nexport function restUrlBuilder(\n  projectConfig: DataConnectOptions,\n  transportOptions: TransportOptions\n): string {\n  const { connector, location, projectId: project, service } = projectConfig;\n  const { host, sslEnabled, port } = transportOptions;\n  const protocol = sslEnabled ? 'https' : 'http';\n  const realHost = host || PROD_HOST;\n  let baseUrl = `${protocol}://${realHost}`;\n  if (typeof port === 'number') {\n    baseUrl += `:${port}`;\n  } else if (typeof port !== 'undefined') {\n    logError('Port type is of an invalid type');\n    throw new DataConnectError(\n      Code.INVALID_ARGUMENT,\n      'Incorrect type for port passed in!'\n    );\n  }\n  return `${baseUrl}/v1/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;\n}\n\nexport function websocketUrlBuilder(\n  projectConfig: DataConnectOptions,\n  transportOptions: TransportOptions\n): string {\n  const { location } = projectConfig;\n  const { host, sslEnabled, port } = transportOptions;\n  const protocol = sslEnabled ? 'wss' : 'ws';\n  const realHost = host || PROD_HOST;\n  let baseUrl = `${protocol}://${realHost}`;\n  if (typeof port === 'number') {\n    baseUrl += `:${port}`;\n  } else if (typeof port !== 'undefined') {\n    logError('Port type is of an invalid type');\n    throw new DataConnectError(\n      Code.INVALID_ARGUMENT,\n      'Incorrect type for port passed in!'\n    );\n  }\n  return `${baseUrl}/${WEBSOCKET_PATH}/Connect/locations/${location}`;\n}\n\nexport function addToken(url: string, apiKey?: string): string {\n  if (!apiKey) {\n    return url;\n  }\n  const newUrl = new URL(url);\n  newUrl.searchParams.append('key', apiKey);\n  return newUrl.toString();\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n  CallerSdkType,\n  CallerSdkTypeEnum,\n  DataConnectResponse,\n  DataConnectResponseWithMaxAge,\n  AbstractDataConnectTransport,\n  SubscribeObserver\n} from '..';\nimport { DataConnectOptions, TransportOptions } from '../../api/DataConnect';\nimport { AppCheckTokenProvider } from '../../core/AppCheckTokenProvider';\nimport { Code, DataConnectError } from '../../core/error';\nimport { AuthTokenProvider } from '../../core/FirebaseAuthProvider';\nimport { addToken, restUrlBuilder } from '../../util/url';\n\nimport { dcFetch } from './fetch';\n\n/**\n * Fetch-based REST implementation of {@link AbstractDataConnectTransport}.\n * @internal\n */\nexport class RESTTransport extends AbstractDataConnectTransport {\n  constructor(\n    options: DataConnectOptions,\n    apiKey?: string | undefined,\n    appId?: string | null,\n    authProvider?: AuthTokenProvider | undefined,\n    appCheckProvider?: AppCheckTokenProvider | undefined,\n    transportOptions?: TransportOptions | undefined,\n    _isUsingGen = false,\n    _callerSdkType: CallerSdkType = CallerSdkTypeEnum.Base\n  ) {\n    super(\n      options,\n      apiKey,\n      appId,\n      authProvider,\n      appCheckProvider,\n      transportOptions,\n      _isUsingGen,\n      _callerSdkType\n    );\n  }\n\n  get endpointUrl(): string {\n    return restUrlBuilder(\n      {\n        connector: this._connectorName,\n        location: this._location,\n        projectId: this._project,\n        service: this._serviceName\n      },\n      {\n        host: this._host,\n        sslEnabled: this._secure,\n        port: this._port\n      }\n    );\n  }\n\n  invokeQuery: <Data, Variables>(\n    queryName: string,\n    body?: Variables\n  ) => Promise<DataConnectResponseWithMaxAge<Data>> = <\n    Data,\n    Variables = unknown\n  >(\n    queryName: string,\n    body: Variables\n  ) => {\n    const abortController = new AbortController();\n\n    // TODO(mtewani): Update to proper value\n    const withAuth = this.withRetry(() =>\n      dcFetch<Data, Variables>(\n        addToken(`${this.endpointUrl}:executeQuery`, this.apiKey),\n        {\n          name: this._connectorResourcePath,\n          operationName: queryName,\n          variables: body\n        },\n        abortController,\n        this.appId,\n        this._authToken,\n        this._appCheckToken,\n        this._isUsingGen,\n        this._callerSdkType,\n        this._isUsingEmulator\n      )\n    );\n    return withAuth;\n  };\n\n  invokeMutation: <Data, Variables>(\n    queryName: string,\n    body?: Variables\n  ) => Promise<DataConnectResponse<Data>> = <Data, Variables = unknown>(\n    mutationName: string,\n    body: Variables\n  ) => {\n    const abortController = new AbortController();\n    const taskResult = this.withRetry(() => {\n      return dcFetch<Data, Variables>(\n        addToken(`${this.endpointUrl}:executeMutation`, this.apiKey),\n        {\n          name: this._connectorResourcePath,\n          operationName: mutationName,\n          variables: body\n        },\n        abortController,\n        this.appId,\n        this._authToken,\n        this._appCheckToken,\n        this._isUsingGen,\n        this._callerSdkType,\n        this._isUsingEmulator\n      );\n    });\n    return taskResult;\n  };\n\n  invokeSubscribe<Data, Variables>(\n    observer: SubscribeObserver<Data>,\n    queryName: string,\n    body?: Variables\n  ): void {\n    throw new DataConnectError(\n      Code.NOT_SUPPORTED,\n      'Subscriptions are not supported using REST!'\n    );\n  }\n\n  invokeUnsubscribe<Variables>(queryName: string, body?: Variables): void {\n    throw new DataConnectError(\n      Code.NOT_SUPPORTED,\n      'Unsubscriptions are not supported using REST!'\n    );\n  }\n\n  onAuthTokenChanged(newToken: string | null): void {\n    this._authToken = newToken;\n  }\n}\n","/**\n * @license\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\n\nimport { DataConnectOptions, TransportOptions } from '../../api/DataConnect';\nimport { AppCheckTokenProvider } from '../../core/AppCheckTokenProvider';\nimport {\n  Code,\n  DataConnectError,\n  DataConnectOperationError,\n  DataConnectOperationFailureResponse\n} from '../../core/error';\nimport { AuthTokenProvider } from '../../core/FirebaseAuthProvider';\nimport { SDK_VERSION } from '../../core/version';\nimport { logError, logDebug } from '../../logger';\nimport {\n  AbstractDataConnectTransport,\n  CallerSdkType,\n  CallerSdkTypeEnum,\n  DataConnectResponse,\n  SubscribeObserver,\n  getGoogApiClientValue\n} from '../transport';\n\nimport {\n  CancelStreamRequest,\n  DataConnectStreamRequest,\n  ExecuteStreamRequest,\n  ResumeStreamRequest,\n  StreamRequestHeaders,\n  SubscribeStreamRequest\n} from './wire';\n\n/** The Request ID of the first request over the stream */\nconst FIRST_REQUEST_ID = 1;\n\n/** Time to wait before closing an idle connection (no active subscriptions). */\nconst IDLE_CONNECTION_TIMEOUT_MS = 15 * 1000; // 15 seconds\n\n/** Initial reconnect delay in ms */\nconst INITIAL_RECONNECT_DELAY_MS = 1000; // 1 second\n/** Max reconnect delay in ms */\nconst MAX_RECONNECT_DELAY_MS = 60 * 1000; // 60 seconds\n/** Factor to multiply delay by on failure */\nconst RECONNECT_BACKOFF_FACTOR = 1.5;\n\n/**\n * A promise returned to the user when invoking an operation via {@linkcode AbstractDataConnectStreamTransport.invokeQuery | invokeQuery}\n * or {@linkcode AbstractDataConnectStreamTransport.invokeMutation | invokeMutation} and the functions\n * that resolve/reject it.\n * @internal\n */\nexport interface InvokeOperationPromise<Data> {\n  responsePromise: Promise<DataConnectResponse<Data>>;\n  resolveFn: (response: DataConnectResponse<Data>) => void;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  rejectFn: (reason: any) => void;\n}\n\n/**\n * The base class for all Stream Transport implementations.\n * Handles management of logical streams (requests), authentication, data routing to query layer,\n * request optimizations, etc.\n * @internal\n */\nexport abstract class AbstractDataConnectStreamTransport extends AbstractDataConnectTransport {\n  /** Optional callback invoked when the stream closes (gracefully or fatally). */\n  onCloseCallback?: () => void;\n\n  /** True if the physical stream connection is fully open and ready to transmit data. */\n  abstract get streamIsReady(): boolean;\n\n  /** Is the stream currently waiting to close connection? */\n  get isPendingClose(): boolean {\n    return !!this.idleTimeout;\n  }\n\n  /** True if the transport is unable to connect to the server */\n  isUnableToConnect = false;\n\n  /** True if there are active subscriptions on the stream */\n  get hasActiveSubscriptions(): boolean {\n    return this.activeInvokeSubscribeRequests.size > 0;\n  }\n\n  /** True if there are active execute or mutation requests on the stream */\n  get hasActiveExecuteRequests(): boolean {\n    return (\n      this.activeInvokeQueryRequests.size > 0 ||\n      this.activeInvokeMutationRequests.size > 0\n    );\n  }\n\n  constructor(\n    options: DataConnectOptions,\n    protected apiKey?: string | undefined,\n    protected appId?: string | null,\n    protected authProvider?: AuthTokenProvider | undefined,\n    protected appCheckProvider?: AppCheckTokenProvider | undefined,\n    transportOptions?: TransportOptions | undefined,\n    protected _isUsingGen = false,\n    protected _callerSdkType: CallerSdkType = CallerSdkTypeEnum.Base\n  ) {\n    super(\n      options,\n      apiKey,\n      appId,\n      authProvider,\n      appCheckProvider,\n      transportOptions,\n      _isUsingGen,\n      _callerSdkType\n    );\n\n    this.registerBrowserEventListeners();\n  }\n\n  /**\n   * Register event listeners for browser-specific events like online/offline and visibility changes.\n   */\n  private registerBrowserEventListeners(): void {\n    if ('addEventListener' in globalThis) {\n      const listener = this.onOnlineEventListener;\n      globalThis.addEventListener('online', listener);\n      this.removeOnlineEventListener = () =>\n        globalThis.removeEventListener('online', listener);\n    }\n\n    const doc = globalThis.document;\n    if (doc && 'addEventListener' in doc) {\n      const listener = this.onVisibilityChangeEventListener;\n      doc.addEventListener('visibilitychange', listener);\n      this.removeVisibilityChangeEventListener = () =>\n        doc.removeEventListener('visibilitychange', listener);\n    }\n  }\n\n  /**\n   * Remove event listeners registered by {@linkcode AbstractDataConnectStreamTransport.registerBrowserEventListeners | registerBrowserEventListeners()}\n   * for browser-specific events like online/offline and visibility changes.\n   */\n  private cleanupBrowserEventListeners(): void {\n    this.removeVisibilityChangeEventListener?.();\n    this.removeVisibilityChangeEventListener = null;\n    this.removeOnlineEventListener?.();\n    this.removeOnlineEventListener = null;\n  }\n\n  /**\n   * Disposes of the transport instance, cleaning up event listeners and timers,\n   * and closing the connection.\n   */\n  async cleanupAndTerminate(code?: Code, reason?: string): Promise<void> {\n    this.cleanupBrowserEventListeners();\n    this.cancelReconnect();\n    this.cancelClose();\n    this.rejectAllRequests(code ?? Code.OTHER, reason ?? 'Stream disposed.');\n    await this.closeConnection();\n    this.onCloseCallback?.();\n  }\n\n  /**\n   * Open a physical connection to the server.\n   * @returns a promise which resolves when the connection is ready, or rejects if it fails to open.\n   */\n  protected abstract openConnection(): Promise<void>;\n\n  /**\n   * Close the physical connection with the server. Handles no cleanup - simply closes the\n   * implementation-specific connection. On failure to close, the connection is still considered closed.\n   * @returns a promise which resolves when the connection is closed, or rejects if it fails to close.\n   */\n  protected abstract closeConnection(): Promise<void>;\n\n  /**\n   * Queue a {@linkcode DataConnectStreamRequest} to be sent over the stream.\n   * @param requestBody The body of the message to be sent.\n   * @throws DataConnectError if sending fails.\n   */\n  protected abstract sendMessage<Variables>(\n    requestBody: DataConnectStreamRequest<Variables>\n  ): Promise<void>;\n\n  /**\n   * Ensures that that there is an open connection. If there is none, it initiates a new one.\n   * If a connection attempt is already in progress, it returns the existing connection promise.\n   * @returns A promise that resolves when the stream is open and ready.\n   */\n  protected abstract ensureConnection(): Promise<void>;\n\n  /** The Request ID of the next message to be sent. Monotonically increasing sequence number starting at {@linkcode FIRST_REQUEST_ID}. */\n  private requestNumber = FIRST_REQUEST_ID;\n  /**\n   * Generates and returns the next Request ID. Starts at {@linkcode FIRST_REQUEST_ID} and increments\n   * for each request sent.\n   */\n  private nextRequestId(): string {\n    return (this.requestNumber++).toString();\n  }\n\n  /**\n   * Map of query/variables to their active {@linkcode ExecuteStreamRequest} or {@linkcode ResumeStreamRequest}\n   * request bodies. These requests are de-duplicated by query/variables so that there is only one active\n   * request for each query/variables combination.\n   */\n  private activeInvokeQueryRequests = new Map<\n    string,\n    ExecuteStreamRequest<unknown> | ResumeStreamRequest\n  >();\n\n  /**\n   * Map of query/variables to the promises returned to the user, for invokeQuery requests which are\n   * queued and waiting for active request to resolve.\n   */\n  private queuedInvokeQueryRequests = new Map<\n    string,\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    InvokeOperationPromise<any>\n  >();\n\n  /**\n   * Map of mutation/variables to their active {@linkcode ExecuteStreamRequest} request bodies. Mutations\n   * can have more than one active request at a time as they are not idempotent, and therefore should\n   * not be de-duplicated.\n   */\n  private activeInvokeMutationRequests = new Map<\n    string,\n    Array<ExecuteStreamRequest<unknown>>\n  >();\n\n  /**\n   * Map of query/variables to their active {@linkcode SubscribeStreamRequest} request bodies. There\n   * may only be one active request for each query/variables combination.\n   */\n  private activeInvokeSubscribeRequests = new Map<\n    string,\n    SubscribeStreamRequest<unknown>\n  >();\n\n  /**\n   * Map of active {@linkcode ExecuteStreamRequest} RequestIds from {@linkcode invokeQuery} and {@linkcode invokeMutation},\n   * and their corresponding {@linkcode InvokeOperationPromise}.\n   */\n  private executeRequestPromises = new Map<\n    string,\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    InvokeOperationPromise<any>\n  >();\n\n  /**\n   * Map of active {@linkcode ResumeStreamRequest} RequestIds from {@linkcode invokeQuery}, and their\n   * corresponding {@linkcode InvokeOperationPromise}.\n   */\n  private resumeRequestPromises = new Map<\n    string,\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    InvokeOperationPromise<any>\n  >();\n\n  /**\n   * Map of active {@linkcode invokeSubscribe} RequestIds and their corresponding {@linkcode SubscribeObserver}.\n   */\n  private subscribeObservers = new Map<string, SubscribeObserver<unknown>>();\n\n  /**\n   * Map of subscribe RequestIds to deferred unsubscription requests. Used when a client unsubscribes\n   * while a resume request is actively pending.\n   */\n  private pendingCancellations = new Map<\n    string,\n    { operationName: string; variables: unknown }\n  >();\n\n  /** current idle timeout, if any */\n  private idleTimeout: ReturnType<typeof setTimeout> | null = null;\n\n  /** current auth uid. used to detect if a different user logs in */\n  private authUid: string | null | undefined;\n  /** Flag to ensure we wait for the initial auth state once per connection attempt. */\n  private hasWaitedForInitialAuth = false;\n\n  /**\n   * Tracks an {@linkcode invokeMutation} request, storing the request body and creating and storing a\n   * response promise that will be resolved when the response is received.\n   * @returns The tracked {@linkcode InvokeOperationPromise}.\n   *\n   * @remarks\n   * This method returns a promise, but is synchronous.\n   */\n  private trackInvokeMutationRequest<Data>(\n    requestId: string,\n    mapKey: string,\n    executeBody: ExecuteStreamRequest<unknown>\n  ): InvokeOperationPromise<Data> {\n    let resolveFn: (response: DataConnectResponse<Data>) => void;\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    let rejectFn: (reason: any) => void;\n    const responsePromise = new Promise<DataConnectResponse<Data>>(\n      (resolve, reject) => {\n        resolveFn = resolve;\n        rejectFn = reject;\n      }\n    );\n    const executeRequestPromise: InvokeOperationPromise<Data> = {\n      responsePromise,\n      resolveFn: resolveFn!,\n      rejectFn: rejectFn!\n    };\n\n    const activeRequests = this.activeInvokeMutationRequests.get(mapKey) || [];\n    activeRequests.push(executeBody);\n    this.activeInvokeMutationRequests.set(mapKey, activeRequests);\n    this.executeRequestPromises.set(requestId, executeRequestPromise);\n\n    return executeRequestPromise;\n  }\n\n  /**\n   * Tracks an {@linkcode invokeSubscribe} request, storing the request body and the {@linkcode SubscribeObserver}.\n   * @remarks\n   * This method is synchronous.\n   */\n  private trackInvokeSubscribeRequest<Data>(\n    requestId: string,\n    mapKey: string,\n    subscribeBody: SubscribeStreamRequest<unknown>,\n    observer: SubscribeObserver<Data>\n  ): void {\n    this.activeInvokeSubscribeRequests.set(mapKey, subscribeBody);\n    this.subscribeObservers.set(requestId, observer);\n  }\n\n  /**\n   * Cleans up the query execute request tracking data structures, deleting the tracked request and\n   * it's associated promise.\n   */\n  private cleanupInvokeQueryRequest(requestId: string, mapKey: string): void {\n    this.activeInvokeQueryRequests.delete(mapKey);\n    this.executeRequestPromises.delete(requestId);\n    this.resumeRequestPromises.delete(requestId);\n  }\n\n  /**\n   * Cleans up the mutation execute request tracking data structures, deleting the tracked request and\n   * it's associated promise.\n   */\n  private cleanupInvokeMutationRequest(\n    requestId: string,\n    mapKey: string\n  ): void {\n    const executeRequests = this.activeInvokeMutationRequests.get(mapKey);\n    if (executeRequests) {\n      const updatedRequests = executeRequests.filter(\n        request => request.requestId !== requestId\n      );\n      if (updatedRequests.length > 0) {\n        this.activeInvokeMutationRequests.set(mapKey, updatedRequests);\n      } else {\n        this.activeInvokeMutationRequests.delete(mapKey);\n      }\n    }\n    this.executeRequestPromises.delete(requestId);\n  }\n\n  /**\n   * Cleans up the subscribe request tracking data structures, deleting the tracked request and\n   * it's associated promise.\n   */\n  private cleanupInvokeSubscribeRequest(\n    requestId: string,\n    mapKey: string\n  ): void {\n    this.activeInvokeSubscribeRequests.delete(mapKey);\n    this.subscribeObservers.delete(requestId);\n  }\n\n  /** Delay for next reconnection attempt in ms */\n  private reconnectDelayMs = INITIAL_RECONNECT_DELAY_MS;\n  /** Timer for reconnection */\n  private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n  /** Number of consecutive reconnection attempts */\n  private reconnectAttempts = 0;\n\n  /** Callback to remove online event listener */\n  private removeOnlineEventListener: (() => void) | null = null;\n  /** Callback to remove visibility change event listener */\n  private removeVisibilityChangeEventListener: (() => void) | null = null;\n\n  /**\n   * Short-circuit a reconnection attempt, if one is pending. Triggered when an online event is\n   * dispatched.\n   */\n  onOnlineEventListener = (): void => {\n    if (this.reconnectTimer) {\n      this.cancelReconnect();\n      void this.attemptReconnect();\n    }\n  };\n\n  /**\n   * Short-circuit a reconnection attempt, if one is pending. Triggered when a visibility change\n   * event is dispatched.\n   */\n  onVisibilityChangeEventListener = (): void => {\n    const doc = globalThis.document;\n    if (doc && doc.visibilityState === 'visible' && this.reconnectTimer) {\n      this.cancelReconnect();\n      void this.attemptReconnect();\n    }\n  };\n\n  /**\n   * Cancel reconnecting.\n   */\n  private cancelReconnect(): void {\n    if (this.reconnectTimer) {\n      clearTimeout(this.reconnectTimer);\n      this.reconnectTimer = null;\n    }\n  }\n\n  /**\n   * Starts the backoff timer for reconnection attempts. We use an exponential backoff with randomized\n   * jitter to prevent overwhelming the backend with connection attempts.\n   */\n  private startReconnectBackoff(): void {\n    if (this.reconnectTimer) {\n      return;\n    }\n    this.reconnectAttempts++;\n    const delay = this.reconnectDelayMs;\n    this.reconnectDelayMs = Math.min(\n      this.reconnectDelayMs * RECONNECT_BACKOFF_FACTOR,\n      MAX_RECONNECT_DELAY_MS\n    );\n    const jitter = (Math.random() - 0.5) * delay;\n\n    this.reconnectTimer = setTimeout(() => {\n      this.reconnectTimer = null;\n      void this.attemptReconnect();\n    }, delay + jitter);\n  }\n\n  private async attemptReconnect(): Promise<void> {\n    try {\n      await this.ensureConnection();\n      // reset on success\n      this.reconnectDelayMs = INITIAL_RECONNECT_DELAY_MS;\n      this.reconnectAttempts = 0;\n      await this.retriggerActiveRequests();\n    } catch (e) {\n      if (e instanceof FirebaseError) {\n        logDebug(\n          `Reconnect attempt #${this.reconnectAttempts} failed with Firebase error: ${e.message}. Retrying...`\n        );\n        this.startReconnectBackoff();\n      } else {\n        logError(\n          `Unexpected error during reconnect attempt #${this.reconnectAttempts}: ${e}`\n        );\n        void this.cleanupAndTerminate(\n          Code.OTHER,\n          `Unexpected error during reconnect attempt #${this.reconnectAttempts}: ${e}`\n        );\n      }\n    }\n  }\n\n  /**\n   * Retriggers all active requests on the stream connection - first subscribes, then query executions,\n   * and skip mutations. Used after a successful reconnection.\n   */\n  private async retriggerActiveRequests(): Promise<void> {\n    for (const [_, subscribeBody] of this.activeInvokeSubscribeRequests) {\n      await this.sendRequestMessage(subscribeBody);\n    }\n    for (const [_, requestBody] of this.activeInvokeQueryRequests) {\n      await this.sendRequestMessage(requestBody);\n    }\n  }\n\n  /**\n   * Tracks if the next message to be sent is the first message of the stream.\n   */\n  private isFirstStreamMessage = true;\n\n  /**\n   * Tracks the last auth token sent to the server.\n   * Used to detect if the token has changed and needs to be resent.\n   */\n  private lastSentAuthToken: string | null = null;\n\n  /**\n   * Indicates whether we should include the auth token in the next message.\n   * Only true if there is an auth token and it is different from the last sent auth token, or this\n   * is the first message.\n   */\n  private get shouldIncludeAuth(): boolean {\n    return (\n      this.isFirstStreamMessage ||\n      (!!this._authToken && this._authToken !== this.lastSentAuthToken)\n    );\n  }\n\n  /**\n   * Called by the concrete transport implementation when the physical connection is ready.\n   */\n  protected onConnectionReady(): void {\n    this.isFirstStreamMessage = true;\n    this.lastSentAuthToken = null;\n    this.hasWaitedForInitialAuth = false;\n  }\n\n  /**\n   * Begin closing the connection. Waits for {@linkcode IDLE_CONNECTION_TIMEOUT_MS} without cleaning up\n   * any requests (meaning it will not close after the timeout unless the requests are closed first).\n   * This is a graceful close - it will be called when there are no more active subscriptions, so\n   * there's no need to cleanup.\n   */\n  private startIdleCloseTimeout(): void {\n    if (this.idleTimeout) {\n      return;\n    }\n    this.idleTimeout = setTimeout(() => {\n      this.idleTimeout = null;\n      // Safety check: Don't close if new requests arrived during the timeout!\n      if (this.hasActiveSubscriptions || this.hasActiveExecuteRequests) {\n        return;\n      }\n      void this.cleanupAndTerminate(\n        Code.OTHER,\n        'Stream closed due to idleness.'\n      );\n    }, IDLE_CONNECTION_TIMEOUT_MS);\n  }\n\n  /**\n   * Cancel closing the connection.\n   */\n  private cancelClose(): void {\n    if (this.idleTimeout) {\n      clearTimeout(this.idleTimeout);\n      this.idleTimeout = null;\n    }\n  }\n\n  /**\n   * Reject all active execute promises and notify all subscribe observers with the given error.\n   * Clear active request tracking maps without cancelling or re-invoking any requests.\n   */\n  private rejectAllRequests(code: Code, reason: string): void {\n    this.activeInvokeQueryRequests.clear();\n    this.activeInvokeMutationRequests.clear();\n    this.activeInvokeSubscribeRequests.clear();\n\n    const error = new DataConnectError(code, reason);\n    for (const [mapKey, { rejectFn }] of this.queuedInvokeQueryRequests) {\n      this.queuedInvokeQueryRequests.delete(mapKey);\n      rejectFn(error);\n    }\n    for (const [requestId, { rejectFn }] of this.executeRequestPromises) {\n      this.executeRequestPromises.delete(requestId);\n      rejectFn(error);\n    }\n    for (const [requestId, { rejectFn }] of this.resumeRequestPromises) {\n      this.resumeRequestPromises.delete(requestId);\n      rejectFn(error);\n    }\n    for (const [requestId, observer] of this.subscribeObservers) {\n      this.subscribeObservers.delete(requestId);\n      observer.onDisconnect(code, reason);\n    }\n    this.pendingCancellations.clear();\n    this.cancelReconnect();\n  }\n\n  /**\n   * Reject all mutation execute promises.\n   * Clear active request tracking maps without cancelling or re-invoking any requests.\n   */\n  private rejectAllMutationsOnReconnect(): void {\n    const error = new DataConnectError(\n      Code.OTHER,\n      'Mutation aborted due to stream disconnect.'\n    );\n    for (const [_, requests] of this.activeInvokeMutationRequests) {\n      for (const request of requests) {\n        const promise = this.executeRequestPromises.get(request.requestId);\n        if (promise) {\n          promise.rejectFn(error);\n          this.executeRequestPromises.delete(request.requestId);\n        }\n      }\n    }\n    this.activeInvokeMutationRequests.clear();\n  }\n\n  /**\n   * Called by concrete implementations when the stream is successfully closed, gracefully or otherwise.\n   */\n  protected onStreamClose(code: number, reason: string): void {\n    this.cancelClose();\n    if (!this.hasActiveSubscriptions) {\n      // skip reconnection if there are no active subscriptions\n      void this.cleanupAndTerminate(\n        Code.OTHER,\n        `Stream disconnected while idle with code ${code}: ${reason}`\n      );\n      return;\n    }\n    logDebug(\n      `Stream disconnected with code ${code}: ${reason}. Attempting reconnect...`\n    );\n    this.rejectAllMutationsOnReconnect();\n    this.startReconnectBackoff();\n  }\n\n  /**\n   * Prepares a stream request message by adding necessary headers and metadata.\n   * If this is the first message on the stream, it includes the resource name, auth token, and App Check token.\n   * If the auth token has refreshed since the last message, it includes the new auth token.\n   *\n   * This method is called by the concrete transport implementation before sending a message.\n   *\n   * @returns the requestBody, with attached headers and initial request fields\n   */\n  protected prepareMessage<\n    Variables,\n    StreamBody extends DataConnectStreamRequest<Variables>\n  >(requestBody: StreamBody): StreamBody {\n    const preparedRequestBody: StreamBody = { ...requestBody };\n    const headers: StreamRequestHeaders = {};\n    if (this.appId) {\n      headers['x-firebase-gmpid'] = this.appId;\n    }\n    headers['X-Goog-Api-Client'] = getGoogApiClientValue(\n      this._isUsingGen,\n      this._callerSdkType\n    );\n    if (this.shouldIncludeAuth && this._authToken) {\n      headers['X-Firebase-Auth-Token'] = this._authToken;\n      this.lastSentAuthToken = this._authToken;\n    }\n    if (this.isFirstStreamMessage) {\n      headers['X-Client-Version'] = `web/${SDK_VERSION}`;\n      if (this._appCheckToken) {\n        headers['X-Firebase-App-Check'] = this._appCheckToken;\n      }\n      preparedRequestBody.name = this._connectorResourcePath;\n    }\n    preparedRequestBody.headers = headers;\n    this.isFirstStreamMessage = false;\n    return preparedRequestBody;\n  }\n\n  /**\n   * Sends a request message to the server via the concrete implementation.\n   * Ensures the connection is ready and prepares the message before sending.\n   * @returns A promise that resolves when the request message has been sent.\n   */\n  private async sendRequestMessage<Variables>(\n    requestBody: DataConnectStreamRequest<Variables>\n  ): Promise<void> {\n    if (!this.hasWaitedForInitialAuth && this.authProvider) {\n      await this.getWithAuth();\n      this.hasWaitedForInitialAuth = true;\n    }\n    if (this.streamIsReady) {\n      const prepared = this.prepareMessage(requestBody);\n      return this.sendMessage(prepared);\n    }\n    return this.ensureConnection().then(() => {\n      const prepared = this.prepareMessage(requestBody);\n      return this.sendMessage(prepared);\n    });\n  }\n\n  /**\n   * Helper to generate a consistent string key for the request tracking maps.\n   */\n  private getMapKey(operationName: string, variables?: unknown): string {\n    const sortedVariables = this.sortObjectKeys(variables);\n    return JSON.stringify({ operationName, variables: sortedVariables });\n  }\n\n  /**\n   * Recursively sorts the keys of an object.\n   */\n  private sortObjectKeys(obj: unknown): unknown {\n    if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) {\n      return obj;\n    }\n    const sortedObj: Record<string, unknown> = {};\n    Object.keys(obj as Record<string, unknown>)\n      .sort()\n      .forEach(key => {\n        sortedObj[key] = this.sortObjectKeys(\n          (obj as Record<string, unknown>)[key]\n        );\n      });\n    return sortedObj;\n  }\n\n  /**\n   * @inheritdoc\n   * @remarks\n   * This method synchronously updates the request tracking data structures before sending any message.\n   * If any asynchronous functionality is added to this function, it MUST be done in a way that\n   * preserves the synchronous update of the tracking data structures before the method returns.\n   */\n  invokeQuery<Data, Variables>(\n    queryName: string,\n    variables?: Variables\n  ): Promise<DataConnectResponse<Data>> {\n    const mapKey = this.getMapKey(queryName, variables);\n\n    if (this.activeInvokeQueryRequests.has(mapKey)) {\n      return this.queueInvokeQueryRequest(mapKey);\n    }\n\n    return this.executeOrResumeQuery(queryName, variables, mapKey);\n  }\n\n  /**\n   * Queue a new query execute request to be executed after the currently active query execute\n   * request resolves, and track + return a promise associated with the queued request. If there is\n   * already a queued request for this mapKey, return the existing queued request's promise instead.\n   */\n  private queueInvokeQueryRequest<Data>(\n    mapKey: string\n  ): Promise<DataConnectResponse<Data>> {\n    const existingQueued = this.queuedInvokeQueryRequests.get(mapKey);\n    if (existingQueued) {\n      // only queue one request per mapKey - return existing queued request promise\n      return existingQueued.responsePromise;\n    }\n\n    let resolveFn: (response: DataConnectResponse<Data>) => void;\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    let rejectFn: (reason: any) => void;\n    const responsePromise = new Promise<DataConnectResponse<Data>>(\n      (resolve, reject) => {\n        resolveFn = resolve;\n        rejectFn = reject;\n      }\n    );\n\n    this.queuedInvokeQueryRequests.set(mapKey, {\n      responsePromise,\n      resolveFn: resolveFn!,\n      rejectFn: rejectFn!\n    });\n\n    return responsePromise;\n  }\n\n  /**\n   * Executes or resumes a query. Does not check for any active requests which may be overwritten by\n   * this request - this should be handled by the caller.\n   */\n  private executeOrResumeQuery<Data, Variables>(\n    queryName: string,\n    variables: Variables | undefined,\n    mapKey: string,\n    queuedInvokeOperationPromise?: InvokeOperationPromise<Data>\n  ): Promise<DataConnectResponse<Data>> {\n    const activeSubscription = this.activeInvokeSubscribeRequests.get(mapKey);\n\n    let resolveFn: (response: DataConnectResponse<Data>) => void;\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    let rejectFn: (reason: any) => void;\n    let responsePromise: Promise<DataConnectResponse<Data>>;\n\n    // track the existing queued promise if one exists - otherwise create a new one\n    if (queuedInvokeOperationPromise) {\n      resolveFn = queuedInvokeOperationPromise.resolveFn;\n      rejectFn = queuedInvokeOperationPromise.rejectFn;\n      responsePromise = queuedInvokeOperationPromise.responsePromise;\n    } else {\n      responsePromise = new Promise<DataConnectResponse<Data>>(\n        (resolve, reject) => {\n          resolveFn = resolve;\n          rejectFn = reject;\n        }\n      );\n    }\n\n    let requestId: string;\n    let requestBody: ExecuteStreamRequest<Variables> | ResumeStreamRequest;\n\n    if (activeSubscription) {\n      // resume!\n      requestId = activeSubscription.requestId;\n      requestBody = { requestId, resume: {} };\n      this.resumeRequestPromises.set(requestId, {\n        responsePromise,\n        resolveFn: resolveFn!,\n        rejectFn: rejectFn!\n      });\n    } else {\n      // execute!\n      requestId = this.nextRequestId();\n      requestBody = {\n        requestId,\n        execute: { operationName: queryName, variables }\n      };\n      this.executeRequestPromises.set(requestId, {\n        responsePromise,\n        resolveFn: resolveFn!,\n        rejectFn: rejectFn!\n      });\n    }\n\n    this.activeInvokeQueryRequests.set(mapKey, requestBody);\n\n    responsePromise = responsePromise.finally(() => {\n      this.onInvokeQueryRequestFulfilled(\n        queryName,\n        variables,\n        mapKey,\n        requestId\n      );\n    });\n\n    this.sendRequestMessage(requestBody).catch(err => {\n      rejectFn(err);\n    });\n    return responsePromise;\n  }\n\n  /**\n   * When a query invoke request is fulfilled, clean up and trigger the next queued\n   * request if one exists.\n   */\n  private onInvokeQueryRequestFulfilled(\n    queryName: string,\n    variables: unknown,\n    mapKey: string,\n    requestId: string\n  ): void {\n    this.cleanupInvokeQueryRequest(requestId, mapKey);\n\n    const deferredCancel = this.pendingCancellations.get(requestId);\n    if (deferredCancel) {\n      this.pendingCancellations.delete(requestId);\n      this.cancelSubscription(requestId, mapKey);\n    }\n\n    const queuedRequestPromise = this.queuedInvokeQueryRequests.get(mapKey);\n    if (!queuedRequestPromise) {\n      if (!this.hasActiveSubscriptions && !this.hasActiveExecuteRequests) {\n        this.startIdleCloseTimeout();\n      }\n      return;\n    }\n\n    this.queuedInvokeQueryRequests.delete(mapKey);\n\n    void this.executeOrResumeQuery(\n      queryName,\n      variables,\n      mapKey,\n      queuedRequestPromise\n    );\n  }\n\n  /**\n   * @inheritdoc\n   * @remarks\n   * This method synchronously updates the request tracking data structures before sending any message.\n   * If any asynchronous functionality is added to this function, it MUST be done in a way that\n   * preserves the synchronous update of the tracking data structures before the method returns.\n   */\n  invokeMutation<Data, Variables>(\n    mutationName: string,\n    variables?: Variables\n  ): Promise<DataConnectResponse<Data>> {\n    const requestId = this.nextRequestId();\n    const activeRequestKey = { operationName: mutationName, variables };\n    const mapKey = this.getMapKey(mutationName, variables);\n    const executeBody: ExecuteStreamRequest<Variables> = {\n      requestId,\n      execute: activeRequestKey\n    };\n\n    let { responsePromise, rejectFn } = this.trackInvokeMutationRequest<Data>(\n      requestId,\n      mapKey,\n      executeBody\n    );\n    responsePromise = responsePromise.finally(() => {\n      this.cleanupInvokeMutationRequest(requestId, mapKey);\n      if (!this.hasActiveSubscriptions && !this.hasActiveExecuteRequests) {\n        this.startIdleCloseTimeout();\n      }\n    });\n\n    // asynchronous, fire and forget\n    this.sendRequestMessage<Variables>(executeBody).catch(err => {\n      rejectFn(err);\n    });\n    return responsePromise;\n  }\n\n  /**\n   * @inheritdoc\n   * @remarks\n   * This method synchronously updates the request tracking data structures before sending any message\n   * or cancelling the closing of the stream. If any asynchronous functionality is added to this function,\n   * it MUST be done in a way that preserves the synchronous update of the tracking data structures\n   * before the method returns.\n   */\n  invokeSubscribe<Data, Variables>(\n    observer: SubscribeObserver<Data>,\n    queryName: string,\n    variables: Variables\n  ): void {\n    const mapKey = this.getMapKey(queryName, variables);\n    const existingSubscribe = this.activeInvokeSubscribeRequests.get(mapKey);\n\n    // if this query is pending cancellation, cancel the cancellation!\n    if (existingSubscribe) {\n      const requestId = existingSubscribe.requestId;\n      if (this.pendingCancellations.has(requestId)) {\n        this.pendingCancellations.delete(requestId);\n        this.subscribeObservers.set(requestId, observer);\n      }\n    } else {\n      const requestId = this.nextRequestId();\n      const activeRequestKey = { operationName: queryName, variables };\n      const subscribeBody: SubscribeStreamRequest<Variables> = {\n        requestId,\n        subscribe: activeRequestKey\n      };\n\n      this.trackInvokeSubscribeRequest<Data>(\n        requestId,\n        mapKey,\n        subscribeBody,\n        observer\n      );\n\n      // asynchronous, fire and forget\n      this.sendRequestMessage<Variables>(subscribeBody).catch(err => {\n        observer.onError(err instanceof Error ? err : new Error(String(err)));\n        this.cleanupInvokeSubscribeRequest(requestId, mapKey);\n        if (!this.hasActiveSubscriptions) {\n          this.startIdleCloseTimeout();\n        }\n      });\n    }\n    // if we are waiting to close the stream, cancel closing!\n    this.cancelClose();\n  }\n\n  /**\n   * @inheritdoc\n   * @remarks\n   * This method synchronously updates the request tracking data structures before sending any message.\n   * If any asynchronous functionality is added to this function, it MUST be done in a way that\n   * preserves the synchronous update of the tracking data structures before the method returns.\n   */\n  invokeUnsubscribe<Variables>(queryName: string, variables: Variables): void {\n    const mapKey = this.getMapKey(queryName, variables);\n    const subscribeRequest = this.activeInvokeSubscribeRequests.get(mapKey);\n    if (!subscribeRequest) {\n      return;\n    }\n    const requestId = subscribeRequest.requestId;\n\n    this.subscribeObservers.delete(requestId);\n    const resumePromise = this.resumeRequestPromises.get(requestId);\n    if (resumePromise) {\n      this.pendingCancellations.set(requestId, {\n        operationName: queryName,\n        variables\n      });\n      return;\n    }\n    this.cancelSubscription(requestId, mapKey);\n  }\n\n  /**\n   * Cancels a subscription, cleans up the request tracking data structures, and checks to see if we\n   * should close the stream due to inactivity.\n   */\n  private cancelSubscription(requestId: string, mapKey: string): void {\n    this.cleanupInvokeSubscribeRequest(requestId, mapKey);\n    const cancelBody: CancelStreamRequest = {\n      requestId,\n      cancel: {}\n    };\n\n    // asynchronous, fire and forget\n    this.sendRequestMessage(cancelBody).catch(err => {\n      logError(`Stream Transport failed to send unsubscribe message: ${err}`);\n    });\n\n    if (!this.hasActiveSubscriptions) {\n      this.startIdleCloseTimeout();\n    }\n  }\n\n  onAuthTokenChanged(newToken: string | null): void {\n    const oldAuthToken = this._authToken;\n    this._authToken = newToken;\n\n    const oldAuthUid = this.authUid;\n    const newAuthUid = this.authProvider?.getAuth()?.getUid();\n    this.authUid = newAuthUid;\n\n    // onAuthTokenChanged gets called by the auth provider once it initializes, so we must make sure\n    // we don't prematurely disconnect the stream if this is the initial call.\n    const isInitialAuth = oldAuthUid === undefined;\n    if (isInitialAuth) {\n      return;\n    }\n\n    if (\n      (oldAuthToken && newToken === null) || // user logged out\n      (!oldAuthUid && newAuthUid) || // user logged in\n      (oldAuthUid && newAuthUid !== oldAuthUid) // logged in user changed\n    ) {\n      void this.cleanupAndTerminate(\n        Code.UNAUTHORIZED,\n        'Stream disconnected due to auth change.'\n      );\n    }\n  }\n\n  /**\n   * Handle a response message from the server. Called by the connection-specific implementation after\n   * it's transformed a message from the server into a {@linkcode DataConnectResponse}.\n   * @param requestId the Request ID associated with this response.\n   * @param response the response from the server.\n   */\n  protected async handleResponse<Data>(\n    requestId: string,\n    response: DataConnectResponse<Data>\n  ): Promise<void> {\n    if (this.executeRequestPromises.has(requestId)) {\n      const { resolveFn, rejectFn } =\n        this.executeRequestPromises.get(requestId)!;\n      this.handleInvokeOperationResponse(resolveFn, rejectFn, response);\n    } else if (\n      this.subscribeObservers.has(requestId) ||\n      this.resumeRequestPromises.has(requestId)\n    ) {\n      const observer = this.subscribeObservers.get(requestId);\n      const resumePromise = this.resumeRequestPromises.get(requestId);\n\n      if (resumePromise) {\n        this.resumeRequestPromises.delete(requestId);\n        const { resolveFn, rejectFn } = resumePromise;\n        this.handleInvokeOperationResponse(resolveFn, rejectFn, response);\n      }\n\n      if (observer) {\n        try {\n          await observer.onData(response);\n        } catch (e) {\n          logError(`Error in observer callback: ${e}`);\n        }\n      }\n    } else {\n      logError(\n        `Stream response contained unrecognized requestId '${requestId}'`\n      );\n    }\n  }\n\n  /**\n   * Handles an invoke operation response, resolving or rejecting the promise returned to the user\n   * Does not handle any cleanup for requests - this should be handled by the caller or the promise's\n   * finally() block.\n   */\n  private handleInvokeOperationResponse<Data>(\n    resolveFn: (value: DataConnectResponse<Data>) => void,\n    rejectFn: (reason: unknown) => void,\n    response: DataConnectResponse<Data>\n  ): void {\n    if (response.errors && response.errors.length) {\n      const failureResponse: DataConnectOperationFailureResponse = {\n        errors: response.errors as [],\n        data: response.data as Record<string, unknown>\n      };\n      const stringified = JSON.stringify(response.errors);\n      rejectFn(\n        new DataConnectOperationError(\n          'DataConnect error while performing request: ' + stringified,\n          failureResponse\n        )\n      );\n    } else {\n      resolveFn(response);\n    }\n  }\n}\n","/**\n * @license\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Code, DataConnectError } from '../../core/error';\nimport { logError } from '../../logger';\nimport { websocketUrlBuilder } from '../../util/url';\nimport { DataConnectResponse } from '../transport';\n\nimport { AbstractDataConnectStreamTransport } from './streamTransport';\nimport { DataConnectStreamRequest, DataConnectStreamResponse } from './wire';\n\n/** The WebSocket implementation to be used by the {@link WebSocketTransport}. */\nlet connectWebSocket: typeof WebSocket | null = globalThis.WebSocket;\n\n/**\n * This function is ONLY used for testing and for ensuring compatability in environments which may\n * be using a poyfill and/or bundlers. It should not be called by users of the Firebase JS SDK.\n * @internal\n */\nexport function initializeWebSocket(webSocketImpl: typeof WebSocket): void {\n  connectWebSocket = webSocketImpl;\n}\n\n/**\n * The code used to close the WebSocket connection.\n * This is a protocol-level code, and is not the same as the {@link Code | DataConnect error code}.\n * @internal\n */\nexport const WEBSOCKET_CLOSE_CODE = 1000;\n\n/**\n * An {@link AbstractDataConnectStreamTransport | Stream Transport} implementation that uses {@link WebSocket | WebSockets} to stream requests and responses.\n * This class handles the lifecycle of the WebSocket connection, including automatic\n * reconnection and request correlation.\n * @internal\n */\nexport class WebSocketTransport extends AbstractDataConnectStreamTransport {\n  get endpointUrl(): string {\n    return websocketUrlBuilder(\n      {\n        connector: this._connectorName,\n        location: this._location,\n        projectId: this._project,\n        service: this._serviceName\n      },\n      {\n        host: this._host,\n        sslEnabled: this._secure,\n        port: this._port\n      }\n    );\n  }\n\n  /** Decodes binary WebSocket responses to strings */\n  private decoder: TextDecoder | undefined = undefined;\n\n  /**\n   * Decodes a WebSocket response from a Uint8Array to a JSON object.\n   * Emulator does not send messages as Uint8Arrays, but prod does.\n   */\n  private decodeBinaryResponse(data: ArrayBuffer): string {\n    if (!this.decoder) {\n      this.decoder = new TextDecoder('utf-8');\n    }\n    return this.decoder.decode(data);\n  }\n\n  /** The current connection to the server. Undefined if disconnected. */\n  private connection: WebSocket | undefined = undefined;\n\n  get streamIsReady(): boolean {\n    return this.connection?.readyState === WebSocket.OPEN;\n  }\n\n  /**\n   * Current connection attempt. If null, we are not currently attemping to connect (not connected,\n   * or already connected). Will be resolved or rejected when the connection is opened or fails to open.\n   */\n  private connectionAttempt: Promise<void> | null = null;\n\n  protected ensureConnection(): Promise<void> {\n    try {\n      if (this.streamIsReady) {\n        return Promise.resolve();\n      }\n      if (this.connectionAttempt) {\n        return this.connectionAttempt;\n      }\n      this.connectionAttempt = new Promise<void>((resolve, reject) => {\n        if (!connectWebSocket) {\n          throw new DataConnectError(\n            Code.OTHER,\n            'No WebSocket Implementation detected!'\n          );\n        }\n        const ws = new connectWebSocket(this.endpointUrl);\n        this.connection = ws;\n        this.connection!.binaryType = 'arraybuffer';\n\n        ws.onopen = () => {\n          this.isUnableToConnect = false;\n          this.onConnectionReady();\n          resolve();\n        };\n\n        ws.onerror = event => {\n          this.connectionAttempt = null;\n          this.isUnableToConnect = true;\n          const error = new DataConnectError(\n            Code.OTHER,\n            `Error using WebSocket connection, closing WebSocket`\n          );\n          this.handleError(error);\n          reject(error);\n        };\n\n        ws.onmessage = ev =>\n          this.handleWebSocketMessage(ev).catch(async reason => {\n            this.handleError(reason);\n          });\n\n        ws.onclose = ev => this.handleWebsocketDisconnect(ev);\n      });\n\n      return this.connectionAttempt;\n    } catch (error) {\n      this.handleError(error);\n      throw error;\n    }\n  }\n\n  protected openConnection(): Promise<void> {\n    return this.ensureConnection().catch(err => {\n      throw new DataConnectError(\n        Code.OTHER,\n        `Failed to open connection: ${err}`\n      );\n    });\n  }\n\n  protected closeConnection(code?: number, reason?: string): Promise<void> {\n    if (!this.connection) {\n      this.connectionAttempt = null;\n      return Promise.resolve();\n    }\n    let error;\n    try {\n      if (reason) {\n        // reason string can be max 123 bytes (not characters, bytes)\n        // https://developer.mozilla.org/en-US/docs/Web/API/WebSocketStream/close#parameters\n        const MAX_BYTES = 123;\n        const encoder = new TextEncoder();\n        const bytes = encoder.encode(reason);\n        if (bytes.length <= MAX_BYTES) {\n          this.connection.close(code, reason);\n        } else {\n          const buf = new Uint8Array(MAX_BYTES);\n          const { read } = encoder.encodeInto(reason, buf);\n          const truncatedReason = reason.substring(0, read);\n          this.connection.close(code, truncatedReason);\n        }\n      } else {\n        this.connection.close(code);\n      }\n    } catch (e) {\n      error = e;\n    } finally {\n      this.connection = undefined;\n      this.connectionAttempt = null;\n    }\n    if (error) {\n      return Promise.reject(error);\n    }\n    return Promise.resolve();\n  }\n\n  /**\n   * Handle a disconnection from the server. Initiates graceful clean up and reconnection attempts.\n   * @param ev the {@link CloseEvent} that closed the WebSocket.\n   */\n  private handleWebsocketDisconnect(ev: CloseEvent): void {\n    this.connection = undefined;\n    this.connectionAttempt = null;\n    this.onStreamClose(ev.code, ev.reason);\n  }\n\n  /**\n   * Handle an error that occurred on the WebSocket. Close the connection and reject all active requests.\n   */\n  private handleError(error?: unknown): void {\n    logError(`DataConnect WebSocket error, closing stream: ${error}`);\n    let reason = error ? String(error) : 'Unknown Error';\n    if (error instanceof DataConnectError) {\n      reason = error.message;\n    }\n    void this.closeConnection(WEBSOCKET_CLOSE_CODE, reason);\n  }\n\n  protected sendMessage<Variables>(\n    requestBody: DataConnectStreamRequest<Variables>\n  ): Promise<void> {\n    return this.ensureConnection().then(() => {\n      try {\n        this.connection!.send(JSON.stringify(requestBody));\n        return Promise.resolve();\n      } catch (err) {\n        this.handleError(err);\n        throw new DataConnectError(\n          Code.OTHER,\n          `Failed to send message: ${String(err)}`\n        );\n      }\n    });\n  }\n\n  /**\n   * Handles incoming WebSocket messages.\n   * @param ev The {@link MessageEvent} from the WebSocket.\n   */\n  private async handleWebSocketMessage(ev: MessageEvent): Promise<void> {\n    const result: DataConnectStreamResponse<unknown> = this.parseWebSocketData(\n      ev.data\n    );\n    const requestId = result.requestId;\n\n    const response: DataConnectResponse<unknown> = {\n      data: result.data,\n      errors: result.errors,\n      extensions: result.extensions || { dataConnect: [] }\n    };\n\n    await this.handleResponse(requestId, response);\n  }\n\n  /**\n   * Parse a response from the server. Assert that it has a {@link DataConnectStreamResponse.requestId | requestId}.\n   * @param data the message from the server to be parsed\n   * @returns the parsed message as a {@link DataConnectStreamResponse}\n   * @throws {DataConnectError} if parsing fails or message is malformed.\n   */\n  private parseWebSocketData<Data>(\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    data: any\n  ): DataConnectStreamResponse<Data> {\n    const dataIsString = typeof data === 'string';\n    /** raw websocket message */\n    let webSocketMessage;\n    /** object containing data, errors, and extensions */\n    let result;\n    try {\n      if (dataIsString) {\n        webSocketMessage = JSON.parse(data);\n      } else {\n        webSocketMessage = JSON.parse(this.decodeBinaryResponse(data));\n      }\n    } catch (err) {\n      throw new DataConnectError(\n        Code.OTHER,\n        `Could not parse WebSocket message: ${\n          err instanceof Error ? err.message : String(err)\n        }`\n      );\n    }\n    if (typeof webSocketMessage !== 'object' || webSocketMessage === null) {\n      throw new DataConnectError(\n        Code.OTHER,\n        'WebSocket message is not an object'\n      );\n    }\n    if (dataIsString) {\n      if (!('result' in webSocketMessage)) {\n        throw new DataConnectError(\n          Code.OTHER,\n          'WebSocket message from emulator did not include result'\n        );\n      }\n      if (\n        typeof webSocketMessage.result !== 'object' ||\n        webSocketMessage.result === null\n      ) {\n        throw new DataConnectError(\n          Code.OTHER,\n          'WebSocket message result is not an object'\n        );\n      }\n      result = webSocketMessage.result;\n    } else {\n      result = webSocketMessage;\n    }\n    if (!('requestId' in result)) {\n      throw new DataConnectError(\n        Code.OTHER,\n        'WebSocket message did not include requestId'\n      );\n    }\n    return result;\n  }\n}\n","/**\n * @license\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DataConnectOptions, TransportOptions } from '../api/DataConnect';\nimport { AppCheckTokenProvider } from '../core/AppCheckTokenProvider';\nimport { Code, DataConnectError } from '../core/error';\nimport { AuthTokenProvider } from '../core/FirebaseAuthProvider';\n\nimport { RESTTransport } from './rest';\nimport { AbstractDataConnectStreamTransport } from './stream/streamTransport';\nimport { WebSocketTransport } from './stream/websocket';\nimport {\n  CallerSdkType,\n  DataConnectResponse,\n  DataConnectResponseWithMaxAge,\n  DataConnectTransportInterface,\n  SubscribeObserver\n} from './transport';\n\n/**\n * Entry point for the transport layer. Manages routing between transport implementations.\n * @internal\n */\nexport class DataConnectTransportManager\n  implements DataConnectTransportInterface\n{\n  private restTransport: RESTTransport;\n  private streamTransport?: AbstractDataConnectStreamTransport;\n  private isUsingEmulator = false;\n\n  constructor(\n    private options: DataConnectOptions,\n    private apiKey?: string,\n    private appId?: string | null,\n    private authProvider?: AuthTokenProvider,\n    private appCheckProvider?: AppCheckTokenProvider,\n    private transportOptions?: TransportOptions,\n    private _isUsingGen = false,\n    private _callerSdkType?: CallerSdkType\n  ) {\n    this.restTransport = new RESTTransport(\n      options,\n      apiKey,\n      appId,\n      authProvider,\n      appCheckProvider,\n      transportOptions,\n      _isUsingGen,\n      _callerSdkType\n    );\n  }\n\n  /**\n   * Initializes the stream transport if it hasn't been already.\n   */\n  private initStreamTransport(): AbstractDataConnectStreamTransport {\n    if (!this.streamTransport) {\n      this.streamTransport = new WebSocketTransport(\n        this.options,\n        this.apiKey,\n        this.appId,\n        this.authProvider,\n        this.appCheckProvider,\n        this.transportOptions,\n        this._isUsingGen,\n        this._callerSdkType\n      );\n      if (this.isUsingEmulator && this.transportOptions) {\n        this.streamTransport.useEmulator(\n          this.transportOptions.host!,\n          this.transportOptions.port,\n          this.transportOptions.sslEnabled\n        );\n      }\n      this.streamTransport.onCloseCallback = () => {\n        this.streamTransport = undefined;\n      };\n    }\n    return this.streamTransport;\n  }\n\n  /**\n   * Returns true if the stream is in a healthy, ready connection state and has active subscriptions.\n   */\n  private executeShouldUseStream(): boolean {\n    return (\n      !!this.streamTransport &&\n      !this.streamTransport.isPendingClose &&\n      this.streamTransport.streamIsReady &&\n      this.streamTransport.hasActiveSubscriptions &&\n      !this.streamTransport.isUnableToConnect\n    );\n  }\n\n  /**\n   * Prefer to use Streaming Transport connection when one is available.\n   * @inheritdoc\n   */\n  invokeQuery<Data, Variables>(\n    queryName: string,\n    body?: Variables\n  ): Promise<DataConnectResponseWithMaxAge<Data>> {\n    if (this.executeShouldUseStream()) {\n      return this.streamTransport!.invokeQuery<Data, Variables>(\n        queryName,\n        body\n      ).catch(err => {\n        if (this.executeShouldUseStream()) {\n          throw err;\n        }\n        return this.restTransport.invokeQuery<Data, Variables>(queryName, body);\n      });\n    }\n    return this.restTransport.invokeQuery(queryName, body);\n  }\n\n  /**\n   * Prefer to use Streaming Transport connection when one is available.\n   * @inheritdoc\n   */\n  invokeMutation<Data, Variables>(\n    queryName: string,\n    body?: Variables\n  ): Promise<DataConnectResponse<Data>> {\n    if (this.executeShouldUseStream()) {\n      return this.streamTransport!.invokeMutation<Data, Variables>(\n        queryName,\n        body\n      ).catch(err => {\n        if (this.executeShouldUseStream()) {\n          throw err;\n        }\n        return this.restTransport.invokeMutation<Data, Variables>(\n          queryName,\n          body\n        );\n      });\n    }\n    return this.restTransport.invokeMutation(queryName, body);\n  }\n\n  invokeSubscribe<Data, Variables>(\n    observer: SubscribeObserver<Data>,\n    queryName: string,\n    body?: Variables\n  ): void {\n    const streamTransport = this.initStreamTransport();\n    if (streamTransport.isUnableToConnect) {\n      throw new DataConnectError(\n        Code.OTHER,\n        'Unable to connect streaming connection to server. Subscriptions are unavailable.'\n      );\n    }\n    streamTransport.invokeSubscribe(observer, queryName, body);\n  }\n\n  invokeUnsubscribe<Variables>(queryName: string, body?: Variables): void {\n    if (this.streamTransport) {\n      this.streamTransport.invokeUnsubscribe(queryName, body);\n    }\n  }\n\n  useEmulator(host: string, port?: number, sslEnabled?: boolean): void {\n    this.isUsingEmulator = true;\n    this.transportOptions = { host, port, sslEnabled };\n    this.restTransport.useEmulator(host, port, sslEnabled);\n    if (this.streamTransport) {\n      this.streamTransport.useEmulator(host, port, sslEnabled);\n    }\n  }\n\n  onAuthTokenChanged(token: string | null): void {\n    this.restTransport.onAuthTokenChanged(token);\n    if (this.streamTransport) {\n      this.streamTransport.onAuthTokenChanged(token);\n    }\n  }\n\n  _setCallerSdkType(callerSdkType: CallerSdkType): void {\n    this._callerSdkType = callerSdkType;\n    this.restTransport._setCallerSdkType(callerSdkType);\n    if (this.streamTransport) {\n      this.streamTransport._setCallerSdkType(callerSdkType);\n    }\n  }\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DataConnectTransportInterface } from '../network';\n\nimport { DataConnect } from './DataConnect';\nimport {\n  DataConnectResult,\n  MUTATION_STR,\n  OperationRef,\n  SOURCE_SERVER\n} from './Reference';\n\nexport interface MutationRef<Data, Variables>\n  extends OperationRef<Data, Variables> {\n  refType: typeof MUTATION_STR;\n}\n\n/**\n * Creates a `MutationRef`\n * @param dcInstance Data Connect instance\n * @param mutationName name of mutation\n */\nexport function mutationRef<Data>(\n  dcInstance: DataConnect,\n  mutationName: string\n): MutationRef<Data, undefined>;\n/**\n *\n * @param dcInstance Data Connect instance\n * @param mutationName name of mutation\n * @param variables variables to send with mutation\n */\nexport function mutationRef<Data, Variables>(\n  dcInstance: DataConnect,\n  mutationName: string,\n  variables: Variables\n): MutationRef<Data, Variables>;\n/**\n *\n * @param dcInstance Data Connect instance\n * @param mutationName name of mutation\n * @param variables variables to send with mutation\n * @returns `MutationRef`\n */\nexport function mutationRef<Data, Variables>(\n  dcInstance: DataConnect,\n  mutationName: string,\n  variables?: Variables\n): MutationRef<Data, Variables> {\n  dcInstance.setInitialized();\n  const ref: MutationRef<Data, Variables> = {\n    dataConnect: dcInstance,\n    name: mutationName,\n    refType: MUTATION_STR,\n    variables: variables as Variables\n  };\n  return ref;\n}\n\n/**\n * @internal\n */\nexport class MutationManager {\n  private _inflight: Array<Promise<unknown>> = [];\n  constructor(private _transport: DataConnectTransportInterface) {}\n  executeMutation<Data, Variables>(\n    mutationRef: MutationRef<Data, Variables>\n  ): MutationPromise<Data, Variables> {\n    const result = this._transport.invokeMutation<Data, Variables>(\n      mutationRef.name,\n      mutationRef.variables\n    );\n    const withRefPromise = result.then(res => {\n      const obj: MutationResult<Data, Variables> = {\n        ...res, // Double check that the result is result.data, not just result\n        source: SOURCE_SERVER,\n        ref: mutationRef,\n        fetchTime: Date.now().toLocaleString()\n      };\n      return obj;\n    });\n    this._inflight.push(result);\n    const removePromise = (): Array<Promise<unknown>> =>\n      (this._inflight = this._inflight.filter(promise => promise !== result));\n    result.then(removePromise, removePromise);\n    return withRefPromise;\n  }\n}\n\n/**\n * Mutation Result from `executeMutation`\n */\nexport interface MutationResult<Data, Variables>\n  extends DataConnectResult<Data, Variables> {\n  ref: MutationRef<Data, Variables>;\n}\n/**\n * Mutation return value from `executeMutation`\n */\nexport interface MutationPromise<Data, Variables>\n  extends Promise<MutationResult<Data, Variables>> {\n  // reserved for special actions like cancellation\n}\n\n/**\n * Execute Mutation\n * @param mutationRef mutation to execute\n * @returns `MutationRef`\n */\nexport function executeMutation<Data, Variables>(\n  mutationRef: MutationRef<Data, Variables>\n): MutationPromise<Data, Variables> {\n  return mutationRef.dataConnect._mutationManager.executeMutation(mutationRef);\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n  FirebaseApp,\n  _getProvider,\n  _removeServiceInstance,\n  getApp\n} from '@firebase/app';\nimport { AppCheckInternalComponentName } from '@firebase/app-check-interop-types';\nimport { FirebaseAuthInternalName } from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\nimport { isCloudWorkstation, pingServer } from '@firebase/util';\n\nimport { DataConnectCache, MemoryStub } from '../cache/Cache';\nimport { InternalCacheProvider } from '../cache/CacheProvider';\nimport { AppCheckTokenProvider } from '../core/AppCheckTokenProvider';\nimport { Code, DataConnectError } from '../core/error';\nimport {\n  AuthTokenProvider,\n  FirebaseAuthProvider\n} from '../core/FirebaseAuthProvider';\nimport { QueryManager } from '../core/query/QueryManager';\nimport { logDebug, logError } from '../logger';\nimport {\n  DataConnectTransportInterface,\n  TransportClass,\n  CallerSdkType,\n  CallerSdkTypeEnum\n} from '../network';\nimport { DataConnectTransportManager } from '../network/manager';\nimport { PROD_HOST } from '../util/url';\n\nimport { MutationManager } from './Mutation';\n\n/**\n * Connector Config for calling Data Connect backend.\n */\nexport interface ConnectorConfig {\n  location: string;\n  connector: string;\n  service: string;\n}\n\n/**\n * Options to connect to emulator\n */\nexport interface TransportOptions {\n  host: string;\n  sslEnabled?: boolean;\n  port?: number;\n}\n\nconst FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR =\n  'FIREBASE_DATA_CONNECT_EMULATOR_HOST';\n\n/**\n *\n * @param fullHost\n * @returns TransportOptions\n * @internal\n */\nexport function parseOptions(fullHost: string): TransportOptions {\n  const [protocol, hostName] = fullHost.split('://');\n  const isSecure = protocol === 'https';\n  const [host, portAsString] = hostName.split(':');\n  const port = Number(portAsString);\n  return { host, port, sslEnabled: isSecure };\n}\n/**\n * DataConnectOptions including project id\n */\nexport interface DataConnectOptions extends ConnectorConfig {\n  projectId: string;\n}\n\n/**\n * Class representing Firebase Data Connect\n */\nexport class DataConnect {\n  _queryManager!: QueryManager;\n  _mutationManager!: MutationManager;\n  isEmulator = false;\n  _initialized = false;\n  private _transport!: DataConnectTransportInterface;\n  private _transportClass: TransportClass | undefined;\n  private _transportOptions?: TransportOptions;\n  private _authTokenProvider?: AuthTokenProvider;\n  _isUsingGeneratedSdk: boolean = false;\n  _callerSdkType: CallerSdkType = CallerSdkTypeEnum.Base;\n  private _appCheckTokenProvider?: AppCheckTokenProvider;\n  private _cacheSettings?: CacheSettings;\n  /**\n   * @internal\n   */\n  private cache?: DataConnectCache;\n  // @internal\n  constructor(\n    public readonly app: FirebaseApp,\n    // TODO(mtewani): Replace with _dataConnectOptions in the future\n    private readonly dataConnectOptions: DataConnectOptions,\n    private readonly _authProvider: Provider<FirebaseAuthInternalName>,\n    private readonly _appCheckProvider: Provider<AppCheckInternalComponentName>\n  ) {\n    if (typeof process !== 'undefined' && process.env) {\n      const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];\n      if (host) {\n        logDebug('Found custom host. Using emulator');\n        this.isEmulator = true;\n        this._transportOptions = parseOptions(host);\n      }\n    }\n  }\n  /**\n   * @internal\n   */\n  getCache(): DataConnectCache | undefined {\n    return this.cache;\n  }\n  // @internal\n  _useGeneratedSdk(): void {\n    if (!this._isUsingGeneratedSdk) {\n      this._isUsingGeneratedSdk = true;\n    }\n  }\n  _setCallerSdkType(callerSdkType: CallerSdkType): void {\n    this._callerSdkType = callerSdkType;\n    if (this._initialized) {\n      this._transport._setCallerSdkType(callerSdkType);\n    }\n  }\n  _delete(): Promise<void> {\n    _removeServiceInstance(\n      this.app,\n      'data-connect',\n      JSON.stringify(this.getSettings())\n    );\n    return Promise.resolve();\n  }\n\n  // @internal\n  getSettings(): ConnectorConfig {\n    const copy = JSON.parse(JSON.stringify(this.dataConnectOptions));\n    delete copy.projectId;\n    return copy;\n  }\n\n  /**\n   * @internal\n   */\n  setCacheSettings(cacheSettings: CacheSettings): void {\n    this._cacheSettings = cacheSettings;\n  }\n\n  // @internal\n  setInitialized(): void {\n    if (this._initialized) {\n      return;\n    }\n    if (this._transportClass === undefined) {\n      logDebug(\n        'transportClass not provided. Defaulting to DataConnectTransportManager.'\n      );\n      this._transportClass = DataConnectTransportManager;\n    }\n\n    this._authTokenProvider = new FirebaseAuthProvider(\n      this.app.name,\n      this.app.options,\n      this._authProvider\n    );\n    const connectorConfig: ConnectorConfig = {\n      connector: this.dataConnectOptions.connector,\n      service: this.dataConnectOptions.service,\n      location: this.dataConnectOptions.location\n    };\n    if (this._cacheSettings) {\n      this.cache = new DataConnectCache(\n        this._authTokenProvider,\n        this.app.options.projectId!,\n        connectorConfig,\n        this._transportOptions?.host || PROD_HOST,\n        this._cacheSettings\n      );\n    }\n\n    if (this._appCheckProvider) {\n      this._appCheckTokenProvider = new AppCheckTokenProvider(\n        this.app,\n        this._appCheckProvider\n      );\n    }\n\n    this._transport = new this._transportClass(\n      this.dataConnectOptions,\n      this.app.options.apiKey,\n      this.app.options.appId,\n      this._authTokenProvider,\n      this._appCheckTokenProvider,\n      undefined,\n      this._isUsingGeneratedSdk,\n      this._callerSdkType\n    );\n    if (this._transportOptions) {\n      this._transport.useEmulator(\n        this._transportOptions.host,\n        this._transportOptions.port,\n        this._transportOptions.sslEnabled\n      );\n    }\n\n    this._queryManager = new QueryManager(this._transport, this, this.cache);\n    this._mutationManager = new MutationManager(this._transport);\n    this._initialized = true;\n  }\n\n  // @internal\n  enableEmulator(transportOptions: TransportOptions): void {\n    if (\n      this._transportOptions &&\n      this._initialized &&\n      !areTransportOptionsEqual(this._transportOptions, transportOptions)\n    ) {\n      logError('enableEmulator called after initialization');\n      throw new DataConnectError(\n        Code.ALREADY_INITIALIZED,\n        'DataConnect instance already initialized!'\n      );\n    }\n    this._transportOptions = transportOptions;\n    this.isEmulator = true;\n  }\n}\n\n/**\n * @internal\n * @param transportOptions1\n * @param transportOptions2\n * @returns\n */\nexport function areTransportOptionsEqual(\n  transportOptions1: TransportOptions,\n  transportOptions2: TransportOptions\n): boolean {\n  return (\n    transportOptions1.host === transportOptions2.host &&\n    transportOptions1.port === transportOptions2.port &&\n    transportOptions1.sslEnabled === transportOptions2.sslEnabled\n  );\n}\n\n/**\n * Connect to the DataConnect Emulator\n * @param dc Data Connect instance\n * @param host host of emulator server\n * @param port port of emulator server\n * @param sslEnabled use https\n */\nexport function connectDataConnectEmulator(\n  dc: DataConnect,\n  host: string,\n  port?: number,\n  sslEnabled = false\n): void {\n  // Workaround to get cookies in Firebase Studio\n  if (isCloudWorkstation(host)) {\n    void pingServer(`https://${host}${port ? `:${port}` : ''}`);\n  }\n  dc.enableEmulator({ host, port, sslEnabled });\n}\n\nexport interface DataConnectSettings {\n  cacheSettings?: CacheSettings;\n}\n\n/**\n * Initialize DataConnect instance\n * @param options ConnectorConfig\n */\nexport function getDataConnect(\n  options: ConnectorConfig,\n  settings?: DataConnectSettings\n): DataConnect;\nexport function getDataConnect(options: ConnectorConfig): DataConnect;\n/**\n * Initialize DataConnect instance\n * @param app FirebaseApp to initialize to.\n * @param connectorConfig ConnectorConfig\n */\nexport function getDataConnect(\n  app: FirebaseApp,\n  connectorConfig: ConnectorConfig\n): DataConnect;\n\n/**\n * Initialize DataConnect instance\n * @param app FirebaseApp to initialize to.\n * @param connectorConfig ConnectorConfig\n */\nexport function getDataConnect(\n  app: FirebaseApp,\n  connectorConfig: ConnectorConfig,\n  settings: DataConnectSettings\n): DataConnect;\n\nexport function getDataConnect(\n  appOrConnectorConfig: FirebaseApp | ConnectorConfig,\n  settingsOrConnectorConfig?: ConnectorConfig | DataConnectSettings,\n  settings?: DataConnectSettings\n): DataConnect {\n  let app: FirebaseApp;\n  let connectorConfig: ConnectorConfig;\n  let realSettings: DataConnectSettings;\n  if ('location' in appOrConnectorConfig) {\n    connectorConfig = appOrConnectorConfig;\n    app = getApp();\n    realSettings = settingsOrConnectorConfig as DataConnectSettings;\n  } else {\n    app = appOrConnectorConfig;\n    connectorConfig = settingsOrConnectorConfig as ConnectorConfig;\n    realSettings = settings as DataConnectSettings;\n  }\n\n  if (!app || Object.keys(app).length === 0) {\n    app = getApp();\n  }\n\n  // Options to store in Firebase Component Provider.\n  const serializedOptions = {\n    ...connectorConfig,\n    projectId: app.options.projectId\n  };\n\n  // We should sort the keys before initialization.\n  const sortedSerialized = Object.fromEntries(\n    Object.entries(serializedOptions).sort()\n  );\n\n  const provider = _getProvider(app, 'data-connect');\n  const identifier = JSON.stringify(sortedSerialized);\n  if (provider.isInitialized(identifier)) {\n    const dcInstance = provider.getImmediate({ identifier });\n    const options = provider.getOptions(identifier);\n    const optionsValid = Object.keys(options).length > 0;\n    if (optionsValid) {\n      logDebug('Re-using cached instance');\n      return dcInstance;\n    }\n  }\n  validateDCOptions(connectorConfig);\n\n  logDebug('Creating new DataConnect instance');\n  // Initialize with options.\n  const dataConnect = provider.initialize({\n    instanceIdentifier: identifier,\n    options: Object.fromEntries(\n      Object.entries({\n        ...sortedSerialized\n      }).sort()\n    )\n  });\n  if (realSettings?.cacheSettings) {\n    dataConnect.setCacheSettings(realSettings.cacheSettings);\n  }\n  return dataConnect;\n}\n\n/**\n *\n * @param dcOptions\n * @returns {void}\n * @internal\n */\nexport function validateDCOptions(dcOptions: ConnectorConfig): boolean {\n  const fields = ['connector', 'location', 'service'];\n  if (!dcOptions) {\n    throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');\n  }\n  fields.forEach(field => {\n    if (\n      dcOptions[field as keyof ConnectorConfig] === null ||\n      dcOptions[field as keyof ConnectorConfig] === undefined\n    ) {\n      throw new DataConnectError(Code.INVALID_ARGUMENT, `${field} Required`);\n    }\n  });\n  return true;\n}\n\n/**\n * Delete DataConnect instance\n * @param dataConnect DataConnect instance\n * @returns\n */\nexport function terminate(dataConnect: DataConnect): Promise<void> {\n  return dataConnect._delete();\n  // TODO(mtewani): Stop pending tasks\n}\nexport const StorageType = {\n  MEMORY: 'MEMORY'\n} as const;\n\nexport type StorageType = (typeof StorageType)[keyof typeof StorageType];\n\nexport interface CacheSettings {\n  cacheProvider: CacheProvider<StorageType>;\n  maxAgeSeconds?: number;\n}\nexport interface CacheProvider<T extends StorageType> {\n  type: T;\n  /**\n   * @internal\n   */\n  initialize(cacheId: string): InternalCacheProvider;\n}\n\nexport function makeMemoryCacheProvider(): CacheProvider<'MEMORY'> {\n  return new MemoryStub();\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const QueryFetchPolicy = {\n  PREFER_CACHE: 'PREFER_CACHE',\n  CACHE_ONLY: 'CACHE_ONLY',\n  SERVER_ONLY: 'SERVER_ONLY'\n} as const;\n\n/*\n * Represents policy for how executeQuery fetches data\n */\nexport type QueryFetchPolicy =\n  (typeof QueryFetchPolicy)[keyof typeof QueryFetchPolicy];\n\n/**\n * Options for executing a query.\n */\nexport interface ExecuteQueryOptions {\n  fetchPolicy: QueryFetchPolicy;\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Code, DataConnectError } from '../core/error';\nimport {\n  ExecuteQueryOptions,\n  QueryFetchPolicy\n} from '../core/query/queryOptions';\nimport { DataConnectExtensionWithMaxAge } from '../network';\n\nimport { DataConnect, getDataConnect } from './DataConnect';\nimport {\n  OperationRef,\n  QUERY_STR,\n  DataConnectResult,\n  SerializedRef\n} from './Reference';\n\n/**\n * QueryRef object\n */\nexport interface QueryRef<Data, Variables>\n  extends OperationRef<Data, Variables> {\n  refType: typeof QUERY_STR;\n}\n\n/** @internal */\nexport type InternalQueryResult<Data, Variables> = QueryResult<\n  Data,\n  Variables\n> &\n  Omit<DataConnectResult<Data, Variables>, 'extensions'> & {\n    extensions?: {\n      dataConnect?: DataConnectExtensionWithMaxAge[];\n    };\n  };\n\n/**\n * Result of `executeQuery`\n */\nexport interface QueryResult<Data, Variables>\n  extends DataConnectResult<Data, Variables> {\n  ref: QueryRef<Data, Variables>;\n  toJSON: () => SerializedRef<Data, Variables>;\n}\n/**\n * Promise returned from `executeQuery`\n */\nexport interface QueryPromise<Data, Variables>\n  extends Promise<QueryResult<Data, Variables>> {\n  // reserved for special actions like cancellation\n}\n\n/**\n * Execute Query\n * @param queryRef query to execute.\n * @returns `QueryPromise`\n */\nexport function executeQuery<Data, Variables>(\n  queryRef: QueryRef<Data, Variables>,\n  options?: ExecuteQueryOptions\n): QueryPromise<Data, Variables> {\n  if (queryRef.refType !== QUERY_STR) {\n    return Promise.reject(\n      new DataConnectError(\n        Code.INVALID_ARGUMENT,\n        `ExecuteQuery can only execute query operations`\n      )\n    );\n  }\n  const queryManager = queryRef.dataConnect._queryManager;\n  const fetchPolicy = options?.fetchPolicy ?? QueryFetchPolicy.PREFER_CACHE;\n  switch (fetchPolicy) {\n    case QueryFetchPolicy.SERVER_ONLY:\n      return queryManager.fetchServerResults(queryRef);\n    case QueryFetchPolicy.CACHE_ONLY:\n      return queryManager.fetchCacheResults(queryRef, true);\n    case QueryFetchPolicy.PREFER_CACHE:\n      return queryManager.preferCacheResults(queryRef, false);\n    default:\n      throw new DataConnectError(\n        Code.INVALID_ARGUMENT,\n        `Invalid fetch policy: ${fetchPolicy}`\n      );\n  }\n}\n\n/**\n * Execute Query\n * @param dcInstance Data Connect instance to use.\n * @param queryName Query to execute\n * @returns `QueryRef`\n */\nexport function queryRef<Data>(\n  dcInstance: DataConnect,\n  queryName: string\n): QueryRef<Data, undefined>;\n/**\n * Execute Query\n * @param dcInstance Data Connect instance to use.\n * @param queryName Query to execute\n * @param variables Variables to execute with\n * @returns `QueryRef`\n */\nexport function queryRef<Data, Variables>(\n  dcInstance: DataConnect,\n  queryName: string,\n  variables: Variables\n): QueryRef<Data, Variables>;\n/**\n * Execute Query\n * @param dcInstance Data Connect instance to use.\n * @param queryName Query to execute\n * @param variables Variables to execute with\n * @param initialCache initial cache to use for client hydration\n * @returns `QueryRef`\n */\nexport function queryRef<Data, Variables>(\n  dcInstance: DataConnect,\n  queryName: string,\n  variables?: Variables,\n  initialCache?: QueryResult<Data, Variables>\n): QueryRef<Data, Variables> {\n  dcInstance.setInitialized();\n  if (initialCache !== undefined) {\n    dcInstance._queryManager.updateSSR(initialCache);\n  }\n  return {\n    dataConnect: dcInstance,\n    refType: QUERY_STR,\n    name: queryName,\n    variables: variables as Variables\n  };\n}\n/**\n * Converts serialized ref to query ref\n * @param serializedRef ref to convert to `QueryRef`\n * @returns `QueryRef`\n */\nexport function toQueryRef<Data, Variables>(\n  serializedRef: SerializedRef<Data, Variables>\n): QueryRef<Data, Variables> {\n  const {\n    refInfo: { name, variables, connectorConfig }\n  } = serializedRef;\n  return queryRef(getDataConnect(connectorConfig), name, variables);\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ExecuteQueryOptions } from '../api';\nimport {\n  ConnectorConfig,\n  DataConnect,\n  getDataConnect\n} from '../api/DataConnect';\nimport { Code, DataConnectError } from '../core/error';\n\ninterface ParsedArgs<Variables> {\n  dc: DataConnect;\n  vars: Variables;\n  options?: ExecuteQueryOptions;\n}\n\n/**\n * The generated SDK will allow the user to pass in either the variables or the data connect instance\n * with the variables. This function validates the variables and returns back the DataConnect instance\n * and variables based on the arguments passed in.\n *\n * Generated SDKs generated from versions 3.2.0 and lower of the Data Connect emulator binary are\n * NOT concerned with options, and will use this function to validate arguments.\n *\n * @param connectorConfig\n * @param dcOrVars\n * @param vars\n * @param variablesRequired\n * @returns {DataConnect} and {Variables} instance\n * @internal\n */\nexport function validateArgs<Variables extends object>(\n  connectorConfig: ConnectorConfig,\n  dcOrVars?: DataConnect | Variables,\n  vars?: Variables,\n  variablesRequired?: boolean\n): ParsedArgs<Variables> {\n  let dcInstance: DataConnect;\n  let realVars: Variables;\n\n  const dcFirstArg = dcOrVars && 'enableEmulator' in dcOrVars;\n\n  if (dcFirstArg) {\n    dcInstance = dcOrVars as DataConnect;\n    realVars = vars as Variables;\n  } else {\n    dcInstance = getDataConnect(connectorConfig);\n    realVars = dcOrVars as Variables;\n  }\n\n  if (!dcInstance || (!realVars && variablesRequired)) {\n    throw new DataConnectError(Code.INVALID_ARGUMENT, 'Variables required.');\n  }\n\n  return { dc: dcInstance, vars: realVars };\n}\n\n/**\n * The generated SDK will allow the user to pass in either the variables or the data connect instance\n * with the variables, and/or options. This function validates the variables and returns back the\n * DataConnect instance and variables, and potentially options, based on the arguments passed in.\n *\n * Generated SDKs generated from versions 3.2.0 and higher of the Data Connect emulator binary are\n * in fact concerned with options, and will use this function to validate arguments.\n *\n * @param connectorConfig\n * @param dcOrVarsOrOptions\n * @param varsOrOptions\n * @param variablesRequired\n * @param options\n * @returns {DataConnect} and {Variables} instance, and optionally {ExecuteQueryOptions}\n * @internal\n */\nexport function validateArgsWithOptions<Variables extends object>(\n  connectorConfig: ConnectorConfig,\n  dcOrVarsOrOptions?: DataConnect | Variables | ExecuteQueryOptions,\n  varsOrOptions?: Variables | ExecuteQueryOptions,\n  options?: ExecuteQueryOptions,\n  hasVars?: boolean,\n  variablesRequired?: boolean\n): ParsedArgs<Variables> {\n  let dcInstance: DataConnect;\n  let realVars: Variables;\n  let realOptions: ExecuteQueryOptions;\n\n  const dcFirstArg = dcOrVarsOrOptions && 'enableEmulator' in dcOrVarsOrOptions;\n\n  if (dcFirstArg) {\n    dcInstance = dcOrVarsOrOptions as DataConnect;\n    if (hasVars) {\n      realVars = varsOrOptions as Variables;\n      realOptions = options as ExecuteQueryOptions;\n    } else {\n      realVars = undefined as unknown as Variables;\n      realOptions = varsOrOptions as ExecuteQueryOptions;\n    }\n  } else {\n    dcInstance = getDataConnect(connectorConfig);\n    if (hasVars) {\n      realVars = dcOrVarsOrOptions as Variables;\n      realOptions = varsOrOptions as ExecuteQueryOptions;\n    } else {\n      realVars = undefined as unknown as Variables;\n      realOptions = dcOrVarsOrOptions as ExecuteQueryOptions;\n    }\n  }\n\n  if (!dcInstance || (!realVars && variablesRequired)) {\n    throw new DataConnectError(Code.INVALID_ARGUMENT, 'Variables required.');\n  }\n\n  return { dc: dcInstance, vars: realVars, options: realOptions };\n}\n","/**\n * @license\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { QueryRef, QueryResult, toQueryRef } from '../../api/query';\nimport { SerializedRef } from '../../api/Reference';\nimport { DataConnectError, Code } from '../error';\n\nimport { getRefSerializer } from './QueryManager';\n\n/**\n * `OnCompleteSubscription`\n */\nexport type OnCompleteSubscription = () => void;\n/**\n * Representation of full observer options in `subscribe`\n */\nexport interface SubscriptionOptions<Data, Variables> {\n  onNext?: OnResultSubscription<Data, Variables>;\n  onErr?: OnErrorSubscription;\n  onComplete?: OnCompleteSubscription;\n}\n\n/**\n * Signature for `OnResultSubscription` for `subscribe`\n */\nexport type OnResultSubscription<Data, Variables> = (\n  res: QueryResult<Data, Variables>\n) => void;\n/**\n * Signature for `OnErrorSubscription` for `subscribe`\n */\nexport type OnErrorSubscription = (err?: DataConnectError) => void;\n/**\n * Signature for unsubscribe from `subscribe`\n */\nexport type QueryUnsubscribe = () => void;\n/**\n * Representation of user provided subscription options.\n */\nexport interface DataConnectSubscription<Data, Variables> {\n  userCallback: OnResultSubscription<Data, Variables>;\n  errCallback?: (e?: DataConnectError) => void;\n  unsubscribe: () => void;\n}\n\n/**\n * Subscribe to a `QueryRef`\n * @param queryRefOrSerializedResult query ref or serialized result.\n * @param observer observer object to use for subscribing.\n * @returns `SubscriptionOptions`\n */\nexport function subscribe<Data, Variables>(\n  queryRefOrSerializedResult:\n    | QueryRef<Data, Variables>\n    | SerializedRef<Data, Variables>,\n  observer: SubscriptionOptions<Data, Variables>\n): QueryUnsubscribe;\n/**\n * Subscribe to a `QueryRef`\n * @param queryRefOrSerializedResult query ref or serialized result.\n * @param onNext Callback to call when result comes back.\n * @param onError Callback to call when error gets thrown.\n * @param onComplete Called when subscription completes.\n * @returns `SubscriptionOptions`\n */\nexport function subscribe<Data, Variables>(\n  queryRefOrSerializedResult:\n    | QueryRef<Data, Variables>\n    | SerializedRef<Data, Variables>,\n  onNext: OnResultSubscription<Data, Variables>,\n  onError?: OnErrorSubscription,\n  onComplete?: OnCompleteSubscription\n): QueryUnsubscribe;\n/**\n * Subscribe to a `QueryRef`\n * @param queryRefOrSerializedResult query ref or serialized result.\n * @param observerOrOnNext observer object or next function.\n * @param onError Callback to call when error gets thrown.\n * @param onComplete Called when subscription completes.\n * @returns `SubscriptionOptions`\n */\nexport function subscribe<Data, Variables>(\n  queryRefOrSerializedResult:\n    | QueryRef<Data, Variables>\n    | SerializedRef<Data, Variables>,\n  observerOrOnNext:\n    | SubscriptionOptions<Data, Variables>\n    | OnResultSubscription<Data, Variables>,\n  onError?: OnErrorSubscription,\n  onComplete?: OnCompleteSubscription\n): QueryUnsubscribe {\n  let ref: QueryRef<Data, Variables>;\n  let initialCache: QueryResult<Data, Variables> | undefined;\n  if ('refInfo' in queryRefOrSerializedResult) {\n    const serializedRef: SerializedRef<Data, Variables> =\n      queryRefOrSerializedResult;\n    const { data, source, fetchTime } = serializedRef;\n\n    ref = toQueryRef(serializedRef);\n    initialCache = {\n      data,\n      source,\n      fetchTime,\n      ref,\n      toJSON: getRefSerializer(ref, data, source, fetchTime)\n    };\n  } else {\n    ref = queryRefOrSerializedResult;\n  }\n  let onResult: OnResultSubscription<Data, Variables> | undefined = undefined;\n  if (typeof observerOrOnNext === 'function') {\n    onResult = observerOrOnNext;\n  } else {\n    onResult = observerOrOnNext.onNext;\n    onError = observerOrOnNext.onErr;\n    onComplete = observerOrOnNext.onComplete;\n  }\n  if (!onResult) {\n    throw new DataConnectError(Code.INVALID_ARGUMENT, 'Must provide onNext');\n  }\n  return ref.dataConnect._queryManager.addSubscription(\n    ref,\n    onResult,\n    onComplete,\n    onError,\n    initialCache\n  );\n}\n","/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport {\n  _registerComponent,\n  registerVersion,\n  SDK_VERSION\n} from '@firebase/app';\nimport { Component, ComponentType } from '@firebase/component';\n\nimport { name, version } from '../package.json';\nimport { setSDKVersion } from '../src/core/version';\n\nimport { DataConnect, ConnectorConfig } from './api/DataConnect';\nimport { Code, DataConnectError } from './core/error';\n\nexport function registerDataConnect(variant?: string): void {\n  setSDKVersion(SDK_VERSION);\n  _registerComponent(\n    new Component(\n      'data-connect',\n      (container, { instanceIdentifier: connectorConfigStr, options }) => {\n        const app = container.getProvider('app').getImmediate()!;\n        const authProvider = container.getProvider('auth-internal');\n        const appCheckProvider = container.getProvider('app-check-internal');\n        let newOpts = options as ConnectorConfig;\n        if (connectorConfigStr) {\n          newOpts = {\n            ...JSON.parse(connectorConfigStr),\n            ...newOpts\n          };\n        }\n        if (!app.options.projectId) {\n          throw new DataConnectError(\n            Code.INVALID_ARGUMENT,\n            'Project ID must be provided. Did you pass in a proper projectId to initializeApp?'\n          );\n        }\n        return new DataConnect(\n          app,\n          { ...newOpts, projectId: app.options.projectId! },\n          authProvider,\n          appCheckProvider\n        );\n      },\n      ComponentType.PUBLIC\n    ).setMultipleInstances(true)\n  );\n  registerVersion(name, version, variant);\n  // BUILD_TARGET will be replaced by values like esm, cjs, etc during the compilation\n  registerVersion(name, version, '__BUILD_TARGET__');\n}\n","/**\n * Firebase Data Connect\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { DataConnect } from './api/DataConnect';\nimport { registerDataConnect } from './register';\n\nexport * from './api';\nexport * from './api.browser';\n\nregisterDataConnect();\n\ndeclare module '@firebase/component' {\n  interface NameServiceMapping {\n    'data-connect': DataConnect;\n  }\n}\n"],"names":["FirebaseError","Error","constructor","code","message","customData","super","this","name","Object","setPrototypeOf","prototype","captureStackTrace","ErrorFactory","create","service","serviceName","errors","data","fullCode","template","replaceTemplate","ptr","result","length","start","indexOf","substring","end","key","value","String","e","fullMessage","isCloudWorkstation","url","startsWith","URL","hostname","endsWith","Component","instanceFactory","type","multipleInstances","serviceProps","instantiationMode","onInstanceCreated","setInstantiationMode","mode","setMultipleInstances","setServiceProps","props","setInstanceCreatedCallback","callback","LogLevel","levelStringToEnum","debug","DEBUG","verbose","VERBOSE","info","INFO","warn","WARN","error","ERROR","silent","SILENT","defaultLogLevel","ConsoleMethod","defaultLogHandler","instance","logType","args","logLevel","now","Date","toISOString","method","console","SDK_VERSION","Code","OTHER","ALREADY_INITIALIZED","NOT_INITIALIZED","NOT_SUPPORTED","INVALID_ARGUMENT","PARTIAL_ERROR","UNAUTHORIZED","DataConnectError","toString","DataConnectOperationError","response","EntityDataObject","getServerValue","serverValues","globalID","referencedFrom","Set","getServerValues","toJSON","map","Array","from","fromJSON","json","edo","updateServerValue","requestedFrom","add","InMemoryCacheProvider","_keyId","edos","Map","resultTrees","setResultTree","queryId","rt","set","getResultTree","get","updateEntityData","entityData","getEntityData","globalId","has","close","Promise","resolve","GLOBAL_ID_KEY","EntityNode","scalars","references","objectLists","entityDataKeys","loadData","values","entityIds","acc","cacheProvider","undefined","isArray","hasOwnProperty","ids","objArray","scalarArray","index","entries","entityNode","push","impactedRefs","resultObject","EncodingMode","hydrated","assign","obj","fromJson","sdo","backingData","ResultTree","rootStub","maxAge","cachedAt","lastAccessed","_lastAccessed","isStale","getTime","updateMaxAge","maxAgeInSeconds","updateAccessed","getRootStub","ImpactedQueryRefsAccumulator","impacted","filter","ref","forEach","consumeEvents","events","clear","ResultTreeProcessor","hydrateResults","rootStubObject","dehydrateResults","DataConnectCache","authProvider","projectId","connectorConfig","host","cacheSettings","uid","addTokenChangeListener","async","_","newUid","getAuth","getUid","identifier","getIdentifier","initializeNewProviders","initialize","connector","location","generateSHA256Hash","input","TextEncoder","encode","hashBuffer","crypto","subtle","digest","Uint8Array","b","padStart","join","containsResultTree","getResultJSON","processor","resultTree","update","stubDataObject","maxAgeSeconds","MemoryStub","cacheId","AppCheckTokenProvider","app","appCheckProvider","_isFirebaseServerApp","settings","appCheckToken","serverAppAppCheckToken","appCheck","getImmediate","optional","then","catch","getToken","token","reject","setTimeout","listener","addTokenListener","logger","Logger","_logLevel","_logHandler","_userLogHandler","val","TypeError","setLogLevel","logHandler","userLogHandler","log","logDebug","msg","logError","FirebaseAuthProvider","_appName","_options","_authProvider","_auth","onInit","auth","forceRefresh","JSON","stringify","addAuthTokenListener","removeTokenChangeListener","removeAuthTokenListener","err","QUERY_STR","MUTATION_STR","SOURCE_SERVER","SOURCE_CACHE","populatePath","path","toUpdate","extension","curObj","slice","entityId","entityArr","i","_id","encoderImpl","decoderImpl","sortKeysForObj","o","keys","sort","reduce","accumulator","currentKey","getRefSerializer","queryRef","source","fetchTime","refInfo","variables","dataConnect","options","getSettings","setEncoder","encoder","setDecoder","decoder","s","parse","QueryManager","preferCacheResults","allowStale","cacheResult","fetchCacheResults","fetchServerResults","transport","dc","cache","callbacks","subscriptionCache","queue","waitForQueuedWrites","promise","updateSSR","updatedData","updateCache","publishCacheResultsToSubscribers","extensions","parseEntityIds","dataConnectExtensions","dataCopy","ret","updatedMaxAge","getMaxAgeFromExtensions","Number","refType","addSubscription","onResultCallback","onCompleteCallback","onErrorCallback","initialCache","unsubscribe","newList","subscription","delete","invokeUnsubscribe","userCallback","errCallback","invokeSubscribe","makeSubscribeObserver","invokeQuery","originalExtensions","queryResult","getDataConnectExtensionsWithoutMaxAge","updatedKeys","publishDataToSubscribers","publishErrorToSubscribers","getFromResultTreeCache","getFromSubscriberCache","impactedQueries","query","newJson","enableEmulator","port","useEmulator","onData","handleStreamNotification","onDisconnect","reason","handleStreamDisconnect","onError","stringified","failureResponse","cb","CallerSdkTypeEnum","Base","Generated","TanstackReactCore","GeneratedReact","TanstackAngularCore","GeneratedAngular","getGoogApiClientValue","isUsingGen","callerSdkType","str","toLowerCase","AbstractDataConnectTransport","apiKey","appId","transportOptions","_isUsingGen","_callerSdkType","_host","_location","_connectorName","_secure","_project","_authToken","_appCheckToken","_lastToken","_isUsingEmulator","_port","sslEnabled","project","_serviceName","_connectorResourcePath","onAuthTokenChanged","isSecure","getWithAuth","forceToken","starterPromise","accessToken","withRetry","promiseFactory","retry","isNewToken","res","_setLastToken","lastToken","_setCallerSdkType","connectFetch","globalThis","fetch","dcFetch","body","signal","headers","fetchOptions","jsonResponse","credentials","getErrorMessage","status","PROD_HOST","addToken","newUrl","searchParams","append","RESTTransport","queryName","abortController","AbortController","endpointUrl","operationName","invokeMutation","mutationName","restUrlBuilder","projectConfig","baseUrl","observer","newToken","AbstractDataConnectStreamTransport","isPendingClose","idleTimeout","hasActiveSubscriptions","activeInvokeSubscribeRequests","size","hasActiveExecuteRequests","activeInvokeQueryRequests","activeInvokeMutationRequests","isUnableToConnect","requestNumber","queuedInvokeQueryRequests","executeRequestPromises","resumeRequestPromises","subscribeObservers","pendingCancellations","hasWaitedForInitialAuth","reconnectDelayMs","reconnectTimer","reconnectAttempts","removeOnlineEventListener","removeVisibilityChangeEventListener","onOnlineEventListener","cancelReconnect","attemptReconnect","onVisibilityChangeEventListener","doc","document","visibilityState","isFirstStreamMessage","lastSentAuthToken","registerBrowserEventListeners","addEventListener","removeEventListener","cleanupBrowserEventListeners","cleanupAndTerminate","cancelClose","rejectAllRequests","closeConnection","onCloseCallback","nextRequestId","trackInvokeMutationRequest","requestId","mapKey","executeBody","resolveFn","rejectFn","executeRequestPromise","responsePromise","activeRequests","trackInvokeSubscribeRequest","subscribeBody","cleanupInvokeQueryRequest","cleanupInvokeMutationRequest","executeRequests","updatedRequests","request","cleanupInvokeSubscribeRequest","clearTimeout","startReconnectBackoff","delay","Math","min","jitter","random","ensureConnection","retriggerActiveRequests","sendRequestMessage","requestBody","shouldIncludeAuth","onConnectionReady","startIdleCloseTimeout","rejectAllMutationsOnReconnect","requests","onStreamClose","prepareMessage","preparedRequestBody","streamIsReady","prepared","sendMessage","getMapKey","sortedVariables","sortObjectKeys","sortedObj","queueInvokeQueryRequest","executeOrResumeQuery","existingQueued","queuedInvokeOperationPromise","activeSubscription","resume","execute","finally","onInvokeQueryRequestFulfilled","cancelSubscription","queuedRequestPromise","activeRequestKey","existingSubscribe","subscribe","subscribeRequest","cancelBody","cancel","oldAuthToken","oldAuthUid","authUid","newAuthUid","handleResponse","handleInvokeOperationResponse","resumePromise","connectWebSocket","WebSocket","WebSocketTransport","connection","connectionAttempt","websocketUrlBuilder","decodeBinaryResponse","TextDecoder","decode","readyState","OPEN","ws","binaryType","onopen","onerror","event","handleError","onmessage","ev","handleWebSocketMessage","onclose","handleWebsocketDisconnect","openConnection","MAX_BYTES","buf","read","encodeInto","truncatedReason","send","parseWebSocketData","dataIsString","webSocketMessage","DataConnectTransportManager","isUsingEmulator","restTransport","initStreamTransport","streamTransport","executeShouldUseStream","mutationRef","dcInstance","setInitialized","MutationManager","_transport","_inflight","executeMutation","withRefPromise","toLocaleString","removePromise","_mutationManager","parseOptions","fullHost","protocol","hostName","split","portAsString","DataConnect","dataConnectOptions","_appCheckProvider","isEmulator","_initialized","_isUsingGeneratedSdk","process","env","_transportOptions","getCache","_useGeneratedSdk","_delete","_removeServiceInstance","copy","setCacheSettings","_cacheSettings","_transportClass","_authTokenProvider","_appCheckTokenProvider","_queryManager","areTransportOptionsEqual","transportOptions1","transportOptions2","connectDataConnectEmulator","pingServer","endpoint","ok","getDataConnect","appOrConnectorConfig","settingsOrConnectorConfig","realSettings","getApp","serializedOptions","sortedSerialized","fromEntries","provider","_getProvider","isInitialized","getOptions","validateDCOptions","instanceIdentifier","dcOptions","field","terminate","StorageType","MEMORY","makeMemoryCacheProvider","QueryFetchPolicy","PREFER_CACHE","CACHE_ONLY","SERVER_ONLY","executeQuery","queryManager","fetchPolicy","toQueryRef","serializedRef","validateArgs","dcOrVars","vars","variablesRequired","realVars","validateArgsWithOptions","dcOrVarsOrOptions","varsOrOptions","hasVars","realOptions","queryRefOrSerializedResult","observerOrOnNext","onComplete","onResult","onNext","onErr","registerDataConnect","variant","setSDKVersion","version","_registerComponent","container","connectorConfigStr","getProvider","newOpts","registerVersion"],"mappings":"wKAyEM,MAAOA,sBAAsBC,MAIjC,WAAAC,CAEWC,EACTC,EAEOC,GAEPC,MAAMF,GALGG,KAAAJ,KAAAA,EAGFI,KAAAF,WAAAA,EAPAE,KAAAC,KAdQ,gBA6BfC,OAAOC,eAAeH,KAAMP,cAAcW,WAItCV,MAAMW,mBACRX,MAAMW,kBAAkBL,KAAMM,aAAaF,UAAUG,OAEzD,EAGW,MAAAD,aAIX,WAAAX,CACmBa,EACAC,EACAC,GAFAV,KAAAQ,QAAAA,EACAR,KAAAS,YAAAA,EACAT,KAAAU,OAAAA,CAChB,CAEH,MAAAH,CACEX,KACGe,GAEH,MAAMb,EAAca,EAAK,IAAoB,CAAA,EACvCC,EAAW,GAAGZ,KAAKQ,WAAWZ,IAC9BiB,EAAWb,KAAKU,OAAOd,GAEvBC,EAAUgB,EAUpB,SAASC,gBAAgBD,EAAkBF,GACzC,IACE,IAAII,EAAM,EACNC,EAAS,GACb,KAAOD,EAAMF,EAASI,QAAQ,CAC5B,MAAMC,EAAQL,EAASM,QAAQ,KAAMJ,GACrC,IAAe,IAAXG,EAAc,CAChBF,GAAUH,EAASO,UAAUL,GAC7B,KACF,CACA,MAAMM,EAAMR,EAASM,QAAQ,IAAKD,EAAQ,GAC1C,IAAa,IAATG,EAAY,CACdL,GAAUH,EAASO,UAAUL,GAC7B,KACF,CACA,MAAMO,EAAMT,EAASO,UAAUF,EAAQ,EAAGG,GACpCE,EAAQZ,EAAKW,GACnBN,GACEH,EAASO,UAAUL,EAAKG,IACd,MAATK,EAAgBC,OAAOD,GAAS,IAAID,OACvCP,EAAMM,EAAM,CACd,CACA,OAAOL,CACT,CAAE,MAAOS,GAEP,OAAOZ,CACT,CACF,CArC+BC,CAAgBD,EAAUf,GAAc,QAE7D4B,EAAc,GAAG1B,KAAKS,gBAAgBZ,MAAYe,MAIxD,OAFc,IAAInB,cAAcmB,EAAUc,EAAa5B,EAGzD,ECxGI,SAAU6B,mBAAmBC,GAKjC,IAKE,OAHEA,EAAIC,WAAW,YAAcD,EAAIC,WAAW,YACxC,IAAIC,IAAIF,GAAKG,SACbH,GACMI,SAAS,yBACvB,CAAE,MACA,OAAO,CACT,CACF,CCPa,MAAAC,UAiBX,WAAAtC,CACWM,EACAiC,EACAC,GAFAnC,KAAAC,KAAAA,EACAD,KAAAkC,gBAAAA,EACAlC,KAAAmC,KAAAA,EAnBXnC,KAAAoC,mBAAoB,EAIpBpC,KAAAqC,aAA2B,CAAA,EAE3BrC,KAAAsC,kBAAiB,OAEjBtC,KAAAuC,kBAAyD,IAYtD,CAEH,oBAAAC,CAAqBC,GAEnB,OADAzC,KAAKsC,kBAAoBG,EAClBzC,IACT,CAEA,oBAAA0C,CAAqBN,GAEnB,OADApC,KAAKoC,kBAAoBA,EAClBpC,IACT,CAEA,eAAA2C,CAAgBC,GAEd,OADA5C,KAAKqC,aAAeO,EACb5C,IACT,CAEA,0BAAA6C,CAA2BC,GAEzB,OADA9C,KAAKuC,kBAAoBO,EAClB9C,IACT,ECfU,IAAA+C,GAAZ,SAAYA,GACVA,EAAAA,EAAA,MAAA,GAAA,QACAA,EAAAA,EAAA,QAAA,GAAA,UACAA,EAAAA,EAAA,KAAA,GAAA,OACAA,EAAAA,EAAA,KAAA,GAAA,OACAA,EAAAA,EAAA,MAAA,GAAA,QACAA,EAAAA,EAAA,OAAA,GAAA,QACD,CAPD,CAAYA,IAAAA,EAAQ,CAAA,IASpB,MAAMC,EAA2D,CAC/DC,MAASF,EAASG,MAClBC,QAAWJ,EAASK,QACpBC,KAAQN,EAASO,KACjBC,KAAQR,EAASS,KACjBC,MAASV,EAASW,MAClBC,OAAUZ,EAASa,QAMfC,EAA4Bd,EAASO,KAmBrCQ,EAAgB,CACpB,CAACf,EAASG,OAAQ,MAClB,CAACH,EAASK,SAAU,MACpB,CAACL,EAASO,MAAO,OACjB,CAACP,EAASS,MAAO,OACjB,CAACT,EAASW,OAAQ,SAQdK,kBAAgC,CAACC,EAAUC,KAAYC,KAC3D,GAAID,EAAUD,EAASG,SACrB,OAEF,MAAMC,GAAM,IAAIC,MAAOC,cACjBC,EAAST,EAAcG,GAC7B,IAAIM,EAMF,MAAM,IAAI7E,MACR,8DAA8DuE,MANhEO,QAAQD,GACN,IAAIH,OAASJ,EAAS/D,WACnBiE,EAMP,6CCxGK,IAAIO,EAAc,GCYlB,MAAMC,EAAO,CAClBC,MAAO,QACPC,oBAAqB,sBACrBC,gBAAiB,kBACjBC,cAAe,gBACfC,iBAAkB,mBAClBC,cAAe,gBACfC,aAAc,gBAIV,MAAOC,yBAAyBzF,cAIpC,WAAAE,CAAYC,EAAYC,GACtBE,MAAMH,EAAMC,GAHLG,KAAAC,KAAe,mBAQtBC,OAAOC,eAAeH,KAAMkF,iBAAiB9E,UAC/C,CAGA,QAAA+E,GACE,MAAO,GAAGnF,KAAKC,aAAaD,KAAKJ,UAAUI,KAAKH,SAClD,EAII,MAAOuF,kCAAkCF,iBAQ7C,WAAAvF,CAAYE,EAAiBwF,GAC3BtF,MAAM2E,EAAKM,cAAenF,GAPnBG,KAAAC,KAAe,4BAQtBD,KAAKqF,SAAWA,CAClB,ECtCW,MAAAC,iBACX,cAAAC,CAAejE,GACb,OAAOtB,KAAKwF,aAAalE,EAC3B,CAGA,WAAA3B,CAA4B8F,GAAAzF,KAAAyF,SAAAA,EAFpBzF,KAAAwF,aAAkD,CAAA,EAClDxF,KAAA0F,eAAiB,IAAIC,GACkB,CAC/C,eAAAC,GACE,OAAO5F,KAAKwF,YACd,CACA,MAAAK,GACE,MAAO,CACLJ,SAAUzF,KAAKyF,SACfK,IAAK9F,KAAKwF,aACVE,eAAgBK,MAAMC,KAAKhG,KAAK0F,gBAEpC,CACA,eAAOO,CAASC,GACd,MAAMC,EAAM,IAAIb,iBAAiBY,EAAKT,UAGtC,OAFAU,EAAIX,aAAeU,EAAKJ,IACxBK,EAAIT,eAAiB,IAAIC,IAAIO,EAAKR,gBAC3BS,CACT,CAEA,iBAAAC,CACE9E,EACAC,EACA8E,GAIA,OAFArG,KAAKwF,aAAalE,GAAOC,EACzBvB,KAAK0F,eAAeY,IAAID,GACjBN,MAAMC,KAAKhG,KAAK0F,eACzB,EC7CW,MAAAa,sBAGX,WAAA5G,CAAoB6G,GAAAxG,KAAAwG,OAAAA,EAFZxG,KAAAyG,KAAO,IAAIC,IACX1G,KAAA2G,YAAc,IAAID,GACW,CAErC,mBAAME,CAAcC,EAAiBC,GACnC9G,KAAK2G,YAAYI,IAAIF,EAASC,EAChC,CACA,mBAAME,CAAcH,GAClB,OAAO7G,KAAK2G,YAAYM,IAAIJ,EAC9B,CACA,sBAAMK,CAAiBC,GACrBnH,KAAKyG,KAAKM,IAAII,EAAW1B,SAAU0B,EACrC,CACA,mBAAMC,CAAcC,GAKlB,OAJKrH,KAAKyG,KAAKa,IAAID,IACjBrH,KAAKyG,KAAKM,IAAIM,EAAU,IAAI/B,iBAAiB+B,IAGxCrH,KAAKyG,KAAKQ,IAAII,EACvB,CACA,KAAAE,GAEE,OAAOC,QAAQC,SACjB,EClBK,MAAMC,EAAgB,MAKhB,MAAAC,WAAb,WAAAhI,GAEEK,KAAA4H,QAA0C,CAAA,EAC1C5H,KAAA6H,WAA4C,CAAA,EAC5C7H,KAAA8H,YAEI,CAAA,EAEJ9H,KAAA+H,eAA8B,IAAIpC,GAgNpC,CA9ME,cAAMqC,CACJnB,EACAoB,EACAC,EACAC,EACAC,GAEA,QAAeC,IAAXJ,EAAJ,CAGA,GAAsB,iBAAXA,GAAuBlC,MAAMuC,QAAQL,GAC9C,MAAM,IAAI/C,iBACRR,EAAKK,iBACL,gDAGJ,GAAe,OAAXkD,EAAJ,CAKoB,iBAAXA,GACPC,GACAA,EAAUR,IAC0B,iBAA7BQ,EAAUR,KAEjB1H,KAAKqH,SAAWa,EAAUR,GAC1B1H,KAAKmH,iBAAmBiB,EAAchB,cAAcpH,KAAKqH,WAE3D,IAAK,MAAM/F,KAAO2G,EAChB,GAAIA,EAAOM,eAAejH,GACxB,GAA2B,iBAAhB2G,EAAO3G,GAChB,GAAIyE,MAAMuC,QAAQL,EAAO3G,IAAO,CAC9B,MAAMkH,EACJN,GAAcA,EAAU5G,GACpBmH,EAAyB,GACzBC,EAAkD,GACxD,IAAK,MAAOC,EAAOpH,KAAU0G,EAAO3G,GAAKsH,UACvC,GAAqB,iBAAVrH,EACT,GAAIwE,MAAMuC,QAAQ/G,QAEX,CACL,MAAMsH,EAAa,IAAIlB,iBACjBkB,EAAWb,SACfnB,EACAtF,EACAiH,GAAQA,EAAIG,GACZR,EACAC,GAEFK,EAASK,KAAKD,EAChB,MAEAH,EAAYI,KAAKvH,GAGrB,GAAImH,EAAYzH,OAAS,GAAKwH,EAASxH,OAAS,EAC9CjB,KAAK4H,QAAQtG,GAAO2G,EAAO3G,QACtB,GAAIoH,EAAYzH,OAAS,EAC9B,GAAIjB,KAAKmH,WAAY,CACnB,MAAM4B,EAAe/I,KAAKmH,WAAWf,kBACnC9E,EACAoH,EACA7B,GAEF7G,KAAK+H,eAAezB,IAAIhF,GACxB6G,EAAI7B,IAAIyC,EACV,MACE/I,KAAK4H,QAAQtG,GAAOoH,OAEbD,EAASxH,OAAS,EAC3BjB,KAAK8H,YAAYxG,GAAOmH,EAExBzI,KAAK4H,QAAQtG,GAAO,EAExB,KAAO,CACL,GAAoB,OAAhB2G,EAAO3G,GAAe,CACxBtB,KAAK4H,QAAQtG,GAAO,KACpB,QACF,CACA,MAAMuH,EAAa,IAAIlB,iBAEjBkB,EAAWb,SACfnB,EACCoB,EAA0C3G,GAC3C4G,GAAcA,EAAU5G,GACxB6G,EACAC,GAEFpI,KAAK6H,WAAWvG,GAAOuH,CACzB,MAEA,GAAI7I,KAAKmH,WAAY,CACnB,MAAM4B,EAAe/I,KAAKmH,WAAWf,kBACnC9E,EACA2G,EAAO3G,GACPuF,GAEF7G,KAAK+H,eAAezB,IAAIhF,GACxB6G,EAAI7B,IAAIyC,EACV,MACE/I,KAAK4H,QAAQtG,GAAO2G,EAAO3G,GAK/BtB,KAAKmH,kBACDiB,EAAclB,iBAAiBlH,KAAKmH,WAzF5C,CATA,CAoGF,CAEA,MAAAtB,CAAOpD,GACL,MAAMuG,EAAwC,CAAA,EAC9C,GAAIvG,IAASwG,EAAaC,SAAU,CAClC,GAAIlJ,KAAKmH,WACP,IAAK,MAAM7F,KAAOtB,KAAK+H,eACrBiB,EAAa1H,GAAOtB,KAAKmH,WAAW5B,eAAejE,GAOvD,GAHItB,KAAK4H,SACP1H,OAAOiJ,OAAOH,EAAchJ,KAAK4H,SAE/B5H,KAAK6H,WACP,IAAK,MAAMvG,KAAOtB,KAAK6H,WACjB7H,KAAK6H,WAAWU,eAAejH,KACjC0H,EAAa1H,GAAOtB,KAAK6H,WAAWvG,GAAKuE,OAAOpD,IAItD,GAAIzC,KAAK8H,YACP,IAAK,MAAMxG,KAAOtB,KAAK8H,YACjB9H,KAAK8H,YAAYS,eAAejH,KAClC0H,EAAa1H,GAAOtB,KAAK8H,YAAYxG,GAAKwE,KAAIsD,GAC5CA,EAAIvD,OAAOpD,MAKnB,OAAOuG,CACT,CAYE,GAVIhJ,KAAKmH,aACP6B,EAAatB,GAAiB1H,KAAKmH,WAAW1B,UAGhDuD,EAAiC,kBAAIjD,MAAMC,KAAKhG,KAAK+H,gBAEjD/H,KAAK4H,UACPoB,EAAwB,SAAIhJ,KAAK4H,SAG/B5H,KAAK6H,WAAY,CACnB,MAAMA,EAAa,CAAA,EACnB,IAAK,MAAMvG,KAAOtB,KAAK6H,WACjB7H,KAAK6H,WAAWU,eAAejH,KACjCuG,EAAWvG,GAAOtB,KAAK6H,WAAWvG,GAAKuE,OAAOpD,IAGlDuG,EAA2B,YAAInB,CACjC,CACA,GAAI7H,KAAK8H,YAAa,CACpB,MAAMA,EAAc,CAAA,EACpB,IAAK,MAAMxG,KAAOtB,KAAK8H,YACjB9H,KAAK8H,YAAYS,eAAejH,KAClCwG,EAAYxG,GAAOtB,KAAK8H,YAAYxG,GAAKwE,KAAIsD,GAC3CA,EAAIvD,OAAOpD,MAIjBuG,EAA6B,aAAIlB,CACnC,CAGF,OAAOkB,CACT,CAEA,eAAOK,CAASD,GACd,MAAME,EAAM,IAAI3B,WAMhB,GALIyB,EAAIG,cACND,EAAInC,WAAa7B,iBAAiBW,SAASmD,EAAIG,cAEjDD,EAAIjC,SAAW+B,EAAI3D,SACnB6D,EAAI1B,QAAUwB,EAAIxB,QACdwB,EAAIvB,WAAY,CAClB,MAAMA,EAAsC,CAAA,EAC5C,IAAK,MAAMvG,KAAO8H,EAAIvB,WAChBuB,EAAIvB,WAAWU,eAAejH,KAChCuG,EAAWvG,GAAOqG,WAAW0B,SAASD,EAAIvB,WAAWvG,KAGzDgI,EAAIzB,WAAaA,CACnB,CACA,GAAIuB,EAAItB,YAAa,CACnB,MAAMA,EAAuC,CAAA,EAC7C,IAAK,MAAMxG,KAAO8H,EAAItB,YAChBsB,EAAItB,YAAYS,eAAejH,KACjCwG,EAAYxG,GAAO8H,EAAItB,YAAYxG,GAAKwE,KAAIsD,GAC1CzB,WAAW0B,SAASD,MAI1BE,EAAIxB,YAAcA,CACpB,CACA,OAAOwB,CACT,EAcF,IAAYL,GAAZ,SAAYA,GACVA,EAAAA,EAAA,SAAA,GAAA,WACAA,EAAAA,EAAA,WAAA,GAAA,YACD,CAHD,CAAYA,IAAAA,EAAY,CAAA,IClPX,MAAAO,WAMX,eAAOH,CAAS9H,GACd,OAAO,IAAIiI,WACT7B,WAAW0B,SAAS9H,EAAMkI,UAC1BlI,EAAMmI,OACNnI,EAAMoI,SACNpI,EAAMqI,aAEV,CACA,WAAAjK,CACU8J,EACAC,EAAiB,EACTC,EACRE,GAHA7J,KAAAyJ,SAAAA,EACAzJ,KAAA0J,OAAAA,EACQ1J,KAAA2J,SAAAA,EACR3J,KAAA6J,cAAAA,CACP,CACH,OAAAC,GACE,OACEzF,KAAKD,MAAQ,IAAIC,KAAKrE,KAAK2J,SAASI,WAAWA,UACjC,IAAd/J,KAAK0J,MAET,CACA,YAAAM,CAAaC,GACXjK,KAAK0J,OAASO,CAChB,CACA,cAAAC,GACElK,KAAK6J,cAAgB,IAAIxF,IAC3B,CACA,gBAAIuF,GACF,OAAO5J,KAAK6J,aACd,CACA,WAAAM,GACE,OAAOnK,KAAKyJ,QACd,ECvCW,MAAAW,6BAEX,WAAAzK,CAAoBkH,GAAA7G,KAAA6G,QAAAA,EADpB7G,KAAAqK,SAAW,IAAI1E,GACuB,CACtC,GAAAW,CAAI+D,GACFA,EACGC,QAAOC,GAAOA,IAAQvK,KAAK6G,UAC3B2D,SAAQD,GAAOvK,KAAKqK,SAAS/D,IAAIiE,IACtC,CACA,aAAAE,GACE,MAAMC,EAAS3E,MAAMC,KAAKhG,KAAKqK,UAE/B,OADArK,KAAKqK,SAASM,QACPD,CACT,ECHW,MAAAE,oBAMX,cAAAC,CAAeC,GACb,OAAOA,EAAejF,OAAOoD,EAAaC,SAC5C,CASA,sBAAM6B,CACJ7E,EACAgC,EACAE,EACAvB,GAEA,MAAMsB,EAAM,IAAIiC,6BAA6BvD,GACvCgC,EAAa,IAAIlB,WAEvB,aADMkB,EAAWb,SAASnB,EAASX,EAAMgC,EAAWC,EAAKC,GAClD,CACLS,aACAwB,SAAUlC,EAAIsC,gBAElB,ECbW,MAAAO,iBAGX,WAAArL,CACUsL,EACAC,EACAC,EACAC,EACDC,GAJCrL,KAAAiL,aAAAA,EACAjL,KAAAkL,UAAAA,EACAlL,KAAAmL,gBAAAA,EACAnL,KAAAoL,KAAAA,EACDpL,KAAAqL,cAAAA,EAPDrL,KAAAoI,cAA8C,KAC9CpI,KAAAsL,IAAqB,KAQ3BtL,KAAKiL,aAAaM,wBAAuBC,MAAMC,IAC7C,MAAMC,EAAS1L,KAAKiL,aAAaU,UAAUC,SAE3C,GAAI5L,KAAKsL,MAAQI,EAAQ,CACvB1L,KAAKoI,eAAeb,QACpBvH,KAAKsL,IAAMI,EACX,MAAMG,QAAmB7L,KAAK8L,cAAc9L,KAAKsL,KACjDtL,KAAKoI,cAAgBpI,KAAK+L,uBAAuBF,EACnD,IAEJ,CAEA,gBAAMG,GACJ,IAAKhM,KAAKoI,cAAe,CACvB,MAAMyD,QAAmB7L,KAAK8L,cAAc9L,KAAKsL,KACjDtL,KAAKoI,cAAgBpI,KAAK+L,uBAAuBF,EACnD,CACF,CAEA,mBAAMC,CAAcR,GAClB,MAAMO,EAAa,UAEf7L,KAAKkL,aAAalL,KAAKmL,gBAAgB3K,WACzCR,KAAKmL,gBAAgBc,aACnBjM,KAAKmL,gBAAgBe,YAAYZ,KAAOtL,KAAKoL,OAEjD,aCvDGI,eAAeW,mBAAmBC,GACvC,MACMzL,GADc,IAAI0L,aACCC,OAAOF,GAC1BG,QAAmBC,OAAOC,OAAOC,OAAO,UAAW/L,GAKzD,OAFkBoF,MAAMC,KAAK,IAAI2G,WAAWJ,IAClBzG,KAAI8G,GAAKA,EAAEzH,SAAS,IAAI0H,SAAS,EAAG,OAAMC,KAAK,GAE3E,CD6CyBX,CAAmBN,EAE1C,CAEA,sBAAAE,CAAuBF,GACrB,OAAO7L,KAAKqL,cAAcjD,cAAc4D,WAAWH,EACrD,CAEA,wBAAMkB,CAAmBlG,SACjB7G,KAAKgM,aAEX,YAAsB3D,UADGrI,KAAKoI,cAAepB,cAAcH,EAE7D,CACA,mBAAMG,CAAcH,GAElB,aADM7G,KAAKgM,aACJhM,KAAKoI,cAAepB,cAAcH,EAC3C,CACA,mBAAMmG,CAAcnG,SACZ7G,KAAKgM,aACX,MAAMiB,EAAY,IAAIrC,oBAChBxC,EAAgBpI,KAAKoI,cACrB8E,QAAmB9E,EAAepB,cAAcH,GACtD,IAAKqG,EACH,MAAM,IAAIhI,iBACRR,EAAKK,iBACL,GAAG8B,gDAGP,OAAOoG,EAAUpC,eAAeqC,EAAW/C,cAC7C,CACA,YAAMgD,CACJtG,EACArB,EACA0C,SAEMlI,KAAKgM,aACX,MAAMiB,EAAY,IAAIrC,oBAChBxC,EAAgBpI,KAAKoI,eACnBS,WAAYuE,EAAc/C,SAAEA,SAC5B4C,EAAUlC,iBACdvF,EACA0C,EACAE,EACAvB,GAEEzC,EAAM,IAAIC,KAUhB,aATM+D,EAAexB,cACnBC,EACA,IAAI2C,WACF4D,EACA5H,EAAakE,QAAU1J,KAAKqL,cAAcgC,cAC1CjJ,EACAA,IAGGiG,CACT,EAGW,MAAAiD,WAAb,WAAA3N,GACEK,KAAAmC,KAAiB,QAOnB,CAHE,UAAA6J,CAAWuB,GACT,OAAO,IAAIhH,sBAAsBgH,EACnC,EElHW,MAAAC,sBAGX,WAAA7N,CACE8N,EACQC,GAAA1N,KAAA0N,iBAAAA,EAEJC,EAAqBF,IAAQA,EAAIG,SAASC,gBAC5C7N,KAAK8N,uBAAyBL,EAAIG,SAASC,eAE7C7N,KAAK+N,SAAWL,GAAkBM,aAAa,CAAEC,UAAU,IACtDjO,KAAK+N,UACHL,GACDzG,MACDiH,MAAKH,GAAa/N,KAAK+N,SAAWA,IAClCI,OAEP,CAEA,QAAAC,GACE,OAAIpO,KAAK8N,uBACAtG,QAAQC,QAAQ,CAAE4G,MAAOrO,KAAK8N,yBAGlC9N,KAAK+N,SAeH/N,KAAK+N,SAASK,WAdZ,IAAI5G,SAAoC,CAACC,EAAS6G,KAKvDC,YAAW,KACLvO,KAAK+N,SACP/N,KAAKoO,WAAWF,KAAKzG,EAAS6G,GAE9B7G,EAAQ,KACV,GACC,EAAE,GAIX,CAEA,sBAAA8D,CAAuBiD,GAChBxO,KAAK0N,kBACNzG,MACDiH,MAAKH,GAAYA,EAASU,iBAAiBD,IAChD,ECxDF,MAAME,EAAS,IZyGF,MAAAC,OAOX,WAAAhP,CAAmBM,GAAAD,KAAAC,KAAAA,EAUXD,KAAA4O,UAAY/K,EAsBZ7D,KAAA6O,YAA0B9K,kBAc1B/D,KAAA8O,gBAAqC,IAzC7C,CAOA,YAAI3K,GACF,OAAOnE,KAAK4O,SACd,CAEA,YAAIzK,CAAS4K,GACX,KAAMA,KAAOhM,GACX,MAAM,IAAIiM,UAAU,kBAAkBD,+BAExC/O,KAAK4O,UAAYG,CACnB,CAGA,WAAAE,CAAYF,GACV/O,KAAK4O,UAA2B,iBAARG,EAAmB/L,EAAkB+L,GAAOA,CACtE,CAOA,cAAIG,GACF,OAAOlP,KAAK6O,WACd,CACA,cAAIK,CAAWH,GACb,GAAmB,mBAARA,EACT,MAAM,IAAIC,UAAU,qDAEtBhP,KAAK6O,YAAcE,CACrB,CAMA,kBAAII,GACF,OAAOnP,KAAK8O,eACd,CACA,kBAAIK,CAAeJ,GACjB/O,KAAK8O,gBAAkBC,CACzB,CAMA,KAAA9L,IAASiB,GACPlE,KAAK8O,iBAAmB9O,KAAK8O,gBAAgB9O,KAAM+C,EAASG,SAAUgB,GACtElE,KAAK6O,YAAY7O,KAAM+C,EAASG,SAAUgB,EAC5C,CACA,GAAAkL,IAAOlL,GACLlE,KAAK8O,iBACH9O,KAAK8O,gBAAgB9O,KAAM+C,EAASK,WAAYc,GAClDlE,KAAK6O,YAAY7O,KAAM+C,EAASK,WAAYc,EAC9C,CACA,IAAAb,IAAQa,GACNlE,KAAK8O,iBAAmB9O,KAAK8O,gBAAgB9O,KAAM+C,EAASO,QAASY,GACrElE,KAAK6O,YAAY7O,KAAM+C,EAASO,QAASY,EAC3C,CACA,IAAAX,IAAQW,GACNlE,KAAK8O,iBAAmB9O,KAAK8O,gBAAgB9O,KAAM+C,EAASS,QAASU,GACrElE,KAAK6O,YAAY7O,KAAM+C,EAASS,QAASU,EAC3C,CACA,KAAAT,IAASS,GACPlE,KAAK8O,iBAAmB9O,KAAK8O,gBAAgB9O,KAAM+C,EAASW,SAAUQ,GACtElE,KAAK6O,YAAY7O,KAAM+C,EAASW,SAAUQ,EAC5C,GY9LwB,0BACpB,SAAU+K,YAAY9K,GAC1BuK,EAAOO,YAAY9K,EACrB,CACM,SAAUkL,SAASC,GACvBZ,EAAOzL,MAAM,gBAAgBwB,OAAiB6K,IAChD,CAEM,SAAUC,SAASD,GACvBZ,EAAOjL,MAAM,gBAAgBgB,OAAiB6K,IAChD,CCMa,MAAAE,qBAEX,WAAA7P,CACU8P,EACAC,EACAC,GAFA3P,KAAAyP,SAAAA,EACAzP,KAAA0P,SAAAA,EACA1P,KAAA2P,cAAAA,EAER3P,KAAK4P,MAAQD,EAAc3B,aAAa,CAAEC,UAAU,IAC/CjO,KAAK4P,OACRD,EAAcE,QAAOC,GAAS9P,KAAK4P,MAAQE,GAE/C,CACA,OAAAnE,GACE,OAAO3L,KAAK4P,KACd,CACA,QAAAxB,CAAS2B,GACP,OAAK/P,KAAK4P,MAWH5P,KAAK4P,MAAMxB,SAAS2B,GAAc5B,OAAM1K,GACzCA,GAAwB,+BAAfA,EAAM7D,MACjByP,SACE,kEAEK,OAEPE,SACE,qDACES,KAAKC,UAAUxM,IAEZ+D,QAAQ8G,OAAO7K,MArBjB,IAAI+D,SAAQ,CAACC,EAAS6G,KAC3BC,YAAW,KACLvO,KAAK4P,MACP5P,KAAKoO,SAAS2B,GAAc7B,KAAKzG,EAAS6G,GAE1C7G,EAAQ,KACV,GACC,EAAE,GAiBX,CACA,sBAAA8D,CAAuBiD,GACrBxO,KAAK4P,OAAOM,qBAAqB1B,EACnC,CACA,yBAAA2B,CAA0B3B,GACxBxO,KAAK2P,cACF1I,MACAiH,MAAK4B,GAAQA,EAAKM,wBAAwB5B,KAC1CL,OAAMkC,GAAOd,SAASc,IAC3B,EClEK,MAAMC,EAAY,QACZC,EAAe,WAGfC,EAAgB,SAChBC,EAAe,QCYZ,SAAAC,aACdC,EACAC,EACAC,GAEA,IAAIC,EAA2CF,EAC/C,IAAK,MAAMG,KAASJ,EACW,iBAAlBG,EAAOC,KAChBD,EAAOC,GAAS,CAAA,GAElBD,EAASA,EAAOC,GAGlB,GAAI,aAAcF,GAAaA,EAAUG,SACvCF,EAAY,IAAID,EAAUG,cACrB,GAAI,cAAeH,EAAW,CACnC,MAAMI,EAAYJ,EAAU3I,UAC5B,IAAK,IAAIgJ,EAAI,EAAGA,EAAID,EAAUhQ,OAAQiQ,IAAK,CACzC,MAAMF,EAAWC,EAAUC,QACF,IAAdJ,EAAOI,KAChBJ,EAAOI,GAAK,CAAA,GAEbJ,EAAOI,GAA+BC,IAAMH,CAC/C,CACF,CACF,CC5CO,IAAII,EAEAC,EAOX,SAASC,eAAeC,GACtB,OAAOrR,OAAOsR,KAAKD,GAChBE,OACAC,QAAO,CAACC,EAAaC,KACpBD,EAAYC,GAAcL,EAAEK,GACrBD,IACN,CAAA,EACP,CCkBM,SAAUE,iBACdC,EACAnR,EACAoR,EACAC,GAEA,OAAO,SAASnM,SACd,MAAO,CACLlF,OACAsR,QAAS,CACPhS,KAAM6R,EAAS7R,KACfiS,UAAWJ,EAASI,UACpB/G,gBAAiB,CACfD,UAAW4G,EAASK,YAAY1E,IAAI2E,QAAQlH,aACzC4G,EAASK,YAAYE,gBAG5BL,YACAD,SAEJ,CACF,EDpDM,SAAUO,WAAWC,GACzBnB,EAAcmB,CAChB,CAYAD,EAAYf,GAA+BvB,KAAKC,UAAUqB,eAAeC,MAXnE,SAAUiB,WAAWC,GACzBpB,EAAcoB,CAChB,CAUAD,EAAWE,GAAKpB,eAAetB,KAAK2C,MAAMD,MCuC7B,MAAAE,aACX,wBAAMC,CACJf,EACAgB,GAAa,GAEb,IAAIC,EACJ,IACEA,QAAoB/S,KAAKgT,kBAAkBlB,EAAUgB,EACvD,CAAE,MAAOrR,GAET,CACA,OAAIsR,GAGG/S,KAAKiT,mBAAmBnB,EACjC,CAUA,WAAAnS,CACUuT,EACAC,EACAC,GAFApT,KAAAkT,UAAAA,EACAlT,KAAAmT,GAAAA,EACAnT,KAAAoT,MAAAA,EAZFpT,KAAAqT,UAAY,IAAI3M,IAQhB1G,KAAAsT,kBAAoB,IAAI5M,IAMxB1G,KAAAuT,MAAiC,EADtC,CAEH,yBAAMC,GACJ,IAAK,MAAMC,KAAWzT,KAAKuT,YACnBE,EAERzT,KAAKuT,MAAQ,EACf,CAEA,SAAAG,CAA2BC,GACzB3T,KAAKuT,MAAMzK,KACT9I,KAAK4T,YAAYD,GAAazF,MAAK1C,MAAMxK,GACvChB,KAAK6T,iCAAiC7S,EAAQ2S,EAAY3B,aAGhE,CAEA,iBAAM4B,CACJ5S,EACA8S,GAGA,SADM9T,KAAKwT,sBACPxT,KAAKoT,MAAO,CACd,MAAMlL,EF5GN,SAAU6L,eACd/S,GAGA,MAAMgT,EAAwBhT,EAAO8S,YAAY3B,YAC3C8B,EAAW/T,OAAOiJ,OAAOnI,GAC/B,IAAKgT,EACH,OAAOC,EAET,MAAMC,EAA+B,CAAA,EACrC,IAAK,MAAMrD,KAAamD,EAAuB,CAC7C,MAAMrD,KAAEA,GAASE,EACjBH,aAAaC,EAAMuD,EAAKrD,EAC1B,CACA,OAAOqD,CACT,CE6FwBH,CAAe/S,GAC3BmT,EA4YN,SAAUC,wBACdN,GAEA,IAAKA,EACH,OAEF,IAAK,MAAMjD,KAAaiD,EACtB,GACE,WAAYjD,QACSxI,IAArBwI,EAAUnH,QACW,OAArBmH,EAAUnH,QAENmH,EAAUnH,OAAO1H,SAAS,KAC5B,OAAOqS,OACLxD,EAAUnH,OAAOtI,UAAU,EAAGyP,EAAUnH,OAAOzI,OAAS,GAKlE,CA/Z4BmT,CAAwBN,GAI9C,YAHsBzL,IAAlB8L,IACFnU,KAAKoT,MAAM/H,cAAcgC,cAAgB8G,GAEpCnU,KAAKoT,MAAMjG,OAChBiE,EAAY,CACVnR,KAAMe,EAAOuJ,IAAItK,KACjBiS,UAAWlR,EAAOuJ,IAAI2H,UACtBoC,QAAShE,IAEXtP,EAAOL,KACPuH,EAEJ,CAAO,CACL,MAAM5G,EAAM8P,EAAY,CACtBnR,KAAMe,EAAOuJ,IAAItK,KACjBiS,UAAWlR,EAAOuJ,IAAI2H,UACtBoC,QAAShE,IAGX,OADAtQ,KAAKsT,kBAAkBvM,IAAIzF,EAAKN,GACzB,CAACM,EACV,CACF,CAEA,eAAAiT,CACEzC,EACA0C,EACAC,EACAC,EACAC,GAEA,MAAMrT,EAAM8P,EAAY,CACtBnR,KAAM6R,EAAS7R,KACfiS,UAAWJ,EAASI,UACpBoC,QAAShE,IAGLsE,YAAc,KAClB,GAAI5U,KAAKqT,UAAU/L,IAAIhG,GAAM,CAC3B,MACMuT,EADe7U,KAAKqT,UAAUpM,IAAI3F,GACXgJ,QAC3BxH,GAAYA,IAAagS,IAE3B9U,KAAKqT,UAAUtM,IAAIzF,EAAKuT,GAED,IAAnBA,EAAQ5T,SACVjB,KAAKqT,UAAU0B,OAAOzT,GACtBtB,KAAKkT,UAAU8B,kBAAkBlD,EAAS7R,KAAM6R,EAASI,YAE3DuC,KACF,GAEIK,EAAyD,CAC7DG,aAAcT,EACdU,YAAaR,EACbE,yBAGED,GACF3U,KAAK0T,UAAUiB,GAwBjB,OArBgB3U,KAAK6S,mBAAmBf,GAA0B,GAE1D5D,UAAK7F,GAAWgI,QAEpBrQ,KAAKqT,UAAU/L,IAAIhG,GACrBtB,KAAKqT,UACFpM,IAAI3F,GACJwH,KAAKgM,IAER9U,KAAKqT,UAAUtM,IAAIzF,EAAK,CACtBwT,IAIF9U,KAAKkT,UAAUiC,gBACbnV,KAAKoV,sBAAsBtD,GAC3BA,EAAS7R,KACT6R,EAASI,YAIN0C,WACT,CAEA,wBAAM3B,CACJnB,SAEM9R,KAAKwT,sBACX,MAAMlS,EAAM8P,EAAY,CACtBnR,KAAM6R,EAAS7R,KACfiS,UAAWJ,EAASI,UACpBoC,QAAShE,IAEX,IACE,MAAMtP,QAAehB,KAAKkT,UAAUmC,YAClCvD,EAAS7R,KACT6R,EAASI,WAELF,EAAY3N,KAAKD,MAAMe,WACvBmQ,EAAqBtU,EAAO8S,WAC5ByB,EAA4C,IAC7CvU,EACHuJ,IAAKuH,EACLC,OAAQvB,EACRwB,YACArR,KAAMK,EAAOL,KACbmT,WAAY0B,sCAAsCF,GAClDzP,OAAQgM,iBACNC,EACA9Q,EAAOL,KACP6P,EACAwB,IAGEyD,QAAoBzV,KAAK4T,YAC7B2B,EACAD,GAAoBnD,aAQtB,OANAnS,KAAK0V,yBAAyBpU,EAAKiU,GAC/BvV,KAAKoT,YACDpT,KAAK6T,iCAAiC4B,EAAazD,GAEzDhS,KAAKsT,kBAAkBvM,IAAIzF,EAAKiU,GAE3BA,CACT,CAAE,MAAO9T,GAEP,MADAzB,KAAK2V,0BAA0BrU,EAAKG,GAC9BA,CACR,CACF,CAEA,uBAAMuR,CACJlB,EACAgB,GAAa,GAGb,IAAI9R,EAMJ,SAPMhB,KAAKwT,sBAKTxS,EAHGhB,KAAKoT,YAGOpT,KAAK4V,uBAAuB9D,EAAUgB,SAFtC9S,KAAK6V,uBAAuB/D,IAIxC9Q,EACH,MAAM,IAAIkE,iBACRR,EAAKC,MACL,mCAAqCmN,EAAS7R,MAGlD,MAAM+R,EAAY3N,KAAKD,MAAMe,WACvBoQ,EAA4C,IAC7CvU,EACHuJ,IAAKuH,EACLC,OAAQtB,EACRuB,YACArR,KAAMK,EAAOL,KACbmT,WAAY9S,EAAO8S,WACnBjO,OAAQgM,iBAAiBC,EAAU9Q,EAAOL,KAAM8P,EAAcuB,IAEhE,GAAIhS,KAAKoT,MAAO,CACd,MAAM9R,EAAM8P,EAAY,CACtBnR,KAAM6R,EAAS7R,KACfiS,UAAWJ,EAASI,UACpBoC,QAAShE,UAELtQ,KAAK6T,iCAAiC,CAACvS,GAAM0Q,EACrD,KAAO,CACL,MAAM1Q,EAAM8P,EAAY,CACtBnR,KAAM6R,EAAS7R,KACfiS,UAAWJ,EAASI,UACpBoC,QAAShE,IAEXtQ,KAAKsT,kBAAkBvM,IAAIzF,EAAKiU,GAChCvV,KAAK0V,yBAAyBpU,EAAKiU,EACrC,CAEA,OAAOA,CACT,CAEA,yBAAAI,CAA0BrU,EAAa+O,GACrCrQ,KAAKqT,UAAUpM,IAAI3F,IAAMkJ,SAAQsK,IAC3BA,EAAaI,aACfJ,EAAaI,YAAY7E,EAC3B,GAEJ,CAEA,4BAAMuF,CACJ9D,EACAgB,GAAa,GAEb,MAAMxR,EAAM8P,EAAY,CACtBnR,KAAM6R,EAAS7R,KACfiS,UAAWJ,EAASI,UACpBoC,QAAShE,IAEX,IAAKtQ,KAAKoT,cAAiBpT,KAAKoT,MAAMrG,mBAAmBzL,GACvD,OAAO,KAET,MAAMyR,QAA2B/S,KAAKoT,MAAOpG,cAAc1L,GACrD4L,QAAmBlN,KAAKoT,MAAOpM,cAAc1F,GACnD,IAAKwR,GAAc5F,EAAYpD,UAC7B,OAAO,KAET,MAAM9I,EAAuC,CAC3C+Q,OAAQtB,EACRlG,IAAKuH,EACLnR,KAAMoS,EACNlN,OAAQgM,iBACNC,EACAiB,EACAtC,EACAvD,EAAYvD,SAASxE,YAEvB6M,UAAW9E,EAAYvD,SAASxE,YAGlC,aADOnF,KAAKoT,MAAOpM,cAAc1F,IAAO4I,iBACjClJ,CACT,CACA,4BAAM6U,CACJ/D,GAEA,MAAMxQ,EAAM8P,EAAY,CACtBnR,KAAM6R,EAAS7R,KACfiS,UAAWJ,EAASI,UACpBoC,QAAShE,IAEX,IAAKtQ,KAAKsT,kBAAkBhM,IAAIhG,GAC9B,OAEF,MAAMN,EAAShB,KAAKsT,kBAAkBrM,IAAI3F,GAQ1C,OAPAN,EAAQ+Q,OAAStB,EACjBzP,EAAQ6E,OAASgM,iBACf7Q,EAAQuJ,IACRvJ,EAAQL,KACR8P,EACAzP,EAAQgR,WAEHhR,CACT,CAGA,wBAAA0U,CACEpU,EACAiU,GAEA,IAAKvV,KAAKqT,UAAU/L,IAAIhG,GACtB,OAEkBtB,KAAKqT,UAAUpM,IAAI3F,GAC1BkJ,SAAQ1H,IACnBA,EAASmS,aAAaM,EAAY,GAEtC,CACA,sCAAM1B,CACJiC,EACA9D,GAEA,GAAKhS,KAAKoT,MAGV,IAAK,MAAM2C,KAASD,EAAiB,CAEnC,IADkB9V,KAAKqT,UAAUpM,IAAI8O,GAEnC,SAEF,MAAMC,SAAiBhW,KAAKoT,MAAMpM,cAAc+O,IAC7C5L,cACAtE,OAAOoD,EAAaC,WACjBjJ,KAAEA,EAAIiS,UAAEA,GAAcb,EAAY0E,GAIlCjE,EAAuC,CAC3CK,YAAanS,KAAKmT,GAClBmB,QAAShE,EACTrQ,OACAiS,aAEFlS,KAAK0V,yBAAyBK,EAAO,CACnCpV,KAAMqV,EACNhE,YACAzH,IAAKuH,EACLC,OAAQtB,EACR5K,OAAQgM,iBAAiBC,EAAUkE,EAASvF,EAAcuB,IAE9D,CACF,CACA,cAAAiE,CAAe7K,EAAc8K,GAC3BlW,KAAKkT,UAAUiD,YAAY/K,EAAM8K,EACnC,CAOQ,qBAAAd,CACNtD,GAEA,MAAMxQ,EAAM8P,EAAY,CACtBnR,KAAM6R,EAAS7R,KACfiS,UAAWJ,EAASI,UACpBoC,QAAShE,IAEX,MAAO,CACL8F,OAAQ5K,MAAMnG,UACNrF,KAAKqW,yBAAyB/U,EAAK+D,EAAUyM,EAAS,EAE9DwE,aAAc,CAAC1W,EAAM2W,KACnBvW,KAAKwW,uBAAuBlV,EAAK1B,EAAM2W,EAAO,EAEhDE,QAAShT,IACPzD,KAAK2V,0BAA0BrU,EAAKmC,EAAM,EAGhD,CAMQ,8BAAM4S,CACZ/U,EACA+D,EACAyM,GAEA,GAAIzM,EAAS3E,QAAU2E,EAAS3E,OAAOO,OAAS,EAAG,CACjD,MAAMyV,EAAc1G,KAAKC,UACvB5K,EAAS3E,OAAOoF,KAAIrE,GACdA,GAAkB,iBAANA,EACP,CACL5B,QAAU4B,EAAqC5B,QAC/CD,KAAO6B,EAAoC7B,MAGxC6B,KAGLkV,EAAuD,CAC3DjW,OAAQ2E,EAAS3E,OACjBC,KAAM0E,EAAS1E,MAEX8C,EAAQ,IAAI2B,0BAChB,2DACEsR,EACFC,GAGF,YADA3W,KAAK2V,0BAA0BrU,EAAKmC,EAEtC,CAEA,MAAMuO,EAAY3N,KAAKD,MAAMe,WACvBoQ,EAA4C,CAChDhL,IAAKuH,EACLC,OAAQvB,EACRwB,YACArR,KAAM0E,EAAS1E,KACfmT,WAAY0B,sCAAsCnQ,EAASyO,YAC3DjO,OAAQgM,iBACNC,EACAzM,EAAS1E,KACT6P,EACAwB,IAGEyD,QAAoBzV,KAAK4T,YAC7B2B,EACAlQ,EAASyO,YAAY3B,aAEvBnS,KAAK0V,yBAAyBpU,EAAKiU,GAC/BvV,KAAKoT,aACDpT,KAAK6T,iCAAiC4B,EAAazD,EAE7D,CAKQ,sBAAAwE,CACNlV,EACA1B,EACA2W,GAEA,MAAM9S,EAAQ,IAAIyB,iBAAiBtF,EAAc2W,GACjDvW,KAAK2V,0BAA0BrU,EAAKmC,GAEpC,MAAM4P,EAAYrT,KAAKqT,UAAUpM,IAAI3F,GACjC+R,GACF,IAAIA,GAAW7I,SAAQoM,GAAMA,EAAGhC,eAGpC,EAuBF,SAASY,sCACP1B,GAEA,MAAO,CACL3B,YAAa2B,EAAW3B,aAAa7H,QACnCuG,GAAa,aAAcA,GAAa,cAAeA,IAG7D,CCrgBO,MAAMgG,EAAoB,CAC/BC,KAAM,OACNC,UAAW,YACXC,kBAAmB,oBACnBC,eAAgB,iBAChBC,oBAAqB,sBACrBC,iBAAkB,oBAkJd,SAAUC,wBACdC,EACAC,GAEA,IAAIC,EAAM,eAAiB9S,EAS3B,OAPE6S,IAAkBT,EAAkBC,MACpCQ,IAAkBT,EAAkBE,UAEpCQ,GAAO,OAASD,EAAcE,eACrBH,GAAcC,IAAkBT,EAAkBE,aAC3DQ,GAAO,WAEFA,CACT,CAQsB,MAAAE,6BAiBpB,WAAA9X,CACEyS,EACUsF,EACAC,EACA1M,EACAyC,EACVkK,EACUC,GAAc,EACdC,EAAgCjB,EAAkBC,MANlD9W,KAAA0X,OAAAA,EACA1X,KAAA2X,MAAAA,EACA3X,KAAAiL,aAAAA,EACAjL,KAAA0N,iBAAAA,EAEA1N,KAAA6X,YAAAA,EACA7X,KAAA8X,eAAAA,EAtBF9X,KAAA+X,MAAQ,GAER/X,KAAAgY,UAAY,IACZhY,KAAAiY,eAAiB,GAGjBjY,KAAAkY,SAAU,EACVlY,KAAAmY,SAAW,IAEXnY,KAAAoY,WAA4B,KAC5BpY,KAAAqY,eAA4C,KAC5CrY,KAAAsY,WAA4B,KAC5BtY,KAAAuY,kBAAmB,EAYvBX,IACmC,iBAA1BA,EAAiB1B,OAC1BlW,KAAKwY,MAAQZ,EAAiB1B,WAEW,IAAhC0B,EAAiBa,aAC1BzY,KAAKkY,QAAUN,EAAiBa,YAElCzY,KAAK+X,MAAQH,EAAiBxM,MAEhC,MAAMc,SAAEA,EAAUhB,UAAWwN,EAAOzM,UAAEA,EAASzL,QAAEA,GAAY4R,EAQ7D,GAPIlG,IACFlM,KAAKgY,UAAY9L,GAEfwM,IACF1Y,KAAKmY,SAAWO,GAElB1Y,KAAK2Y,aAAenY,GACfyL,EACH,MAAM,IAAI/G,iBACRR,EAAKK,iBACL,4BAGJ/E,KAAKiY,eAAiBhM,EACtBjM,KAAK4Y,uBAAyB,YAAY5Y,KAAKmY,sBAAsBnY,KAAKgY,sBAAsBhY,KAAK2Y,2BAA2B3Y,KAAKiY,iBACrIjY,KAAKiL,cAAcM,wBAAuB8C,IACxCgB,SAAS,wBAAwBhB,KACjCrO,KAAK6Y,mBAAmBxK,EAAM,IAEhCrO,KAAK0N,kBAAkBnC,wBAAuBvK,IAC5C,MAAMqN,MAAEA,GAAUrN,EAClBqO,SAAS,kCAAkChB,KAC3CrO,KAAKqY,eAAiBhK,CAAK,GAE/B,CAKA,WAAA8H,CAAY/K,EAAc8K,EAAe4C,GACvC9Y,KAAK+X,MAAQ3M,EACbpL,KAAKuY,kBAAmB,EACJ,iBAATrC,IACTlW,KAAKwY,MAAQtC,QAES,IAAb4C,IACT9Y,KAAKkY,QAAUY,EAEnB,CAEA,iBAAMC,CAAYC,GAAa,GAC7B,IAAIC,EAAyC,IAAIzR,SAAQC,GACvDA,EAAQzH,KAAKoY,cAEf,GAAIpY,KAAK0N,iBAAkB,CACzB,MAAMG,QAAsB7N,KAAK0N,iBAAiBU,WAC9CP,IACF7N,KAAKqY,eAAiBxK,EAAcQ,MAExC,CAcA,OAZE4K,EADEjZ,KAAKiL,aACUjL,KAAKiL,aACnBmD,SAAyB4K,GACzB9K,MAAKvN,GACCA,GAGLX,KAAKoY,WAAazX,EAAKuY,YAChBlZ,KAAKoY,YAHH,OAMI,IAAI5Q,SAAQC,GAAWA,EAAQ,MAE3CwR,CACT,CAEA,eAAME,CACJC,EACAC,GAAQ,GAER,IAAIC,GAAa,EACjB,OAAOtZ,KAAK+Y,YAAYM,GACrBnL,MAAKqL,IACJD,EAAatZ,KAAKsY,aAAeiB,EACjCvZ,KAAKsY,WAAaiB,EACXA,KAERrL,KAAKkL,GACLjL,OAAMkC,IAEL,GACE,SAAUA,GACVA,EAAIzQ,OAAS8E,EAAKO,eACjBoU,GACDC,EAGA,OADAjK,SAAS,gCACFrP,KAAKmZ,UAAUC,GAAgB,GAExC,MAAM/I,CAAG,GAEf,CAEA,aAAAmJ,CAAcC,GACZzZ,KAAKsY,WAAamB,CACpB,CAyBA,iBAAAC,CAAkBpC,GAChBtX,KAAK8X,eAAiBR,CACxB,EC7UF,IAAIqC,EAAoCC,WAAWC,MAWnD,SAASzC,sBACPS,EACAC,GAEA,IAAIP,EAAM,eAAiB9S,EAS3B,OAPEqT,IAAmBjB,EAAkBC,MACrCgB,IAAmBjB,EAAkBE,UAErCQ,GAAO,OAASO,EAAeN,eACtBK,GAAeC,IAAmBjB,EAAkBE,aAC7DQ,GAAO,WAEFA,CACT,CAMO/L,eAAesO,QACpBlY,EACAmY,GACAC,OAAEA,GACFrC,EACAuB,EACArL,EACAgK,EACAC,EACAS,GAEA,IAAKoB,EACH,MAAM,IAAIzU,iBAAiBR,EAAKC,MAAO,qCAEzC,MAAMsV,EAAuB,CAC3B,eAAgB,mBAChB,oBAAqB7C,sBAAsBS,EAAaC,GACxD,mBAAoB,OAAOrT,KAEzByU,IACFe,EAAQ,yBAA2Bf,GAEjCvB,IACFsC,EAAQ,oBAAsBtC,GAE5B9J,IACFoM,EAAQ,uBAAyBpM,GAEnC,MACMqM,EAA4B,CAChCH,KAFc/J,KAAKC,UAAU8J,GAG7BxV,OAAQ,OACR0V,UACAD,UAMF,IAAI3U,EAUA8U,EAdAxY,mBAAmBC,IAAQ2W,IAC7B2B,EAAaE,YAAc,WAI7B,IACE/U,QAAiBsU,EAAa/X,EAAKsY,EACrC,CAAE,MAAO7J,GACP,MAAMxQ,EACJwQ,GAAsB,iBAARA,GAAoB,YAAaA,EAC1CA,EAAoD,QACrD7O,OAAO6O,GACb,MAAM,IAAInL,iBAAiBR,EAAKC,MAAO,oBAAsB9E,EAC/D,CAEA,IACEsa,QAAqB9U,EAASa,MAChC,CAAE,MAAOzE,GACP,MAAM5B,EACJ4B,GAAkB,iBAANA,GAAkB,YAAaA,EACtCA,EAAkD,QACnDD,OAAOC,GACb,MAAM,IAAIyD,iBACRR,EAAKC,MACL,kCAAoC9E,EAExC,CACA,MAAMA,EAgCR,SAASwa,gBAAgBjR,GACvB,GAAI,YAAaA,GAAOA,EAAIvJ,QAC1B,OAAOuJ,EAAIvJ,QAEb,OAAOmQ,KAAKC,UAAU7G,EACxB,CArCkBiR,CAAgBF,GAChC,GAAI9U,EAASiV,QAAU,IAAK,CAE1B,GADA/K,SAAS,mCAAqCS,KAAKC,UAAUkK,IACrC,MAApB9U,EAASiV,OACX,MAAM,IAAIpV,iBAAiBR,EAAKO,aAAcpF,GAEhD,MAAM,IAAIqF,iBAAiBR,EAAKC,MAAO9E,EACzC,CACA,GAAIsa,EAAazZ,QAAUyZ,EAAazZ,OAAOO,OAAQ,CACrD,MAAMyV,EAAc1G,KAAKC,UAAUkK,EAAazZ,QAC1CiW,EAAuD,CAC3DjW,OAAQyZ,EAAazZ,OACrBC,KAAMwZ,EAAaxZ,MAErB,MAAM,IAAIyE,0BACR,+CAAiDsR,EACjDC,EAEJ,CAMA,OALKwD,EAAarG,aAChBqG,EAAarG,WAAa,CACxB3B,YAAa,KAGVgI,CACT,CCpIO,MAAMI,EAAY,qCA8CnB,SAAUC,SAAS5Y,EAAa8V,GACpC,IAAKA,EACH,OAAO9V,EAET,MAAM6Y,EAAS,IAAI3Y,IAAIF,GAEvB,OADA6Y,EAAOC,aAAaC,OAAO,MAAOjD,GAC3B+C,EAAOtV,UAChB,CCrCM,MAAOyV,sBAAsBnD,6BACjC,WAAA9X,CACEyS,EACAsF,EACAC,EACA1M,EACAyC,EACAkK,EACAC,GAAc,EACdC,EAAgCjB,EAAkBC,MAElD/W,MACEqS,EACAsF,EACAC,EACA1M,EACAyC,EACAkK,EACAC,EACAC,GAoBJ9X,KAAAqV,YAGoD,CAIlDwF,EACAd,KAEA,MAAMe,EAAkB,IAAIC,gBAoB5B,OAjBiB/a,KAAKmZ,WAAU,IAC9BW,QACEU,SAAS,GAAGxa,KAAKgb,2BAA4Bhb,KAAK0X,QAClD,CACEzX,KAAMD,KAAK4Y,uBACXqC,cAAeJ,EACf3I,UAAW6H,GAEbe,EACA9a,KAAK2X,MACL3X,KAAKoY,WACLpY,KAAKqY,eACLrY,KAAK6X,YACL7X,KAAK8X,eACL9X,KAAKuY,mBAGM,EAGjBvY,KAAAkb,eAG0C,CACxCC,EACApB,KAEA,MAAMe,EAAkB,IAAIC,gBAkB5B,OAjBmB/a,KAAKmZ,WAAU,IACzBW,QACLU,SAAS,GAAGxa,KAAKgb,8BAA+Bhb,KAAK0X,QACrD,CACEzX,KAAMD,KAAK4Y,uBACXqC,cAAeE,EACfjJ,UAAW6H,GAEbe,EACA9a,KAAK2X,MACL3X,KAAKoY,WACLpY,KAAKqY,eACLrY,KAAK6X,YACL7X,KAAK8X,eACL9X,KAAKuY,mBAGQ,CA5EnB,CAEA,eAAIyC,GACF,ODpCE,SAAUI,eACdC,EACAzD,GAEA,MAAM3L,UAAEA,EAASC,SAAEA,EAAUhB,UAAWwN,EAAOlY,QAAEA,GAAY6a,GACvDjQ,KAAEA,EAAIqN,WAAEA,EAAUvC,KAAEA,GAAS0B,EAGnC,IAAI0D,EAAU,GAFG7C,EAAa,QAAU,YACvBrN,GAAQmP,IAEzB,GAAoB,iBAATrE,EACToF,GAAW,IAAIpF,SACV,QAAoB,IAATA,EAEhB,MADA3G,SAAS,mCACH,IAAIrK,iBACRR,EAAKK,iBACL,sCAGJ,MAAO,GAAGuW,iBAAuB5C,eAAqBxM,cAAqB1L,gBAAsByL,GACnG,CCiBWmP,CACL,CACEnP,UAAWjM,KAAKiY,eAChB/L,SAAUlM,KAAKgY,UACf9M,UAAWlL,KAAKmY,SAChB3X,QAASR,KAAK2Y,cAEhB,CACEvN,KAAMpL,KAAK+X,MACXU,WAAYzY,KAAKkY,QACjBhC,KAAMlW,KAAKwY,OAGjB,CA+DA,eAAArD,CACEoG,EACAV,EACAd,GAEA,MAAM,IAAI7U,iBACRR,EAAKI,cACL,8CAEJ,CAEA,iBAAAkQ,CAA6B6F,EAAmBd,GAC9C,MAAM,IAAI7U,iBACRR,EAAKI,cACL,gDAEJ,CAEA,kBAAA+T,CAAmB2C,GACjBxb,KAAKoY,WAAaoD,CACpB,EC7EI,MAAgBC,2CAA2ChE,6BAQ/D,kBAAIiE,GACF,QAAS1b,KAAK2b,WAChB,CAMA,0BAAIC,GACF,OAAO5b,KAAK6b,8BAA8BC,KAAO,CACnD,CAGA,4BAAIC,GACF,OACE/b,KAAKgc,0BAA0BF,KAAO,GACtC9b,KAAKic,6BAA6BH,KAAO,CAE7C,CAEA,WAAAnc,CACEyS,EACUsF,EACAC,EACA1M,EACAyC,EACVkK,EACUC,GAAc,EACdC,EAAgCjB,EAAkBC,MAE5D/W,MACEqS,EACAsF,EACAC,EACA1M,EACAyC,EACAkK,EACAC,EACAC,GAhBQ9X,KAAA0X,OAAAA,EACA1X,KAAA2X,MAAAA,EACA3X,KAAAiL,aAAAA,EACAjL,KAAA0N,iBAAAA,EAEA1N,KAAA6X,YAAAA,EACA7X,KAAA8X,eAAAA,EAvBZ9X,KAAAkc,mBAAoB,EAiHZlc,KAAAmc,cA7Je,EA2Kfnc,KAAAgc,0BAA4B,IAAItV,IAShC1G,KAAAoc,0BAA4B,IAAI1V,IAWhC1G,KAAAic,6BAA+B,IAAIvV,IASnC1G,KAAA6b,8BAAgC,IAAInV,IASpC1G,KAAAqc,uBAAyB,IAAI3V,IAU7B1G,KAAAsc,sBAAwB,IAAI5V,IAS5B1G,KAAAuc,mBAAqB,IAAI7V,IAMzB1G,KAAAwc,qBAAuB,IAAI9V,IAM3B1G,KAAA2b,YAAoD,KAKpD3b,KAAAyc,yBAA0B,EAkG1Bzc,KAAA0c,iBAjVyB,IAmVzB1c,KAAA2c,eAAuD,KAEvD3c,KAAA4c,kBAAoB,EAGpB5c,KAAA6c,0BAAiD,KAEjD7c,KAAA8c,oCAA2D,KAMnE9c,KAAA+c,sBAAwB,KAClB/c,KAAK2c,iBACP3c,KAAKgd,kBACAhd,KAAKid,mBACZ,EAOFjd,KAAAkd,gCAAkC,KAChC,MAAMC,EAAMvD,WAAWwD,SACnBD,GAA+B,YAAxBA,EAAIE,iBAAiCrd,KAAK2c,iBACnD3c,KAAKgd,kBACAhd,KAAKid,mBACZ,EA4EMjd,KAAAsd,sBAAuB,EAMvBtd,KAAAud,kBAAmC,KAxXzCvd,KAAKwd,+BACP,CAKQ,6BAAAA,GACN,GAAI,qBAAsB5D,WAAY,CACpC,MAAMpL,EAAWxO,KAAK+c,sBACtBnD,WAAW6D,iBAAiB,SAAUjP,GACtCxO,KAAK6c,0BAA4B,IAC/BjD,WAAW8D,oBAAoB,SAAUlP,EAC7C,CAEA,MAAM2O,EAAMvD,WAAWwD,SACvB,GAAID,GAAO,qBAAsBA,EAAK,CACpC,MAAM3O,EAAWxO,KAAKkd,gCACtBC,EAAIM,iBAAiB,mBAAoBjP,GACzCxO,KAAK8c,oCAAsC,IACzCK,EAAIO,oBAAoB,mBAAoBlP,EAChD,CACF,CAMQ,4BAAAmP,GACN3d,KAAK8c,wCACL9c,KAAK8c,oCAAsC,KAC3C9c,KAAK6c,8BACL7c,KAAK6c,0BAA4B,IACnC,CAMA,yBAAMe,CAAoBhe,EAAa2W,GACrCvW,KAAK2d,+BACL3d,KAAKgd,kBACLhd,KAAK6d,cACL7d,KAAK8d,kBAAkBle,GAAQ8E,EAAKC,MAAO4R,GAAU,0BAC/CvW,KAAK+d,kBACX/d,KAAKge,mBACP,CAqCQ,aAAAC,GACN,OAAQje,KAAKmc,iBAAiBhX,UAChC,CA2FQ,0BAAA+Y,CACNC,EACAC,EACAC,GAEA,IAAIC,EAEAC,EACJ,MAMMC,EAAsD,CAC1DC,gBAPsB,IAAIjX,SAC1B,CAACC,EAAS6G,KACRgQ,EAAY7W,EACZ8W,EAAWjQ,CAAM,IAKnBgQ,UAAWA,EACXC,SAAUA,GAGNG,EAAiB1e,KAAKic,6BAA6BhV,IAAImX,IAAW,GAKxE,OAJAM,EAAe5V,KAAKuV,GACpBre,KAAKic,6BAA6BlV,IAAIqX,EAAQM,GAC9C1e,KAAKqc,uBAAuBtV,IAAIoX,EAAWK,GAEpCA,CACT,CAOQ,2BAAAG,CACNR,EACAC,EACAQ,EACArD,GAEAvb,KAAK6b,8BAA8B9U,IAAIqX,EAAQQ,GAC/C5e,KAAKuc,mBAAmBxV,IAAIoX,EAAW5C,EACzC,CAMQ,yBAAAsD,CAA0BV,EAAmBC,GACnDpe,KAAKgc,0BAA0BjH,OAAOqJ,GACtCpe,KAAKqc,uBAAuBtH,OAAOoJ,GACnCne,KAAKsc,sBAAsBvH,OAAOoJ,EACpC,CAMQ,4BAAAW,CACNX,EACAC,GAEA,MAAMW,EAAkB/e,KAAKic,6BAA6BhV,IAAImX,GAC9D,GAAIW,EAAiB,CACnB,MAAMC,EAAkBD,EAAgBzU,QACtC2U,GAAWA,EAAQd,YAAcA,IAE/Ba,EAAgB/d,OAAS,EAC3BjB,KAAKic,6BAA6BlV,IAAIqX,EAAQY,GAE9Chf,KAAKic,6BAA6BlH,OAAOqJ,EAE7C,CACApe,KAAKqc,uBAAuBtH,OAAOoJ,EACrC,CAMQ,6BAAAe,CACNf,EACAC,GAEApe,KAAK6b,8BAA8B9G,OAAOqJ,GAC1Cpe,KAAKuc,mBAAmBxH,OAAOoJ,EACjC,CAwCQ,eAAAnB,GACFhd,KAAK2c,iBACPwC,aAAanf,KAAK2c,gBAClB3c,KAAK2c,eAAiB,KAE1B,CAMQ,qBAAAyC,GACN,GAAIpf,KAAK2c,eACP,OAEF3c,KAAK4c,oBACL,MAAMyC,EAAQrf,KAAK0c,iBACnB1c,KAAK0c,iBAAmB4C,KAAKC,IAnYA,IAoY3Bvf,KAAK0c,iBAtYoB,KAyY3B,MAAM8C,GAAUF,KAAKG,SAAW,IAAOJ,EAEvCrf,KAAK2c,eAAiBpO,YAAW,KAC/BvO,KAAK2c,eAAiB,KACjB3c,KAAKid,kBAAkB,GAC3BoC,EAAQG,EACb,CAEQ,sBAAMvC,GACZ,UACQjd,KAAK0f,mBAEX1f,KAAK0c,iBAvZwB,IAwZ7B1c,KAAK4c,kBAAoB,QACnB5c,KAAK2f,yBACb,CAAE,MAAOle,GACHA,aAAahC,eACf4P,SACE,sBAAsBrP,KAAK4c,iDAAiDnb,EAAE5B,wBAEhFG,KAAKof,0BAEL7P,SACE,8CAA8CvP,KAAK4c,sBAAsBnb,KAEtEzB,KAAK4d,oBACRlZ,EAAKC,MACL,8CAA8C3E,KAAK4c,sBAAsBnb,KAG/E,CACF,CAMQ,6BAAMke,GACZ,IAAK,MAAOlU,EAAGmT,KAAkB5e,KAAK6b,oCAC9B7b,KAAK4f,mBAAmBhB,GAEhC,IAAK,MAAOnT,EAAGoU,KAAgB7f,KAAKgc,gCAC5Bhc,KAAK4f,mBAAmBC,EAElC,CAkBA,qBAAYC,GACV,OACE9f,KAAKsd,wBACFtd,KAAKoY,YAAcpY,KAAKoY,aAAepY,KAAKud,iBAEnD,CAKU,iBAAAwC,GACR/f,KAAKsd,sBAAuB,EAC5Btd,KAAKud,kBAAoB,KACzBvd,KAAKyc,yBAA0B,CACjC,CAQQ,qBAAAuD,GACFhgB,KAAK2b,cAGT3b,KAAK2b,YAAcpN,YAAW,KAC5BvO,KAAK2b,YAAc,KAEf3b,KAAK4b,wBAA0B5b,KAAK+b,0BAGnC/b,KAAK4d,oBACRlZ,EAAKC,MACL,iCACD,GA/e4B,MAifjC,CAKQ,WAAAkZ,GACF7d,KAAK2b,cACPwD,aAAanf,KAAK2b,aAClB3b,KAAK2b,YAAc,KAEvB,CAMQ,iBAAAmC,CAAkBle,EAAY2W,GACpCvW,KAAKgc,0BAA0BrR,QAC/B3K,KAAKic,6BAA6BtR,QAClC3K,KAAK6b,8BAA8BlR,QAEnC,MAAMlH,EAAQ,IAAIyB,iBAAiBtF,EAAM2W,GACzC,IAAK,MAAO6H,GAAQG,SAAEA,MAAeve,KAAKoc,0BACxCpc,KAAKoc,0BAA0BrH,OAAOqJ,GACtCG,EAAS9a,GAEX,IAAK,MAAO0a,GAAWI,SAAEA,MAAeve,KAAKqc,uBAC3Crc,KAAKqc,uBAAuBtH,OAAOoJ,GACnCI,EAAS9a,GAEX,IAAK,MAAO0a,GAAWI,SAAEA,MAAeve,KAAKsc,sBAC3Ctc,KAAKsc,sBAAsBvH,OAAOoJ,GAClCI,EAAS9a,GAEX,IAAK,MAAO0a,EAAW5C,KAAavb,KAAKuc,mBACvCvc,KAAKuc,mBAAmBxH,OAAOoJ,GAC/B5C,EAASjF,aAAa1W,EAAM2W,GAE9BvW,KAAKwc,qBAAqB7R,QAC1B3K,KAAKgd,iBACP,CAMQ,6BAAAiD,GACN,MAAMxc,EAAQ,IAAIyB,iBAChBR,EAAKC,MACL,8CAEF,IAAK,MAAO8G,EAAGyU,KAAalgB,KAAKic,6BAC/B,IAAK,MAAMgD,KAAWiB,EAAU,CAC9B,MAAMzM,EAAUzT,KAAKqc,uBAAuBpV,IAAIgY,EAAQd,WACpD1K,IACFA,EAAQ8K,SAAS9a,GACjBzD,KAAKqc,uBAAuBtH,OAAOkK,EAAQd,WAE/C,CAEFne,KAAKic,6BAA6BtR,OACpC,CAKU,aAAAwV,CAAcvgB,EAAc2W,GACpCvW,KAAK6d,cACA7d,KAAK4b,wBAQVvM,SACE,iCAAiCzP,MAAS2W,8BAE5CvW,KAAKigB,gCACLjgB,KAAKof,yBAVEpf,KAAK4d,oBACRlZ,EAAKC,MACL,4CAA4C/E,MAAS2W,IAS3D,CAWU,cAAA6J,CAGRP,GACA,MAAMQ,EAAkC,IAAKR,GACvC5F,EAAgC,CAAA,EAqBtC,OApBIja,KAAK2X,QACPsC,EAAQ,oBAAsBja,KAAK2X,OAErCsC,EAAQ,qBAAuB7C,wBAC7BpX,KAAK6X,YACL7X,KAAK8X,gBAEH9X,KAAK8f,mBAAqB9f,KAAKoY,aACjC6B,EAAQ,yBAA2Bja,KAAKoY,WACxCpY,KAAKud,kBAAoBvd,KAAKoY,YAE5BpY,KAAKsd,uBACPrD,EAAQ,oBAAsB,OAAOxV,IACjCzE,KAAKqY,iBACP4B,EAAQ,wBAA0Bja,KAAKqY,gBAEzCgI,EAAoBpgB,KAAOD,KAAK4Y,wBAElCyH,EAAoBpG,QAAUA,EAC9Bja,KAAKsd,sBAAuB,EACrB+C,CACT,CAOQ,wBAAMT,CACZC,GAMA,IAJK7f,KAAKyc,yBAA2Bzc,KAAKiL,qBAClCjL,KAAK+Y,cACX/Y,KAAKyc,yBAA0B,GAE7Bzc,KAAKsgB,cAAe,CACtB,MAAMC,EAAWvgB,KAAKogB,eAAeP,GACrC,OAAO7f,KAAKwgB,YAAYD,EAC1B,CACA,OAAOvgB,KAAK0f,mBAAmBxR,MAAK,KAClC,MAAMqS,EAAWvgB,KAAKogB,eAAeP,GACrC,OAAO7f,KAAKwgB,YAAYD,EAAS,GAErC,CAKQ,SAAAE,CAAUxF,EAAuB/I,GACvC,MAAMwO,EAAkB1gB,KAAK2gB,eAAezO,GAC5C,OAAOlC,KAAKC,UAAU,CAAEgL,gBAAe/I,UAAWwO,GACpD,CAKQ,cAAAC,CAAevX,GACrB,GAAY,OAARA,GAA+B,iBAARA,GAAoBrD,MAAMuC,QAAQc,GAC3D,OAAOA,EAET,MAAMwX,EAAqC,CAAA,EAQ3C,OAPA1gB,OAAOsR,KAAKpI,GACTqI,OACAjH,SAAQlJ,IACPsf,EAAUtf,GAAOtB,KAAK2gB,eACnBvX,EAAgC9H,GAClC,IAEEsf,CACT,CASA,WAAAvL,CACEwF,EACA3I,GAEA,MAAMkM,EAASpe,KAAKygB,UAAU5F,EAAW3I,GAEzC,OAAIlS,KAAKgc,0BAA0B1U,IAAI8W,GAC9Bpe,KAAK6gB,wBAAwBzC,GAG/Bpe,KAAK8gB,qBAAqBjG,EAAW3I,EAAWkM,EACzD,CAOQ,uBAAAyC,CACNzC,GAEA,MAAM2C,EAAiB/gB,KAAKoc,0BAA0BnV,IAAImX,GAC1D,GAAI2C,EAEF,OAAOA,EAAetC,gBAGxB,IAAIH,EAEAC,EACJ,MAAME,EAAkB,IAAIjX,SAC1B,CAACC,EAAS6G,KACRgQ,EAAY7W,EACZ8W,EAAWjQ,CAAM,IAUrB,OANAtO,KAAKoc,0BAA0BrV,IAAIqX,EAAQ,CACzCK,kBACAH,UAAWA,EACXC,SAAUA,IAGLE,CACT,CAMQ,oBAAAqC,CACNjG,EACA3I,EACAkM,EACA4C,GAEA,MAAMC,EAAqBjhB,KAAK6b,8BAA8B5U,IAAImX,GAElE,IAAIE,EAEAC,EACAE,EAgBAN,EACA0B,EAuCJ,OArDImB,GACF1C,EAAY0C,EAA6B1C,UACzCC,EAAWyC,EAA6BzC,SACxCE,EAAkBuC,EAA6BvC,iBAE/CA,EAAkB,IAAIjX,SACpB,CAACC,EAAS6G,KACRgQ,EAAY7W,EACZ8W,EAAWjQ,CAAM,IAQnB2S,GAEF9C,EAAY8C,EAAmB9C,UAC/B0B,EAAc,CAAE1B,YAAW+C,OAAQ,IACnClhB,KAAKsc,sBAAsBvV,IAAIoX,EAAW,CACxCM,kBACAH,UAAWA,EACXC,SAAUA,MAIZJ,EAAYne,KAAKie,gBACjB4B,EAAc,CACZ1B,YACAgD,QAAS,CAAElG,cAAeJ,EAAW3I,cAEvClS,KAAKqc,uBAAuBtV,IAAIoX,EAAW,CACzCM,kBACAH,UAAWA,EACXC,SAAUA,KAIdve,KAAKgc,0BAA0BjV,IAAIqX,EAAQyB,GAE3CpB,EAAkBA,EAAgB2C,SAAQ,KACxCphB,KAAKqhB,8BACHxG,EACA3I,EACAkM,EACAD,EACD,IAGHne,KAAK4f,mBAAmBC,GAAa1R,OAAMkC,IACzCkO,EAASlO,EAAI,IAERoO,CACT,CAMQ,6BAAA4C,CACNxG,EACA3I,EACAkM,EACAD,GAEAne,KAAK6e,0BAA0BV,EAAWC,GAEnBpe,KAAKwc,qBAAqBvV,IAAIkX,KAEnDne,KAAKwc,qBAAqBzH,OAAOoJ,GACjCne,KAAKshB,mBAAmBnD,EAAWC,IAGrC,MAAMmD,EAAuBvhB,KAAKoc,0BAA0BnV,IAAImX,GAC3DmD,GAOLvhB,KAAKoc,0BAA0BrH,OAAOqJ,GAEjCpe,KAAK8gB,qBACRjG,EACA3I,EACAkM,EACAmD,IAZKvhB,KAAK4b,wBAA2B5b,KAAK+b,0BACxC/b,KAAKggB,uBAaX,CASA,cAAA9E,CACEC,EACAjJ,GAEA,MAAMiM,EAAYne,KAAKie,gBACjBuD,EAAmB,CAAEvG,cAAeE,EAAcjJ,aAClDkM,EAASpe,KAAKygB,UAAUtF,EAAcjJ,GACtCmM,EAA+C,CACnDF,YACAgD,QAASK,GAGX,IAAI/C,gBAAEA,EAAeF,SAAEA,GAAave,KAAKke,2BACvCC,EACAC,EACAC,GAaF,OAXAI,EAAkBA,EAAgB2C,SAAQ,KACxCphB,KAAK8e,6BAA6BX,EAAWC,GACxCpe,KAAK4b,wBAA2B5b,KAAK+b,0BACxC/b,KAAKggB,uBACP,IAIFhgB,KAAK4f,mBAA8BvB,GAAalQ,OAAMkC,IACpDkO,EAASlO,EAAI,IAERoO,CACT,CAUA,eAAAtJ,CACEoG,EACAV,EACA3I,GAEA,MAAMkM,EAASpe,KAAKygB,UAAU5F,EAAW3I,GACnCuP,EAAoBzhB,KAAK6b,8BAA8B5U,IAAImX,GAGjE,GAAIqD,EAAmB,CACrB,MAAMtD,EAAYsD,EAAkBtD,UAChCne,KAAKwc,qBAAqBlV,IAAI6W,KAChCne,KAAKwc,qBAAqBzH,OAAOoJ,GACjCne,KAAKuc,mBAAmBxV,IAAIoX,EAAW5C,GAE3C,KAAO,CACL,MAAM4C,EAAYne,KAAKie,gBAEjBW,EAAmD,CACvDT,YACAuD,UAHuB,CAAEzG,cAAeJ,EAAW3I,cAMrDlS,KAAK2e,4BACHR,EACAC,EACAQ,EACArD,GAIFvb,KAAK4f,mBAA8BhB,GAAezQ,OAAMkC,IACtDkL,EAAS9E,QAAQpG,aAAe3Q,MAAQ2Q,EAAM,IAAI3Q,MAAM8B,OAAO6O,KAC/DrQ,KAAKkf,8BAA8Bf,EAAWC,GACzCpe,KAAK4b,wBACR5b,KAAKggB,uBACP,GAEJ,CAEAhgB,KAAK6d,aACP,CASA,iBAAA7I,CAA6B6F,EAAmB3I,GAC9C,MAAMkM,EAASpe,KAAKygB,UAAU5F,EAAW3I,GACnCyP,EAAmB3hB,KAAK6b,8BAA8B5U,IAAImX,GAChE,IAAKuD,EACH,OAEF,MAAMxD,EAAYwD,EAAiBxD,UAEnCne,KAAKuc,mBAAmBxH,OAAOoJ,GACTne,KAAKsc,sBAAsBrV,IAAIkX,GAEnDne,KAAKwc,qBAAqBzV,IAAIoX,EAAW,CACvClD,cAAeJ,EACf3I,cAIJlS,KAAKshB,mBAAmBnD,EAAWC,EACrC,CAMQ,kBAAAkD,CAAmBnD,EAAmBC,GAC5Cpe,KAAKkf,8BAA8Bf,EAAWC,GAC9C,MAAMwD,EAAkC,CACtCzD,YACA0D,OAAQ,CAAA,GAIV7hB,KAAK4f,mBAAmBgC,GAAYzT,OAAMkC,IACxCd,SAAS,wDAAwDc,IAAM,IAGpErQ,KAAK4b,wBACR5b,KAAKggB,uBAET,CAEA,kBAAAnH,CAAmB2C,GACjB,MAAMsG,EAAe9hB,KAAKoY,WAC1BpY,KAAKoY,WAAaoD,EAElB,MAAMuG,EAAa/hB,KAAKgiB,QAClBC,EAAajiB,KAAKiL,cAAcU,WAAWC,SACjD5L,KAAKgiB,QAAUC,OAIsB5Z,IAAf0Z,IAMnBD,GAA6B,OAAbtG,IACfuG,GAAcE,GACfF,GAAcE,IAAeF,IAEzB/hB,KAAK4d,oBACRlZ,EAAKO,aACL,0CAGN,CAQU,oBAAMid,CACd/D,EACA9Y,GAEA,GAAIrF,KAAKqc,uBAAuB/U,IAAI6W,GAAY,CAC9C,MAAMG,UAAEA,EAASC,SAAEA,GACjBve,KAAKqc,uBAAuBpV,IAAIkX,GAClCne,KAAKmiB,8BAA8B7D,EAAWC,EAAUlZ,EAC1D,MAAO,GACLrF,KAAKuc,mBAAmBjV,IAAI6W,IAC5Bne,KAAKsc,sBAAsBhV,IAAI6W,GAC/B,CACA,MAAM5C,EAAWvb,KAAKuc,mBAAmBtV,IAAIkX,GACvCiE,EAAgBpiB,KAAKsc,sBAAsBrV,IAAIkX,GAErD,GAAIiE,EAAe,CACjBpiB,KAAKsc,sBAAsBvH,OAAOoJ,GAClC,MAAMG,UAAEA,EAASC,SAAEA,GAAa6D,EAChCpiB,KAAKmiB,8BAA8B7D,EAAWC,EAAUlZ,EAC1D,CAEA,GAAIkW,EACF,UACQA,EAASnF,OAAO/Q,EACxB,CAAE,MAAO5D,GACP8N,SAAS,+BAA+B9N,IAC1C,CAEJ,MACE8N,SACE,qDAAqD4O,KAG3D,CAOQ,6BAAAgE,CACN7D,EACAC,EACAlZ,GAEA,GAAIA,EAAS3E,QAAU2E,EAAS3E,OAAOO,OAAQ,CAC7C,MAAM0V,EAAuD,CAC3DjW,OAAQ2E,EAAS3E,OACjBC,KAAM0E,EAAS1E,MAEX+V,EAAc1G,KAAKC,UAAU5K,EAAS3E,QAC5C6d,EACE,IAAInZ,0BACF,+CAAiDsR,EACjDC,GAGN,MACE2H,EAAUjZ,EAEd,EC7jCF,IAAIgd,EAA4CzI,WAAW0I,UAwBrD,MAAOC,2BAA2B9G,mCAAxC,WAAA9b,uBAkBUK,KAAAyS,aAAmCpK,EAcnCrI,KAAAwiB,gBAAoCna,EAUpCrI,KAAAyiB,kBAA0C,IA2NpD,CApQE,eAAIzH,GACF,OHNE,SAAU0H,oBACdrH,EACAzD,GAEA,MAAM1L,SAAEA,GAAamP,GACfjQ,KAAEA,EAAIqN,WAAEA,EAAUvC,KAAEA,GAAS0B,EAGnC,IAAI0D,EAAU,GAFG7C,EAAa,MAAQ,UACrBrN,GAAQmP,IAEzB,GAAoB,iBAATrE,EACToF,GAAW,IAAIpF,SACV,QAAoB,IAATA,EAEhB,MADA3G,SAAS,mCACH,IAAIrK,iBACRR,EAAKK,iBACL,sCAGJ,MAAO,GAAGuW,gFAA+CpP,GAC3D,CGbWwW,CACL,CACEzW,UAAWjM,KAAKiY,eAChB/L,SAAUlM,KAAKgY,UACf9M,UAAWlL,KAAKmY,SAChB3X,QAASR,KAAK2Y,cAEhB,CACEvN,KAAMpL,KAAK+X,MACXU,WAAYzY,KAAKkY,QACjBhC,KAAMlW,KAAKwY,OAGjB,CASQ,oBAAAmK,CAAqBhiB,GAI3B,OAHKX,KAAKyS,UACRzS,KAAKyS,QAAU,IAAImQ,YAAY,UAE1B5iB,KAAKyS,QAAQoQ,OAAOliB,EAC7B,CAKA,iBAAI2f,GACF,OAAOtgB,KAAKwiB,YAAYM,aAAeR,UAAUS,IACnD,CAQU,gBAAArD,GACR,IACE,OAAI1f,KAAKsgB,cACA9Y,QAAQC,WAEbzH,KAAKyiB,oBAGTziB,KAAKyiB,kBAAoB,IAAIjb,SAAc,CAACC,EAAS6G,KACnD,IAAK+T,EACH,MAAM,IAAInd,iBACRR,EAAKC,MACL,yCAGJ,MAAMqe,EAAK,IAAIX,EAAiBriB,KAAKgb,aACrChb,KAAKwiB,WAAaQ,EAClBhjB,KAAKwiB,WAAYS,WAAa,cAE9BD,EAAGE,OAAS,KACVljB,KAAKkc,mBAAoB,EACzBlc,KAAK+f,oBACLtY,GAAS,EAGXub,EAAGG,QAAUC,IACXpjB,KAAKyiB,kBAAoB,KACzBziB,KAAKkc,mBAAoB,EACzB,MAAMzY,EAAQ,IAAIyB,iBAChBR,EAAKC,MACL,uDAEF3E,KAAKqjB,YAAY5f,GACjB6K,EAAO7K,EAAM,EAGfuf,EAAGM,UAAYC,GACbvjB,KAAKwjB,uBAAuBD,GAAIpV,OAAM3C,MAAM+K,IAC1CvW,KAAKqjB,YAAY9M,EAAO,IAG5ByM,EAAGS,QAAUF,GAAMvjB,KAAK0jB,0BAA0BH,EAAG,KAnC9CvjB,KAAKyiB,kBAuChB,CAAE,MAAOhf,GAEP,MADAzD,KAAKqjB,YAAY5f,GACXA,CACR,CACF,CAEU,cAAAkgB,GACR,OAAO3jB,KAAK0f,mBAAmBvR,OAAMkC,IACnC,MAAM,IAAInL,iBACRR,EAAKC,MACL,8BAA8B0L,IAC/B,GAEL,CAEU,eAAA0N,CAAgBne,EAAe2W,GACvC,IAAKvW,KAAKwiB,WAER,OADAxiB,KAAKyiB,kBAAoB,KAClBjb,QAAQC,UAEjB,IAAIhE,EACJ,IACE,GAAI8S,EAAQ,CAGV,MAAMqN,EAAY,IACZrR,EAAU,IAAIlG,YAEpB,GADckG,EAAQjG,OAAOiK,GACnBtV,QAAU2iB,EAClB5jB,KAAKwiB,WAAWjb,MAAM3H,EAAM2W,OACvB,CACL,MAAMsN,EAAM,IAAIlX,WAAWiX,IACrBE,KAAEA,GAASvR,EAAQwR,WAAWxN,EAAQsN,GACtCG,EAAkBzN,EAAOnV,UAAU,EAAG0iB,GAC5C9jB,KAAKwiB,WAAWjb,MAAM3H,EAAMokB,EAC9B,CACF,MACEhkB,KAAKwiB,WAAWjb,MAAM3H,EAE1B,CAAE,MAAO6B,GACPgC,EAAQhC,CACV,SACEzB,KAAKwiB,gBAAana,EAClBrI,KAAKyiB,kBAAoB,IAC3B,CACA,OAAIhf,EACK+D,QAAQ8G,OAAO7K,GAEjB+D,QAAQC,SACjB,CAMQ,yBAAAic,CAA0BH,GAChCvjB,KAAKwiB,gBAAana,EAClBrI,KAAKyiB,kBAAoB,KACzBziB,KAAKmgB,cAAcoD,EAAG3jB,KAAM2jB,EAAGhN,OACjC,CAKQ,WAAA8M,CAAY5f,GAClB8L,SAAS,gDAAgD9L,KACzD,IAAI8S,EAAS9S,EAAQjC,OAAOiC,GAAS,gBACjCA,aAAiByB,mBACnBqR,EAAS9S,EAAM5D,SAEZG,KAAK+d,gBAvKsB,IAuKgBxH,EAClD,CAEU,WAAAiK,CACRX,GAEA,OAAO7f,KAAK0f,mBAAmBxR,MAAK,KAClC,IAEE,OADAlO,KAAKwiB,WAAYyB,KAAKjU,KAAKC,UAAU4P,IAC9BrY,QAAQC,SACjB,CAAE,MAAO4I,GAEP,MADArQ,KAAKqjB,YAAYhT,GACX,IAAInL,iBACRR,EAAKC,MACL,2BAA2BnD,OAAO6O,KAEtC,IAEJ,CAMQ,4BAAMmT,CAAuBD,GACnC,MAAMviB,EAA6ChB,KAAKkkB,mBACtDX,EAAG5iB,MAECwd,EAAYnd,EAAOmd,UAEnB9Y,EAAyC,CAC7C1E,KAAMK,EAAOL,KACbD,OAAQM,EAAON,OACfoT,WAAY9S,EAAO8S,YAAc,CAAE3B,YAAa,WAG5CnS,KAAKkiB,eAAe/D,EAAW9Y,EACvC,CAQQ,kBAAA6e,CAENvjB,GAEA,MAAMwjB,EAA+B,iBAATxjB,EAE5B,IAAIyjB,EAEApjB,EACJ,IAEIojB,EADED,EACiBnU,KAAK2C,MAAMhS,GAEXqP,KAAK2C,MAAM3S,KAAK2iB,qBAAqBhiB,GAE5D,CAAE,MAAO0P,GACP,MAAM,IAAInL,iBACRR,EAAKC,MACL,sCACE0L,aAAe3Q,MAAQ2Q,EAAIxQ,QAAU2B,OAAO6O,KAGlD,CACA,GAAgC,iBAArB+T,GAAsD,OAArBA,EAC1C,MAAM,IAAIlf,iBACRR,EAAKC,MACL,sCAGJ,GAAIwf,EAAc,CAChB,KAAM,WAAYC,GAChB,MAAM,IAAIlf,iBACRR,EAAKC,MACL,0DAGJ,GACqC,iBAA5Byf,EAAiBpjB,QACI,OAA5BojB,EAAiBpjB,OAEjB,MAAM,IAAIkE,iBACRR,EAAKC,MACL,6CAGJ3D,EAASojB,EAAiBpjB,MAC5B,MACEA,EAASojB,EAEX,KAAM,cAAepjB,GACnB,MAAM,IAAIkE,iBACRR,EAAKC,MACL,+CAGJ,OAAO3D,CACT,ECjRW,MAAAqjB,4BAOX,WAAA1kB,CACUyS,EACAsF,EACAC,EACA1M,EACAyC,EACAkK,EACAC,GAAc,EACdC,GAPA9X,KAAAoS,QAAAA,EACApS,KAAA0X,OAAAA,EACA1X,KAAA2X,MAAAA,EACA3X,KAAAiL,aAAAA,EACAjL,KAAA0N,iBAAAA,EACA1N,KAAA4X,iBAAAA,EACA5X,KAAA6X,YAAAA,EACA7X,KAAA8X,eAAAA,EAVF9X,KAAAskB,iBAAkB,EAYxBtkB,KAAKukB,cAAgB,IAAI3J,cACvBxI,EACAsF,EACAC,EACA1M,EACAyC,EACAkK,EACAC,EACAC,EAEJ,CAKQ,mBAAA0M,GAuBN,OAtBKxkB,KAAKykB,kBACRzkB,KAAKykB,gBAAkB,IAAIlC,mBACzBviB,KAAKoS,QACLpS,KAAK0X,OACL1X,KAAK2X,MACL3X,KAAKiL,aACLjL,KAAK0N,iBACL1N,KAAK4X,iBACL5X,KAAK6X,YACL7X,KAAK8X,gBAEH9X,KAAKskB,iBAAmBtkB,KAAK4X,kBAC/B5X,KAAKykB,gBAAgBtO,YACnBnW,KAAK4X,iBAAiBxM,KACtBpL,KAAK4X,iBAAiB1B,KACtBlW,KAAK4X,iBAAiBa,YAG1BzY,KAAKykB,gBAAgBzG,gBAAkB,KACrChe,KAAKykB,qBAAkBpc,CAAS,GAG7BrI,KAAKykB,eACd,CAKQ,sBAAAC,GACN,QACI1kB,KAAKykB,kBACNzkB,KAAKykB,gBAAgB/I,gBACtB1b,KAAKykB,gBAAgBnE,eACrBtgB,KAAKykB,gBAAgB7I,yBACpB5b,KAAKykB,gBAAgBvI,iBAE1B,CAMA,WAAA7G,CACEwF,EACAd,GAEA,OAAI/Z,KAAK0kB,yBACA1kB,KAAKykB,gBAAiBpP,YAC3BwF,EACAd,GACA5L,OAAMkC,IACN,GAAIrQ,KAAK0kB,yBACP,MAAMrU,EAER,OAAOrQ,KAAKukB,cAAclP,YAA6BwF,EAAWd,EAAK,IAGpE/Z,KAAKukB,cAAclP,YAAYwF,EAAWd,EACnD,CAMA,cAAAmB,CACEL,EACAd,GAEA,OAAI/Z,KAAK0kB,yBACA1kB,KAAKykB,gBAAiBvJ,eAC3BL,EACAd,GACA5L,OAAMkC,IACN,GAAIrQ,KAAK0kB,yBACP,MAAMrU,EAER,OAAOrQ,KAAKukB,cAAcrJ,eACxBL,EACAd,EACD,IAGE/Z,KAAKukB,cAAcrJ,eAAeL,EAAWd,EACtD,CAEA,eAAA5E,CACEoG,EACAV,EACAd,GAEA,MAAM0K,EAAkBzkB,KAAKwkB,sBAC7B,GAAIC,EAAgBvI,kBAClB,MAAM,IAAIhX,iBACRR,EAAKC,MACL,oFAGJ8f,EAAgBtP,gBAAgBoG,EAAUV,EAAWd,EACvD,CAEA,iBAAA/E,CAA6B6F,EAAmBd,GAC1C/Z,KAAKykB,iBACPzkB,KAAKykB,gBAAgBzP,kBAAkB6F,EAAWd,EAEtD,CAEA,WAAA5D,CAAY/K,EAAc8K,EAAeuC,GACvCzY,KAAKskB,iBAAkB,EACvBtkB,KAAK4X,iBAAmB,CAAExM,OAAM8K,OAAMuC,cACtCzY,KAAKukB,cAAcpO,YAAY/K,EAAM8K,EAAMuC,GACvCzY,KAAKykB,iBACPzkB,KAAKykB,gBAAgBtO,YAAY/K,EAAM8K,EAAMuC,EAEjD,CAEA,kBAAAI,CAAmBxK,GACjBrO,KAAKukB,cAAc1L,mBAAmBxK,GAClCrO,KAAKykB,iBACPzkB,KAAKykB,gBAAgB5L,mBAAmBxK,EAE5C,CAEA,iBAAAqL,CAAkBpC,GAChBtX,KAAK8X,eAAiBR,EACtBtX,KAAKukB,cAAc7K,kBAAkBpC,GACjCtX,KAAKykB,iBACPzkB,KAAKykB,gBAAgB/K,kBAAkBpC,EAE3C,EC3Ic,SAAAqN,YACdC,EACAzJ,EACAjJ,GAEA0S,EAAWC,iBAOX,MAN0C,CACxC1S,YAAayS,EACb3kB,KAAMkb,EACN7G,QAAS/D,EACT2B,UAAWA,EAGf,CAKa,MAAA4S,gBAEX,WAAAnlB,CAAoBolB,GAAA/kB,KAAA+kB,WAAAA,EADZ/kB,KAAAglB,UAAqC,EACmB,CAChE,eAAAC,CACEN,GAEA,MAAM3jB,EAAShB,KAAK+kB,WAAW7J,eAC7ByJ,EAAY1kB,KACZ0kB,EAAYzS,WAERgT,EAAiBlkB,EAAOkN,MAAKqL,IACY,IACxCA,EACHxH,OAAQvB,EACRjG,IAAKoa,EACL3S,UAAW3N,KAAKD,MAAM+gB,qBAI1BnlB,KAAKglB,UAAUlc,KAAK9H,GACpB,MAAMokB,cAAgB,IACnBplB,KAAKglB,UAAYhlB,KAAKglB,UAAU1a,QAAOmJ,GAAWA,IAAYzS,IAEjE,OADAA,EAAOkN,KAAKkX,cAAeA,eACpBF,CACT,EAuBI,SAAUD,gBACdN,GAEA,OAAOA,EAAYxS,YAAYkT,iBAAiBJ,gBAAgBN,EAClE,CCpDM,SAAUW,aAAaC,GAC3B,MAAOC,EAAUC,GAAYF,EAASG,MAAM,OACtC5M,EAAwB,UAAb0M,GACVpa,EAAMua,GAAgBF,EAASC,MAAM,KAE5C,MAAO,CAAEta,OAAM8K,KADF7B,OAAOsR,GACClN,WAAYK,EACnC,CAWa,MAAA8M,YAkBX,WAAAjmB,CACkB8N,EAECoY,EACAlW,EACAmW,GAEjB,GANgB9lB,KAAAyN,IAAAA,EAECzN,KAAA6lB,mBAAAA,EACA7lB,KAAA2P,cAAAA,EACA3P,KAAA8lB,kBAAAA,EApBnB9lB,KAAA+lB,YAAa,EACb/lB,KAAAgmB,cAAe,EAKfhmB,KAAAimB,sBAAgC,EAChCjmB,KAAA8X,eAAgCjB,EAAkBC,KAezB,oBAAZoP,SAA2BA,QAAQC,IAAK,CACjD,MAAM/a,EAAO8a,QAAQC,IAA2C,oCAC5D/a,IACFiE,SAAS,qCACTrP,KAAK+lB,YAAa,EAClB/lB,KAAKomB,kBAAoBd,aAAala,GAE1C,CACF,CAIA,QAAAib,GACE,OAAOrmB,KAAKoT,KACd,CAEA,gBAAAkT,GACOtmB,KAAKimB,uBACRjmB,KAAKimB,sBAAuB,EAEhC,CACA,iBAAAvM,CAAkBpC,GAChBtX,KAAK8X,eAAiBR,EAClBtX,KAAKgmB,cACPhmB,KAAK+kB,WAAWrL,kBAAkBpC,EAEtC,CACA,OAAAiP,GAME,OALAC,EACExmB,KAAKyN,IACL,eACAuC,KAAKC,UAAUjQ,KAAKqS,gBAEf7K,QAAQC,SACjB,CAGA,WAAA4K,GACE,MAAMoU,EAAOzW,KAAK2C,MAAM3C,KAAKC,UAAUjQ,KAAK6lB,qBAE5C,cADOY,EAAKvb,UACLub,CACT,CAKA,gBAAAC,CAAiBrb,GACfrL,KAAK2mB,eAAiBtb,CACxB,CAGA,cAAAwZ,GACE,GAAI7kB,KAAKgmB,aACP,YAE2B3d,IAAzBrI,KAAK4mB,kBACPvX,SACE,2EAEFrP,KAAK4mB,gBAAkBvC,6BAGzBrkB,KAAK6mB,mBAAqB,IAAIrX,qBAC5BxP,KAAKyN,IAAIxN,KACTD,KAAKyN,IAAI2E,QACTpS,KAAK2P,eAEP,MAAMxE,EAAmC,CACvCc,UAAWjM,KAAK6lB,mBAAmB5Z,UACnCzL,QAASR,KAAK6lB,mBAAmBrlB,QACjC0L,SAAUlM,KAAK6lB,mBAAmB3Z,UAEhClM,KAAK2mB,iBACP3mB,KAAKoT,MAAQ,IAAIpI,iBACfhL,KAAK6mB,mBACL7mB,KAAKyN,IAAI2E,QAAQlH,UACjBC,EACAnL,KAAKomB,mBAAmBhb,MAAQmP,EAChCva,KAAK2mB,iBAIL3mB,KAAK8lB,oBACP9lB,KAAK8mB,uBAAyB,IAAItZ,sBAChCxN,KAAKyN,IACLzN,KAAK8lB,oBAIT9lB,KAAK+kB,WAAa,IAAI/kB,KAAK4mB,gBACzB5mB,KAAK6lB,mBACL7lB,KAAKyN,IAAI2E,QAAQsF,OACjB1X,KAAKyN,IAAI2E,QAAQuF,MACjB3X,KAAK6mB,mBACL7mB,KAAK8mB,4BACLze,EACArI,KAAKimB,qBACLjmB,KAAK8X,gBAEH9X,KAAKomB,mBACPpmB,KAAK+kB,WAAW5O,YACdnW,KAAKomB,kBAAkBhb,KACvBpL,KAAKomB,kBAAkBlQ,KACvBlW,KAAKomB,kBAAkB3N,YAI3BzY,KAAK+mB,cAAgB,IAAInU,aAAa5S,KAAK+kB,WAAY/kB,KAAMA,KAAKoT,OAClEpT,KAAKqlB,iBAAmB,IAAIP,gBAAgB9kB,KAAK+kB,YACjD/kB,KAAKgmB,cAAe,CACtB,CAGA,cAAA/P,CAAe2B,GACb,GACE5X,KAAKomB,mBACLpmB,KAAKgmB,eACJgB,yBAAyBhnB,KAAKomB,kBAAmBxO,GAGlD,MADArI,SAAS,8CACH,IAAIrK,iBACRR,EAAKE,oBACL,6CAGJ5E,KAAKomB,kBAAoBxO,EACzB5X,KAAK+lB,YAAa,CACpB,EASI,SAAUiB,yBACdC,EACAC,GAEA,OACED,EAAkB7b,OAAS8b,EAAkB9b,MAC7C6b,EAAkB/Q,OAASgR,EAAkBhR,MAC7C+Q,EAAkBxO,aAAeyO,EAAkBzO,UAEvD,CASM,SAAU0O,2BACdhU,EACA/H,EACA8K,EACAuC,GAAa,GAGT9W,mBAAmByJ,I5B7OlBI,eAAe4b,WAAWC,GAI/B,aAHqBxN,MAAMwN,EAAU,CACnCjN,YAAa,aAEDkN,EAChB,C4ByOSF,CAAW,WAAWhc,IAAO8K,EAAO,IAAIA,IAAS,MAExD/C,EAAG8C,eAAe,CAAE7K,OAAM8K,OAAMuC,cAClC,CAoCgB,SAAA8O,eACdC,EACAC,EACA7Z,GAEA,IAAIH,EACAtC,EACAuc,EACA,aAAcF,GAChBrc,EAAkBqc,EAClB/Z,EAAMka,IACND,EAAeD,IAEfha,EAAM+Z,EACNrc,EAAkBsc,EAClBC,EAAe9Z,GAGZH,GAAmC,IAA5BvN,OAAOsR,KAAK/D,GAAKxM,SAC3BwM,EAAMka,KAIR,MAAMC,EAAoB,IACrBzc,EACHD,UAAWuC,EAAI2E,QAAQlH,WAInB2c,EAAmB3nB,OAAO4nB,YAC9B5nB,OAAO0I,QAAQgf,GAAmBnW,QAG9BsW,EAAWC,aAAava,EAAK,gBAC7B5B,EAAamE,KAAKC,UAAU4X,GAClC,GAAIE,EAASE,cAAcpc,GAAa,CACtC,MAAM+Y,EAAamD,EAAS/Z,aAAa,CAAEnC,eACrCuG,EAAU2V,EAASG,WAAWrc,GAEpC,GADqB3L,OAAOsR,KAAKY,GAASnR,OAAS,EAGjD,OADAoO,SAAS,4BACFuV,CAEX,CACAuD,kBAAkBhd,GAElBkE,SAAS,qCAET,MAAM8C,EAAc4V,EAAS/b,WAAW,CACtCoc,mBAAoBvc,EACpBuG,QAASlS,OAAO4nB,YACd5nB,OAAO0I,QAAQ,IACVif,IACFpW,UAMP,OAHIiW,GAAcrc,eAChB8G,EAAYuU,iBAAiBgB,EAAarc,eAErC8G,CACT,CAQM,SAAUgW,kBAAkBE,GAEhC,IAAKA,EACH,MAAM,IAAInjB,iBAAiBR,EAAKK,iBAAkB,sBAUpD,MAZe,CAAC,YAAa,WAAY,WAIlCyF,SAAQ8d,IACb,GACgD,OAA9CD,EAAUC,SACoCjgB,IAA9CggB,EAAUC,GAEV,MAAM,IAAIpjB,iBAAiBR,EAAKK,iBAAkB,GAAGujB,aACvD,KAEK,CACT,CAOM,SAAUC,UAAUpW,GACxB,OAAOA,EAAYoU,SAErB,CACO,MAAMiC,EAAc,CACzBC,OAAQ,UAiBM,SAAAC,0BACd,OAAO,IAAIpb,UACb,CC/ZO,MAAMqb,EAAmB,CAC9BC,aAAc,eACdC,WAAY,aACZC,YAAa,eCoDT,SAAUC,aACdjX,EACAM,GAEA,GAAIN,EAASwC,UAAYhE,EACvB,OAAO9I,QAAQ8G,OACb,IAAIpJ,iBACFR,EAAKK,iBACL,mDAIN,MAAMikB,EAAelX,EAASK,YAAY4U,cACpCkC,EAAc7W,GAAS6W,aAAeN,EAAiBC,aAC7D,OAAQK,GACN,KAAKN,EAAiBG,YACpB,OAAOE,EAAa/V,mBAAmBnB,GACzC,KAAK6W,EAAiBE,WACpB,OAAOG,EAAahW,kBAAkBlB,GAAU,GAClD,KAAK6W,EAAiBC,aACpB,OAAOI,EAAanW,mBAAmBf,GAAU,GACnD,QACE,MAAM,IAAI5M,iBACRR,EAAKK,iBACL,yBAAyBkkB,KAGjC,CAgCM,SAAUnX,SACd8S,EACA/J,EACA3I,EACAyC,GAMA,OAJAiQ,EAAWC,sBACUxc,IAAjBsM,GACFiQ,EAAWmC,cAAcrT,UAAUiB,GAE9B,CACLxC,YAAayS,EACbtQ,QAAShE,EACTrQ,KAAM4a,EACN3I,UAAWA,EAEf,CAMM,SAAUgX,WACdC,GAEA,MACElX,SAAShS,KAAEA,EAAIiS,UAAEA,EAAS/G,gBAAEA,IAC1Bge,EACJ,OAAOrX,SAASyV,eAAepc,GAAkBlL,EAAMiS,EACzD,CClHM,SAAUkX,aACdje,EACAke,EACAC,EACAC,GAEA,IAAI3E,EACA4E,EAYJ,GAVmBH,GAAY,mBAAoBA,GAGjDzE,EAAayE,EACbG,EAAWF,IAEX1E,EAAa2C,eAAepc,GAC5Bqe,EAAWH,IAGRzE,IAAgB4E,GAAYD,EAC/B,MAAM,IAAIrkB,iBAAiBR,EAAKK,iBAAkB,uBAGpD,MAAO,CAAEoO,GAAIyR,EAAY0E,KAAME,EACjC,CAkBM,SAAUC,wBACdte,EACAue,EACAC,EACAvX,EACAwX,EACAL,GAEA,IAAI3E,EACA4E,EACAK,EAwBJ,GAtBmBH,GAAqB,mBAAoBA,GAG1D9E,EAAa8E,EACTE,GACFJ,EAAWG,EACXE,EAAczX,IAEdoX,OAAWnhB,EACXwhB,EAAcF,KAGhB/E,EAAa2C,eAAepc,GACxBye,GACFJ,EAAWE,EACXG,EAAcF,IAEdH,OAAWnhB,EACXwhB,EAAcH,KAIb9E,IAAgB4E,GAAYD,EAC/B,MAAM,IAAIrkB,iBAAiBR,EAAKK,iBAAkB,uBAGpD,MAAO,CAAEoO,GAAIyR,EAAY0E,KAAME,EAAUpX,QAASyX,EACpD,CChCM,SAAUnI,UACdoI,EAGAC,EAGAtT,EACAuT,GAEA,IAAIzf,EACAoK,EAiBAsV,EAhBJ,GAAI,YAAaH,EAA4B,CAC3C,MAAMX,EACJW,GACInpB,KAAEA,EAAIoR,OAAEA,EAAMC,UAAEA,GAAcmX,EAEpC5e,EAAM2e,WAAWC,GACjBxU,EAAe,CACbhU,OACAoR,SACAC,YACAzH,MACA1E,OAAQgM,iBAAiBtH,EAAK5J,EAAMoR,EAAQC,GAEhD,MACEzH,EAAMuf,EAUR,GAPgC,mBAArBC,EACTE,EAAWF,GAEXE,EAAWF,EAAiBG,OAC5BzT,EAAUsT,EAAiBI,MAC3BH,EAAaD,EAAiBC,aAE3BC,EACH,MAAM,IAAI/kB,iBAAiBR,EAAKK,iBAAkB,uBAEpD,OAAOwF,EAAI4H,YAAY4U,cAAcxS,gBACnChK,EACA0f,EACAD,EACAvT,EACA9B,EAEJ,EC/GM,SAAUyV,oBAAoBC,I9BN9B,SAAUC,cAAcC,GAC5B9lB,EAAc8lB,CAChB,C8BKED,CAAc7lB,GACd+lB,EACE,IAAIvoB,UACF,gBACA,CAACwoB,GAAarC,mBAAoBsC,EAAoBtY,cACpD,MAAM3E,EAAMgd,EAAUE,YAAY,OAAO3c,eACnC/C,EAAewf,EAAUE,YAAY,iBACrCjd,EAAmB+c,EAAUE,YAAY,sBAC/C,IAAIC,EAAUxY,EAOd,GANIsY,IACFE,EAAU,IACL5a,KAAK2C,MAAM+X,MACXE,KAGFnd,EAAI2E,QAAQlH,UACf,MAAM,IAAIhG,iBACRR,EAAKK,iBACL,qFAGJ,OAAO,IAAI6gB,YACTnY,EACA,IAAKmd,EAAS1f,UAAWuC,EAAI2E,QAAQlH,WACrCD,EACAyC,EACD,GACF,UAEDhL,sBAAqB,IAEzBmoB,EAAgB5qB,EAAMsqB,EAASF,GAE/BQ,EAAgB5qB,EAAMsqB,EAAS,UACjC,CCrCAH","preExistingComment":"firebase-data-connect.js.map"}