File: //opt/LC/node_modules/firebase/firebase-performance-standalone-compat.js.map
{"version":3,"file":"firebase-performance-standalone-compat.js","sources":["../util/src/crypt.ts","../util/src/deepCopy.ts","../util/src/defaults.ts","../util/src/global.ts","../util/src/deferred.ts","../util/src/environment.ts","../util/src/errors.ts","../util/src/obj.ts","../component/src/component.ts","../component/src/constants.ts","../component/src/provider.ts","../component/src/component_container.ts","../logger/src/logger.ts","../../node_modules/idb/build/wrap-idb-value.js","../../node_modules/idb/build/index.js","../app/src/platformLoggerService.ts","../app/src/logger.ts","../app/src/constants.ts","../app/src/internal.ts","../app/src/errors.ts","../app/src/firebaseApp.ts","../app/src/firebaseServerApp.ts","../app/src/api.ts","../app/src/indexeddb.ts","../app/src/heartbeatService.ts","../app/src/registerCoreComponents.ts","../app/src/index.ts","../app-compat/src/lite/firebaseAppLite.ts","../app-compat/src/errors.ts","../app-compat/src/firebaseNamespaceCore.ts","../app-compat/src/index.lite.ts","../app-compat/src/lite/firebaseNamespaceLite.ts","../app-compat/src/registerCoreComponents.ts","compat/app/index.ts","../installations/src/util/constants.ts","../installations/src/util/errors.ts","../installations/src/functions/common.ts","../installations/src/util/sleep.ts","../installations/src/helpers/generate-fid.ts","../installations/src/helpers/buffer-to-base64-url-safe.ts","../installations/src/util/get-key.ts","../installations/src/helpers/fid-changed.ts","../installations/src/helpers/idb-manager.ts","../installations/src/helpers/get-installation-entry.ts","../installations/src/functions/create-installation-request.ts","../installations/src/functions/generate-auth-token-request.ts","../installations/src/helpers/refresh-auth-token.ts","../installations/src/api/get-token.ts","../installations/src/helpers/extract-app-config.ts","../installations/src/functions/config.ts","../installations/src/api/get-id.ts","../installations/src/index.ts","../performance/src/constants.ts","../performance/src/utils/errors.ts","../performance/src/utils/console_logger.ts","../performance/src/services/api_service.ts","../performance/src/services/iid_service.ts","../performance/src/services/settings_service.ts","../performance/src/utils/string_merger.ts","../performance/src/utils/attributes_utils.ts","../performance/src/utils/app_utils.ts","../performance/src/services/remote_config_service.ts","../performance/src/services/initialization_service.ts","../performance/src/services/transport_service.ts","../performance/src/services/perf_logger.ts","../performance/src/utils/metric_utils.ts","../performance/src/resources/trace.ts","../performance/src/resources/network_request.ts","../performance/src/services/oob_resources_service.ts","../performance/src/controllers/perf.ts","../performance/src/index.ts","../performance-compat/src/performance.ts","../util/src/compat.ts","../performance-compat/src/index.ts","compat/index.perf.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\nconst stringToByteArray = function (str: string): number[] {\n // TODO(user): Use native implementations if/when available\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (\n (c & 0xfc00) === 0xd800 &&\n i + 1 < str.length &&\n (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00\n ) {\n // Surrogate Pair\n c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Turns an array of numbers into the string given by the concatenation of the\n * characters to which the numbers correspond.\n * @param bytes Array of numbers representing characters.\n * @return Stringification of the array.\n */\nconst byteArrayToString = function (bytes: number[]): string {\n // TODO(user): Use native implementations if/when available\n const out: string[] = [];\n let pos = 0,\n c = 0;\n while (pos < bytes.length) {\n const c1 = bytes[pos++];\n if (c1 < 128) {\n out[c++] = String.fromCharCode(c1);\n } else if (c1 > 191 && c1 < 224) {\n const c2 = bytes[pos++];\n out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));\n } else if (c1 > 239 && c1 < 365) {\n // Surrogate Pair\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n const c4 = bytes[pos++];\n const u =\n (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -\n 0x10000;\n out[c++] = String.fromCharCode(0xd800 + (u >> 10));\n out[c++] = String.fromCharCode(0xdc00 + (u & 1023));\n } else {\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n out[c++] = String.fromCharCode(\n ((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)\n );\n }\n }\n return out.join('');\n};\n\ninterface Base64 {\n byteToCharMap_: { [key: number]: string } | null;\n charToByteMap_: { [key: string]: number } | null;\n byteToCharMapWebSafe_: { [key: number]: string } | null;\n charToByteMapWebSafe_: { [key: string]: number } | null;\n ENCODED_VALS_BASE: string;\n readonly ENCODED_VALS: string;\n readonly ENCODED_VALS_WEBSAFE: string;\n HAS_NATIVE_SUPPORT: boolean;\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string;\n encodeString(input: string, webSafe?: boolean): string;\n decodeString(input: string, webSafe: boolean): string;\n decodeStringToByteArray(input: string, webSafe: boolean): number[];\n init_(): void;\n}\n\n// We define it as an object literal instead of a class because a class compiled down to es5 can't\n// be treeshaked. https://github.com/rollup/rollup/issues/1691\n// Static lookup maps, lazily populated by init_()\n// TODO(dlarocque): Define this as a class, since we no longer target ES5.\nexport const base64: Base64 = {\n /**\n * Maps bytes to characters.\n */\n byteToCharMap_: null,\n\n /**\n * Maps characters to bytes.\n */\n charToByteMap_: null,\n\n /**\n * Maps bytes to websafe characters.\n * @private\n */\n byteToCharMapWebSafe_: null,\n\n /**\n * Maps websafe characters to bytes.\n * @private\n */\n charToByteMapWebSafe_: null,\n\n /**\n * Our default alphabet, shared between\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\n */\n ENCODED_VALS_BASE:\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',\n\n /**\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\n */\n get ENCODED_VALS() {\n return this.ENCODED_VALS_BASE + '+/=';\n },\n\n /**\n * Our websafe alphabet.\n */\n get ENCODED_VALS_WEBSAFE() {\n return this.ENCODED_VALS_BASE + '-_.';\n },\n\n /**\n * Whether this browser supports the atob and btoa functions. This extension\n * started at Mozilla but is now implemented by many browsers. We use the\n * ASSUME_* variables to avoid pulling in the full useragent detection library\n * but still allowing the standard per-browser compilations.\n *\n */\n HAS_NATIVE_SUPPORT: typeof atob === 'function',\n\n /**\n * Base64-encode an array of bytes.\n *\n * @param input An array of bytes (numbers with\n * value in [0, 255]) to encode.\n * @param webSafe Boolean indicating we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string {\n if (!Array.isArray(input)) {\n throw Error('encodeByteArray takes an array as a parameter');\n }\n\n this.init_();\n\n const byteToCharMap = webSafe\n ? this.byteToCharMapWebSafe_!\n : this.byteToCharMap_!;\n\n const output = [];\n\n for (let i = 0; i < input.length; i += 3) {\n const byte1 = input[i];\n const haveByte2 = i + 1 < input.length;\n const byte2 = haveByte2 ? input[i + 1] : 0;\n const haveByte3 = i + 2 < input.length;\n const byte3 = haveByte3 ? input[i + 2] : 0;\n\n const outByte1 = byte1 >> 2;\n const outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\n let outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);\n let outByte4 = byte3 & 0x3f;\n\n if (!haveByte3) {\n outByte4 = 64;\n\n if (!haveByte2) {\n outByte3 = 64;\n }\n }\n\n output.push(\n byteToCharMap[outByte1],\n byteToCharMap[outByte2],\n byteToCharMap[outByte3],\n byteToCharMap[outByte4]\n );\n }\n\n return output.join('');\n },\n\n /**\n * Base64-encode a string.\n *\n * @param input A string to encode.\n * @param webSafe If true, we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeString(input: string, webSafe?: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return btoa(input);\n }\n return this.encodeByteArray(stringToByteArray(input), webSafe);\n },\n\n /**\n * Base64-decode a string.\n *\n * @param input to decode.\n * @param webSafe True if we should use the\n * alternative alphabet.\n * @return string representing the decoded value.\n */\n decodeString(input: string, webSafe: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return atob(input);\n }\n return byteArrayToString(this.decodeStringToByteArray(input, webSafe));\n },\n\n /**\n * Base64-decode a string.\n *\n * In base-64 decoding, groups of four characters are converted into three\n * bytes. If the encoder did not apply padding, the input length may not\n * be a multiple of 4.\n *\n * In this case, the last group will have fewer than 4 characters, and\n * padding will be inferred. If the group has one or two characters, it decodes\n * to one byte. If the group has three characters, it decodes to two bytes.\n *\n * @param input Input to decode.\n * @param webSafe True if we should use the web-safe alphabet.\n * @return bytes representing the decoded value.\n */\n decodeStringToByteArray(input: string, webSafe: boolean): number[] {\n this.init_();\n\n const charToByteMap = webSafe\n ? this.charToByteMapWebSafe_!\n : this.charToByteMap_!;\n\n const output: number[] = [];\n\n for (let i = 0; i < input.length; ) {\n const byte1 = charToByteMap[input.charAt(i++)];\n\n const haveByte2 = i < input.length;\n const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\n ++i;\n\n const haveByte3 = i < input.length;\n const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n const haveByte4 = i < input.length;\n const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\n throw new DecodeBase64StringError();\n }\n\n const outByte1 = (byte1 << 2) | (byte2 >> 4);\n output.push(outByte1);\n\n if (byte3 !== 64) {\n const outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);\n output.push(outByte2);\n\n if (byte4 !== 64) {\n const outByte3 = ((byte3 << 6) & 0xc0) | byte4;\n output.push(outByte3);\n }\n }\n }\n\n return output;\n },\n\n /**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\n init_() {\n if (!this.byteToCharMap_) {\n this.byteToCharMap_ = {};\n this.charToByteMap_ = {};\n this.byteToCharMapWebSafe_ = {};\n this.charToByteMapWebSafe_ = {};\n\n // We want quick mappings back and forth, so we precompute two maps.\n for (let i = 0; i < this.ENCODED_VALS.length; i++) {\n this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\n\n // Be forgiving when decoding and correctly decode both encodings.\n if (i >= this.ENCODED_VALS_BASE.length) {\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\n }\n }\n }\n }\n};\n\n/**\n * An error encountered while decoding base64 string.\n */\nexport class DecodeBase64StringError extends Error {\n readonly name = 'DecodeBase64StringError';\n}\n\n/**\n * URL-safe base64 encoding\n */\nexport const base64Encode = function (str: string): string {\n const utf8Bytes = stringToByteArray(str);\n return base64.encodeByteArray(utf8Bytes, true);\n};\n\n/**\n * URL-safe base64 encoding (without \".\" padding in the end).\n * e.g. Used in JSON Web Token (JWT) parts.\n */\nexport const base64urlEncodeWithoutPadding = function (str: string): string {\n // Use base64url encoding and remove padding in the end (dot characters).\n return base64Encode(str).replace(/\\./g, '');\n};\n\n/**\n * URL-safe base64 decoding\n *\n * NOTE: DO NOT use the global atob() function - it does NOT support the\n * base64Url variant encoding.\n *\n * @param str To be decoded\n * @return Decoded result, if possible\n */\nexport const base64Decode = function (str: string): string | null {\n try {\n return base64.decodeString(str, true);\n } catch (e) {\n console.error('base64Decode failed: ', e);\n }\n return null;\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\n/**\n * Do a deep-copy of basic JavaScript Objects or Arrays.\n */\nexport function deepCopy<T>(value: T): T {\n return deepExtend(undefined, value) as T;\n}\n\n/**\n * Copy properties from source to target (recursively allows extension\n * of Objects and Arrays). Scalar values in the target are over-written.\n * If target is undefined, an object of the appropriate type will be created\n * (and returned).\n *\n * We recursively copy all child properties of plain Objects in the source- so\n * that namespace- like dictionaries are merged.\n *\n * Note that the target can be a function, in which case the properties in\n * the source Object are copied onto it as static properties of the Function.\n *\n * Note: we don't merge __proto__ to prevent prototype pollution\n */\nexport function deepExtend(target: unknown, source: unknown): unknown {\n if (!(source instanceof Object)) {\n return source;\n }\n\n switch (source.constructor) {\n case Date:\n // Treat Dates like scalars; if the target date object had any child\n // properties - they will be lost!\n const dateValue = source as Date;\n return new Date(dateValue.getTime());\n\n case Object:\n if (target === undefined) {\n target = {};\n }\n break;\n case Array:\n // Always copy the array source and overwrite the target.\n target = [];\n break;\n\n default:\n // Not a plain Object - treat it as a scalar.\n return source;\n }\n\n for (const prop in source) {\n // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202\n if (!source.hasOwnProperty(prop) || !isValidKey(prop)) {\n continue;\n }\n (target as Record<string, unknown>)[prop] = deepExtend(\n (target as Record<string, unknown>)[prop],\n (source as Record<string, unknown>)[prop]\n );\n }\n\n return target;\n}\n\nfunction isValidKey(key: string): boolean {\n return key !== '__proto__';\n}\n","/**\n * @license\n * Copyright 2022 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 { base64Decode } from './crypt';\nimport { getGlobal } from './global';\n\n/**\n * Keys for experimental properties on the `FirebaseDefaults` object.\n * @public\n */\nexport type ExperimentalKey = 'authTokenSyncURL' | 'authIdTokenMaxAge';\n\n/**\n * An object that can be injected into the environment as __FIREBASE_DEFAULTS__,\n * either as a property of globalThis, a shell environment variable, or a\n * cookie.\n *\n * This object can be used to automatically configure and initialize\n * a Firebase app as well as any emulators.\n *\n * @public\n */\nexport interface FirebaseDefaults {\n config?: Record<string, string>;\n emulatorHosts?: Record<string, string>;\n _authTokenSyncURL?: string;\n _authIdTokenMaxAge?: number;\n /**\n * Override Firebase's runtime environment detection and\n * force the SDK to act as if it were in the specified environment.\n */\n forceEnvironment?: 'browser' | 'node';\n [key: string]: unknown;\n}\n\ndeclare global {\n // Need `var` for this to work.\n // eslint-disable-next-line no-var\n var __FIREBASE_DEFAULTS__: FirebaseDefaults | undefined;\n}\n\nconst getDefaultsFromGlobal = (): FirebaseDefaults | undefined =>\n getGlobal().__FIREBASE_DEFAULTS__;\n\n/**\n * Attempt to read defaults from a JSON string provided to\n * process(.)env(.)__FIREBASE_DEFAULTS__ or a JSON file whose path is in\n * process(.)env(.)__FIREBASE_DEFAULTS_PATH__\n * The dots are in parens because certain compilers (Vite?) cannot\n * handle seeing that variable in comments.\n * See https://github.com/firebase/firebase-js-sdk/issues/6838\n */\nconst getDefaultsFromEnvVariable = (): FirebaseDefaults | undefined => {\n if (typeof process === 'undefined' || typeof process.env === 'undefined') {\n return;\n }\n const defaultsJsonString = process.env.__FIREBASE_DEFAULTS__;\n if (defaultsJsonString) {\n return JSON.parse(defaultsJsonString);\n }\n};\n\nconst getDefaultsFromCookie = (): FirebaseDefaults | undefined => {\n if (typeof document === 'undefined') {\n return;\n }\n let match;\n try {\n match = document.cookie.match(/__FIREBASE_DEFAULTS__=([^;]+)/);\n } catch (e) {\n // Some environments such as Angular Universal SSR have a\n // `document` object but error on accessing `document.cookie`.\n return;\n }\n const decoded = match && base64Decode(match[1]);\n return decoded && JSON.parse(decoded);\n};\n\n/**\n * Get the __FIREBASE_DEFAULTS__ object. It checks in order:\n * (1) if such an object exists as a property of `globalThis`\n * (2) if such an object was provided on a shell environment variable\n * (3) if such an object exists in a cookie\n * @public\n */\nexport const getDefaults = (): FirebaseDefaults | undefined => {\n try {\n return (\n getDefaultsFromGlobal() ||\n getDefaultsFromEnvVariable() ||\n getDefaultsFromCookie()\n );\n } catch (e) {\n /**\n * Catch-all for being unable to get __FIREBASE_DEFAULTS__ due\n * to any environment case we have not accounted for. Log to\n * info instead of swallowing so we can find these unknown cases\n * and add paths for them if needed.\n */\n console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${e}`);\n return;\n }\n};\n\n/**\n * Returns emulator host stored in the __FIREBASE_DEFAULTS__ object\n * for the given product.\n * @returns a URL host formatted like `127.0.0.1:9999` or `[::1]:4000` if available\n * @public\n */\nexport const getDefaultEmulatorHost = (\n productName: string\n): string | undefined => getDefaults()?.emulatorHosts?.[productName];\n\n/**\n * Returns emulator hostname and port stored in the __FIREBASE_DEFAULTS__ object\n * for the given product.\n * @returns a pair of hostname and port like `[\"::1\", 4000]` if available\n * @public\n */\nexport const getDefaultEmulatorHostnameAndPort = (\n productName: string\n): [hostname: string, port: number] | undefined => {\n const host = getDefaultEmulatorHost(productName);\n if (!host) {\n return undefined;\n }\n const separatorIndex = host.lastIndexOf(':'); // Finding the last since IPv6 addr also has colons.\n if (separatorIndex <= 0 || separatorIndex + 1 === host.length) {\n throw new Error(`Invalid host ${host} with no separate hostname and port!`);\n }\n // eslint-disable-next-line no-restricted-globals\n const port = parseInt(host.substring(separatorIndex + 1), 10);\n if (host[0] === '[') {\n // Bracket-quoted `[ipv6addr]:port` => return \"ipv6addr\" (without brackets).\n return [host.substring(1, separatorIndex - 1), port];\n } else {\n return [host.substring(0, separatorIndex), port];\n }\n};\n\n/**\n * Returns Firebase app config stored in the __FIREBASE_DEFAULTS__ object.\n * @public\n */\nexport const getDefaultAppConfig = (): Record<string, string> | undefined =>\n getDefaults()?.config;\n\n/**\n * Returns an experimental setting on the __FIREBASE_DEFAULTS__ object (properties\n * prefixed by \"_\")\n * @public\n */\nexport const getExperimentalSetting = <T extends ExperimentalKey>(\n name: T\n): FirebaseDefaults[`_${T}`] =>\n getDefaults()?.[`_${name}`] as FirebaseDefaults[`_${T}`];\n","/**\n * @license\n * Copyright 2022 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 * Polyfill for `globalThis` object.\n * @returns the `globalThis` object for the given environment.\n * @public\n */\nexport function getGlobal(): typeof globalThis {\n if (typeof self !== 'undefined') {\n return self;\n }\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n throw new Error('Unable to locate global object.');\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 class Deferred<R> {\n promise: Promise<R>;\n reject: (value?: unknown) => void = () => {};\n resolve: (value?: unknown) => void = () => {};\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.resolve = resolve as (value?: unknown) => void;\n this.reject = reject as (value?: unknown) => void;\n });\n }\n\n /**\n * Our API internals are not promisified and cannot because our callback APIs have subtle expectations around\n * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback\n * and returns a node-style callback which will resolve or reject the Deferred's promise.\n */\n wrapCallback(\n callback?: (error?: unknown, value?: unknown) => void\n ): (error: unknown, value?: unknown) => void {\n return (error, value?) => {\n if (error) {\n this.reject(error);\n } else {\n this.resolve(value);\n }\n if (typeof callback === 'function') {\n // Attaching noop handler just in case developer wasn't expecting\n // promises\n this.promise.catch(() => {});\n\n // Some of our callbacks don't expect a value and our own tests\n // assert that the parameter length is 1\n if (callback.length === 1) {\n callback(error);\n } else {\n callback(error, value);\n }\n }\n };\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\nimport { CONSTANTS } from './constants';\nimport { getDefaults } from './defaults';\n\n/**\n * Type placeholder for `WorkerGlobalScope` from `webworker`\n */\ndeclare class WorkerGlobalScope {}\n\n/**\n * Returns navigator.userAgent string or '' if it's not defined.\n * @return user agent string\n */\nexport function getUA(): string {\n if (\n typeof navigator !== 'undefined' &&\n typeof navigator['userAgent'] === 'string'\n ) {\n return navigator['userAgent'];\n } else {\n return '';\n }\n}\n\n/**\n * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.\n *\n * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap\n * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally\n * wait for a callback.\n */\nexport function isMobileCordova(): boolean {\n return (\n typeof window !== 'undefined' &&\n // @ts-ignore Setting up an broadly applicable index signature for Window\n // just to deal with this case would probably be a bad idea.\n !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&\n /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA())\n );\n}\n\n/**\n * Detect Node.js.\n *\n * @return true if Node.js environment is detected or specified.\n */\n// Node detection logic from: https://github.com/iliakan/detect-node/\nexport function isNode(): boolean {\n const forceEnvironment = getDefaults()?.forceEnvironment;\n if (forceEnvironment === 'node') {\n return true;\n } else if (forceEnvironment === 'browser') {\n return false;\n }\n\n try {\n return (\n Object.prototype.toString.call(global.process) === '[object process]'\n );\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Detect Browser Environment.\n * Note: This will return true for certain test frameworks that are incompletely\n * mimicking a browser, and should not lead to assuming all browser APIs are\n * available.\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' || isWebWorker();\n}\n\n/**\n * Detect Web Worker context.\n */\nexport function isWebWorker(): boolean {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n typeof self !== 'undefined' &&\n self instanceof WorkerGlobalScope\n );\n}\n\n/**\n * Detect Cloudflare Worker context.\n */\nexport function isCloudflareWorker(): boolean {\n return (\n typeof navigator !== 'undefined' &&\n navigator.userAgent === 'Cloudflare-Workers'\n );\n}\n\n/**\n * Detect browser extensions (Chrome and Firefox at least).\n */\ninterface BrowserRuntime {\n id?: unknown;\n}\ndeclare const chrome: { runtime?: BrowserRuntime };\ndeclare const browser: { runtime?: BrowserRuntime };\nexport function isBrowserExtension(): boolean {\n const runtime =\n typeof chrome === 'object'\n ? chrome.runtime\n : typeof browser === 'object'\n ? browser.runtime\n : undefined;\n return typeof runtime === 'object' && runtime.id !== undefined;\n}\n\n/**\n * Detect React Native.\n *\n * @return true if ReactNative environment is detected.\n */\nexport function isReactNative(): boolean {\n return (\n typeof navigator === 'object' && navigator['product'] === 'ReactNative'\n );\n}\n\n/** Detects Electron apps. */\nexport function isElectron(): boolean {\n return getUA().indexOf('Electron/') >= 0;\n}\n\n/** Detects Internet Explorer. */\nexport function isIE(): boolean {\n const ua = getUA();\n return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;\n}\n\n/** Detects Universal Windows Platform apps. */\nexport function isUWP(): boolean {\n return getUA().indexOf('MSAppHost/') >= 0;\n}\n\n/**\n * Detect whether the current SDK build is the Node version.\n *\n * @return true if it's the Node SDK build.\n */\nexport function isNodeSdk(): boolean {\n return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;\n}\n\n/** Returns true if we are running in Safari. */\nexport function isSafari(): boolean {\n return (\n !isNode() &&\n !!navigator.userAgent &&\n navigator.userAgent.includes('Safari') &&\n !navigator.userAgent.includes('Chrome')\n );\n}\n\n/**\n * This method checks if indexedDB is supported by current browser/service worker context\n * @return true if indexedDB is supported by current browser/service worker context\n */\nexport function isIndexedDBAvailable(): boolean {\n try {\n return typeof indexedDB === 'object';\n } catch (e) {\n return false;\n }\n}\n\n/**\n * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject\n * if errors occur during the database open operation.\n *\n * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox\n * private browsing)\n */\nexport function validateIndexedDBOpenable(): Promise<boolean> {\n return new Promise((resolve, reject) => {\n try {\n let preExist: boolean = true;\n const DB_CHECK_NAME =\n 'validate-browser-context-for-indexeddb-analytics-module';\n const request = self.indexedDB.open(DB_CHECK_NAME);\n request.onsuccess = () => {\n request.result.close();\n // delete database only when it doesn't pre-exist\n if (!preExist) {\n self.indexedDB.deleteDatabase(DB_CHECK_NAME);\n }\n resolve(true);\n };\n request.onupgradeneeded = () => {\n preExist = false;\n };\n\n request.onerror = () => {\n reject(request.error?.message || '');\n };\n } catch (error) {\n reject(error);\n }\n });\n}\n\n/**\n *\n * This method checks whether cookie is enabled within current browser\n * @return true if cookie is enabled within current browser\n */\nexport function areCookiesEnabled(): boolean {\n if (typeof navigator === 'undefined' || !navigator.cookieEnabled) {\n return false;\n }\n return true;\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/**\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 return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? String(value) : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\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 function contains<T extends object>(obj: T, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\nexport function safeGet<T extends object, K extends keyof T>(\n obj: T,\n key: K\n): T[K] | undefined {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return obj[key];\n } else {\n return undefined;\n }\n}\n\nexport function isEmpty(obj: object): obj is {} {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return false;\n }\n }\n return true;\n}\n\nexport function map<K extends string, V, U>(\n obj: { [key in K]: V },\n fn: (value: V, key: K, obj: { [key in K]: V }) => U,\n contextObj?: unknown\n): { [key in K]: U } {\n const res: Partial<{ [key in K]: U }> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n res[key] = fn.call(contextObj, obj[key], key, obj);\n }\n }\n return res as { [key in K]: U };\n}\n\n/**\n * Deep equal two objects. Support Arrays and Objects.\n */\nexport function deepEqual(a: object, b: object): boolean {\n if (a === b) {\n return true;\n }\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n for (const k of aKeys) {\n if (!bKeys.includes(k)) {\n return false;\n }\n\n const aProp = (a as Record<string, unknown>)[k];\n const bProp = (b as Record<string, unknown>)[k];\n if (isObject(aProp) && isObject(bProp)) {\n if (!deepEqual(aProp, bProp)) {\n return false;\n }\n } else if (aProp !== bProp) {\n return false;\n }\n }\n\n for (const k of bKeys) {\n if (!aKeys.includes(k)) {\n return false;\n }\n }\n return true;\n}\n\nfunction isObject(thing: unknown): thing is object {\n return thing !== null && typeof thing === 'object';\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 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 */\n\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\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 */\n\nimport { Deferred } from '@firebase/util';\nimport { ComponentContainer } from './component_container';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport {\n InitializeOptions,\n InstantiationMode,\n Name,\n NameServiceMapping,\n OnInitCallBack\n} from './types';\nimport { Component } from './component';\n\n/**\n * Provider for instance for service name T, e.g. 'auth', 'auth-internal'\n * NameServiceMapping[T] is an alias for the type of the instance\n */\nexport class Provider<T extends Name> {\n private component: Component<T> | null = null;\n private readonly instances: Map<string, NameServiceMapping[T]> = new Map();\n private readonly instancesDeferred: Map<\n string,\n Deferred<NameServiceMapping[T]>\n > = new Map();\n private readonly instancesOptions: Map<string, Record<string, unknown>> =\n new Map();\n private onInitCallbacks: Map<string, Set<OnInitCallBack<T>>> = new Map();\n\n constructor(\n private readonly name: T,\n private readonly container: ComponentContainer\n ) {}\n\n /**\n * @param identifier A provider can provide multiple instances of a service\n * if this.component.multipleInstances is true.\n */\n get(identifier?: string): Promise<NameServiceMapping[T]> {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n\n if (!this.instancesDeferred.has(normalizedIdentifier)) {\n const deferred = new Deferred<NameServiceMapping[T]>();\n this.instancesDeferred.set(normalizedIdentifier, deferred);\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n // initialize the service if it can be auto-initialized\n try {\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n if (instance) {\n deferred.resolve(instance);\n }\n } catch (e) {\n // when the instance factory throws an exception during get(), it should not cause\n // a fatal error. We just return the unresolved promise in this case.\n }\n }\n }\n\n return this.instancesDeferred.get(normalizedIdentifier)!.promise;\n }\n\n /**\n *\n * @param options.identifier A provider can provide multiple instances of a service\n * if this.component.multipleInstances is true.\n * @param options.optional If optional is false or not provided, the method throws an error when\n * the service is not immediately available.\n * If optional is true, the method returns null if the service is not immediately available.\n */\n getImmediate(options: {\n identifier?: string;\n optional: true;\n }): NameServiceMapping[T] | null;\n getImmediate(options?: {\n identifier?: string;\n optional?: false;\n }): NameServiceMapping[T];\n getImmediate(options?: {\n identifier?: string;\n optional?: boolean;\n }): NameServiceMapping[T] | null {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n options?.identifier\n );\n const optional = options?.optional ?? false;\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n try {\n return this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n } catch (e) {\n if (optional) {\n return null;\n } else {\n throw e;\n }\n }\n } else {\n // In case a component is not initialized and should/cannot be auto-initialized at the moment, return null if the optional flag is set, or throw\n if (optional) {\n return null;\n } else {\n throw Error(`Service ${this.name} is not available`);\n }\n }\n }\n\n getComponent(): Component<T> | null {\n return this.component;\n }\n\n setComponent(component: Component<T>): void {\n if (component.name !== this.name) {\n throw Error(\n `Mismatching Component ${component.name} for Provider ${this.name}.`\n );\n }\n\n if (this.component) {\n throw Error(`Component for ${this.name} has already been provided`);\n }\n\n this.component = component;\n\n // return early without attempting to initialize the component if the component requires explicit initialization (calling `Provider.initialize()`)\n if (!this.shouldAutoInitialize()) {\n return;\n }\n\n // if the service is eager, initialize the default instance\n if (isComponentEager(component)) {\n try {\n this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME });\n } catch (e) {\n // when the instance factory for an eager Component throws an exception during the eager\n // initialization, it should not cause a fatal error.\n // TODO: Investigate if we need to make it configurable, because some component may want to cause\n // a fatal error in this case?\n }\n }\n\n // Create service instances for the pending promises and resolve them\n // NOTE: if this.multipleInstances is false, only the default instance will be created\n // and all promises with resolve with it regardless of the identifier.\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n\n try {\n // `getOrInitializeService()` should always return a valid instance since a component is guaranteed. use ! to make typescript happy.\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n })!;\n instanceDeferred.resolve(instance);\n } catch (e) {\n // when the instance factory throws an exception, it should not cause\n // a fatal error. We just leave the promise unresolved.\n }\n }\n }\n\n clearInstance(identifier: string = DEFAULT_ENTRY_NAME): void {\n this.instancesDeferred.delete(identifier);\n this.instancesOptions.delete(identifier);\n this.instances.delete(identifier);\n }\n\n // app.delete() will call this method on every provider to delete the services\n // TODO: should we mark the provider as deleted?\n async delete(): Promise<void> {\n const services = Array.from(this.instances.values());\n\n await Promise.all([\n ...services\n .filter(service => 'INTERNAL' in service) // legacy services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any).INTERNAL!.delete()),\n ...services\n .filter(service => '_delete' in service) // modularized services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any)._delete())\n ]);\n }\n\n isComponentSet(): boolean {\n return this.component != null;\n }\n\n isInitialized(identifier: string = DEFAULT_ENTRY_NAME): boolean {\n return this.instances.has(identifier);\n }\n\n getOptions(identifier: string = DEFAULT_ENTRY_NAME): Record<string, unknown> {\n return this.instancesOptions.get(identifier) || {};\n }\n\n initialize(opts: InitializeOptions = {}): NameServiceMapping[T] {\n const { options = {} } = opts;\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n opts.instanceIdentifier\n );\n if (this.isInitialized(normalizedIdentifier)) {\n throw Error(\n `${this.name}(${normalizedIdentifier}) has already been initialized`\n );\n }\n\n if (!this.isComponentSet()) {\n throw Error(`Component ${this.name} has not been registered yet`);\n }\n\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier,\n options\n })!;\n\n // resolve any pending promise waiting for the service instance\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedDeferredIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n if (normalizedIdentifier === normalizedDeferredIdentifier) {\n instanceDeferred.resolve(instance);\n }\n }\n\n return instance;\n }\n\n /**\n *\n * @param callback - a function that will be invoked after the provider has been initialized by calling provider.initialize().\n * The function is invoked SYNCHRONOUSLY, so it should not execute any longrunning tasks in order to not block the program.\n *\n * @param identifier An optional instance identifier\n * @returns a function to unregister the callback\n */\n onInit(callback: OnInitCallBack<T>, identifier?: string): () => void {\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n const existingCallbacks =\n this.onInitCallbacks.get(normalizedIdentifier) ??\n new Set<OnInitCallBack<T>>();\n existingCallbacks.add(callback);\n this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks);\n\n const existingInstance = this.instances.get(normalizedIdentifier);\n if (existingInstance) {\n callback(existingInstance, normalizedIdentifier);\n }\n\n return () => {\n existingCallbacks.delete(callback);\n };\n }\n\n /**\n * Invoke onInit callbacks synchronously\n * @param instance the service instance`\n */\n private invokeOnInitCallbacks(\n instance: NameServiceMapping[T],\n identifier: string\n ): void {\n const callbacks = this.onInitCallbacks.get(identifier);\n if (!callbacks) {\n return;\n }\n for (const callback of callbacks) {\n try {\n callback(instance, identifier);\n } catch {\n // ignore errors in the onInit callback\n }\n }\n }\n\n private getOrInitializeService({\n instanceIdentifier,\n options = {}\n }: {\n instanceIdentifier: string;\n options?: Record<string, unknown>;\n }): NameServiceMapping[T] | null {\n let instance = this.instances.get(instanceIdentifier);\n if (!instance && this.component) {\n instance = this.component.instanceFactory(this.container, {\n instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier),\n options\n });\n this.instances.set(instanceIdentifier, instance);\n this.instancesOptions.set(instanceIdentifier, options);\n\n /**\n * Invoke onInit listeners.\n * Note this.component.onInstanceCreated is different, which is used by the component creator,\n * while onInit listeners are registered by consumers of the provider.\n */\n this.invokeOnInitCallbacks(instance, instanceIdentifier);\n\n /**\n * Order is important\n * onInstanceCreated() should be called after this.instances.set(instanceIdentifier, instance); which\n * makes `isInitialized()` return true.\n */\n if (this.component.onInstanceCreated) {\n try {\n this.component.onInstanceCreated(\n this.container,\n instanceIdentifier,\n instance\n );\n } catch {\n // ignore errors in the onInstanceCreatedCallback\n }\n }\n }\n\n return instance || null;\n }\n\n private normalizeInstanceIdentifier(\n identifier: string = DEFAULT_ENTRY_NAME\n ): string {\n if (this.component) {\n return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME;\n } else {\n return identifier; // assume multiple instances are supported before the component is provided.\n }\n }\n\n private shouldAutoInitialize(): boolean {\n return (\n !!this.component &&\n this.component.instantiationMode !== InstantiationMode.EXPLICIT\n );\n }\n}\n\n// undefined should be passed to the service factory for the default instance\nfunction normalizeIdentifierForFactory(identifier: string): string | undefined {\n return identifier === DEFAULT_ENTRY_NAME ? undefined : identifier;\n}\n\nfunction isComponentEager<T extends Name>(component: Component<T>): boolean {\n return component.instantiationMode === InstantiationMode.EAGER;\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 */\n\nimport { Provider } from './provider';\nimport { Component } from './component';\nimport { Name } from './types';\n\n/**\n * ComponentContainer that provides Providers for service name T, e.g. `auth`, `auth-internal`\n */\nexport class ComponentContainer {\n private readonly providers = new Map<string, Provider<Name>>();\n\n constructor(private readonly name: string) {}\n\n /**\n *\n * @param component Component being added\n * @param overwrite When a component with the same name has already been registered,\n * if overwrite is true: overwrite the existing component with the new component and create a new\n * provider with the new component. It can be useful in tests where you want to use different mocks\n * for different tests.\n * if overwrite is false: throw an exception\n */\n addComponent<T extends Name>(component: Component<T>): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n throw new Error(\n `Component ${component.name} has already been registered with ${this.name}`\n );\n }\n\n provider.setComponent(component);\n }\n\n addOrOverwriteComponent<T extends Name>(component: Component<T>): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n // delete the existing provider from the container, so we can register the new component\n this.providers.delete(component.name);\n }\n\n this.addComponent(component);\n }\n\n /**\n * getProvider provides a type safe interface where it can only be called with a field name\n * present in NameServiceMapping interface.\n *\n * Firebase SDKs providing services should extend NameServiceMapping interface to register\n * themselves.\n */\n getProvider<T extends Name>(name: T): Provider<T> {\n if (this.providers.has(name)) {\n return this.providers.get(name) as unknown as Provider<T>;\n }\n\n // create a Provider for a service that hasn't registered with Firebase\n const provider = new Provider<T>(name, this);\n this.providers.set(name, provider as unknown as Provider<Name>);\n\n return provider as Provider<T>;\n }\n\n getProviders(): Array<Provider<Name>> {\n return Array.from(this.providers.values());\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","const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst cursorRequestMap = new WeakMap();\nconst transactionDoneMap = new WeakMap();\nconst transactionStoreNamesMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n promise\n .then((value) => {\n // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval\n // (see wrapFunction).\n if (value instanceof IDBCursor) {\n cursorRequestMap.set(value, request);\n }\n // Catching to avoid \"Uncaught Promise exceptions\"\n })\n .catch(() => { });\n // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Polyfill for objectStoreNames because of Edge.\n if (prop === 'objectStoreNames') {\n return target.objectStoreNames || transactionStoreNamesMap.get(target);\n }\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Edge doesn't support objectStoreNames (booo), so we polyfill it here.\n if (func === IDBDatabase.prototype.transaction &&\n !('objectStoreNames' in IDBTransaction.prototype)) {\n return function (storeNames, ...args) {\n const tx = func.call(unwrap(this), storeNames, ...args);\n transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);\n return wrap(tx);\n };\n }\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(cursorRequestMap.get(this));\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\nexport { reverseTransformCache as a, instanceOfAny as i, replaceTraps as r, unwrap as u, wrap as w };\n","import { w as wrap, r as replaceTraps } from './wrap-idb-value.js';\nexport { u as unwrap, w as wrap } from './wrap-idb-value.js';\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);\n });\n }\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event.newVersion, event));\n }\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking) {\n db.addEventListener('versionchange', (event) => blocking(event.oldVersion, event.newVersion, event));\n }\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event));\n }\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nexport { deleteDB, openDB };\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 */\n\nimport {\n ComponentContainer,\n ComponentType,\n Provider,\n Name\n} from '@firebase/component';\nimport { PlatformLoggerService, VersionService } from './types';\n\nexport class PlatformLoggerServiceImpl implements PlatformLoggerService {\n constructor(private readonly container: ComponentContainer) {}\n // In initial implementation, this will be called by installations on\n // auth token refresh, and installations will send this string.\n getPlatformInfoString(): string {\n const providers = this.container.getProviders();\n // Loop through providers and get library/version pairs from any that are\n // version components.\n return providers\n .map(provider => {\n if (isVersionServiceProvider(provider)) {\n const service = provider.getImmediate() as VersionService;\n return `${service.library}/${service.version}`;\n } else {\n return null;\n }\n })\n .filter(logString => logString)\n .join(' ');\n }\n}\n/**\n *\n * @param provider check if this provider provides a VersionService\n *\n * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider\n * provides VersionService. The provider is not necessarily a 'app-version'\n * provider.\n */\nfunction isVersionServiceProvider(provider: Provider<Name>): boolean {\n const component = provider.getComponent();\n return component?.type === ComponentType.VERSION;\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 */\n\nimport { Logger } from '@firebase/logger';\n\nexport const logger = new Logger('@firebase/app');\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 */\n\nimport { name as appName } from '../package.json';\nimport { name as appCompatName } from '../../app-compat/package.json';\nimport { name as analyticsCompatName } from '../../../packages/analytics-compat/package.json';\nimport { name as analyticsName } from '../../../packages/analytics/package.json';\nimport { name as appCheckCompatName } from '../../../packages/app-check-compat/package.json';\nimport { name as appCheckName } from '../../../packages/app-check/package.json';\nimport { name as authName } from '../../../packages/auth/package.json';\nimport { name as authCompatName } from '../../../packages/auth-compat/package.json';\nimport { name as databaseName } from '../../../packages/database/package.json';\nimport { name as dataconnectName } from '../../../packages/data-connect/package.json';\nimport { name as databaseCompatName } from '../../../packages/database-compat/package.json';\nimport { name as functionsName } from '../../../packages/functions/package.json';\nimport { name as functionsCompatName } from '../../../packages/functions-compat/package.json';\nimport { name as installationsName } from '../../../packages/installations/package.json';\nimport { name as installationsCompatName } from '../../../packages/installations-compat/package.json';\nimport { name as messagingName } from '../../../packages/messaging/package.json';\nimport { name as messagingCompatName } from '../../../packages/messaging-compat/package.json';\nimport { name as performanceName } from '../../../packages/performance/package.json';\nimport { name as performanceCompatName } from '../../../packages/performance-compat/package.json';\nimport { name as remoteConfigName } from '../../../packages/remote-config/package.json';\nimport { name as remoteConfigCompatName } from '../../../packages/remote-config-compat/package.json';\nimport { name as storageName } from '../../../packages/storage/package.json';\nimport { name as storageCompatName } from '../../../packages/storage-compat/package.json';\nimport { name as firestoreName } from '../../../packages/firestore/package.json';\nimport { name as vertexName } from '../../../packages/vertexai/package.json';\nimport { name as firestoreCompatName } from '../../../packages/firestore-compat/package.json';\nimport { name as packageName } from '../../../packages/firebase/package.json';\n\n/**\n * The default app name\n *\n * @internal\n */\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n\nexport const PLATFORM_LOG_STRING = {\n [appName]: 'fire-core',\n [appCompatName]: 'fire-core-compat',\n [analyticsName]: 'fire-analytics',\n [analyticsCompatName]: 'fire-analytics-compat',\n [appCheckName]: 'fire-app-check',\n [appCheckCompatName]: 'fire-app-check-compat',\n [authName]: 'fire-auth',\n [authCompatName]: 'fire-auth-compat',\n [databaseName]: 'fire-rtdb',\n [dataconnectName]: 'fire-data-connect',\n [databaseCompatName]: 'fire-rtdb-compat',\n [functionsName]: 'fire-fn',\n [functionsCompatName]: 'fire-fn-compat',\n [installationsName]: 'fire-iid',\n [installationsCompatName]: 'fire-iid-compat',\n [messagingName]: 'fire-fcm',\n [messagingCompatName]: 'fire-fcm-compat',\n [performanceName]: 'fire-perf',\n [performanceCompatName]: 'fire-perf-compat',\n [remoteConfigName]: 'fire-rc',\n [remoteConfigCompatName]: 'fire-rc-compat',\n [storageName]: 'fire-gcs',\n [storageCompatName]: 'fire-gcs-compat',\n [firestoreName]: 'fire-fst',\n [firestoreCompatName]: 'fire-fst-compat',\n [vertexName]: 'fire-vertex',\n 'fire-js': 'fire-js', // Platform identifier for JS SDK.\n [packageName]: 'fire-js-all'\n} as const;\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 */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseServerApp\n} from './public-types';\nimport { Component, Provider, Name } from '@firebase/component';\nimport { logger } from './logger';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { FirebaseServerAppImpl } from './firebaseServerApp';\n\n/**\n * @internal\n */\nexport const _apps = new Map<string, FirebaseApp>();\n\n/**\n * @internal\n */\nexport const _serverApps = new Map<string, FirebaseServerApp>();\n\n/**\n * Registered components.\n *\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const _components = new Map<string, Component<any>>();\n\n/**\n * @param component - the component being added to this app's container\n *\n * @internal\n */\nexport function _addComponent<T extends Name>(\n app: FirebaseApp,\n component: Component<T>\n): void {\n try {\n (app as FirebaseAppImpl).container.addComponent(component);\n } catch (e) {\n logger.debug(\n `Component ${component.name} failed to register with FirebaseApp ${app.name}`,\n e\n );\n }\n}\n\n/**\n *\n * @internal\n */\nexport function _addOrOverwriteComponent(\n app: FirebaseApp,\n component: Component\n): void {\n (app as FirebaseAppImpl).container.addOrOverwriteComponent(component);\n}\n\n/**\n *\n * @param component - the component to register\n * @returns whether or not the component is registered successfully\n *\n * @internal\n */\nexport function _registerComponent<T extends Name>(\n component: Component<T>\n): boolean {\n const componentName = component.name;\n if (_components.has(componentName)) {\n logger.debug(\n `There were multiple attempts to register component ${componentName}.`\n );\n\n return false;\n }\n\n _components.set(componentName, component);\n\n // add the component to existing app instances\n for (const app of _apps.values()) {\n _addComponent(app as FirebaseAppImpl, component);\n }\n\n for (const serverApp of _serverApps.values()) {\n _addComponent(serverApp as FirebaseServerAppImpl, component);\n }\n\n return true;\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n *\n * @returns the provider for the service with the matching name\n *\n * @internal\n */\nexport function _getProvider<T extends Name>(\n app: FirebaseApp,\n name: T\n): Provider<T> {\n const heartbeatController = (app as FirebaseAppImpl).container\n .getProvider('heartbeat')\n .getImmediate({ optional: true });\n if (heartbeatController) {\n void heartbeatController.triggerHeartbeat();\n }\n return (app as FirebaseAppImpl).container.getProvider(name);\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n * @param instanceIdentifier - service instance identifier in case the service supports multiple instances\n *\n * @internal\n */\nexport function _removeServiceInstance<T extends Name>(\n app: FirebaseApp,\n name: T,\n instanceIdentifier: string = DEFAULT_ENTRY_NAME\n): void {\n _getProvider(app, name).clearInstance(instanceIdentifier);\n}\n\n/**\n *\n * @param obj - an object of type FirebaseApp or FirebaseOptions.\n *\n * @returns true if the provide object is of type FirebaseApp.\n *\n * @internal\n */\nexport function _isFirebaseApp(\n obj: FirebaseApp | FirebaseOptions\n): obj is FirebaseApp {\n return (obj as FirebaseApp).options !== undefined;\n}\n\n/**\n *\n * @param obj - an object of type FirebaseApp.\n *\n * @returns true if the provided object is of type FirebaseServerAppImpl.\n *\n * @internal\n */\nexport function _isFirebaseServerApp(\n obj: FirebaseApp | FirebaseServerApp\n): obj is FirebaseServerApp {\n return (obj as FirebaseServerApp).settings !== undefined;\n}\n\n/**\n * Test only\n *\n * @internal\n */\nexport function _clearComponents(): void {\n _components.clear();\n}\n\n/**\n * Exported in order to be used in app-compat package\n */\nexport { DEFAULT_ENTRY_NAME as _DEFAULT_ENTRY_NAME };\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 */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum AppError {\n NO_APP = 'no-app',\n BAD_APP_NAME = 'bad-app-name',\n DUPLICATE_APP = 'duplicate-app',\n APP_DELETED = 'app-deleted',\n SERVER_APP_DELETED = 'server-app-deleted',\n NO_OPTIONS = 'no-options',\n INVALID_APP_ARGUMENT = 'invalid-app-argument',\n INVALID_LOG_ARGUMENT = 'invalid-log-argument',\n IDB_OPEN = 'idb-open',\n IDB_GET = 'idb-get',\n IDB_WRITE = 'idb-set',\n IDB_DELETE = 'idb-delete',\n FINALIZATION_REGISTRY_NOT_SUPPORTED = 'finalization-registry-not-supported',\n INVALID_SERVER_APP_ENVIRONMENT = 'invalid-server-app-environment'\n}\n\nconst ERRORS: ErrorMap<AppError> = {\n [AppError.NO_APP]:\n \"No Firebase App '{$appName}' has been created - \" +\n 'call initializeApp() first',\n [AppError.BAD_APP_NAME]: \"Illegal App name: '{$appName}'\",\n [AppError.DUPLICATE_APP]:\n \"Firebase App named '{$appName}' already exists with different options or config\",\n [AppError.APP_DELETED]: \"Firebase App named '{$appName}' already deleted\",\n [AppError.SERVER_APP_DELETED]: 'Firebase Server App has been deleted',\n [AppError.NO_OPTIONS]:\n 'Need to provide options, when not being deployed to hosting via source.',\n [AppError.INVALID_APP_ARGUMENT]:\n 'firebase.{$appName}() takes either no argument or a ' +\n 'Firebase App instance.',\n [AppError.INVALID_LOG_ARGUMENT]:\n 'First argument to `onLog` must be null or a function.',\n [AppError.IDB_OPEN]:\n 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_GET]:\n 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_WRITE]:\n 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_DELETE]:\n 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.FINALIZATION_REGISTRY_NOT_SUPPORTED]:\n 'FirebaseServerApp deleteOnDeref field defined but the JS runtime does not support FinalizationRegistry.',\n [AppError.INVALID_SERVER_APP_ENVIRONMENT]:\n 'FirebaseServerApp is not for use in browser environments.'\n};\n\ninterface ErrorParams {\n [AppError.NO_APP]: { appName: string };\n [AppError.BAD_APP_NAME]: { appName: string };\n [AppError.DUPLICATE_APP]: { appName: string };\n [AppError.APP_DELETED]: { appName: string };\n [AppError.INVALID_APP_ARGUMENT]: { appName: string };\n [AppError.IDB_OPEN]: { originalErrorMessage?: string };\n [AppError.IDB_GET]: { originalErrorMessage?: string };\n [AppError.IDB_WRITE]: { originalErrorMessage?: string };\n [AppError.IDB_DELETE]: { originalErrorMessage?: string };\n [AppError.FINALIZATION_REGISTRY_NOT_SUPPORTED]: { appName?: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory<AppError, ErrorParams>(\n 'app',\n 'Firebase',\n ERRORS\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 */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport {\n ComponentContainer,\n Component,\n ComponentType\n} from '@firebase/component';\nimport { ERROR_FACTORY, AppError } from './errors';\n\nexport class FirebaseAppImpl implements FirebaseApp {\n protected readonly _options: FirebaseOptions;\n protected readonly _name: string;\n /**\n * Original config values passed in as a constructor parameter.\n * It is only used to compare with another config object to support idempotent initializeApp().\n *\n * Updating automaticDataCollectionEnabled on the App instance will not change its value in _config.\n */\n private readonly _config: Required<FirebaseAppSettings>;\n private _automaticDataCollectionEnabled: boolean;\n protected _isDeleted = false;\n private readonly _container: ComponentContainer;\n\n constructor(\n options: FirebaseOptions,\n config: Required<FirebaseAppSettings>,\n container: ComponentContainer\n ) {\n this._options = { ...options };\n this._config = { ...config };\n this._name = config.name;\n this._automaticDataCollectionEnabled =\n config.automaticDataCollectionEnabled;\n this._container = container;\n this.container.addComponent(\n new Component('app', () => this, ComponentType.PUBLIC)\n );\n }\n\n get automaticDataCollectionEnabled(): boolean {\n this.checkDestroyed();\n return this._automaticDataCollectionEnabled;\n }\n\n set automaticDataCollectionEnabled(val: boolean) {\n this.checkDestroyed();\n this._automaticDataCollectionEnabled = val;\n }\n\n get name(): string {\n this.checkDestroyed();\n return this._name;\n }\n\n get options(): FirebaseOptions {\n this.checkDestroyed();\n return this._options;\n }\n\n get config(): Required<FirebaseAppSettings> {\n this.checkDestroyed();\n return this._config;\n }\n\n get container(): ComponentContainer {\n return this._container;\n }\n\n get isDeleted(): boolean {\n return this._isDeleted;\n }\n\n set isDeleted(val: boolean) {\n this._isDeleted = val;\n }\n\n /**\n * This function will throw an Error if the App has already been deleted -\n * use before performing API actions on the App.\n */\n protected checkDestroyed(): void {\n if (this.isDeleted) {\n throw ERROR_FACTORY.create(AppError.APP_DELETED, { appName: this._name });\n }\n }\n}\n","/**\n * @license\n * Copyright 2023 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 FirebaseAppSettings,\n FirebaseServerApp,\n FirebaseServerAppSettings,\n FirebaseOptions\n} from './public-types';\nimport { deleteApp, registerVersion } from './api';\nimport { ComponentContainer } from '@firebase/component';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport { name as packageName, version } from '../package.json';\n\nexport class FirebaseServerAppImpl\n extends FirebaseAppImpl\n implements FirebaseServerApp\n{\n private readonly _serverConfig: FirebaseServerAppSettings;\n private _finalizationRegistry: FinalizationRegistry<object> | null;\n private _refCount: number;\n\n constructor(\n options: FirebaseOptions | FirebaseAppImpl,\n serverConfig: FirebaseServerAppSettings,\n name: string,\n container: ComponentContainer\n ) {\n // Build configuration parameters for the FirebaseAppImpl base class.\n const automaticDataCollectionEnabled =\n serverConfig.automaticDataCollectionEnabled !== undefined\n ? serverConfig.automaticDataCollectionEnabled\n : false;\n\n // Create the FirebaseAppSettings object for the FirebaseAppImp constructor.\n const config: Required<FirebaseAppSettings> = {\n name,\n automaticDataCollectionEnabled\n };\n\n if ((options as FirebaseOptions).apiKey !== undefined) {\n // Construct the parent FirebaseAppImp object.\n super(options as FirebaseOptions, config, container);\n } else {\n const appImpl: FirebaseAppImpl = options as FirebaseAppImpl;\n super(appImpl.options, config, container);\n }\n\n // Now construct the data for the FirebaseServerAppImpl.\n this._serverConfig = {\n automaticDataCollectionEnabled,\n ...serverConfig\n };\n\n this._finalizationRegistry = null;\n if (typeof FinalizationRegistry !== 'undefined') {\n this._finalizationRegistry = new FinalizationRegistry(() => {\n this.automaticCleanup();\n });\n }\n\n this._refCount = 0;\n this.incRefCount(this._serverConfig.releaseOnDeref);\n\n // Do not retain a hard reference to the dref object, otherwise the FinalizationRegistry\n // will never trigger.\n this._serverConfig.releaseOnDeref = undefined;\n serverConfig.releaseOnDeref = undefined;\n\n registerVersion(packageName, version, 'serverapp');\n }\n\n toJSON(): undefined {\n return undefined;\n }\n\n get refCount(): number {\n return this._refCount;\n }\n\n // Increment the reference count of this server app. If an object is provided, register it\n // with the finalization registry.\n incRefCount(obj: object | undefined): void {\n if (this.isDeleted) {\n return;\n }\n this._refCount++;\n if (obj !== undefined && this._finalizationRegistry !== null) {\n this._finalizationRegistry.register(obj, this);\n }\n }\n\n // Decrement the reference count.\n decRefCount(): number {\n if (this.isDeleted) {\n return 0;\n }\n return --this._refCount;\n }\n\n // Invoked by the FinalizationRegistry callback to note that this app should go through its\n // reference counts and delete itself if no reference count remain. The coordinating logic that\n // handles this is in deleteApp(...).\n private automaticCleanup(): void {\n void deleteApp(this);\n }\n\n get settings(): FirebaseServerAppSettings {\n this.checkDestroyed();\n return this._serverConfig;\n }\n\n /**\n * This function will throw an Error if the App has already been deleted -\n * use before performing API actions on the App.\n */\n protected checkDestroyed(): void {\n if (this.isDeleted) {\n throw ERROR_FACTORY.create(AppError.SERVER_APP_DELETED);\n }\n }\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 */\n\nimport {\n FirebaseApp,\n FirebaseServerApp,\n FirebaseOptions,\n FirebaseAppSettings,\n FirebaseServerAppSettings\n} from './public-types';\nimport { DEFAULT_ENTRY_NAME, PLATFORM_LOG_STRING } from './constants';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport {\n ComponentContainer,\n Component,\n Name,\n ComponentType\n} from '@firebase/component';\nimport { version } from '../../firebase/package.json';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { FirebaseServerAppImpl } from './firebaseServerApp';\nimport {\n _apps,\n _components,\n _isFirebaseApp,\n _registerComponent,\n _serverApps\n} from './internal';\nimport { logger } from './logger';\nimport {\n LogLevelString,\n setLogLevel as setLogLevelImpl,\n LogCallback,\n LogOptions,\n setUserLogHandler\n} from '@firebase/logger';\nimport {\n deepEqual,\n getDefaultAppConfig,\n isBrowser,\n isWebWorker\n} from '@firebase/util';\n\nexport { FirebaseError } from '@firebase/util';\n\n/**\n * The current SDK version.\n *\n * @public\n */\nexport const SDK_VERSION = version;\n\n/**\n * Creates and initializes a {@link @firebase/app#FirebaseApp} instance.\n *\n * See\n * {@link\n * https://firebase.google.com/docs/web/setup#add_firebase_to_your_app\n * | Add Firebase to your app} and\n * {@link\n * https://firebase.google.com/docs/web/setup#multiple-projects\n * | Initialize multiple projects} for detailed documentation.\n *\n * @example\n * ```javascript\n *\n * // Initialize default app\n * // Retrieve your own options values by adding a web app on\n * // https://console.firebase.google.com\n * initializeApp({\n * apiKey: \"AIza....\", // Auth / General Use\n * authDomain: \"YOUR_APP.firebaseapp.com\", // Auth with popup/redirect\n * databaseURL: \"https://YOUR_APP.firebaseio.com\", // Realtime Database\n * storageBucket: \"YOUR_APP.appspot.com\", // Storage\n * messagingSenderId: \"123456789\" // Cloud Messaging\n * });\n * ```\n *\n * @example\n * ```javascript\n *\n * // Initialize another app\n * const otherApp = initializeApp({\n * databaseURL: \"https://<OTHER_DATABASE_NAME>.firebaseio.com\",\n * storageBucket: \"<OTHER_STORAGE_BUCKET>.appspot.com\"\n * }, \"otherApp\");\n * ```\n *\n * @param options - Options to configure the app's services.\n * @param name - Optional name of the app to initialize. If no name\n * is provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The initialized app.\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n name?: string\n): FirebaseApp;\n/**\n * Creates and initializes a FirebaseApp instance.\n *\n * @param options - Options to configure the app's services.\n * @param config - FirebaseApp Configuration\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n config?: FirebaseAppSettings\n): FirebaseApp;\n/**\n * Creates and initializes a FirebaseApp instance.\n *\n * @public\n */\nexport function initializeApp(): FirebaseApp;\nexport function initializeApp(\n _options?: FirebaseOptions,\n rawConfig = {}\n): FirebaseApp {\n let options = _options;\n\n if (typeof rawConfig !== 'object') {\n const name = rawConfig;\n rawConfig = { name };\n }\n\n const config: Required<FirebaseAppSettings> = {\n name: DEFAULT_ENTRY_NAME,\n automaticDataCollectionEnabled: false,\n ...rawConfig\n };\n const name = config.name;\n\n if (typeof name !== 'string' || !name) {\n throw ERROR_FACTORY.create(AppError.BAD_APP_NAME, {\n appName: String(name)\n });\n }\n\n options ||= getDefaultAppConfig();\n\n if (!options) {\n throw ERROR_FACTORY.create(AppError.NO_OPTIONS);\n }\n\n const existingApp = _apps.get(name) as FirebaseAppImpl;\n if (existingApp) {\n // return the existing app if options and config deep equal the ones in the existing app.\n if (\n deepEqual(options, existingApp.options) &&\n deepEqual(config, existingApp.config)\n ) {\n return existingApp;\n } else {\n throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, { appName: name });\n }\n }\n\n const container = new ComponentContainer(name);\n for (const component of _components.values()) {\n container.addComponent(component);\n }\n\n const newApp = new FirebaseAppImpl(options, config, container);\n\n _apps.set(name, newApp);\n\n return newApp;\n}\n\n/**\n * Creates and initializes a {@link @firebase/app#FirebaseServerApp} instance.\n *\n * The `FirebaseServerApp` is similar to `FirebaseApp`, but is intended for execution in\n * server side rendering environments only. Initialization will fail if invoked from a\n * browser environment.\n *\n * See\n * {@link\n * https://firebase.google.com/docs/web/setup#add_firebase_to_your_app\n * | Add Firebase to your app} and\n * {@link\n * https://firebase.google.com/docs/web/setup#multiple-projects\n * | Initialize multiple projects} for detailed documentation.\n *\n * @example\n * ```javascript\n *\n * // Initialize an instance of `FirebaseServerApp`.\n * // Retrieve your own options values by adding a web app on\n * // https://console.firebase.google.com\n * initializeServerApp({\n * apiKey: \"AIza....\", // Auth / General Use\n * authDomain: \"YOUR_APP.firebaseapp.com\", // Auth with popup/redirect\n * databaseURL: \"https://YOUR_APP.firebaseio.com\", // Realtime Database\n * storageBucket: \"YOUR_APP.appspot.com\", // Storage\n * messagingSenderId: \"123456789\" // Cloud Messaging\n * },\n * {\n * authIdToken: \"Your Auth ID Token\"\n * });\n * ```\n *\n * @param options - `Firebase.AppOptions` to configure the app's services, or a\n * a `FirebaseApp` instance which contains the `AppOptions` within.\n * @param config - `FirebaseServerApp` configuration.\n *\n * @returns The initialized `FirebaseServerApp`.\n *\n * @public\n */\nexport function initializeServerApp(\n options: FirebaseOptions | FirebaseApp,\n config: FirebaseServerAppSettings\n): FirebaseServerApp;\n\nexport function initializeServerApp(\n _options: FirebaseOptions | FirebaseApp,\n _serverAppConfig: FirebaseServerAppSettings\n): FirebaseServerApp {\n if (isBrowser() && !isWebWorker()) {\n // FirebaseServerApp isn't designed to be run in browsers.\n throw ERROR_FACTORY.create(AppError.INVALID_SERVER_APP_ENVIRONMENT);\n }\n\n if (_serverAppConfig.automaticDataCollectionEnabled === undefined) {\n _serverAppConfig.automaticDataCollectionEnabled = false;\n }\n\n let appOptions: FirebaseOptions;\n if (_isFirebaseApp(_options)) {\n appOptions = _options.options;\n } else {\n appOptions = _options;\n }\n\n // Build an app name based on a hash of the configuration options.\n const nameObj = {\n ..._serverAppConfig,\n ...appOptions\n };\n\n // However, Do not mangle the name based on releaseOnDeref, since it will vary between the\n // construction of FirebaseServerApp instances. For example, if the object is the request headers.\n if (nameObj.releaseOnDeref !== undefined) {\n delete nameObj.releaseOnDeref;\n }\n\n const hashCode = (s: string): number => {\n return [...s].reduce(\n (hash, c) => (Math.imul(31, hash) + c.charCodeAt(0)) | 0,\n 0\n );\n };\n\n if (_serverAppConfig.releaseOnDeref !== undefined) {\n if (typeof FinalizationRegistry === 'undefined') {\n throw ERROR_FACTORY.create(\n AppError.FINALIZATION_REGISTRY_NOT_SUPPORTED,\n {}\n );\n }\n }\n\n const nameString = '' + hashCode(JSON.stringify(nameObj));\n const existingApp = _serverApps.get(nameString) as FirebaseServerApp;\n if (existingApp) {\n (existingApp as FirebaseServerAppImpl).incRefCount(\n _serverAppConfig.releaseOnDeref\n );\n return existingApp;\n }\n\n const container = new ComponentContainer(nameString);\n for (const component of _components.values()) {\n container.addComponent(component);\n }\n\n const newApp = new FirebaseServerAppImpl(\n appOptions,\n _serverAppConfig,\n nameString,\n container\n );\n\n _serverApps.set(nameString, newApp);\n\n return newApp;\n}\n\n/**\n * Retrieves a {@link @firebase/app#FirebaseApp} instance.\n *\n * When called with no arguments, the default app is returned. When an app name\n * is provided, the app corresponding to that name is returned.\n *\n * An exception is thrown if the app being retrieved has not yet been\n * initialized.\n *\n * @example\n * ```javascript\n * // Return the default app\n * const app = getApp();\n * ```\n *\n * @example\n * ```javascript\n * // Return a named app\n * const otherApp = getApp(\"otherApp\");\n * ```\n *\n * @param name - Optional name of the app to return. If no name is\n * provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The app corresponding to the provided app name.\n * If no app name is provided, the default app is returned.\n *\n * @public\n */\nexport function getApp(name: string = DEFAULT_ENTRY_NAME): FirebaseApp {\n const app = _apps.get(name);\n if (!app && name === DEFAULT_ENTRY_NAME && getDefaultAppConfig()) {\n return initializeApp();\n }\n if (!app) {\n throw ERROR_FACTORY.create(AppError.NO_APP, { appName: name });\n }\n\n return app;\n}\n\n/**\n * A (read-only) array of all initialized apps.\n * @public\n */\nexport function getApps(): FirebaseApp[] {\n return Array.from(_apps.values());\n}\n\n/**\n * Renders this app unusable and frees the resources of all associated\n * services.\n *\n * @example\n * ```javascript\n * deleteApp(app)\n * .then(function() {\n * console.log(\"App deleted successfully\");\n * })\n * .catch(function(error) {\n * console.log(\"Error deleting app:\", error);\n * });\n * ```\n *\n * @public\n */\nexport async function deleteApp(app: FirebaseApp): Promise<void> {\n let cleanupProviders = false;\n const name = app.name;\n if (_apps.has(name)) {\n cleanupProviders = true;\n _apps.delete(name);\n } else if (_serverApps.has(name)) {\n const firebaseServerApp = app as FirebaseServerAppImpl;\n if (firebaseServerApp.decRefCount() <= 0) {\n _serverApps.delete(name);\n cleanupProviders = true;\n }\n }\n\n if (cleanupProviders) {\n await Promise.all(\n (app as FirebaseAppImpl).container\n .getProviders()\n .map(provider => provider.delete())\n );\n (app as FirebaseAppImpl).isDeleted = true;\n }\n}\n\n/**\n * Registers a library's name and version for platform logging purposes.\n * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)\n * @param version - Current version of that library.\n * @param variant - Bundle variant, e.g., node, rn, etc.\n *\n * @public\n */\nexport function registerVersion(\n libraryKeyOrName: string,\n version: string,\n variant?: string\n): void {\n // TODO: We can use this check to whitelist strings when/if we set up\n // a good whitelist system.\n let library = PLATFORM_LOG_STRING[libraryKeyOrName] ?? libraryKeyOrName;\n if (variant) {\n library += `-${variant}`;\n }\n const libraryMismatch = library.match(/\\s|\\//);\n const versionMismatch = version.match(/\\s|\\//);\n if (libraryMismatch || versionMismatch) {\n const warning = [\n `Unable to register library \"${library}\" with version \"${version}\":`\n ];\n if (libraryMismatch) {\n warning.push(\n `library name \"${library}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n if (libraryMismatch && versionMismatch) {\n warning.push('and');\n }\n if (versionMismatch) {\n warning.push(\n `version name \"${version}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n logger.warn(warning.join(' '));\n return;\n }\n _registerComponent(\n new Component(\n `${library}-version` as Name,\n () => ({ library, version }),\n ComponentType.VERSION\n )\n );\n}\n\n/**\n * Sets log handler for all Firebase SDKs.\n * @param logCallback - An optional custom log handler that executes user code whenever\n * the Firebase SDK makes a logging call.\n *\n * @public\n */\nexport function onLog(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n if (logCallback !== null && typeof logCallback !== 'function') {\n throw ERROR_FACTORY.create(AppError.INVALID_LOG_ARGUMENT);\n }\n setUserLogHandler(logCallback, options);\n}\n\n/**\n * Sets log level for all Firebase SDKs.\n *\n * All of the log types above the current log level are captured (i.e. if\n * you set the log level to `info`, errors are logged, but `debug` and\n * `verbose` logs are not).\n *\n * @public\n */\nexport function setLogLevel(logLevel: LogLevelString): void {\n setLogLevelImpl(logLevel);\n}\n","/**\n * @license\n * Copyright 2021 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';\nimport { DBSchema, openDB, IDBPDatabase } from 'idb';\nimport { AppError, ERROR_FACTORY } from './errors';\nimport { FirebaseApp } from './public-types';\nimport { HeartbeatsInIndexedDB } from './types';\nimport { logger } from './logger';\n\nconst DB_NAME = 'firebase-heartbeat-database';\nconst DB_VERSION = 1;\nconst STORE_NAME = 'firebase-heartbeat-store';\n\ninterface AppDB extends DBSchema {\n 'firebase-heartbeat-store': {\n key: string;\n value: HeartbeatsInIndexedDB;\n };\n}\n\nlet dbPromise: Promise<IDBPDatabase<AppDB>> | null = null;\nfunction getDbPromise(): Promise<IDBPDatabase<AppDB>> {\n if (!dbPromise) {\n dbPromise = openDB<AppDB>(DB_NAME, DB_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n try {\n db.createObjectStore(STORE_NAME);\n } catch (e) {\n // Safari/iOS browsers throw occasional exceptions on\n // db.createObjectStore() that may be a bug. Avoid blocking\n // the rest of the app functionality.\n console.warn(e);\n }\n }\n }\n }).catch(e => {\n throw ERROR_FACTORY.create(AppError.IDB_OPEN, {\n originalErrorMessage: e.message\n });\n });\n }\n return dbPromise;\n}\n\nexport async function readHeartbeatsFromIndexedDB(\n app: FirebaseApp\n): Promise<HeartbeatsInIndexedDB | undefined> {\n try {\n const db = await getDbPromise();\n const tx = db.transaction(STORE_NAME);\n const result = await tx.objectStore(STORE_NAME).get(computeKey(app));\n // We already have the value but tx.done can throw,\n // so we need to await it here to catch errors\n await tx.done;\n return result;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_GET, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nexport async function writeHeartbeatsToIndexedDB(\n app: FirebaseApp,\n heartbeatObject: HeartbeatsInIndexedDB\n): Promise<void> {\n try {\n const db = await getDbPromise();\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(STORE_NAME);\n await objectStore.put(heartbeatObject, computeKey(app));\n await tx.done;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_WRITE, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nfunction computeKey(app: FirebaseApp): string {\n return `${app.name}!${app.options.appId}`;\n}\n","/**\n * @license\n * Copyright 2021 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 { ComponentContainer } from '@firebase/component';\nimport {\n base64urlEncodeWithoutPadding,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\nimport {\n readHeartbeatsFromIndexedDB,\n writeHeartbeatsToIndexedDB\n} from './indexeddb';\nimport { FirebaseApp } from './public-types';\nimport {\n HeartbeatsByUserAgent,\n HeartbeatService,\n HeartbeatsInIndexedDB,\n HeartbeatStorage,\n SingleDateHeartbeat\n} from './types';\nimport { logger } from './logger';\n\nconst MAX_HEADER_BYTES = 1024;\n// 30 days\nconst STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1000;\n\nexport class HeartbeatServiceImpl implements HeartbeatService {\n /**\n * The persistence layer for heartbeats\n * Leave public for easier testing.\n */\n _storage: HeartbeatStorageImpl;\n\n /**\n * In-memory cache for heartbeats, used by getHeartbeatsHeader() to generate\n * the header string.\n * Stores one record per date. This will be consolidated into the standard\n * format of one record per user agent string before being sent as a header.\n * Populated from indexedDB when the controller is instantiated and should\n * be kept in sync with indexedDB.\n * Leave public for easier testing.\n */\n _heartbeatsCache: HeartbeatsInIndexedDB | null = null;\n\n /**\n * the initialization promise for populating heartbeatCache.\n * If getHeartbeatsHeader() is called before the promise resolves\n * (heartbeatsCache == null), it should wait for this promise\n * Leave public for easier testing.\n */\n _heartbeatsCachePromise: Promise<HeartbeatsInIndexedDB>;\n constructor(private readonly container: ComponentContainer) {\n const app = this.container.getProvider('app').getImmediate();\n this._storage = new HeartbeatStorageImpl(app);\n this._heartbeatsCachePromise = this._storage.read().then(result => {\n this._heartbeatsCache = result;\n return result;\n });\n }\n\n /**\n * Called to report a heartbeat. The function will generate\n * a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it\n * to IndexedDB.\n * Note that we only store one heartbeat per day. So if a heartbeat for today is\n * already logged, subsequent calls to this function in the same day will be ignored.\n */\n async triggerHeartbeat(): Promise<void> {\n try {\n const platformLogger = this.container\n .getProvider('platform-logger')\n .getImmediate();\n\n // This is the \"Firebase user agent\" string from the platform logger\n // service, not the browser user agent.\n const agent = platformLogger.getPlatformInfoString();\n const date = getUTCDateString();\n if (this._heartbeatsCache?.heartbeats == null) {\n this._heartbeatsCache = await this._heartbeatsCachePromise;\n // If we failed to construct a heartbeats cache, then return immediately.\n if (this._heartbeatsCache?.heartbeats == null) {\n return;\n }\n }\n // Do not store a heartbeat if one is already stored for this day\n // or if a header has already been sent today.\n if (\n this._heartbeatsCache.lastSentHeartbeatDate === date ||\n this._heartbeatsCache.heartbeats.some(\n singleDateHeartbeat => singleDateHeartbeat.date === date\n )\n ) {\n return;\n } else {\n // There is no entry for this date. Create one.\n this._heartbeatsCache.heartbeats.push({ date, agent });\n }\n // Remove entries older than 30 days.\n this._heartbeatsCache.heartbeats =\n this._heartbeatsCache.heartbeats.filter(singleDateHeartbeat => {\n const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();\n const now = Date.now();\n return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;\n });\n return this._storage.overwrite(this._heartbeatsCache);\n } catch (e) {\n logger.warn(e);\n }\n }\n\n /**\n * Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.\n * It also clears all heartbeats from memory as well as in IndexedDB.\n *\n * NOTE: Consuming product SDKs should not send the header if this method\n * returns an empty string.\n */\n async getHeartbeatsHeader(): Promise<string> {\n try {\n if (this._heartbeatsCache === null) {\n await this._heartbeatsCachePromise;\n }\n // If it's still null or the array is empty, there is no data to send.\n if (\n this._heartbeatsCache?.heartbeats == null ||\n this._heartbeatsCache.heartbeats.length === 0\n ) {\n return '';\n }\n const date = getUTCDateString();\n // Extract as many heartbeats from the cache as will fit under the size limit.\n const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(\n this._heartbeatsCache.heartbeats\n );\n const headerString = base64urlEncodeWithoutPadding(\n JSON.stringify({ version: 2, heartbeats: heartbeatsToSend })\n );\n // Store last sent date to prevent another being logged/sent for the same day.\n this._heartbeatsCache.lastSentHeartbeatDate = date;\n if (unsentEntries.length > 0) {\n // Store any unsent entries if they exist.\n this._heartbeatsCache.heartbeats = unsentEntries;\n // This seems more likely than emptying the array (below) to lead to some odd state\n // since the cache isn't empty and this will be called again on the next request,\n // and is probably safest if we await it.\n await this._storage.overwrite(this._heartbeatsCache);\n } else {\n this._heartbeatsCache.heartbeats = [];\n // Do not wait for this, to reduce latency.\n void this._storage.overwrite(this._heartbeatsCache);\n }\n return headerString;\n } catch (e) {\n logger.warn(e);\n return '';\n }\n }\n}\n\nfunction getUTCDateString(): string {\n const today = new Date();\n // Returns date format 'YYYY-MM-DD'\n return today.toISOString().substring(0, 10);\n}\n\nexport function extractHeartbeatsForHeader(\n heartbeatsCache: SingleDateHeartbeat[],\n maxSize = MAX_HEADER_BYTES\n): {\n heartbeatsToSend: HeartbeatsByUserAgent[];\n unsentEntries: SingleDateHeartbeat[];\n} {\n // Heartbeats grouped by user agent in the standard format to be sent in\n // the header.\n const heartbeatsToSend: HeartbeatsByUserAgent[] = [];\n // Single date format heartbeats that are not sent.\n let unsentEntries = heartbeatsCache.slice();\n for (const singleDateHeartbeat of heartbeatsCache) {\n // Look for an existing entry with the same user agent.\n const heartbeatEntry = heartbeatsToSend.find(\n hb => hb.agent === singleDateHeartbeat.agent\n );\n if (!heartbeatEntry) {\n // If no entry for this user agent exists, create one.\n heartbeatsToSend.push({\n agent: singleDateHeartbeat.agent,\n dates: [singleDateHeartbeat.date]\n });\n if (countBytes(heartbeatsToSend) > maxSize) {\n // If the header would exceed max size, remove the added heartbeat\n // entry and stop adding to the header.\n heartbeatsToSend.pop();\n break;\n }\n } else {\n heartbeatEntry.dates.push(singleDateHeartbeat.date);\n // If the header would exceed max size, remove the added date\n // and stop adding to the header.\n if (countBytes(heartbeatsToSend) > maxSize) {\n heartbeatEntry.dates.pop();\n break;\n }\n }\n // Pop unsent entry from queue. (Skipped if adding the entry exceeded\n // quota and the loop breaks early.)\n unsentEntries = unsentEntries.slice(1);\n }\n return {\n heartbeatsToSend,\n unsentEntries\n };\n}\n\nexport class HeartbeatStorageImpl implements HeartbeatStorage {\n private _canUseIndexedDBPromise: Promise<boolean>;\n constructor(public app: FirebaseApp) {\n this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck();\n }\n async runIndexedDBEnvironmentCheck(): Promise<boolean> {\n if (!isIndexedDBAvailable()) {\n return false;\n } else {\n return validateIndexedDBOpenable()\n .then(() => true)\n .catch(() => false);\n }\n }\n /**\n * Read all heartbeats.\n */\n async read(): Promise<HeartbeatsInIndexedDB> {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return { heartbeats: [] };\n } else {\n const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app);\n if (idbHeartbeatObject?.heartbeats) {\n return idbHeartbeatObject;\n } else {\n return { heartbeats: [] };\n }\n }\n }\n // overwrite the storage with the provided heartbeats\n async overwrite(heartbeatsObject: HeartbeatsInIndexedDB): Promise<void> {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: heartbeatsObject.heartbeats\n });\n }\n }\n // add heartbeats\n async add(heartbeatsObject: HeartbeatsInIndexedDB): Promise<void> {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: [\n ...existingHeartbeatsObject.heartbeats,\n ...heartbeatsObject.heartbeats\n ]\n });\n }\n }\n}\n\n/**\n * Calculate bytes of a HeartbeatsByUserAgent array after being wrapped\n * in a platform logging header JSON object, stringified, and converted\n * to base 64.\n */\nexport function countBytes(heartbeatsCache: HeartbeatsByUserAgent[]): number {\n // base64 has a restricted set of characters, all of which should be 1 byte.\n return base64urlEncodeWithoutPadding(\n // heartbeatsCache wrapper properties\n JSON.stringify({ version: 2, heartbeats: heartbeatsCache })\n ).length;\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 */\n\nimport { Component, ComponentType } from '@firebase/component';\nimport { PlatformLoggerServiceImpl } from './platformLoggerService';\nimport { name, version } from '../package.json';\nimport { _registerComponent } from './internal';\nimport { registerVersion } from './api';\nimport { HeartbeatServiceImpl } from './heartbeatService';\n\nexport function registerCoreComponents(variant?: string): void {\n _registerComponent(\n new Component(\n 'platform-logger',\n container => new PlatformLoggerServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n _registerComponent(\n new Component(\n 'heartbeat',\n container => new HeartbeatServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n\n // Register `app` package.\n registerVersion(name, version, variant);\n // BUILD_TARGET will be replaced by values like esm2017, cjs2017, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n // Register platform SDK identifier (no version).\n registerVersion('fire-js', '');\n}\n","/**\n * Firebase App\n *\n * @remarks This package coordinates the communication between the different Firebase components\n * @packageDocumentation\n */\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 */\n\nimport { registerCoreComponents } from './registerCoreComponents';\n\nexport * from './api';\nexport * from './internal';\nexport * from './public-types';\n\nregisterCoreComponents('__RUNTIME_ENV__');\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 */\n\nimport { FirebaseApp, FirebaseOptions } from '../public-types';\nimport { _FirebaseNamespace, _FirebaseService } from '../types';\nimport {\n deleteApp,\n _addComponent,\n _DEFAULT_ENTRY_NAME,\n _FirebaseAppInternal as FirebaseAppExp\n} from '@firebase/app';\nimport { Component, ComponentType, Name } from '@firebase/component';\nimport { Compat } from '@firebase/util';\n\n/**\n * Global context object for a collection of services using\n * a shared authentication state.\n */\nexport class FirebaseAppLiteImpl\n implements FirebaseApp, Compat<FirebaseAppExp>\n{\n constructor(\n readonly _delegate: FirebaseAppExp,\n private readonly firebase: _FirebaseNamespace\n ) {\n // add itself to container\n _addComponent(\n _delegate,\n new Component('app-compat', () => this, ComponentType.PUBLIC)\n );\n }\n\n get automaticDataCollectionEnabled(): boolean {\n return this._delegate.automaticDataCollectionEnabled;\n }\n\n set automaticDataCollectionEnabled(val) {\n this.automaticDataCollectionEnabled = val;\n }\n\n get name(): string {\n return this._delegate.name;\n }\n\n get options(): FirebaseOptions {\n return this._delegate.options;\n }\n\n delete(): Promise<void> {\n this.firebase.INTERNAL.removeApp(this.name);\n return deleteApp(this._delegate);\n }\n\n /**\n * Return a service instance associated with this app (creating it\n * on demand), identified by the passed instanceIdentifier.\n *\n * NOTE: Currently storage is the only one that is leveraging this\n * functionality. They invoke it by calling:\n *\n * ```javascript\n * firebase.app().storage('STORAGE BUCKET ID')\n * ```\n *\n * The service name is passed to this already\n * @internal\n */\n _getService(\n name: string,\n instanceIdentifier: string = _DEFAULT_ENTRY_NAME\n ): _FirebaseService {\n this._delegate.checkDestroyed();\n\n // getImmediate will always succeed because _getService is only called for registered components.\n return this._delegate.container.getProvider(name as Name).getImmediate({\n identifier: instanceIdentifier\n }) as unknown as _FirebaseService;\n }\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 */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum AppError {\n NO_APP = 'no-app',\n INVALID_APP_ARGUMENT = 'invalid-app-argument'\n}\n\nconst ERRORS: ErrorMap<AppError> = {\n [AppError.NO_APP]:\n \"No Firebase App '{$appName}' has been created - \" +\n 'call Firebase App.initializeApp()',\n [AppError.INVALID_APP_ARGUMENT]:\n 'firebase.{$appName}() takes either no argument or a ' +\n 'Firebase App instance.'\n};\n\ntype ErrorParams = { [key in AppError]: { appName: string } };\n\nexport const ERROR_FACTORY = new ErrorFactory<AppError, ErrorParams>(\n 'app-compat',\n 'Firebase',\n ERRORS\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 */\n\nimport { FirebaseApp, FirebaseOptions } from './public-types';\nimport {\n _FirebaseNamespace,\n _FirebaseService,\n FirebaseServiceNamespace\n} from './types';\nimport * as modularAPIs from '@firebase/app';\nimport { _FirebaseAppInternal as _FirebaseAppExp } from '@firebase/app';\nimport { Component, ComponentType, Name } from '@firebase/component';\n\nimport { deepExtend, contains } from '@firebase/util';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport { FirebaseAppLiteImpl } from './lite/firebaseAppLite';\n\n/**\n * Because auth can't share code with other components, we attach the utility functions\n * in an internal namespace to share code.\n * This function return a firebase namespace object without\n * any utility functions, so it can be shared between the regular firebaseNamespace and\n * the lite version.\n */\nexport function createFirebaseNamespaceCore(\n firebaseAppImpl: typeof FirebaseAppImpl | typeof FirebaseAppLiteImpl\n): _FirebaseNamespace {\n const apps: { [name: string]: FirebaseApp } = {};\n // // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // const components = new Map<string, Component<any>>();\n\n // A namespace is a plain JavaScript Object.\n const namespace: _FirebaseNamespace = {\n // Hack to prevent Babel from modifying the object returned\n // as the firebase namespace.\n // @ts-ignore\n __esModule: true,\n initializeApp: initializeAppCompat,\n // @ts-ignore\n app,\n registerVersion: modularAPIs.registerVersion,\n setLogLevel: modularAPIs.setLogLevel,\n onLog: modularAPIs.onLog,\n // @ts-ignore\n apps: null,\n SDK_VERSION: modularAPIs.SDK_VERSION,\n INTERNAL: {\n registerComponent: registerComponentCompat,\n removeApp,\n useAsService,\n modularAPIs\n }\n };\n\n // Inject a circular default export to allow Babel users who were previously\n // using:\n //\n // import firebase from 'firebase';\n // which becomes: var firebase = require('firebase').default;\n //\n // instead of\n //\n // import * as firebase from 'firebase';\n // which becomes: var firebase = require('firebase');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (namespace as any)['default'] = namespace;\n\n // firebase.apps is a read-only getter.\n Object.defineProperty(namespace, 'apps', {\n get: getApps\n });\n\n /**\n * Called by App.delete() - but before any services associated with the App\n * are deleted.\n */\n function removeApp(name: string): void {\n delete apps[name];\n }\n\n /**\n * Get the App object for a given name (or DEFAULT).\n */\n function app(name?: string): FirebaseApp {\n name = name || modularAPIs._DEFAULT_ENTRY_NAME;\n if (!contains(apps, name)) {\n throw ERROR_FACTORY.create(AppError.NO_APP, { appName: name });\n }\n return apps[name];\n }\n\n // @ts-ignore\n app['App'] = firebaseAppImpl;\n\n /**\n * Create a new App instance (name must be unique).\n *\n * This function is idempotent. It can be called more than once and return the same instance using the same options and config.\n */\n function initializeAppCompat(\n options: FirebaseOptions,\n rawConfig = {}\n ): FirebaseApp {\n const app = modularAPIs.initializeApp(\n options,\n rawConfig\n ) as _FirebaseAppExp;\n\n if (contains(apps, app.name)) {\n return apps[app.name];\n }\n\n const appCompat = new firebaseAppImpl(app, namespace);\n apps[app.name] = appCompat;\n return appCompat;\n }\n\n /*\n * Return an array of all the non-deleted FirebaseApps.\n */\n function getApps(): FirebaseApp[] {\n // Make a copy so caller cannot mutate the apps list.\n return Object.keys(apps).map(name => apps[name]);\n }\n\n function registerComponentCompat<T extends Name>(\n component: Component<T>\n ): FirebaseServiceNamespace<_FirebaseService> | null {\n const componentName = component.name;\n const componentNameWithoutCompat = componentName.replace('-compat', '');\n if (\n modularAPIs._registerComponent(component) &&\n component.type === ComponentType.PUBLIC\n ) {\n // create service namespace for public components\n // The Service namespace is an accessor function ...\n const serviceNamespace = (\n appArg: FirebaseApp = app()\n ): _FirebaseService => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (typeof (appArg as any)[componentNameWithoutCompat] !== 'function') {\n // Invalid argument.\n // This happens in the following case: firebase.storage('gs:/')\n throw ERROR_FACTORY.create(AppError.INVALID_APP_ARGUMENT, {\n appName: componentName\n });\n }\n\n // Forward service instance lookup to the FirebaseApp.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (appArg as any)[componentNameWithoutCompat]();\n };\n\n // ... and a container for service-level properties.\n if (component.serviceProps !== undefined) {\n deepExtend(serviceNamespace, component.serviceProps);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (namespace as any)[componentNameWithoutCompat] = serviceNamespace;\n\n // Patch the FirebaseAppImpl prototype\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (firebaseAppImpl.prototype as any)[componentNameWithoutCompat] =\n // TODO: The eslint disable can be removed and the 'ignoreRestArgs'\n // option added to the no-explicit-any rule when ESlint releases it.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function (...args: any) {\n const serviceFxn = this._getService.bind(this, componentName);\n return serviceFxn.apply(\n this,\n component.multipleInstances ? args : []\n );\n };\n }\n\n return component.type === ComponentType.PUBLIC\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (namespace as any)[componentNameWithoutCompat]\n : null;\n }\n\n // Map the requested service to a registered service name\n // (used to map auth to serverAuth service when needed).\n function useAsService(app: FirebaseApp, name: string): string | null {\n if (name === 'serverAuth') {\n return null;\n }\n\n const useService = name;\n\n return useService;\n }\n\n return namespace;\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 */\n\nimport { createFirebaseNamespaceLite } from './lite/firebaseNamespaceLite';\nimport { registerCoreComponents } from './registerCoreComponents';\n\nconst firebase = createFirebaseNamespaceLite();\n\nregisterCoreComponents('lite');\n\n// eslint-disable-next-line import/no-default-export\nexport default firebase;\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 */\n\nimport { FirebaseNamespace } from '../public-types';\nimport { FirebaseServiceNamespace, _FirebaseService } from '../types';\nimport { FirebaseAppLiteImpl } from './firebaseAppLite';\nimport { createFirebaseNamespaceCore } from '../firebaseNamespaceCore';\nimport { Component, ComponentType } from '@firebase/component';\n\nexport function createFirebaseNamespaceLite(): FirebaseNamespace {\n const namespace = createFirebaseNamespaceCore(FirebaseAppLiteImpl);\n\n namespace.SDK_VERSION = `${namespace.SDK_VERSION}_LITE`;\n\n const registerComponent = namespace.INTERNAL.registerComponent;\n namespace.INTERNAL.registerComponent = registerComponentForLite;\n\n /**\n * This is a special implementation, so it only works with performance.\n * only allow performance SDK to register.\n */\n function registerComponentForLite(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n component: Component<any>\n ): FirebaseServiceNamespace<_FirebaseService> | null {\n // only allow performance to register with firebase lite\n if (\n component.type === ComponentType.PUBLIC &&\n !component.name.includes('performance') &&\n !component.name.includes('installations')\n ) {\n throw Error(`${name} cannot register with the standalone perf instance`);\n }\n\n return registerComponent(component);\n }\n\n return namespace;\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 */\n\nimport { registerVersion } from '@firebase/app';\n\nimport { name, version } from '../package.json';\n\nexport function registerCoreComponents(variant?: string): void {\n // Register `app` package.\n registerVersion(name, version, variant);\n}\n","/**\n * @license\n * Copyright 2020 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 firebase from '@firebase/app-compat';\nimport { name, version } from '../../package.json';\n\nfirebase.registerVersion(name, version, 'app-compat');\n\nexport default firebase;\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 */\n\nimport { version } from '../../package.json';\n\nexport const PENDING_TIMEOUT_MS = 10000;\n\nexport const PACKAGE_VERSION = `w:${version}`;\nexport const INTERNAL_AUTH_VERSION = 'FIS_v2';\n\nexport const INSTALLATIONS_API_URL =\n 'https://firebaseinstallations.googleapis.com/v1';\n\nexport const TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour\n\nexport const SERVICE = 'installations';\nexport const SERVICE_NAME = 'Installations';\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 */\n\nimport { ErrorFactory, FirebaseError } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from './constants';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n NOT_REGISTERED = 'not-registered',\n INSTALLATION_NOT_FOUND = 'installation-not-found',\n REQUEST_FAILED = 'request-failed',\n APP_OFFLINE = 'app-offline',\n DELETE_PENDING_REGISTRATION = 'delete-pending-registration'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.NOT_REGISTERED]: 'Firebase Installation is not registered.',\n [ErrorCode.INSTALLATION_NOT_FOUND]: 'Firebase Installation not found.',\n [ErrorCode.REQUEST_FAILED]:\n '{$requestName} request failed with error \"{$serverCode} {$serverStatus}: {$serverMessage}\"',\n [ErrorCode.APP_OFFLINE]: 'Could not process request. Application offline.',\n [ErrorCode.DELETE_PENDING_REGISTRATION]:\n \"Can't delete installation while there is a pending registration request.\"\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.REQUEST_FAILED]: {\n requestName: string;\n [index: string]: string | number; // to make TypeScript 3.8 happy\n } & ServerErrorData;\n}\n\nexport const ERROR_FACTORY = new ErrorFactory<ErrorCode, ErrorParams>(\n SERVICE,\n SERVICE_NAME,\n ERROR_DESCRIPTION_MAP\n);\n\nexport interface ServerErrorData {\n serverCode: number;\n serverMessage: string;\n serverStatus: string;\n}\n\nexport type ServerError = FirebaseError & { customData: ServerErrorData };\n\n/** Returns true if error is a FirebaseError that is based on an error from the server. */\nexport function isServerError(error: unknown): error is ServerError {\n return (\n error instanceof FirebaseError &&\n error.code.includes(ErrorCode.REQUEST_FAILED)\n );\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 */\n\nimport { FirebaseError } from '@firebase/util';\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport {\n INSTALLATIONS_API_URL,\n INTERNAL_AUTH_VERSION\n} from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { AppConfig } from '../interfaces/installation-impl';\n\nexport function getInstallationsEndpoint({ projectId }: AppConfig): string {\n return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`;\n}\n\nexport function extractAuthTokenInfoFromResponse(\n response: GenerateAuthTokenResponse\n): CompletedAuthToken {\n return {\n token: response.token,\n requestStatus: RequestStatus.COMPLETED,\n expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),\n creationTime: Date.now()\n };\n}\n\nexport async function getErrorFromResponse(\n requestName: string,\n response: Response\n): Promise<FirebaseError> {\n const responseJson: ErrorResponse = await response.json();\n const errorData = responseJson.error;\n return ERROR_FACTORY.create(ErrorCode.REQUEST_FAILED, {\n requestName,\n serverCode: errorData.code,\n serverMessage: errorData.message,\n serverStatus: errorData.status\n });\n}\n\nexport function getHeaders({ apiKey }: AppConfig): Headers {\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': apiKey\n });\n}\n\nexport function getHeadersWithAuth(\n appConfig: AppConfig,\n { refreshToken }: RegisteredInstallationEntry\n): Headers {\n const headers = getHeaders(appConfig);\n headers.append('Authorization', getAuthorizationHeader(refreshToken));\n return headers;\n}\n\nexport interface ErrorResponse {\n error: {\n code: number;\n message: string;\n status: string;\n };\n}\n\n/**\n * Calls the passed in fetch wrapper and returns the response.\n * If the returned response has a status of 5xx, re-runs the function once and\n * returns the response.\n */\nexport async function retryIfServerError(\n fn: () => Promise<Response>\n): Promise<Response> {\n const result = await fn();\n\n if (result.status >= 500 && result.status < 600) {\n // Internal Server Error. Retry request.\n return fn();\n }\n\n return result;\n}\n\nfunction getExpiresInFromResponseExpiresIn(responseExpiresIn: string): number {\n // This works because the server will never respond with fractions of a second.\n return Number(responseExpiresIn.replace('s', '000'));\n}\n\nfunction getAuthorizationHeader(refreshToken: string): string {\n return `${INTERNAL_AUTH_VERSION} ${refreshToken}`;\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 */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise<void> {\n return new Promise<void>(resolve => {\n setTimeout(resolve, ms);\n });\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 */\n\nimport { bufferToBase64UrlSafe } from './buffer-to-base64-url-safe';\n\nexport const VALID_FID_PATTERN = /^[cdef][\\w-]{21}$/;\nexport const INVALID_FID = '';\n\n/**\n * Generates a new FID using random values from Web Crypto API.\n * Returns an empty string if FID generation fails for any reason.\n */\nexport function generateFid(): string {\n try {\n // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5\n // bytes. our implementation generates a 17 byte array instead.\n const fidByteArray = new Uint8Array(17);\n const crypto =\n self.crypto || (self as unknown as { msCrypto: Crypto }).msCrypto;\n crypto.getRandomValues(fidByteArray);\n\n // Replace the first 4 random bits with the constant FID header of 0b0111.\n fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000);\n\n const fid = encode(fidByteArray);\n\n return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;\n } catch {\n // FID generation errored\n return INVALID_FID;\n }\n}\n\n/** Converts a FID Uint8Array to a base64 string representation. */\nfunction encode(fidByteArray: Uint8Array): string {\n const b64String = bufferToBase64UrlSafe(fidByteArray);\n\n // Remove the 23rd character that was added because of the extra 4 bits at the\n // end of our 17 byte array, and the '=' padding.\n return b64String.substr(0, 22);\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 */\n\nexport function bufferToBase64UrlSafe(array: Uint8Array): string {\n const b64 = btoa(String.fromCharCode(...array));\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_');\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 */\n\nimport { AppConfig } from '../interfaces/installation-impl';\n\n/** Returns a string key that can be used to identify the app. */\nexport function getKey(appConfig: AppConfig): string {\n return `${appConfig.appName}!${appConfig.appId}`;\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 */\n\nimport { getKey } from '../util/get-key';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { IdChangeCallbackFn } from '../api';\n\nconst fidChangeCallbacks: Map<string, Set<IdChangeCallbackFn>> = new Map();\n\n/**\n * Calls the onIdChange callbacks with the new FID value, and broadcasts the\n * change to other tabs.\n */\nexport function fidChanged(appConfig: AppConfig, fid: string): void {\n const key = getKey(appConfig);\n\n callFidChangeCallbacks(key, fid);\n broadcastFidChange(key, fid);\n}\n\nexport function addCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n // Open the broadcast channel if it's not already open,\n // to be able to listen to change events from other tabs.\n getBroadcastChannel();\n\n const key = getKey(appConfig);\n\n let callbackSet = fidChangeCallbacks.get(key);\n if (!callbackSet) {\n callbackSet = new Set();\n fidChangeCallbacks.set(key, callbackSet);\n }\n callbackSet.add(callback);\n}\n\nexport function removeCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n const key = getKey(appConfig);\n\n const callbackSet = fidChangeCallbacks.get(key);\n\n if (!callbackSet) {\n return;\n }\n\n callbackSet.delete(callback);\n if (callbackSet.size === 0) {\n fidChangeCallbacks.delete(key);\n }\n\n // Close broadcast channel if there are no more callbacks.\n closeBroadcastChannel();\n}\n\nfunction callFidChangeCallbacks(key: string, fid: string): void {\n const callbacks = fidChangeCallbacks.get(key);\n if (!callbacks) {\n return;\n }\n\n for (const callback of callbacks) {\n callback(fid);\n }\n}\n\nfunction broadcastFidChange(key: string, fid: string): void {\n const channel = getBroadcastChannel();\n if (channel) {\n channel.postMessage({ key, fid });\n }\n closeBroadcastChannel();\n}\n\nlet broadcastChannel: BroadcastChannel | null = null;\n/** Opens and returns a BroadcastChannel if it is supported by the browser. */\nfunction getBroadcastChannel(): BroadcastChannel | null {\n if (!broadcastChannel && 'BroadcastChannel' in self) {\n broadcastChannel = new BroadcastChannel('[Firebase] FID Change');\n broadcastChannel.onmessage = e => {\n callFidChangeCallbacks(e.data.key, e.data.fid);\n };\n }\n return broadcastChannel;\n}\n\nfunction closeBroadcastChannel(): void {\n if (fidChangeCallbacks.size === 0 && broadcastChannel) {\n broadcastChannel.close();\n broadcastChannel = null;\n }\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 */\n\nimport { DBSchema, IDBPDatabase, openDB } from 'idb';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { InstallationEntry } from '../interfaces/installation-entry';\nimport { getKey } from '../util/get-key';\nimport { fidChanged } from './fid-changed';\n\nconst DATABASE_NAME = 'firebase-installations-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-installations-store';\n\ninterface InstallationsDB extends DBSchema {\n 'firebase-installations-store': {\n key: string;\n value: InstallationEntry | undefined;\n };\n}\n\nlet dbPromise: Promise<IDBPDatabase<InstallationsDB>> | null = null;\nfunction getDbPromise(): Promise<IDBPDatabase<InstallationsDB>> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function get(\n appConfig: AppConfig\n): Promise<InstallationEntry | undefined> {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n return db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key) as Promise<InstallationEntry>;\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function set<ValueType extends InstallationEntry>(\n appConfig: AppConfig,\n value: ValueType\n): Promise<ValueType> {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue = (await objectStore.get(key)) as InstallationEntry;\n await objectStore.put(value, key);\n await tx.done;\n\n if (!oldValue || oldValue.fid !== value.fid) {\n fidChanged(appConfig, value.fid);\n }\n\n return value;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function remove(appConfig: AppConfig): Promise<void> {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/**\n * Atomically updates a record with the result of updateFn, which gets\n * called with the current value. If newValue is undefined, the record is\n * deleted instead.\n * @return Updated value\n */\nexport async function update<ValueType extends InstallationEntry | undefined>(\n appConfig: AppConfig,\n updateFn: (previousValue: InstallationEntry | undefined) => ValueType\n): Promise<ValueType> {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const store = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue: InstallationEntry | undefined = (await store.get(\n key\n )) as InstallationEntry;\n const newValue = updateFn(oldValue);\n\n if (newValue === undefined) {\n await store.delete(key);\n } else {\n await store.put(newValue, key);\n }\n await tx.done;\n\n if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {\n fidChanged(appConfig, newValue.fid);\n }\n\n return newValue;\n}\n\nexport async function clear(): Promise<void> {\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).clear();\n await tx.done;\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 */\n\nimport { createInstallationRequest } from '../functions/create-installation-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n InProgressInstallationEntry,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { generateFid, INVALID_FID } from './generate-fid';\nimport { remove, set, update } from './idb-manager';\n\nexport interface InstallationEntryWithRegistrationPromise {\n installationEntry: InstallationEntry;\n /** Exist iff the installationEntry is not registered. */\n registrationPromise?: Promise<RegisteredInstallationEntry>;\n}\n\n/**\n * Updates and returns the InstallationEntry from the database.\n * Also triggers a registration request if it is necessary and possible.\n */\nexport async function getInstallationEntry(\n installations: FirebaseInstallationsImpl\n): Promise<InstallationEntryWithRegistrationPromise> {\n let registrationPromise: Promise<RegisteredInstallationEntry> | undefined;\n\n const installationEntry = await update(installations.appConfig, oldEntry => {\n const installationEntry = updateOrCreateInstallationEntry(oldEntry);\n const entryWithPromise = triggerRegistrationIfNecessary(\n installations,\n installationEntry\n );\n registrationPromise = entryWithPromise.registrationPromise;\n return entryWithPromise.installationEntry;\n });\n\n if (installationEntry.fid === INVALID_FID) {\n // FID generation failed. Waiting for the FID from the server.\n return { installationEntry: await registrationPromise! };\n }\n\n return {\n installationEntry,\n registrationPromise\n };\n}\n\n/**\n * Creates a new Installation Entry if one does not exist.\n * Also clears timed out pending requests.\n */\nfunction updateOrCreateInstallationEntry(\n oldEntry: InstallationEntry | undefined\n): InstallationEntry {\n const entry: InstallationEntry = oldEntry || {\n fid: generateFid(),\n registrationStatus: RequestStatus.NOT_STARTED\n };\n\n return clearTimedOutRequest(entry);\n}\n\n/**\n * If the Firebase Installation is not registered yet, this will trigger the\n * registration and return an InProgressInstallationEntry.\n *\n * If registrationPromise does not exist, the installationEntry is guaranteed\n * to be registered.\n */\nfunction triggerRegistrationIfNecessary(\n installations: FirebaseInstallationsImpl,\n installationEntry: InstallationEntry\n): InstallationEntryWithRegistrationPromise {\n if (installationEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n if (!navigator.onLine) {\n // Registration required but app is offline.\n const registrationPromiseWithError = Promise.reject(\n ERROR_FACTORY.create(ErrorCode.APP_OFFLINE)\n );\n return {\n installationEntry,\n registrationPromise: registrationPromiseWithError\n };\n }\n\n // Try registering. Change status to IN_PROGRESS.\n const inProgressEntry: InProgressInstallationEntry = {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.IN_PROGRESS,\n registrationTime: Date.now()\n };\n const registrationPromise = registerInstallation(\n installations,\n inProgressEntry\n );\n return { installationEntry: inProgressEntry, registrationPromise };\n } else if (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS\n ) {\n return {\n installationEntry,\n registrationPromise: waitUntilFidRegistration(installations)\n };\n } else {\n return { installationEntry };\n }\n}\n\n/** This will be executed only once for each new Firebase Installation. */\nasync function registerInstallation(\n installations: FirebaseInstallationsImpl,\n installationEntry: InProgressInstallationEntry\n): Promise<RegisteredInstallationEntry> {\n try {\n const registeredInstallationEntry = await createInstallationRequest(\n installations,\n installationEntry\n );\n return set(installations.appConfig, registeredInstallationEntry);\n } catch (e) {\n if (isServerError(e) && e.customData.serverCode === 409) {\n // Server returned a \"FID cannot be used\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n // Registration failed. Set FID as not registered.\n await set(installations.appConfig, {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n });\n }\n throw e;\n }\n}\n\n/** Call if FID registration is pending in another request. */\nasync function waitUntilFidRegistration(\n installations: FirebaseInstallationsImpl\n): Promise<RegisteredInstallationEntry> {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry: InstallationEntry = await updateInstallationRequest(\n installations.appConfig\n );\n while (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // createInstallation request still in progress.\n await sleep(100);\n\n entry = await updateInstallationRequest(installations.appConfig);\n }\n\n if (entry.registrationStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n const { installationEntry, registrationPromise } =\n await getInstallationEntry(installations);\n\n if (registrationPromise) {\n return registrationPromise;\n } else {\n // if there is no registrationPromise, entry is registered.\n return installationEntry as RegisteredInstallationEntry;\n }\n }\n\n return entry;\n}\n\n/**\n * Called only if there is a CreateInstallation request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * CreateInstallation request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateInstallationRequest(\n appConfig: AppConfig\n): Promise<InstallationEntry> {\n return update(appConfig, oldEntry => {\n if (!oldEntry) {\n throw ERROR_FACTORY.create(ErrorCode.INSTALLATION_NOT_FOUND);\n }\n return clearTimedOutRequest(oldEntry);\n });\n}\n\nfunction clearTimedOutRequest(entry: InstallationEntry): InstallationEntry {\n if (hasInstallationRequestTimedOut(entry)) {\n return {\n fid: entry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n };\n }\n\n return entry;\n}\n\nfunction hasInstallationRequestTimedOut(\n installationEntry: InstallationEntry\n): boolean {\n return (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS &&\n installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now()\n );\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 */\n\nimport { CreateInstallationResponse } from '../interfaces/api-response';\nimport {\n InProgressInstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { INTERNAL_AUTH_VERSION, PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeaders,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\n\nexport async function createInstallationRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n { fid }: InProgressInstallationEntry\n): Promise<RegisteredInstallationEntry> {\n const endpoint = getInstallationsEndpoint(appConfig);\n\n const headers = getHeaders(appConfig);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n fid,\n authVersion: INTERNAL_AUTH_VERSION,\n appId: appConfig.appId,\n sdkVersion: PACKAGE_VERSION\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: CreateInstallationResponse = await response.json();\n const registeredInstallationEntry: RegisteredInstallationEntry = {\n fid: responseValue.fid || fid,\n registrationStatus: RequestStatus.COMPLETED,\n refreshToken: responseValue.refreshToken,\n authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)\n };\n return registeredInstallationEntry;\n } else {\n throw await getErrorFromResponse('Create Installation', response);\n }\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 */\n\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry\n} from '../interfaces/installation-entry';\nimport { PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport {\n FirebaseInstallationsImpl,\n AppConfig\n} from '../interfaces/installation-impl';\n\nexport async function generateAuthTokenRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise<CompletedAuthToken> {\n const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n installation: {\n sdkVersion: PACKAGE_VERSION,\n appId: appConfig.appId\n }\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: GenerateAuthTokenResponse = await response.json();\n const completedAuthToken: CompletedAuthToken =\n extractAuthTokenInfoFromResponse(responseValue);\n return completedAuthToken;\n } else {\n throw await getErrorFromResponse('Generate Auth Token', response);\n }\n}\n\nfunction getGenerateAuthTokenEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`;\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 */\n\nimport { generateAuthTokenRequest } from '../functions/generate-auth-token-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n AuthToken,\n CompletedAuthToken,\n InProgressAuthToken,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS, TOKEN_EXPIRATION_BUFFER } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { remove, set, update } from './idb-manager';\n\n/**\n * Returns a valid authentication token for the installation. Generates a new\n * token if one doesn't exist, is expired or about to expire.\n *\n * Should only be called if the Firebase Installation is registered.\n */\nexport async function refreshAuthToken(\n installations: FirebaseInstallationsImpl,\n forceRefresh = false\n): Promise<CompletedAuthToken> {\n let tokenPromise: Promise<CompletedAuthToken> | undefined;\n const entry = await update(installations.appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {\n // There is a valid token in the DB.\n return oldEntry;\n } else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // There already is a token request in progress.\n tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);\n return oldEntry;\n } else {\n // No token or token expired.\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n }\n\n const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);\n tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);\n return inProgressEntry;\n }\n });\n\n const authToken = tokenPromise\n ? await tokenPromise\n : (entry.authToken as CompletedAuthToken);\n return authToken;\n}\n\n/**\n * Call only if FID is registered and Auth Token request is in progress.\n *\n * Waits until the current pending request finishes. If the request times out,\n * tries once in this thread as well.\n */\nasync function waitUntilAuthTokenRequest(\n installations: FirebaseInstallationsImpl,\n forceRefresh: boolean\n): Promise<CompletedAuthToken> {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry = await updateAuthTokenRequest(installations.appConfig);\n while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // generateAuthToken still in progress.\n await sleep(100);\n\n entry = await updateAuthTokenRequest(installations.appConfig);\n }\n\n const authToken = entry.authToken;\n if (authToken.requestStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n return refreshAuthToken(installations, forceRefresh);\n } else {\n return authToken;\n }\n}\n\n/**\n * Called only if there is a GenerateAuthToken request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * GenerateAuthToken request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateAuthTokenRequest(\n appConfig: AppConfig\n): Promise<RegisteredInstallationEntry> {\n return update(appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (hasAuthTokenRequestTimedOut(oldAuthToken)) {\n return {\n ...oldEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n }\n\n return oldEntry;\n });\n}\n\nasync function fetchAuthTokenFromServer(\n installations: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise<CompletedAuthToken> {\n try {\n const authToken = await generateAuthTokenRequest(\n installations,\n installationEntry\n );\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken\n };\n await set(installations.appConfig, updatedInstallationEntry);\n return authToken;\n } catch (e) {\n if (\n isServerError(e) &&\n (e.customData.serverCode === 401 || e.customData.serverCode === 404)\n ) {\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n await set(installations.appConfig, updatedInstallationEntry);\n }\n throw e;\n }\n}\n\nfunction isEntryRegistered(\n installationEntry: InstallationEntry | undefined\n): installationEntry is RegisteredInstallationEntry {\n return (\n installationEntry !== undefined &&\n installationEntry.registrationStatus === RequestStatus.COMPLETED\n );\n}\n\nfunction isAuthTokenValid(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.COMPLETED &&\n !isAuthTokenExpired(authToken)\n );\n}\n\nfunction isAuthTokenExpired(authToken: CompletedAuthToken): boolean {\n const now = Date.now();\n return (\n now < authToken.creationTime ||\n authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER\n );\n}\n\n/** Returns an updated InstallationEntry with an InProgressAuthToken. */\nfunction makeAuthTokenRequestInProgressEntry(\n oldEntry: RegisteredInstallationEntry\n): RegisteredInstallationEntry {\n const inProgressAuthToken: InProgressAuthToken = {\n requestStatus: RequestStatus.IN_PROGRESS,\n requestTime: Date.now()\n };\n return {\n ...oldEntry,\n authToken: inProgressAuthToken\n };\n}\n\nfunction hasAuthTokenRequestTimedOut(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.IN_PROGRESS &&\n authToken.requestTime + PENDING_TIMEOUT_MS < Date.now()\n );\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 */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns a Firebase Installations auth token, identifying the current\n * Firebase Installation.\n * @param installations - The `Installations` instance.\n * @param forceRefresh - Force refresh regardless of token expiration.\n *\n * @public\n */\nexport async function getToken(\n installations: Installations,\n forceRefresh = false\n): Promise<string> {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n await completeInstallationRegistration(installationsImpl);\n\n // At this point we either have a Registered Installation in the DB, or we've\n // already thrown an error.\n const authToken = await refreshAuthToken(installationsImpl, forceRefresh);\n return authToken.token;\n}\n\nasync function completeInstallationRegistration(\n installations: FirebaseInstallationsImpl\n): Promise<void> {\n const { registrationPromise } = await getInstallationEntry(installations);\n\n if (registrationPromise) {\n // A createInstallation request is in progress. Wait until it finishes.\n await registrationPromise;\n }\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 */\n\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: Array<keyof FirebaseOptions> = [\n 'projectId',\n 'apiKey',\n 'appId'\n ];\n\n for (const keyName of configKeys) {\n if (!app.options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: app.options.projectId!,\n apiKey: app.options.apiKey!,\n appId: app.options.appId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n","/**\n * @license\n * Copyright 2020 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 { _registerComponent, _getProvider } from '@firebase/app';\nimport {\n Component,\n ComponentType,\n InstanceFactory,\n ComponentContainer\n} from '@firebase/component';\nimport { getId, getToken } from '../api/index';\nimport { _FirebaseInstallationsInternal } from '../interfaces/public-types';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { extractAppConfig } from '../helpers/extract-app-config';\n\nconst INSTALLATIONS_NAME = 'installations';\nconst INSTALLATIONS_NAME_INTERNAL = 'installations-internal';\n\nconst publicFactory: InstanceFactory<'installations'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Throws if app isn't configured properly.\n const appConfig = extractAppConfig(app);\n const heartbeatServiceProvider = _getProvider(app, 'heartbeat');\n\n const installationsImpl: FirebaseInstallationsImpl = {\n app,\n appConfig,\n heartbeatServiceProvider,\n _delete: () => Promise.resolve()\n };\n return installationsImpl;\n};\n\nconst internalFactory: InstanceFactory<'installations-internal'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Internal FIS instance relies on public FIS instance.\n const installations = _getProvider(app, INSTALLATIONS_NAME).getImmediate();\n\n const installationsInternal: _FirebaseInstallationsInternal = {\n getId: () => getId(installations),\n getToken: (forceRefresh?: boolean) => getToken(installations, forceRefresh)\n };\n return installationsInternal;\n};\n\nexport function registerInstallations(): void {\n _registerComponent(\n new Component(INSTALLATIONS_NAME, publicFactory, ComponentType.PUBLIC)\n );\n _registerComponent(\n new Component(\n INSTALLATIONS_NAME_INTERNAL,\n internalFactory,\n ComponentType.PRIVATE\n )\n );\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 */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Creates a Firebase Installation if there isn't one for the app and\n * returns the Installation ID.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function getId(installations: Installations): Promise<string> {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n const { installationEntry, registrationPromise } = await getInstallationEntry(\n installationsImpl\n );\n\n if (registrationPromise) {\n registrationPromise.catch(console.error);\n } else {\n // If the installation is already registered, update the authentication\n // token if needed.\n refreshAuthToken(installationsImpl).catch(console.error);\n }\n\n return installationEntry.fid;\n}\n","/**\n * The Firebase Installations Web SDK.\n * This SDK does not work in a Node.js environment.\n *\n * @packageDocumentation\n */\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 */\n\nimport { registerInstallations } from './functions/config';\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nexport * from './api';\nexport * from './interfaces/public-types';\n\nregisterInstallations();\nregisterVersion(name, version);\n// BUILD_TARGET will be replaced by values like esm2017, cjs2017, etc during the compilation\nregisterVersion(name, version, '__BUILD_TARGET__');\n","/**\n * @license\n * Copyright 2020 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 { version } from '../package.json';\n\nexport const SDK_VERSION = version;\n/** The prefix for start User Timing marks used for creating Traces. */\nexport const TRACE_START_MARK_PREFIX = 'FB-PERF-TRACE-START';\n/** The prefix for stop User Timing marks used for creating Traces. */\nexport const TRACE_STOP_MARK_PREFIX = 'FB-PERF-TRACE-STOP';\n/** The prefix for User Timing measure used for creating Traces. */\nexport const TRACE_MEASURE_PREFIX = 'FB-PERF-TRACE-MEASURE';\n/** The prefix for out of the box page load Trace name. */\nexport const OOB_TRACE_PAGE_LOAD_PREFIX = '_wt_';\n\nexport const FIRST_PAINT_COUNTER_NAME = '_fp';\n\nexport const FIRST_CONTENTFUL_PAINT_COUNTER_NAME = '_fcp';\n\nexport const FIRST_INPUT_DELAY_COUNTER_NAME = '_fid';\n\nexport const CONFIG_LOCAL_STORAGE_KEY = '@firebase/performance/config';\n\nexport const CONFIG_EXPIRY_LOCAL_STORAGE_KEY =\n '@firebase/performance/configexpire';\n\nexport const SERVICE = 'performance';\nexport const SERVICE_NAME = 'Performance';\n","/**\n * @license\n * Copyright 2020 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 { ErrorFactory } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from '../constants';\n\nexport const enum ErrorCode {\n TRACE_STARTED_BEFORE = 'trace started',\n TRACE_STOPPED_BEFORE = 'trace stopped',\n NONPOSITIVE_TRACE_START_TIME = 'nonpositive trace startTime',\n NONPOSITIVE_TRACE_DURATION = 'nonpositive trace duration',\n NO_WINDOW = 'no window',\n NO_APP_ID = 'no app id',\n NO_PROJECT_ID = 'no project id',\n NO_API_KEY = 'no api key',\n INVALID_CC_LOG = 'invalid cc log',\n FB_NOT_DEFAULT = 'FB not default',\n RC_NOT_OK = 'RC response not ok',\n INVALID_ATTRIBUTE_NAME = 'invalid attribute name',\n INVALID_ATTRIBUTE_VALUE = 'invalid attribute value',\n INVALID_CUSTOM_METRIC_NAME = 'invalid custom metric name',\n INVALID_STRING_MERGER_PARAMETER = 'invalid String merger input',\n ALREADY_INITIALIZED = 'already initialized'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n [ErrorCode.TRACE_STARTED_BEFORE]: 'Trace {$traceName} was started before.',\n [ErrorCode.TRACE_STOPPED_BEFORE]: 'Trace {$traceName} is not running.',\n [ErrorCode.NONPOSITIVE_TRACE_START_TIME]:\n 'Trace {$traceName} startTime should be positive.',\n [ErrorCode.NONPOSITIVE_TRACE_DURATION]:\n 'Trace {$traceName} duration should be positive.',\n [ErrorCode.NO_WINDOW]: 'Window is not available.',\n [ErrorCode.NO_APP_ID]: 'App id is not available.',\n [ErrorCode.NO_PROJECT_ID]: 'Project id is not available.',\n [ErrorCode.NO_API_KEY]: 'Api key is not available.',\n [ErrorCode.INVALID_CC_LOG]: 'Attempted to queue invalid cc event',\n [ErrorCode.FB_NOT_DEFAULT]:\n 'Performance can only start when Firebase app instance is the default one.',\n [ErrorCode.RC_NOT_OK]: 'RC response is not ok',\n [ErrorCode.INVALID_ATTRIBUTE_NAME]:\n 'Attribute name {$attributeName} is invalid.',\n [ErrorCode.INVALID_ATTRIBUTE_VALUE]:\n 'Attribute value {$attributeValue} is invalid.',\n [ErrorCode.INVALID_CUSTOM_METRIC_NAME]:\n 'Custom metric name {$customMetricName} is invalid',\n [ErrorCode.INVALID_STRING_MERGER_PARAMETER]:\n 'Input for String merger is invalid, contact support team to resolve.',\n [ErrorCode.ALREADY_INITIALIZED]:\n 'initializePerformance() has already been called with ' +\n 'different options. To avoid this error, call initializePerformance() with the ' +\n 'same options as when it was originally called, or call getPerformance() to return the' +\n ' already initialized instance.'\n};\n\ninterface ErrorParams {\n [ErrorCode.TRACE_STARTED_BEFORE]: { traceName: string };\n [ErrorCode.TRACE_STOPPED_BEFORE]: { traceName: string };\n [ErrorCode.NONPOSITIVE_TRACE_START_TIME]: { traceName: string };\n [ErrorCode.NONPOSITIVE_TRACE_DURATION]: { traceName: string };\n [ErrorCode.INVALID_ATTRIBUTE_NAME]: { attributeName: string };\n [ErrorCode.INVALID_ATTRIBUTE_VALUE]: { attributeValue: string };\n [ErrorCode.INVALID_CUSTOM_METRIC_NAME]: { customMetricName: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory<ErrorCode, ErrorParams>(\n SERVICE,\n SERVICE_NAME,\n ERROR_DESCRIPTION_MAP\n);\n","/**\n * @license\n * Copyright 2020 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 { Logger, LogLevel } from '@firebase/logger';\nimport { SERVICE_NAME } from '../constants';\n\nexport const consoleLogger = new Logger(SERVICE_NAME);\nconsoleLogger.logLevel = LogLevel.INFO;\n","/**\n * @license\n * Copyright 2020 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 { ERROR_FACTORY, ErrorCode } from '../utils/errors';\nimport { isIndexedDBAvailable, areCookiesEnabled } from '@firebase/util';\nimport { consoleLogger } from '../utils/console_logger';\n\ndeclare global {\n interface Window {\n PerformanceObserver: typeof PerformanceObserver;\n perfMetrics?: { onFirstInputDelay(fn: (fid: number) => void): void };\n }\n}\n\nlet apiInstance: Api | undefined;\nlet windowInstance: Window | undefined;\n\nexport type EntryType =\n | 'mark'\n | 'measure'\n | 'paint'\n | 'resource'\n | 'frame'\n | 'navigation';\n\n/**\n * This class holds a reference to various browser related objects injected by\n * set methods.\n */\nexport class Api {\n private readonly performance: Performance;\n /** PerformanceObserver constructor function. */\n private readonly PerformanceObserver: typeof PerformanceObserver;\n private readonly windowLocation: Location;\n readonly onFirstInputDelay?: (fn: (fid: number) => void) => void;\n readonly localStorage?: Storage;\n readonly document: Document;\n readonly navigator: Navigator;\n\n constructor(readonly window?: Window) {\n if (!window) {\n throw ERROR_FACTORY.create(ErrorCode.NO_WINDOW);\n }\n this.performance = window.performance;\n this.PerformanceObserver = window.PerformanceObserver;\n this.windowLocation = window.location;\n this.navigator = window.navigator;\n this.document = window.document;\n if (this.navigator && this.navigator.cookieEnabled) {\n // If user blocks cookies on the browser, accessing localStorage will\n // throw an exception.\n this.localStorage = window.localStorage;\n }\n if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) {\n this.onFirstInputDelay = window.perfMetrics.onFirstInputDelay;\n }\n }\n\n getUrl(): string {\n // Do not capture the string query part of url.\n return this.windowLocation.href.split('?')[0];\n }\n\n mark(name: string): void {\n if (!this.performance || !this.performance.mark) {\n return;\n }\n this.performance.mark(name);\n }\n\n measure(measureName: string, mark1: string, mark2: string): void {\n if (!this.performance || !this.performance.measure) {\n return;\n }\n this.performance.measure(measureName, mark1, mark2);\n }\n\n getEntriesByType(type: EntryType): PerformanceEntry[] {\n if (!this.performance || !this.performance.getEntriesByType) {\n return [];\n }\n return this.performance.getEntriesByType(type);\n }\n\n getEntriesByName(name: string): PerformanceEntry[] {\n if (!this.performance || !this.performance.getEntriesByName) {\n return [];\n }\n return this.performance.getEntriesByName(name);\n }\n\n getTimeOrigin(): number {\n // Polyfill the time origin with performance.timing.navigationStart.\n return (\n this.performance &&\n (this.performance.timeOrigin || this.performance.timing.navigationStart)\n );\n }\n\n requiredApisAvailable(): boolean {\n if (!fetch || !Promise || !areCookiesEnabled()) {\n consoleLogger.info(\n 'Firebase Performance cannot start if browser does not support fetch and Promise or cookie is disabled.'\n );\n return false;\n }\n\n if (!isIndexedDBAvailable()) {\n consoleLogger.info('IndexedDB is not supported by current browser');\n return false;\n }\n return true;\n }\n\n setupObserver(\n entryType: EntryType,\n callback: (entry: PerformanceEntry) => void\n ): void {\n if (!this.PerformanceObserver) {\n return;\n }\n const observer = new this.PerformanceObserver(list => {\n for (const entry of list.getEntries()) {\n // `entry` is a PerformanceEntry instance.\n callback(entry);\n }\n });\n\n // Start observing the entry types you care about.\n observer.observe({ entryTypes: [entryType] });\n }\n\n static getInstance(): Api {\n if (apiInstance === undefined) {\n apiInstance = new Api(windowInstance);\n }\n return apiInstance;\n }\n}\n\nexport function setupApi(window: Window): void {\n windowInstance = window;\n}\n","/**\n * @license\n * Copyright 2020 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 { _FirebaseInstallationsInternal } from '@firebase/installations';\n\nlet iid: string | undefined;\nlet authToken: string | undefined;\n\nexport function getIidPromise(\n installationsService: _FirebaseInstallationsInternal\n): Promise<string> {\n const iidPromise = installationsService.getId();\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n iidPromise.then((iidVal: string) => {\n iid = iidVal;\n });\n return iidPromise;\n}\n\n// This method should be used after the iid is retrieved by getIidPromise method.\nexport function getIid(): string | undefined {\n return iid;\n}\n\nexport function getAuthTokenPromise(\n installationsService: _FirebaseInstallationsInternal\n): Promise<string> {\n const authTokenPromise = installationsService.getToken();\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n authTokenPromise.then((authTokenVal: string) => {\n authToken = authTokenVal;\n });\n return authTokenPromise;\n}\n\nexport function getAuthenticationToken(): string | undefined {\n return authToken;\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 */\n\nimport { mergeStrings } from '../utils/string_merger';\n\nlet settingsServiceInstance: SettingsService | undefined;\n\nexport class SettingsService {\n // The variable which controls logging of automatic traces and HTTP/S network monitoring.\n instrumentationEnabled = true;\n\n // The variable which controls logging of custom traces.\n dataCollectionEnabled = true;\n\n // Configuration flags set through remote config.\n loggingEnabled = false;\n // Sampling rate between 0 and 1.\n tracesSamplingRate = 1;\n networkRequestsSamplingRate = 1;\n\n // Address of logging service.\n logEndPointUrl =\n 'https://firebaselogging.googleapis.com/v0cc/log?format=json_proto';\n // Performance event transport endpoint URL which should be compatible with proto3.\n // New Address for transport service, not configurable via Remote Config.\n flTransportEndpointUrl = mergeStrings(\n 'hts/frbslgigp.ogepscmv/ieo/eaylg',\n 'tp:/ieaeogn-agolai.o/1frlglgc/o'\n );\n\n transportKey = mergeStrings('AzSC8r6ReiGqFMyfvgow', 'Iayx0u-XT3vksVM-pIV');\n\n // Source type for performance event logs.\n logSource = 462;\n\n // Flags which control per session logging of traces and network requests.\n logTraceAfterSampling = false;\n logNetworkAfterSampling = false;\n\n // TTL of config retrieved from remote config in hours.\n configTimeToLive = 12;\n\n getFlTransportFullUrl(): string {\n return this.flTransportEndpointUrl.concat('?key=', this.transportKey);\n }\n\n static getInstance(): SettingsService {\n if (settingsServiceInstance === undefined) {\n settingsServiceInstance = new SettingsService();\n }\n return settingsServiceInstance;\n }\n}\n","/**\n * @license\n * Copyright 2020 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 { ERROR_FACTORY, ErrorCode } from './errors';\n\nexport function mergeStrings(part1: string, part2: string): string {\n const sizeDiff = part1.length - part2.length;\n if (sizeDiff < 0 || sizeDiff > 1) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_STRING_MERGER_PARAMETER);\n }\n\n const resultArray = [];\n for (let i = 0; i < part1.length; i++) {\n resultArray.push(part1.charAt(i));\n if (part2.length > i) {\n resultArray.push(part2.charAt(i));\n }\n }\n\n return resultArray.join('');\n}\n","/**\n * @license\n * Copyright 2020 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 { Api } from '../services/api_service';\n\n// The values and orders of the following enums should not be changed.\nconst enum ServiceWorkerStatus {\n UNKNOWN = 0,\n UNSUPPORTED = 1,\n CONTROLLED = 2,\n UNCONTROLLED = 3\n}\n\nexport enum VisibilityState {\n UNKNOWN = 0,\n VISIBLE = 1,\n HIDDEN = 2\n}\n\nconst enum EffectiveConnectionType {\n UNKNOWN = 0,\n CONNECTION_SLOW_2G = 1,\n CONNECTION_2G = 2,\n CONNECTION_3G = 3,\n CONNECTION_4G = 4\n}\n\ntype ConnectionType =\n | 'bluetooth'\n | 'cellular'\n | 'ethernet'\n | 'mixed'\n | 'none'\n | 'other'\n | 'unknown'\n | 'wifi';\n\n/**\n * NetworkInformation\n * This API is not well supported in all major browsers, so TypeScript does not provide types for it.\n *\n * ref: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation\n */\ninterface NetworkInformation extends EventTarget {\n readonly type: ConnectionType;\n}\n\ninterface NetworkInformationWithEffectiveType extends NetworkInformation {\n readonly effectiveType?: 'slow-2g' | '2g' | '3g' | '4g';\n}\n\ninterface NavigatorWithConnection extends Navigator {\n readonly connection: NetworkInformationWithEffectiveType;\n}\n\nconst RESERVED_ATTRIBUTE_PREFIXES = ['firebase_', 'google_', 'ga_'];\nconst ATTRIBUTE_FORMAT_REGEX = new RegExp('^[a-zA-Z]\\\\w*$');\nconst MAX_ATTRIBUTE_NAME_LENGTH = 40;\nconst MAX_ATTRIBUTE_VALUE_LENGTH = 100;\n\nexport function getServiceWorkerStatus(): ServiceWorkerStatus {\n const navigator = Api.getInstance().navigator;\n if (navigator?.serviceWorker) {\n if (navigator.serviceWorker.controller) {\n return ServiceWorkerStatus.CONTROLLED;\n } else {\n return ServiceWorkerStatus.UNCONTROLLED;\n }\n } else {\n return ServiceWorkerStatus.UNSUPPORTED;\n }\n}\n\nexport function getVisibilityState(): VisibilityState {\n const document = Api.getInstance().document;\n const visibilityState = document.visibilityState;\n switch (visibilityState) {\n case 'visible':\n return VisibilityState.VISIBLE;\n case 'hidden':\n return VisibilityState.HIDDEN;\n default:\n return VisibilityState.UNKNOWN;\n }\n}\n\nexport function getEffectiveConnectionType(): EffectiveConnectionType {\n const navigator = Api.getInstance().navigator;\n const navigatorConnection = (navigator as NavigatorWithConnection).connection;\n const effectiveType =\n navigatorConnection && navigatorConnection.effectiveType;\n switch (effectiveType) {\n case 'slow-2g':\n return EffectiveConnectionType.CONNECTION_SLOW_2G;\n case '2g':\n return EffectiveConnectionType.CONNECTION_2G;\n case '3g':\n return EffectiveConnectionType.CONNECTION_3G;\n case '4g':\n return EffectiveConnectionType.CONNECTION_4G;\n default:\n return EffectiveConnectionType.UNKNOWN;\n }\n}\n\nexport function isValidCustomAttributeName(name: string): boolean {\n if (name.length === 0 || name.length > MAX_ATTRIBUTE_NAME_LENGTH) {\n return false;\n }\n const matchesReservedPrefix = RESERVED_ATTRIBUTE_PREFIXES.some(prefix =>\n name.startsWith(prefix)\n );\n return !matchesReservedPrefix && !!name.match(ATTRIBUTE_FORMAT_REGEX);\n}\n\nexport function isValidCustomAttributeValue(value: string): boolean {\n return value.length !== 0 && value.length <= MAX_ATTRIBUTE_VALUE_LENGTH;\n}\n","/**\n * @license\n * Copyright 2020 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 { ERROR_FACTORY, ErrorCode } from './errors';\nimport { FirebaseApp } from '@firebase/app';\n\nexport function getAppId(firebaseApp: FirebaseApp): string {\n const appId = firebaseApp.options?.appId;\n if (!appId) {\n throw ERROR_FACTORY.create(ErrorCode.NO_APP_ID);\n }\n return appId;\n}\n\nexport function getProjectId(firebaseApp: FirebaseApp): string {\n const projectId = firebaseApp.options?.projectId;\n if (!projectId) {\n throw ERROR_FACTORY.create(ErrorCode.NO_PROJECT_ID);\n }\n return projectId;\n}\n\nexport function getApiKey(firebaseApp: FirebaseApp): string {\n const apiKey = firebaseApp.options?.apiKey;\n if (!apiKey) {\n throw ERROR_FACTORY.create(ErrorCode.NO_API_KEY);\n }\n return apiKey;\n}\n","/**\n * @license\n * Copyright 2020 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 CONFIG_EXPIRY_LOCAL_STORAGE_KEY,\n CONFIG_LOCAL_STORAGE_KEY,\n SDK_VERSION\n} from '../constants';\nimport { consoleLogger } from '../utils/console_logger';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\n\nimport { Api } from './api_service';\nimport { getAuthTokenPromise } from './iid_service';\nimport { SettingsService } from './settings_service';\nimport { PerformanceController } from '../controllers/perf';\nimport { getProjectId, getApiKey, getAppId } from '../utils/app_utils';\n\nconst REMOTE_CONFIG_SDK_VERSION = '0.0.1';\n\ninterface SecondaryConfig {\n loggingEnabled?: boolean;\n logSource?: number;\n logEndPointUrl?: string;\n transportKey?: string;\n tracesSamplingRate?: number;\n networkRequestsSamplingRate?: number;\n}\n\n// These values will be used if the remote config object is successfully\n// retrieved, but the template does not have these fields.\nconst DEFAULT_CONFIGS: SecondaryConfig = {\n loggingEnabled: true\n};\n\n/* eslint-disable camelcase */\ninterface RemoteConfigTemplate {\n fpr_enabled?: string;\n fpr_log_source?: string;\n fpr_log_endpoint_url?: string;\n fpr_log_transport_key?: string;\n fpr_log_transport_web_percent?: string;\n fpr_vc_network_request_sampling_rate?: string;\n fpr_vc_trace_sampling_rate?: string;\n fpr_vc_session_sampling_rate?: string;\n}\n/* eslint-enable camelcase */\n\ninterface RemoteConfigResponse {\n entries?: RemoteConfigTemplate;\n state?: string;\n}\n\nconst FIS_AUTH_PREFIX = 'FIREBASE_INSTALLATIONS_AUTH';\n\nexport function getConfig(\n performanceController: PerformanceController,\n iid: string\n): Promise<void> {\n const config = getStoredConfig();\n if (config) {\n processConfig(config);\n return Promise.resolve();\n }\n\n return getRemoteConfig(performanceController, iid)\n .then(processConfig)\n .then(\n config => storeConfig(config),\n /** Do nothing for error, use defaults set in settings service. */\n () => {}\n );\n}\n\nfunction getStoredConfig(): RemoteConfigResponse | undefined {\n const localStorage = Api.getInstance().localStorage;\n if (!localStorage) {\n return;\n }\n const expiryString = localStorage.getItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY);\n if (!expiryString || !configValid(expiryString)) {\n return;\n }\n\n const configStringified = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);\n if (!configStringified) {\n return;\n }\n try {\n const configResponse: RemoteConfigResponse = JSON.parse(configStringified);\n return configResponse;\n } catch {\n return;\n }\n}\n\nfunction storeConfig(config: RemoteConfigResponse | undefined): void {\n const localStorage = Api.getInstance().localStorage;\n if (!config || !localStorage) {\n return;\n }\n\n localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));\n localStorage.setItem(\n CONFIG_EXPIRY_LOCAL_STORAGE_KEY,\n String(\n Date.now() +\n SettingsService.getInstance().configTimeToLive * 60 * 60 * 1000\n )\n );\n}\n\nconst COULD_NOT_GET_CONFIG_MSG =\n 'Could not fetch config, will use default configs';\n\nfunction getRemoteConfig(\n performanceController: PerformanceController,\n iid: string\n): Promise<RemoteConfigResponse | undefined> {\n // Perf needs auth token only to retrieve remote config.\n return getAuthTokenPromise(performanceController.installations)\n .then(authToken => {\n const projectId = getProjectId(performanceController.app);\n const apiKey = getApiKey(performanceController.app);\n const configEndPoint = `https://firebaseremoteconfig.googleapis.com/v1/projects/${projectId}/namespaces/fireperf:fetch?key=${apiKey}`;\n const request = new Request(configEndPoint, {\n method: 'POST',\n headers: { Authorization: `${FIS_AUTH_PREFIX} ${authToken}` },\n /* eslint-disable camelcase */\n body: JSON.stringify({\n app_instance_id: iid,\n app_instance_id_token: authToken,\n app_id: getAppId(performanceController.app),\n app_version: SDK_VERSION,\n sdk_version: REMOTE_CONFIG_SDK_VERSION\n })\n /* eslint-enable camelcase */\n });\n return fetch(request).then(response => {\n if (response.ok) {\n return response.json() as RemoteConfigResponse;\n }\n // In case response is not ok. This will be caught by catch.\n throw ERROR_FACTORY.create(ErrorCode.RC_NOT_OK);\n });\n })\n .catch(() => {\n consoleLogger.info(COULD_NOT_GET_CONFIG_MSG);\n return undefined;\n });\n}\n\n/**\n * Processes config coming either from calling RC or from local storage.\n * This method only runs if call is successful or config in storage\n * is valid.\n */\nfunction processConfig(\n config?: RemoteConfigResponse\n): RemoteConfigResponse | undefined {\n if (!config) {\n return config;\n }\n const settingsServiceInstance = SettingsService.getInstance();\n const entries = config.entries || {};\n if (entries.fpr_enabled !== undefined) {\n // TODO: Change the assignment of loggingEnabled once the received type is\n // known.\n settingsServiceInstance.loggingEnabled =\n String(entries.fpr_enabled) === 'true';\n } else if (DEFAULT_CONFIGS.loggingEnabled !== undefined) {\n // Config retrieved successfully, but there is no fpr_enabled in template.\n // Use secondary configs value.\n settingsServiceInstance.loggingEnabled = DEFAULT_CONFIGS.loggingEnabled;\n }\n if (entries.fpr_log_source) {\n settingsServiceInstance.logSource = Number(entries.fpr_log_source);\n } else if (DEFAULT_CONFIGS.logSource) {\n settingsServiceInstance.logSource = DEFAULT_CONFIGS.logSource;\n }\n\n if (entries.fpr_log_endpoint_url) {\n settingsServiceInstance.logEndPointUrl = entries.fpr_log_endpoint_url;\n } else if (DEFAULT_CONFIGS.logEndPointUrl) {\n settingsServiceInstance.logEndPointUrl = DEFAULT_CONFIGS.logEndPointUrl;\n }\n\n // Key from Remote Config has to be non-empty string, otherwise use local value.\n if (entries.fpr_log_transport_key) {\n settingsServiceInstance.transportKey = entries.fpr_log_transport_key;\n } else if (DEFAULT_CONFIGS.transportKey) {\n settingsServiceInstance.transportKey = DEFAULT_CONFIGS.transportKey;\n }\n\n if (entries.fpr_vc_network_request_sampling_rate !== undefined) {\n settingsServiceInstance.networkRequestsSamplingRate = Number(\n entries.fpr_vc_network_request_sampling_rate\n );\n } else if (DEFAULT_CONFIGS.networkRequestsSamplingRate !== undefined) {\n settingsServiceInstance.networkRequestsSamplingRate =\n DEFAULT_CONFIGS.networkRequestsSamplingRate;\n }\n if (entries.fpr_vc_trace_sampling_rate !== undefined) {\n settingsServiceInstance.tracesSamplingRate = Number(\n entries.fpr_vc_trace_sampling_rate\n );\n } else if (DEFAULT_CONFIGS.tracesSamplingRate !== undefined) {\n settingsServiceInstance.tracesSamplingRate =\n DEFAULT_CONFIGS.tracesSamplingRate;\n }\n // Set the per session trace and network logging flags.\n settingsServiceInstance.logTraceAfterSampling = shouldLogAfterSampling(\n settingsServiceInstance.tracesSamplingRate\n );\n settingsServiceInstance.logNetworkAfterSampling = shouldLogAfterSampling(\n settingsServiceInstance.networkRequestsSamplingRate\n );\n return config;\n}\n\nfunction configValid(expiry: string): boolean {\n return Number(expiry) > Date.now();\n}\n\nfunction shouldLogAfterSampling(samplingRate: number): boolean {\n return Math.random() <= samplingRate;\n}\n","/**\n * @license\n * Copyright 2020 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 { getIidPromise } from './iid_service';\nimport { getConfig } from './remote_config_service';\nimport { Api } from './api_service';\nimport { PerformanceController } from '../controllers/perf';\n\nconst enum InitializationStatus {\n notInitialized = 1,\n initializationPending,\n initialized\n}\n\nlet initializationStatus = InitializationStatus.notInitialized;\n\nlet initializationPromise: Promise<void> | undefined;\n\nexport function getInitializationPromise(\n performanceController: PerformanceController\n): Promise<void> {\n initializationStatus = InitializationStatus.initializationPending;\n\n initializationPromise =\n initializationPromise || initializePerf(performanceController);\n\n return initializationPromise;\n}\n\nexport function isPerfInitialized(): boolean {\n return initializationStatus === InitializationStatus.initialized;\n}\n\nfunction initializePerf(\n performanceController: PerformanceController\n): Promise<void> {\n return getDocumentReadyComplete()\n .then(() => getIidPromise(performanceController.installations))\n .then(iid => getConfig(performanceController, iid))\n .then(\n () => changeInitializationStatus(),\n () => changeInitializationStatus()\n );\n}\n\n/**\n * Returns a promise which resolves whenever the document readystate is complete or\n * immediately if it is called after page load complete.\n */\nfunction getDocumentReadyComplete(): Promise<void> {\n const document = Api.getInstance().document;\n return new Promise(resolve => {\n if (document && document.readyState !== 'complete') {\n const handler = (): void => {\n if (document.readyState === 'complete') {\n document.removeEventListener('readystatechange', handler);\n resolve();\n }\n };\n document.addEventListener('readystatechange', handler);\n } else {\n resolve();\n }\n });\n}\n\nfunction changeInitializationStatus(): void {\n initializationStatus = InitializationStatus.initialized;\n}\n","/**\n * @license\n * Copyright 2020 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 { SettingsService } from './settings_service';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\nimport { consoleLogger } from '../utils/console_logger';\n\nconst DEFAULT_SEND_INTERVAL_MS = 10 * 1000;\nconst INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;\n// If end point does not work, the call will be tried for these many times.\nconst DEFAULT_REMAINING_TRIES = 3;\nconst MAX_EVENT_COUNT_PER_REQUEST = 1000;\nlet remainingTries = DEFAULT_REMAINING_TRIES;\n\ninterface LogResponseDetails {\n responseAction?: string;\n}\n\ninterface BatchEvent {\n message: string;\n eventTime: number;\n}\n\n/* eslint-disable camelcase */\n// CC/Fl accepted log format.\ninterface TransportBatchLogFormat {\n request_time_ms: string;\n client_info: ClientInfo;\n log_source: number;\n log_event: Log[];\n}\n\ninterface ClientInfo {\n client_type: number;\n js_client_info: {};\n}\n\ninterface Log {\n source_extension_json_proto3: string;\n event_time_ms: string;\n}\n/* eslint-enable camelcase */\n\nlet queue: BatchEvent[] = [];\n\nlet isTransportSetup: boolean = false;\n\nexport function setupTransportService(): void {\n if (!isTransportSetup) {\n processQueue(INITIAL_SEND_TIME_DELAY_MS);\n isTransportSetup = true;\n }\n}\n\n/**\n * Utilized by testing to clean up message queue and un-initialize transport service.\n */\nexport function resetTransportService(): void {\n isTransportSetup = false;\n queue = [];\n}\n\nfunction processQueue(timeOffset: number): void {\n setTimeout(() => {\n // If there is no remainingTries left, stop retrying.\n if (remainingTries === 0) {\n return;\n }\n\n // If there are no events to process, wait for DEFAULT_SEND_INTERVAL_MS and try again.\n if (!queue.length) {\n return processQueue(DEFAULT_SEND_INTERVAL_MS);\n }\n\n dispatchQueueEvents();\n }, timeOffset);\n}\n\nfunction dispatchQueueEvents(): void {\n // Extract events up to the maximum cap of single logRequest from top of \"official queue\".\n // The staged events will be used for current logRequest attempt, remaining events will be kept\n // for next attempt.\n const staged = queue.splice(0, MAX_EVENT_COUNT_PER_REQUEST);\n\n /* eslint-disable camelcase */\n // We will pass the JSON serialized event to the backend.\n const log_event: Log[] = staged.map(evt => ({\n source_extension_json_proto3: evt.message,\n event_time_ms: String(evt.eventTime)\n }));\n\n const data: TransportBatchLogFormat = {\n request_time_ms: String(Date.now()),\n client_info: {\n client_type: 1, // 1 is JS\n js_client_info: {}\n },\n log_source: SettingsService.getInstance().logSource,\n log_event\n };\n /* eslint-enable camelcase */\n\n sendEventsToFl(data, staged).catch(() => {\n // If the request fails for some reason, add the events that were attempted\n // back to the primary queue to retry later.\n queue = [...staged, ...queue];\n remainingTries--;\n consoleLogger.info(`Tries left: ${remainingTries}.`);\n processQueue(DEFAULT_SEND_INTERVAL_MS);\n });\n}\n\nfunction sendEventsToFl(\n data: TransportBatchLogFormat,\n staged: BatchEvent[]\n): Promise<void> {\n return postToFlEndpoint(data)\n .then(res => {\n if (!res.ok) {\n consoleLogger.info('Call to Firebase backend failed.');\n }\n return res.json();\n })\n .then(res => {\n // Find the next call wait time from the response.\n const transportWait = Number(res.nextRequestWaitMillis);\n let requestOffset = DEFAULT_SEND_INTERVAL_MS;\n if (!isNaN(transportWait)) {\n requestOffset = Math.max(transportWait, requestOffset);\n }\n\n // Delete request if response include RESPONSE_ACTION_UNKNOWN or DELETE_REQUEST action.\n // Otherwise, retry request using normal scheduling if response include RETRY_REQUEST_LATER.\n const logResponseDetails: LogResponseDetails[] = res.logResponseDetails;\n if (\n Array.isArray(logResponseDetails) &&\n logResponseDetails.length > 0 &&\n logResponseDetails[0].responseAction === 'RETRY_REQUEST_LATER'\n ) {\n queue = [...staged, ...queue];\n consoleLogger.info(`Retry transport request later.`);\n }\n\n remainingTries = DEFAULT_REMAINING_TRIES;\n // Schedule the next process.\n processQueue(requestOffset);\n });\n}\n\nfunction postToFlEndpoint(data: TransportBatchLogFormat): Promise<Response> {\n const flTransportFullUrl =\n SettingsService.getInstance().getFlTransportFullUrl();\n return fetch(flTransportFullUrl, {\n method: 'POST',\n body: JSON.stringify(data)\n });\n}\n\nfunction addToQueue(evt: BatchEvent): void {\n if (!evt.eventTime || !evt.message) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_CC_LOG);\n }\n // Add the new event to the queue.\n queue = [...queue, evt];\n}\n\n/** Log handler for cc service to send the performance logs to the server. */\nexport function transportHandler(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n serializer: (...args: any[]) => string\n): (...args: unknown[]) => void {\n return (...args) => {\n const message = serializer(...args);\n addToQueue({\n message,\n eventTime: Date.now()\n });\n };\n}\n","/**\n * @license\n * Copyright 2020 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 { getIid } from './iid_service';\nimport { NetworkRequest } from '../resources/network_request';\nimport { Trace } from '../resources/trace';\nimport { Api } from './api_service';\nimport { SettingsService } from './settings_service';\nimport {\n getServiceWorkerStatus,\n getVisibilityState,\n VisibilityState,\n getEffectiveConnectionType\n} from '../utils/attributes_utils';\nimport {\n isPerfInitialized,\n getInitializationPromise\n} from './initialization_service';\nimport { transportHandler } from './transport_service';\nimport { SDK_VERSION } from '../constants';\nimport { FirebaseApp } from '@firebase/app';\nimport { getAppId } from '../utils/app_utils';\n\nconst enum ResourceType {\n NetworkRequest,\n Trace\n}\n\n/* eslint-disable camelcase */\ninterface ApplicationInfo {\n google_app_id: string;\n app_instance_id?: string;\n web_app_info: WebAppInfo;\n application_process_state: number;\n}\n\ninterface WebAppInfo {\n sdk_version: string;\n page_url: string;\n service_worker_status: number;\n visibility_state: number;\n effective_connection_type: number;\n}\n\ninterface PerfNetworkLog {\n application_info: ApplicationInfo;\n network_request_metric: NetworkRequestMetric;\n}\n\ninterface PerfTraceLog {\n application_info: ApplicationInfo;\n trace_metric: TraceMetric;\n}\n\ninterface NetworkRequestMetric {\n url: string;\n http_method: number;\n http_response_code: number;\n response_payload_bytes?: number;\n client_start_time_us?: number;\n time_to_response_initiated_us?: number;\n time_to_response_completed_us?: number;\n}\n\ninterface TraceMetric {\n name: string;\n is_auto: boolean;\n client_start_time_us: number;\n duration_us: number;\n counters?: { [key: string]: number };\n custom_attributes?: { [key: string]: string };\n}\n\nlet logger: (\n resource: NetworkRequest | Trace,\n resourceType: ResourceType\n) => void | undefined;\n// This method is not called before initialization.\nfunction sendLog(\n resource: NetworkRequest | Trace,\n resourceType: ResourceType\n): void {\n if (!logger) {\n logger = transportHandler(serializer);\n }\n logger(resource, resourceType);\n}\n\nexport function logTrace(trace: Trace): void {\n const settingsService = SettingsService.getInstance();\n // Do not log if trace is auto generated and instrumentation is disabled.\n if (!settingsService.instrumentationEnabled && trace.isAuto) {\n return;\n }\n // Do not log if trace is custom and data collection is disabled.\n if (!settingsService.dataCollectionEnabled && !trace.isAuto) {\n return;\n }\n // Do not log if required apis are not available.\n if (!Api.getInstance().requiredApisAvailable()) {\n return;\n }\n\n // Only log the page load auto traces if page is visible.\n if (trace.isAuto && getVisibilityState() !== VisibilityState.VISIBLE) {\n return;\n }\n\n if (isPerfInitialized()) {\n sendTraceLog(trace);\n } else {\n // Custom traces can be used before the initialization but logging\n // should wait until after.\n getInitializationPromise(trace.performanceController).then(\n () => sendTraceLog(trace),\n () => sendTraceLog(trace)\n );\n }\n}\n\nfunction sendTraceLog(trace: Trace): void {\n if (!getIid()) {\n return;\n }\n\n const settingsService = SettingsService.getInstance();\n if (\n !settingsService.loggingEnabled ||\n !settingsService.logTraceAfterSampling\n ) {\n return;\n }\n\n setTimeout(() => sendLog(trace, ResourceType.Trace), 0);\n}\n\nexport function logNetworkRequest(networkRequest: NetworkRequest): void {\n const settingsService = SettingsService.getInstance();\n // Do not log network requests if instrumentation is disabled.\n if (!settingsService.instrumentationEnabled) {\n return;\n }\n\n // Do not log the js sdk's call to transport service domain to avoid unnecessary cycle.\n // Need to blacklist both old and new endpoints to avoid migration gap.\n const networkRequestUrl = networkRequest.url;\n\n // Blacklist old log endpoint and new transport endpoint.\n // Because Performance SDK doesn't instrument requests sent from SDK itself.\n const logEndpointUrl = settingsService.logEndPointUrl.split('?')[0];\n const flEndpointUrl = settingsService.flTransportEndpointUrl.split('?')[0];\n if (\n networkRequestUrl === logEndpointUrl ||\n networkRequestUrl === flEndpointUrl\n ) {\n return;\n }\n\n if (\n !settingsService.loggingEnabled ||\n !settingsService.logNetworkAfterSampling\n ) {\n return;\n }\n\n setTimeout(() => sendLog(networkRequest, ResourceType.NetworkRequest), 0);\n}\n\nfunction serializer(\n resource: NetworkRequest | Trace,\n resourceType: ResourceType\n): string {\n if (resourceType === ResourceType.NetworkRequest) {\n return serializeNetworkRequest(resource as NetworkRequest);\n }\n return serializeTrace(resource as Trace);\n}\n\nfunction serializeNetworkRequest(networkRequest: NetworkRequest): string {\n const networkRequestMetric: NetworkRequestMetric = {\n url: networkRequest.url,\n http_method: networkRequest.httpMethod || 0,\n http_response_code: 200,\n response_payload_bytes: networkRequest.responsePayloadBytes,\n client_start_time_us: networkRequest.startTimeUs,\n time_to_response_initiated_us: networkRequest.timeToResponseInitiatedUs,\n time_to_response_completed_us: networkRequest.timeToResponseCompletedUs\n };\n const perfMetric: PerfNetworkLog = {\n application_info: getApplicationInfo(\n networkRequest.performanceController.app\n ),\n network_request_metric: networkRequestMetric\n };\n return JSON.stringify(perfMetric);\n}\n\nfunction serializeTrace(trace: Trace): string {\n const traceMetric: TraceMetric = {\n name: trace.name,\n is_auto: trace.isAuto,\n client_start_time_us: trace.startTimeUs,\n duration_us: trace.durationUs\n };\n\n if (Object.keys(trace.counters).length !== 0) {\n traceMetric.counters = trace.counters;\n }\n const customAttributes = trace.getAttributes();\n if (Object.keys(customAttributes).length !== 0) {\n traceMetric.custom_attributes = customAttributes;\n }\n\n const perfMetric: PerfTraceLog = {\n application_info: getApplicationInfo(trace.performanceController.app),\n trace_metric: traceMetric\n };\n return JSON.stringify(perfMetric);\n}\n\nfunction getApplicationInfo(firebaseApp: FirebaseApp): ApplicationInfo {\n return {\n google_app_id: getAppId(firebaseApp),\n app_instance_id: getIid(),\n web_app_info: {\n sdk_version: SDK_VERSION,\n page_url: Api.getInstance().getUrl(),\n service_worker_status: getServiceWorkerStatus(),\n visibility_state: getVisibilityState(),\n effective_connection_type: getEffectiveConnectionType()\n },\n application_process_state: 0\n };\n}\n\n/* eslint-enable camelcase */\n","/**\n * @license\n * Copyright 2020 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 FIRST_PAINT_COUNTER_NAME,\n FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n FIRST_INPUT_DELAY_COUNTER_NAME,\n OOB_TRACE_PAGE_LOAD_PREFIX\n} from '../constants';\nimport { consoleLogger } from '../utils/console_logger';\n\nconst MAX_METRIC_NAME_LENGTH = 100;\nconst RESERVED_AUTO_PREFIX = '_';\nconst oobMetrics = [\n FIRST_PAINT_COUNTER_NAME,\n FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n FIRST_INPUT_DELAY_COUNTER_NAME\n];\n\n/**\n * Returns true if the metric is custom and does not start with reserved prefix, or if\n * the metric is one of out of the box page load trace metrics.\n */\nexport function isValidMetricName(name: string, traceName?: string): boolean {\n if (name.length === 0 || name.length > MAX_METRIC_NAME_LENGTH) {\n return false;\n }\n return (\n (traceName &&\n traceName.startsWith(OOB_TRACE_PAGE_LOAD_PREFIX) &&\n oobMetrics.indexOf(name) > -1) ||\n !name.startsWith(RESERVED_AUTO_PREFIX)\n );\n}\n\n/**\n * Converts the provided value to an integer value to be used in case of a metric.\n * @param providedValue Provided number value of the metric that needs to be converted to an integer.\n *\n * @returns Converted integer number to be set for the metric.\n */\nexport function convertMetricValueToInteger(providedValue: number): number {\n const valueAsInteger: number = Math.floor(providedValue);\n if (valueAsInteger < providedValue) {\n consoleLogger.info(\n `Metric value should be an Integer, setting the value as : ${valueAsInteger}.`\n );\n }\n return valueAsInteger;\n}\n","/**\n * @license\n * Copyright 2020 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 TRACE_START_MARK_PREFIX,\n TRACE_STOP_MARK_PREFIX,\n TRACE_MEASURE_PREFIX,\n OOB_TRACE_PAGE_LOAD_PREFIX,\n FIRST_PAINT_COUNTER_NAME,\n FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n FIRST_INPUT_DELAY_COUNTER_NAME\n} from '../constants';\nimport { Api } from '../services/api_service';\nimport { logTrace } from '../services/perf_logger';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\nimport {\n isValidCustomAttributeName,\n isValidCustomAttributeValue\n} from '../utils/attributes_utils';\nimport {\n isValidMetricName,\n convertMetricValueToInteger\n} from '../utils/metric_utils';\nimport { PerformanceTrace } from '../public_types';\nimport { PerformanceController } from '../controllers/perf';\n\nconst enum TraceState {\n UNINITIALIZED = 1,\n RUNNING,\n TERMINATED\n}\n\nexport class Trace implements PerformanceTrace {\n private state: TraceState = TraceState.UNINITIALIZED;\n startTimeUs!: number;\n durationUs!: number;\n private customAttributes: { [key: string]: string } = {};\n counters: { [counterName: string]: number } = {};\n private api = Api.getInstance();\n private randomId = Math.floor(Math.random() * 1000000);\n private traceStartMark!: string;\n private traceStopMark!: string;\n private traceMeasure!: string;\n\n /**\n * @param performanceController The performance controller running.\n * @param name The name of the trace.\n * @param isAuto If the trace is auto-instrumented.\n * @param traceMeasureName The name of the measure marker in user timing specification. This field\n * is only set when the trace is built for logging when the user directly uses the user timing\n * api (performance.mark and performance.measure).\n */\n constructor(\n readonly performanceController: PerformanceController,\n readonly name: string,\n readonly isAuto = false,\n traceMeasureName?: string\n ) {\n if (!this.isAuto) {\n this.traceStartMark = `${TRACE_START_MARK_PREFIX}-${this.randomId}-${this.name}`;\n this.traceStopMark = `${TRACE_STOP_MARK_PREFIX}-${this.randomId}-${this.name}`;\n this.traceMeasure =\n traceMeasureName ||\n `${TRACE_MEASURE_PREFIX}-${this.randomId}-${this.name}`;\n\n if (traceMeasureName) {\n // For the case of direct user timing traces, no start stop will happen. The measure object\n // is already available.\n this.calculateTraceMetrics();\n }\n }\n }\n\n /**\n * Starts a trace. The measurement of the duration starts at this point.\n */\n start(): void {\n if (this.state !== TraceState.UNINITIALIZED) {\n throw ERROR_FACTORY.create(ErrorCode.TRACE_STARTED_BEFORE, {\n traceName: this.name\n });\n }\n this.api.mark(this.traceStartMark);\n this.state = TraceState.RUNNING;\n }\n\n /**\n * Stops the trace. The measurement of the duration of the trace stops at this point and trace\n * is logged.\n */\n stop(): void {\n if (this.state !== TraceState.RUNNING) {\n throw ERROR_FACTORY.create(ErrorCode.TRACE_STOPPED_BEFORE, {\n traceName: this.name\n });\n }\n this.state = TraceState.TERMINATED;\n this.api.mark(this.traceStopMark);\n this.api.measure(\n this.traceMeasure,\n this.traceStartMark,\n this.traceStopMark\n );\n this.calculateTraceMetrics();\n logTrace(this);\n }\n\n /**\n * Records a trace with predetermined values. If this method is used a trace is created and logged\n * directly. No need to use start and stop methods.\n * @param startTime Trace start time since epoch in millisec\n * @param duration The duration of the trace in millisec\n * @param options An object which can optionally hold maps of custom metrics and custom attributes\n */\n record(\n startTime: number,\n duration: number,\n options?: {\n metrics?: { [key: string]: number };\n attributes?: { [key: string]: string };\n }\n ): void {\n if (startTime <= 0) {\n throw ERROR_FACTORY.create(ErrorCode.NONPOSITIVE_TRACE_START_TIME, {\n traceName: this.name\n });\n }\n if (duration <= 0) {\n throw ERROR_FACTORY.create(ErrorCode.NONPOSITIVE_TRACE_DURATION, {\n traceName: this.name\n });\n }\n\n this.durationUs = Math.floor(duration * 1000);\n this.startTimeUs = Math.floor(startTime * 1000);\n if (options && options.attributes) {\n this.customAttributes = { ...options.attributes };\n }\n if (options && options.metrics) {\n for (const metricName of Object.keys(options.metrics)) {\n if (!isNaN(Number(options.metrics[metricName]))) {\n this.counters[metricName] = Math.floor(\n Number(options.metrics[metricName])\n );\n }\n }\n }\n logTrace(this);\n }\n\n /**\n * Increments a custom metric by a certain number or 1 if number not specified. Will create a new\n * custom metric if one with the given name does not exist. The value will be floored down to an\n * integer.\n * @param counter Name of the custom metric\n * @param numAsInteger Increment by value\n */\n incrementMetric(counter: string, numAsInteger = 1): void {\n if (this.counters[counter] === undefined) {\n this.putMetric(counter, numAsInteger);\n } else {\n this.putMetric(counter, this.counters[counter] + numAsInteger);\n }\n }\n\n /**\n * Sets a custom metric to a specified value. Will create a new custom metric if one with the\n * given name does not exist. The value will be floored down to an integer.\n * @param counter Name of the custom metric\n * @param numAsInteger Set custom metric to this value\n */\n putMetric(counter: string, numAsInteger: number): void {\n if (isValidMetricName(counter, this.name)) {\n this.counters[counter] = convertMetricValueToInteger(numAsInteger ?? 0);\n } else {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_CUSTOM_METRIC_NAME, {\n customMetricName: counter\n });\n }\n }\n\n /**\n * Returns the value of the custom metric by that name. If a custom metric with that name does\n * not exist will return zero.\n * @param counter\n */\n getMetric(counter: string): number {\n return this.counters[counter] || 0;\n }\n\n /**\n * Sets a custom attribute of a trace to a certain value.\n * @param attr\n * @param value\n */\n putAttribute(attr: string, value: string): void {\n const isValidName = isValidCustomAttributeName(attr);\n const isValidValue = isValidCustomAttributeValue(value);\n if (isValidName && isValidValue) {\n this.customAttributes[attr] = value;\n return;\n }\n // Throw appropriate error when the attribute name or value is invalid.\n if (!isValidName) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_ATTRIBUTE_NAME, {\n attributeName: attr\n });\n }\n if (!isValidValue) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_ATTRIBUTE_VALUE, {\n attributeValue: value\n });\n }\n }\n\n /**\n * Retrieves the value a custom attribute of a trace is set to.\n * @param attr\n */\n getAttribute(attr: string): string | undefined {\n return this.customAttributes[attr];\n }\n\n removeAttribute(attr: string): void {\n if (this.customAttributes[attr] === undefined) {\n return;\n }\n delete this.customAttributes[attr];\n }\n\n getAttributes(): { [key: string]: string } {\n return { ...this.customAttributes };\n }\n\n private setStartTime(startTime: number): void {\n this.startTimeUs = startTime;\n }\n\n private setDuration(duration: number): void {\n this.durationUs = duration;\n }\n\n /**\n * Calculates and assigns the duration and start time of the trace using the measure performance\n * entry.\n */\n private calculateTraceMetrics(): void {\n const perfMeasureEntries = this.api.getEntriesByName(this.traceMeasure);\n const perfMeasureEntry = perfMeasureEntries && perfMeasureEntries[0];\n if (perfMeasureEntry) {\n this.durationUs = Math.floor(perfMeasureEntry.duration * 1000);\n this.startTimeUs = Math.floor(\n (perfMeasureEntry.startTime + this.api.getTimeOrigin()) * 1000\n );\n }\n }\n\n /**\n * @param navigationTimings A single element array which contains the navigationTIming object of\n * the page load\n * @param paintTimings A array which contains paintTiming object of the page load\n * @param firstInputDelay First input delay in millisec\n */\n static createOobTrace(\n performanceController: PerformanceController,\n navigationTimings: PerformanceNavigationTiming[],\n paintTimings: PerformanceEntry[],\n firstInputDelay?: number\n ): void {\n const route = Api.getInstance().getUrl();\n if (!route) {\n return;\n }\n const trace = new Trace(\n performanceController,\n OOB_TRACE_PAGE_LOAD_PREFIX + route,\n true\n );\n const timeOriginUs = Math.floor(Api.getInstance().getTimeOrigin() * 1000);\n trace.setStartTime(timeOriginUs);\n\n // navigationTimings includes only one element.\n if (navigationTimings && navigationTimings[0]) {\n trace.setDuration(Math.floor(navigationTimings[0].duration * 1000));\n trace.putMetric(\n 'domInteractive',\n Math.floor(navigationTimings[0].domInteractive * 1000)\n );\n trace.putMetric(\n 'domContentLoadedEventEnd',\n Math.floor(navigationTimings[0].domContentLoadedEventEnd * 1000)\n );\n trace.putMetric(\n 'loadEventEnd',\n Math.floor(navigationTimings[0].loadEventEnd * 1000)\n );\n }\n\n const FIRST_PAINT = 'first-paint';\n const FIRST_CONTENTFUL_PAINT = 'first-contentful-paint';\n if (paintTimings) {\n const firstPaint = paintTimings.find(\n paintObject => paintObject.name === FIRST_PAINT\n );\n if (firstPaint && firstPaint.startTime) {\n trace.putMetric(\n FIRST_PAINT_COUNTER_NAME,\n Math.floor(firstPaint.startTime * 1000)\n );\n }\n const firstContentfulPaint = paintTimings.find(\n paintObject => paintObject.name === FIRST_CONTENTFUL_PAINT\n );\n if (firstContentfulPaint && firstContentfulPaint.startTime) {\n trace.putMetric(\n FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n Math.floor(firstContentfulPaint.startTime * 1000)\n );\n }\n\n if (firstInputDelay) {\n trace.putMetric(\n FIRST_INPUT_DELAY_COUNTER_NAME,\n Math.floor(firstInputDelay * 1000)\n );\n }\n }\n\n logTrace(trace);\n }\n\n static createUserTimingTrace(\n performanceController: PerformanceController,\n measureName: string\n ): void {\n const trace = new Trace(\n performanceController,\n measureName,\n false,\n measureName\n );\n logTrace(trace);\n }\n}\n","/**\n * @license\n * Copyright 2020 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 { Api } from '../services/api_service';\nimport { logNetworkRequest } from '../services/perf_logger';\nimport { PerformanceController } from '../controllers/perf';\n\n// The order of values of this enum should not be changed.\nexport const enum HttpMethod {\n HTTP_METHOD_UNKNOWN = 0,\n GET = 1,\n PUT = 2,\n POST = 3,\n DELETE = 4,\n HEAD = 5,\n PATCH = 6,\n OPTIONS = 7,\n TRACE = 8,\n CONNECT = 9\n}\n\n// Durations are in microseconds.\nexport interface NetworkRequest {\n performanceController: PerformanceController;\n url: string;\n httpMethod?: HttpMethod;\n requestPayloadBytes?: number;\n responsePayloadBytes?: number;\n httpResponseCode?: number;\n responseContentType?: string;\n startTimeUs?: number;\n timeToRequestCompletedUs?: number;\n timeToResponseInitiatedUs?: number;\n timeToResponseCompletedUs?: number;\n}\n\nexport function createNetworkRequestEntry(\n performanceController: PerformanceController,\n entry: PerformanceEntry\n): void {\n const performanceEntry = entry as PerformanceResourceTiming;\n if (!performanceEntry || performanceEntry.responseStart === undefined) {\n return;\n }\n const timeOrigin = Api.getInstance().getTimeOrigin();\n const startTimeUs = Math.floor(\n (performanceEntry.startTime + timeOrigin) * 1000\n );\n const timeToResponseInitiatedUs = performanceEntry.responseStart\n ? Math.floor(\n (performanceEntry.responseStart - performanceEntry.startTime) * 1000\n )\n : undefined;\n const timeToResponseCompletedUs = Math.floor(\n (performanceEntry.responseEnd - performanceEntry.startTime) * 1000\n );\n // Remove the query params from logged network request url.\n const url = performanceEntry.name && performanceEntry.name.split('?')[0];\n const networkRequest: NetworkRequest = {\n performanceController,\n url,\n responsePayloadBytes: performanceEntry.transferSize,\n startTimeUs,\n timeToResponseInitiatedUs,\n timeToResponseCompletedUs\n };\n\n logNetworkRequest(networkRequest);\n}\n","/**\n * @license\n * Copyright 2020 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 { Api } from './api_service';\nimport { Trace } from '../resources/trace';\nimport { createNetworkRequestEntry } from '../resources/network_request';\nimport { TRACE_MEASURE_PREFIX } from '../constants';\nimport { getIid } from './iid_service';\nimport { PerformanceController } from '../controllers/perf';\n\nconst FID_WAIT_TIME_MS = 5000;\n\nexport function setupOobResources(\n performanceController: PerformanceController\n): void {\n // Do not initialize unless iid is available.\n if (!getIid()) {\n return;\n }\n // The load event might not have fired yet, and that means performance navigation timing\n // object has a duration of 0. The setup should run after all current tasks in js queue.\n setTimeout(() => setupOobTraces(performanceController), 0);\n setTimeout(() => setupNetworkRequests(performanceController), 0);\n setTimeout(() => setupUserTimingTraces(performanceController), 0);\n}\n\nfunction setupNetworkRequests(\n performanceController: PerformanceController\n): void {\n const api = Api.getInstance();\n const resources = api.getEntriesByType('resource');\n for (const resource of resources) {\n createNetworkRequestEntry(performanceController, resource);\n }\n api.setupObserver('resource', entry =>\n createNetworkRequestEntry(performanceController, entry)\n );\n}\n\nfunction setupOobTraces(performanceController: PerformanceController): void {\n const api = Api.getInstance();\n const navigationTimings = api.getEntriesByType(\n 'navigation'\n ) as PerformanceNavigationTiming[];\n const paintTimings = api.getEntriesByType('paint');\n // If First Input Delay polyfill is added to the page, report the fid value.\n // https://github.com/GoogleChromeLabs/first-input-delay\n if (api.onFirstInputDelay) {\n // If the fid call back is not called for certain time, continue without it.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let timeoutId: any = setTimeout(() => {\n Trace.createOobTrace(\n performanceController,\n navigationTimings,\n paintTimings\n );\n timeoutId = undefined;\n }, FID_WAIT_TIME_MS);\n api.onFirstInputDelay((fid: number) => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n Trace.createOobTrace(\n performanceController,\n navigationTimings,\n paintTimings,\n fid\n );\n }\n });\n } else {\n Trace.createOobTrace(\n performanceController,\n navigationTimings,\n paintTimings\n );\n }\n}\n\nfunction setupUserTimingTraces(\n performanceController: PerformanceController\n): void {\n const api = Api.getInstance();\n // Run through the measure performance entries collected up to this point.\n const measures = api.getEntriesByType('measure');\n for (const measure of measures) {\n createUserTimingTrace(performanceController, measure);\n }\n // Setup an observer to capture the measures from this point on.\n api.setupObserver('measure', entry =>\n createUserTimingTrace(performanceController, entry)\n );\n}\n\nfunction createUserTimingTrace(\n performanceController: PerformanceController,\n measure: PerformanceEntry\n): void {\n const measureName = measure.name;\n // Do not create a trace, if the user timing marks and measures are created by the sdk itself.\n if (\n measureName.substring(0, TRACE_MEASURE_PREFIX.length) ===\n TRACE_MEASURE_PREFIX\n ) {\n return;\n }\n Trace.createUserTimingTrace(performanceController, measureName);\n}\n","/**\n * @license\n * Copyright 2020 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 { setupOobResources } from '../services/oob_resources_service';\nimport { SettingsService } from '../services/settings_service';\nimport { getInitializationPromise } from '../services/initialization_service';\nimport { Api } from '../services/api_service';\nimport { FirebaseApp } from '@firebase/app';\nimport { _FirebaseInstallationsInternal } from '@firebase/installations';\nimport { PerformanceSettings, FirebasePerformance } from '../public_types';\nimport { validateIndexedDBOpenable } from '@firebase/util';\nimport { setupTransportService } from '../services/transport_service';\nimport { consoleLogger } from '../utils/console_logger';\n\nexport class PerformanceController implements FirebasePerformance {\n private initialized: boolean = false;\n\n constructor(\n readonly app: FirebaseApp,\n readonly installations: _FirebaseInstallationsInternal\n ) {}\n\n /**\n * This method *must* be called internally as part of creating a\n * PerformanceController instance.\n *\n * Currently it's not possible to pass the settings object through the\n * constructor using Components, so this method exists to be called with the\n * desired settings, to ensure nothing is collected without the user's\n * consent.\n */\n _init(settings?: PerformanceSettings): void {\n if (this.initialized) {\n return;\n }\n\n if (settings?.dataCollectionEnabled !== undefined) {\n this.dataCollectionEnabled = settings.dataCollectionEnabled;\n }\n if (settings?.instrumentationEnabled !== undefined) {\n this.instrumentationEnabled = settings.instrumentationEnabled;\n }\n\n if (Api.getInstance().requiredApisAvailable()) {\n validateIndexedDBOpenable()\n .then(isAvailable => {\n if (isAvailable) {\n setupTransportService();\n getInitializationPromise(this).then(\n () => setupOobResources(this),\n () => setupOobResources(this)\n );\n this.initialized = true;\n }\n })\n .catch(error => {\n consoleLogger.info(`Environment doesn't support IndexedDB: ${error}`);\n });\n } else {\n consoleLogger.info(\n 'Firebase Performance cannot start if the browser does not support ' +\n '\"Fetch\" and \"Promise\", or cookies are disabled.'\n );\n }\n }\n\n set instrumentationEnabled(val: boolean) {\n SettingsService.getInstance().instrumentationEnabled = val;\n }\n get instrumentationEnabled(): boolean {\n return SettingsService.getInstance().instrumentationEnabled;\n }\n\n set dataCollectionEnabled(val: boolean) {\n SettingsService.getInstance().dataCollectionEnabled = val;\n }\n get dataCollectionEnabled(): boolean {\n return SettingsService.getInstance().dataCollectionEnabled;\n }\n}\n","/**\n * The Firebase Performance Monitoring Web SDK.\n * This SDK does not work in a Node.js environment.\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2020 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 FirebasePerformance,\n PerformanceSettings,\n PerformanceTrace\n} from './public_types';\nimport { ERROR_FACTORY, ErrorCode } from './utils/errors';\nimport { setupApi } from './services/api_service';\nimport { PerformanceController } from './controllers/perf';\nimport {\n _registerComponent,\n _getProvider,\n registerVersion,\n FirebaseApp,\n getApp\n} from '@firebase/app';\nimport {\n InstanceFactory,\n ComponentContainer,\n Component,\n ComponentType\n} from '@firebase/component';\nimport { name, version } from '../package.json';\nimport { Trace } from './resources/trace';\nimport '@firebase/installations';\nimport { deepEqual, getModularInstance } from '@firebase/util';\n\nconst DEFAULT_ENTRY_NAME = '[DEFAULT]';\n\n/**\n * Returns a {@link FirebasePerformance} instance for the given app.\n * @param app - The {@link @firebase/app#FirebaseApp} to use.\n * @public\n */\nexport function getPerformance(\n app: FirebaseApp = getApp()\n): FirebasePerformance {\n app = getModularInstance(app);\n const provider = _getProvider(app, 'performance');\n const perfInstance = provider.getImmediate() as PerformanceController;\n return perfInstance;\n}\n\n/**\n * Returns a {@link FirebasePerformance} instance for the given app. Can only be called once.\n * @param app - The {@link @firebase/app#FirebaseApp} to use.\n * @param settings - Optional settings for the {@link FirebasePerformance} instance.\n * @public\n */\nexport function initializePerformance(\n app: FirebaseApp,\n settings?: PerformanceSettings\n): FirebasePerformance {\n app = getModularInstance(app);\n const provider = _getProvider(app, 'performance');\n\n // throw if an instance was already created.\n // It could happen if initializePerformance() is called more than once, or getPerformance() is called first.\n if (provider.isInitialized()) {\n const existingInstance = provider.getImmediate();\n const initialSettings = provider.getOptions() as PerformanceSettings;\n if (deepEqual(initialSettings, settings ?? {})) {\n return existingInstance;\n } else {\n throw ERROR_FACTORY.create(ErrorCode.ALREADY_INITIALIZED);\n }\n }\n\n const perfInstance = provider.initialize({\n options: settings\n }) as PerformanceController;\n return perfInstance;\n}\n\n/**\n * Returns a new `PerformanceTrace` instance.\n * @param performance - The {@link FirebasePerformance} instance to use.\n * @param name - The name of the trace.\n * @public\n */\nexport function trace(\n performance: FirebasePerformance,\n name: string\n): PerformanceTrace {\n performance = getModularInstance(performance);\n return new Trace(performance as PerformanceController, name);\n}\n\nconst factory: InstanceFactory<'performance'> = (\n container: ComponentContainer,\n { options: settings }: { options?: PerformanceSettings }\n) => {\n // Dependencies\n const app = container.getProvider('app').getImmediate();\n const installations = container\n .getProvider('installations-internal')\n .getImmediate();\n\n if (app.name !== DEFAULT_ENTRY_NAME) {\n throw ERROR_FACTORY.create(ErrorCode.FB_NOT_DEFAULT);\n }\n if (typeof window === 'undefined') {\n throw ERROR_FACTORY.create(ErrorCode.NO_WINDOW);\n }\n setupApi(window);\n const perfInstance = new PerformanceController(app, installations);\n perfInstance._init(settings);\n\n return perfInstance;\n};\n\nfunction registerPerformance(): void {\n _registerComponent(\n new Component('performance', factory, ComponentType.PUBLIC)\n );\n registerVersion(name, version);\n // BUILD_TARGET will be replaced by values like esm2017, cjs2017, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n}\n\nregisterPerformance();\n\nexport { FirebasePerformance, PerformanceSettings, PerformanceTrace };\n","/**\n * @license\n * Copyright 2020 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 trace,\n FirebasePerformance,\n // The PerformanceTrace type has not changed between modular and non-modular packages.\n PerformanceTrace\n} from '@firebase/performance';\nimport { FirebasePerformance as FirebasePerformanceCompat } from '@firebase/performance-types';\nimport { FirebaseApp, _FirebaseService } from '@firebase/app-compat';\n\nexport class PerformanceCompatImpl\n implements FirebasePerformanceCompat, _FirebaseService\n{\n constructor(\n public app: FirebaseApp,\n readonly _delegate: FirebasePerformance\n ) {}\n\n get instrumentationEnabled(): boolean {\n return this._delegate.instrumentationEnabled;\n }\n\n set instrumentationEnabled(val: boolean) {\n this._delegate.instrumentationEnabled = val;\n }\n\n get dataCollectionEnabled(): boolean {\n return this._delegate.dataCollectionEnabled;\n }\n\n set dataCollectionEnabled(val: boolean) {\n this._delegate.dataCollectionEnabled = val;\n }\n\n trace(traceName: string): PerformanceTrace {\n return trace(this._delegate, traceName);\n }\n}\n","/**\n * @license\n * Copyright 2021 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 interface Compat<T> {\n _delegate: T;\n}\n\nexport function getModularInstance<ExpService>(\n service: Compat<ExpService> | ExpService\n): ExpService {\n if (service && (service as Compat<ExpService>)._delegate) {\n return (service as Compat<ExpService>)._delegate;\n } else {\n return service as ExpService;\n }\n}\n","/**\n * @license\n * Copyright 2020 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 firebase, { _FirebaseNamespace } from '@firebase/app-compat';\nimport {\n Component,\n ComponentContainer,\n ComponentType\n} from '@firebase/component';\nimport { PerformanceCompatImpl } from './performance';\nimport { name as packageName, version } from '../package.json';\nimport { FirebasePerformance as FirebasePerformanceCompat } from '@firebase/performance-types';\n\nfunction registerPerformanceCompat(firebaseInstance: _FirebaseNamespace): void {\n firebaseInstance.INTERNAL.registerComponent(\n new Component(\n 'performance-compat',\n performanceFactory,\n ComponentType.PUBLIC\n )\n );\n\n firebaseInstance.registerVersion(packageName, version);\n}\n\nfunction performanceFactory(\n container: ComponentContainer\n): PerformanceCompatImpl {\n const app = container.getProvider('app-compat').getImmediate();\n // The following call will always succeed.\n const performance = container.getProvider('performance').getImmediate();\n\n return new PerformanceCompatImpl(app, performance);\n}\n\nregisterPerformanceCompat(firebase as _FirebaseNamespace);\n\ndeclare module '@firebase/app-compat' {\n interface FirebaseNamespace {\n performance: {\n (app?: FirebaseApp): FirebasePerformanceCompat;\n };\n }\n interface FirebaseApp {\n performance(): FirebasePerformanceCompat;\n }\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 */\n\nimport firebase from './app';\nimport './performance';\nimport { name, version } from '../package.json';\n\nfirebase.registerVersion(name, version, 'compat-lite');\n\nexport default firebase;\n"],"names":["stringToByteArray","str","out","p","i","length","c","charCodeAt","base64","byteToCharMap_","charToByteMap_","byteToCharMapWebSafe_","charToByteMapWebSafe_","ENCODED_VALS_BASE","ENCODED_VALS","this","ENCODED_VALS_WEBSAFE","HAS_NATIVE_SUPPORT","atob","encodeByteArray","input","webSafe","Array","isArray","Error","init_","byteToCharMap","output","byte1","haveByte2","byte2","haveByte3","byte3","outByte1","outByte2","outByte3","outByte4","push","join","encodeString","btoa","decodeString","bytes","pos","c1","String","fromCharCode","c2","u","c3","byteArrayToString","decodeStringToByteArray","charToByteMap","charAt","byte4","DecodeBase64StringError","constructor","name","base64urlEncodeWithoutPadding","utf8Bytes","base64Encode","replace","deepExtend","target","source","Object","Date","getTime","undefined","prop","hasOwnProperty","getDefaultsFromGlobal","self","window","global","getGlobal","__FIREBASE_DEFAULTS__","getDefaultsFromCookie","document","match","cookie","e","decoded","console","error","base64Decode","JSON","parse","getDefaults","process","env","defaultsJsonString","getDefaultsFromEnvVariable","info","getDefaultAppConfig","_a","config","Deferred","reject","resolve","promise","Promise","wrapCallback","callback","value","catch","isWebWorker","WorkerGlobalScope","isIndexedDBAvailable","indexedDB","validateIndexedDBOpenable","preExist","DB_CHECK_NAME","request","open","onsuccess","result","close","deleteDatabase","onupgradeneeded","onerror","message","FirebaseError","code","customData","super","setPrototypeOf","prototype","captureStackTrace","ErrorFactory","create","service","serviceName","errors","data","fullCode","template","PATTERN","_","key","replaceTemplate","fullMessage","contains","obj","call","deepEqual","a","b","aKeys","keys","bKeys","k","includes","aProp","bProp","isObject","thing","Component","instanceFactory","type","multipleInstances","serviceProps","instantiationMode","onInstanceCreated","setInstantiationMode","mode","setMultipleInstances","setServiceProps","props","setInstanceCreatedCallback","DEFAULT_ENTRY_NAME","Provider","container","component","instances","Map","instancesDeferred","instancesOptions","onInitCallbacks","get","identifier","normalizedIdentifier","normalizeInstanceIdentifier","has","deferred","set","isInitialized","shouldAutoInitialize","instance","getOrInitializeService","instanceIdentifier","getImmediate","options","optional","getComponent","setComponent","isComponentEager","instanceDeferred","entries","clearInstance","delete","async","services","from","values","all","filter","map","INTERNAL","_delete","isComponentSet","getOptions","initialize","opts","onInit","existingCallbacks","Set","add","existingInstance","invokeOnInitCallbacks","callbacks","ComponentContainer","providers","addComponent","provider","getProvider","addOrOverwriteComponent","getProviders","LogLevel","levelStringToEnum","debug","DEBUG","verbose","VERBOSE","INFO","warn","WARN","ERROR","silent","SILENT","defaultLogLevel","ConsoleMethod","defaultLogHandler","logType","args","logLevel","now","toISOString","method","Logger","_logLevel","_logHandler","_userLogHandler","val","TypeError","setLogLevel","logHandler","userLogHandler","log","idbProxyableTypes","cursorAdvanceMethods","cursorRequestMap","WeakMap","transactionDoneMap","transactionStoreNamesMap","transformCache","reverseTransformCache","idbProxyTraps","receiver","IDBTransaction","objectStoreNames","objectStore","wrap","wrapFunction","func","IDBDatabase","transaction","IDBCursor","advance","continue","continuePrimaryKey","apply","unwrap","storeNames","tx","sort","transformCachableValue","done","unlisten","removeEventListener","complete","DOMException","addEventListener","cacheDonePromiseForTransaction","object","IDBObjectStore","IDBIndex","some","Proxy","IDBRequest","success","then","promisifyRequest","newValue","openDB","version","blocked","upgrade","blocking","terminated","openPromise","event","oldVersion","newVersion","db","readMethods","writeMethods","cachedMethods","getMethod","targetFuncName","useIndex","isWrite","storeName","store","index","shift","oldTraps","PlatformLoggerServiceImpl","getPlatformInfoString","isVersionServiceProvider","library","logString","logger","PLATFORM_LOG_STRING","name$q","appName","firebase","_apps","_serverApps","_components","_addComponent","app","_registerComponent","componentName","serverApp","_getProvider","heartbeatController","triggerHeartbeat","_isFirebaseApp","ERROR_FACTORY","FirebaseAppImpl","_isDeleted","_options","assign","_config","_name","_automaticDataCollectionEnabled","automaticDataCollectionEnabled","_container","checkDestroyed","isDeleted","FirebaseServerAppImpl","serverConfig","apiKey","_serverConfig","_finalizationRegistry","FinalizationRegistry","automaticCleanup","_refCount","incRefCount","releaseOnDeref","registerVersion","packageName","toJSON","refCount","register","decRefCount","deleteApp","settings","SDK_VERSION","initializeApp","rawConfig","existingApp","newApp","cleanupProviders","libraryKeyOrName","variant","libraryMismatch","versionMismatch","warning","onLog","logCallback","customLogLevel","level","arg","toString","stringify","ignored","toLowerCase","setUserLogHandler","forEach","inst","STORE_NAME","dbPromise","getDbPromise","createObjectStore","originalErrorMessage","writeHeartbeatsToIndexedDB","heartbeatObject","put","computeKey","idbGetError","appId","HeartbeatServiceImpl","_heartbeatsCache","_storage","HeartbeatStorageImpl","_heartbeatsCachePromise","read","agent","date","getUTCDateString","heartbeats","_b","lastSentHeartbeatDate","singleDateHeartbeat","hbTimestamp","valueOf","overwrite","heartbeatsToSend","unsentEntries","heartbeatsCache","maxSize","slice","heartbeatEntry","find","hb","dates","countBytes","pop","extractHeartbeatsForHeader","headerString","substring","_canUseIndexedDBPromise","runIndexedDBEnvironmentCheck","idbHeartbeatObject","readHeartbeatsFromIndexedDB","heartbeatsObject","existingHeartbeatsObject","clear","_serverAppConfig","appOptions","nameObj","nameString","s","reduce","hash","Math","imul","FirebaseAppLiteImpl","_delegate","removeApp","_getService","_DEFAULT_ENTRY_NAME","createFirebaseNamespaceCore","firebaseAppImpl","apps","namespace","__esModule","modularAPIs.initializeApp","appCompat","modularAPIs.registerVersion","modularAPIs.setLogLevel","modularAPIs.onLog","modularAPIs.SDK_VERSION","registerComponent","componentNameWithoutCompat","modularAPIs._registerComponent","serviceNamespace","appArg","bind","useAsService","modularAPIs","modularAPIs._DEFAULT_ENTRY_NAME","defineProperty","createFirebaseNamespaceLite","registerCoreComponents","PENDING_TIMEOUT_MS","PACKAGE_VERSION","INTERNAL_AUTH_VERSION","TOKEN_EXPIRATION_BUFFER","isServerError","getInstallationsEndpoint","projectId","extractAuthTokenInfoFromResponse","response","token","requestStatus","expiresIn","responseExpiresIn","Number","creationTime","getErrorFromResponse","requestName","errorData","json","serverCode","serverMessage","serverStatus","status","getHeaders","Headers","Accept","getHeadersWithAuth","appConfig","refreshToken","headers","append","getAuthorizationHeader","retryIfServerError","fn","sleep","ms","setTimeout","VALID_FID_PATTERN","generateFid","fidByteArray","Uint8Array","crypto","msCrypto","getRandomValues","fid","array","substr","encode","test","getKey","fidChangeCallbacks","fidChanged","callFidChangeCallbacks","channel","broadcastChannel","BroadcastChannel","onmessage","getBroadcastChannel","postMessage","size","broadcastFidChange","OBJECT_STORE_NAME","oldValue","remove","update","updateFn","getInstallationEntry","installations","registrationPromise","installationEntry","oldEntry","clearTimedOutRequest","registrationStatus","updateOrCreateInstallationEntry","entryWithPromise","navigator","onLine","inProgressEntry","registrationTime","registeredInstallationEntry","heartbeatServiceProvider","endpoint","heartbeatService","heartbeatsHeader","getHeartbeatsHeader","body","authVersion","sdkVersion","fetch","ok","responseValue","authToken","createInstallationRequest","registerInstallation","waitUntilFidRegistration","triggerRegistrationIfNecessary","entry","updateInstallationRequest","generateAuthTokenRequest","getGenerateAuthTokenEndpoint","installation","refreshAuthToken","forceRefresh","tokenPromise","isEntryRegistered","oldAuthToken","isAuthTokenExpired","isAuthTokenValid","updateAuthTokenRequest","waitUntilAuthTokenRequest","inProgressAuthToken","requestTime","makeAuthTokenRequestInProgressEntry","updatedInstallationEntry","fetchAuthTokenFromServer","getToken","installationsImpl","completeInstallationRegistration","getMissingValueError","valueName","INSTALLATIONS_NAME","internalFactory","getId","configKeys","keyName","extractAppConfig","TRACE_MEASURE_PREFIX","OOB_TRACE_PAGE_LOAD_PREFIX","FIRST_CONTENTFUL_PAINT_COUNTER_NAME","FIRST_INPUT_DELAY_COUNTER_NAME","CONFIG_LOCAL_STORAGE_KEY","CONFIG_EXPIRY_LOCAL_STORAGE_KEY","SERVICE_NAME","consoleLogger","apiInstance","windowInstance","iid","settingsServiceInstance","Api","performance","PerformanceObserver","windowLocation","location","cookieEnabled","localStorage","perfMetrics","onFirstInputDelay","getUrl","href","split","mark","measure","measureName","mark1","mark2","getEntriesByType","getEntriesByName","getTimeOrigin","timeOrigin","timing","navigationStart","requiredApisAvailable","setupObserver","entryType","list","getEntries","observe","entryTypes","static","getIid","mergeStrings","part1","part2","sizeDiff","resultArray","SettingsService","instrumentationEnabled","dataCollectionEnabled","loggingEnabled","tracesSamplingRate","networkRequestsSamplingRate","logEndPointUrl","flTransportEndpointUrl","transportKey","logSource","logTraceAfterSampling","logNetworkAfterSampling","configTimeToLive","getFlTransportFullUrl","concat","VisibilityState","RESERVED_ATTRIBUTE_PREFIXES","ATTRIBUTE_FORMAT_REGEX","RegExp","getServiceWorkerStatus","getInstance","serviceWorker","controller","getVisibilityState","visibilityState","VISIBLE","HIDDEN","UNKNOWN","getEffectiveConnectionType","navigatorConnection","connection","effectiveType","getAppId","firebaseApp","REMOTE_CONFIG_SDK_VERSION","DEFAULT_CONFIGS","FIS_AUTH_PREFIX","getConfig","performanceController","expiryString","getItem","expiry","configStringified","getStoredConfig","processConfig","installationsService","authTokenPromise","authTokenVal","getAuthTokenPromise","getProjectId","getApiKey","Request","Authorization","app_instance_id","app_instance_id_token","app_id","app_version","sdk_version","COULD_NOT_GET_CONFIG_MSG","getRemoteConfig","setItem","storeConfig","fpr_enabled","fpr_log_source","fpr_log_endpoint_url","fpr_log_transport_key","fpr_vc_network_request_sampling_rate","fpr_vc_trace_sampling_rate","shouldLogAfterSampling","samplingRate","random","initializationPromise","initializationStatus","getInitializationPromise","readyState","handler","getDocumentReadyComplete","iidPromise","iidVal","getIidPromise","changeInitializationStatus","initializePerf","DEFAULT_SEND_INTERVAL_MS","remainingTries","queue","isTransportSetup","processQueue","timeOffset","staged","splice","log_event","evt","source_extension_json_proto3","event_time_ms","eventTime","flTransportFullUrl","postToFlEndpoint","res","transportWait","nextRequestWaitMillis","requestOffset","isNaN","max","logResponseDetails","responseAction","sendEventsToFl","request_time_ms","client_info","client_type","js_client_info","log_source","dispatchQueueEvents","transportHandler","serializer","addToQueue","sendLog","resource","resourceType","logTrace","trace","settingsService","isAuto","sendTraceLog","networkRequest","networkRequestMetric","url","http_method","httpMethod","http_response_code","response_payload_bytes","responsePayloadBytes","client_start_time_us","startTimeUs","time_to_response_initiated_us","timeToResponseInitiatedUs","time_to_response_completed_us","timeToResponseCompletedUs","perfMetric","application_info","getApplicationInfo","network_request_metric","serializeNetworkRequest","traceMetric","is_auto","duration_us","durationUs","counters","customAttributes","getAttributes","custom_attributes","trace_metric","serializeTrace","google_app_id","web_app_info","page_url","service_worker_status","visibility_state","effective_connection_type","application_process_state","oobMetrics","Trace","traceMeasureName","state","api","randomId","floor","traceStartMark","traceStopMark","traceMeasure","calculateTraceMetrics","start","traceName","stop","record","startTime","duration","attributes","metrics","metricName","incrementMetric","counter","numAsInteger","putMetric","startsWith","indexOf","isValidMetricName","customMetricName","providedValue","valueAsInteger","convertMetricValueToInteger","getMetric","putAttribute","attr","isValidName","prefix","isValidCustomAttributeName","isValidValue","isValidCustomAttributeValue","attributeName","attributeValue","getAttribute","removeAttribute","setStartTime","setDuration","perfMeasureEntries","perfMeasureEntry","navigationTimings","paintTimings","firstInputDelay","route","timeOriginUs","domInteractive","domContentLoadedEventEnd","loadEventEnd","firstPaint","paintObject","firstContentfulPaint","createNetworkRequestEntry","performanceEntry","responseStart","responseEnd","networkRequestUrl","logEndpointUrl","flEndpointUrl","logNetworkRequest","transferSize","setupOobResources","timeoutId","createOobTrace","clearTimeout","setupOobTraces","resources","setupNetworkRequests","measures","createUserTimingTrace","setupUserTimingTraces","PerformanceController","initialized","_init","isAvailable","setupApi","perfInstance","PerformanceCompatImpl","performanceFactory","firebaseInstance"],"mappings":"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"}