{"version":3,"file":"firebase-messaging.js","sources":["../../node_modules/tslib/tslib.es6.js","../util/src/errors.ts","../component/src/component.ts","../../node_modules/idb/lib/idb.mjs","../installations/src/util/constants.ts","../installations/src/util/errors.ts","../installations/src/api/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/index.ts","../installations/src/helpers/get-installation-entry.ts","../installations/src/api/create-installation-request.ts","../installations/src/api/generate-auth-token-request.ts","../installations/src/helpers/refresh-auth-token.ts","../installations/src/functions/get-token.ts","../installations/src/api/delete-installation-request.ts","../installations/src/functions/on-id-change.ts","../installations/src/helpers/extract-app-config.ts","../installations/src/functions/get-id.ts","../installations/src/functions/delete-installation.ts","../messaging/src/util/errors.ts","../messaging/src/helpers/extract-app-config.ts","../messaging/src/util/constants.ts","../messaging/src/interfaces/internal-message.ts","../messaging/src/helpers/array-base64-translator.ts","../messaging/src/helpers/migrate-old-database.ts","../messaging/src/helpers/idb-manager.ts","../messaging/src/core/api.ts","../messaging/src/core/token-management.ts","../messaging/src/helpers/is-console-message.ts","../messaging/src/controllers/window-controller.ts","../messaging/src/controllers/sw-controller.ts","../messaging/src/helpers/sleep.ts","../messaging/src/index.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\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 = {\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('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.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap = {\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\nexport interface FirebaseError extends Error, ErrorData {\n // Unique code for error - format is service/error-code-string.\n readonly code: string;\n\n // Developer-friendly error message.\n readonly message: string;\n\n // Always 'FirebaseError'.\n readonly name: typeof ERROR_NAME;\n\n // Where available - stack backtrace in a string.\n readonly stack?: string;\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 readonly name = ERROR_NAME;\n\n constructor(readonly code: string, message: string) {\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 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\n ) {}\n\n create(\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);\n\n // Keys with an underscore at the end of their name are not included in\n // error.data for some reason.\n // TODO: Replace with Object.entries when lib is updated to es2017.\n for (const key of Object.keys(customData)) {\n if (key.slice(-1) !== '_') {\n if (key in error) {\n console.warn(\n `Overwriting FirebaseError base field \"${key}\" can cause unexpected behavior.`\n );\n }\n error[key] = customData[key];\n }\n }\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 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} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\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,\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","function toArray(arr) {\n return Array.prototype.slice.call(arr);\n}\n\nfunction promisifyRequest(request) {\n return new Promise(function(resolve, reject) {\n request.onsuccess = function() {\n resolve(request.result);\n };\n\n request.onerror = function() {\n reject(request.error);\n };\n });\n}\n\nfunction promisifyRequestCall(obj, method, args) {\n var request;\n var p = new Promise(function(resolve, reject) {\n request = obj[method].apply(obj, args);\n promisifyRequest(request).then(resolve, reject);\n });\n\n p.request = request;\n return p;\n}\n\nfunction promisifyCursorRequestCall(obj, method, args) {\n var p = promisifyRequestCall(obj, method, args);\n return p.then(function(value) {\n if (!value) return;\n return new Cursor(value, p.request);\n });\n}\n\nfunction proxyProperties(ProxyClass, targetProp, properties) {\n properties.forEach(function(prop) {\n Object.defineProperty(ProxyClass.prototype, prop, {\n get: function() {\n return this[targetProp][prop];\n },\n set: function(val) {\n this[targetProp][prop] = val;\n }\n });\n });\n}\n\nfunction proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) {\n properties.forEach(function(prop) {\n if (!(prop in Constructor.prototype)) return;\n ProxyClass.prototype[prop] = function() {\n return promisifyRequestCall(this[targetProp], prop, arguments);\n };\n });\n}\n\nfunction proxyMethods(ProxyClass, targetProp, Constructor, properties) {\n properties.forEach(function(prop) {\n if (!(prop in Constructor.prototype)) return;\n ProxyClass.prototype[prop] = function() {\n return this[targetProp][prop].apply(this[targetProp], arguments);\n };\n });\n}\n\nfunction proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) {\n properties.forEach(function(prop) {\n if (!(prop in Constructor.prototype)) return;\n ProxyClass.prototype[prop] = function() {\n return promisifyCursorRequestCall(this[targetProp], prop, arguments);\n };\n });\n}\n\nfunction Index(index) {\n this._index = index;\n}\n\nproxyProperties(Index, '_index', [\n 'name',\n 'keyPath',\n 'multiEntry',\n 'unique'\n]);\n\nproxyRequestMethods(Index, '_index', IDBIndex, [\n 'get',\n 'getKey',\n 'getAll',\n 'getAllKeys',\n 'count'\n]);\n\nproxyCursorRequestMethods(Index, '_index', IDBIndex, [\n 'openCursor',\n 'openKeyCursor'\n]);\n\nfunction Cursor(cursor, request) {\n this._cursor = cursor;\n this._request = request;\n}\n\nproxyProperties(Cursor, '_cursor', [\n 'direction',\n 'key',\n 'primaryKey',\n 'value'\n]);\n\nproxyRequestMethods(Cursor, '_cursor', IDBCursor, [\n 'update',\n 'delete'\n]);\n\n// proxy 'next' methods\n['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) {\n if (!(methodName in IDBCursor.prototype)) return;\n Cursor.prototype[methodName] = function() {\n var cursor = this;\n var args = arguments;\n return Promise.resolve().then(function() {\n cursor._cursor[methodName].apply(cursor._cursor, args);\n return promisifyRequest(cursor._request).then(function(value) {\n if (!value) return;\n return new Cursor(value, cursor._request);\n });\n });\n };\n});\n\nfunction ObjectStore(store) {\n this._store = store;\n}\n\nObjectStore.prototype.createIndex = function() {\n return new Index(this._store.createIndex.apply(this._store, arguments));\n};\n\nObjectStore.prototype.index = function() {\n return new Index(this._store.index.apply(this._store, arguments));\n};\n\nproxyProperties(ObjectStore, '_store', [\n 'name',\n 'keyPath',\n 'indexNames',\n 'autoIncrement'\n]);\n\nproxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [\n 'put',\n 'add',\n 'delete',\n 'clear',\n 'get',\n 'getAll',\n 'getKey',\n 'getAllKeys',\n 'count'\n]);\n\nproxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [\n 'openCursor',\n 'openKeyCursor'\n]);\n\nproxyMethods(ObjectStore, '_store', IDBObjectStore, [\n 'deleteIndex'\n]);\n\nfunction Transaction(idbTransaction) {\n this._tx = idbTransaction;\n this.complete = new Promise(function(resolve, reject) {\n idbTransaction.oncomplete = function() {\n resolve();\n };\n idbTransaction.onerror = function() {\n reject(idbTransaction.error);\n };\n idbTransaction.onabort = function() {\n reject(idbTransaction.error);\n };\n });\n}\n\nTransaction.prototype.objectStore = function() {\n return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments));\n};\n\nproxyProperties(Transaction, '_tx', [\n 'objectStoreNames',\n 'mode'\n]);\n\nproxyMethods(Transaction, '_tx', IDBTransaction, [\n 'abort'\n]);\n\nfunction UpgradeDB(db, oldVersion, transaction) {\n this._db = db;\n this.oldVersion = oldVersion;\n this.transaction = new Transaction(transaction);\n}\n\nUpgradeDB.prototype.createObjectStore = function() {\n return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments));\n};\n\nproxyProperties(UpgradeDB, '_db', [\n 'name',\n 'version',\n 'objectStoreNames'\n]);\n\nproxyMethods(UpgradeDB, '_db', IDBDatabase, [\n 'deleteObjectStore',\n 'close'\n]);\n\nfunction DB(db) {\n this._db = db;\n}\n\nDB.prototype.transaction = function() {\n return new Transaction(this._db.transaction.apply(this._db, arguments));\n};\n\nproxyProperties(DB, '_db', [\n 'name',\n 'version',\n 'objectStoreNames'\n]);\n\nproxyMethods(DB, '_db', IDBDatabase, [\n 'close'\n]);\n\n// Add cursor iterators\n// TODO: remove this once browsers do the right thing with promises\n['openCursor', 'openKeyCursor'].forEach(function(funcName) {\n [ObjectStore, Index].forEach(function(Constructor) {\n // Don't create iterateKeyCursor if openKeyCursor doesn't exist.\n if (!(funcName in Constructor.prototype)) return;\n\n Constructor.prototype[funcName.replace('open', 'iterate')] = function() {\n var args = toArray(arguments);\n var callback = args[args.length - 1];\n var nativeObject = this._store || this._index;\n var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1));\n request.onsuccess = function() {\n callback(request.result);\n };\n };\n });\n});\n\n// polyfill getAll\n[Index, ObjectStore].forEach(function(Constructor) {\n if (Constructor.prototype.getAll) return;\n Constructor.prototype.getAll = function(query, count) {\n var instance = this;\n var items = [];\n\n return new Promise(function(resolve) {\n instance.iterateCursor(query, function(cursor) {\n if (!cursor) {\n resolve(items);\n return;\n }\n items.push(cursor.value);\n\n if (count !== undefined && items.length == count) {\n resolve(items);\n return;\n }\n cursor.continue();\n });\n });\n };\n});\n\nexport function openDb(name, version, upgradeCallback) {\n var p = promisifyRequestCall(indexedDB, 'open', [name, version]);\n var request = p.request;\n\n if (request) {\n request.onupgradeneeded = function(event) {\n if (upgradeCallback) {\n upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction));\n }\n };\n }\n\n return p.then(function(db) {\n return new DB(db);\n });\n}\n\nexport function deleteDb(name) {\n return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]);\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 { 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(\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 & 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 { AppConfig } from '../interfaces/app-config';\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';\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 {\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\n): Promise {\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 {\n return new Promise(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/app-config';\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/app-config';\nimport { IdChangeCallbackFn } from '../functions';\n\nconst fidChangeCallbacks: Map> = 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 { DB, openDb } from 'idb';\nimport { AppConfig } from '../interfaces/app-config';\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\nlet dbPromise: Promise | null = null;\nfunction getDbPromise(): Promise {\n if (!dbPromise) {\n dbPromise = openDb(DATABASE_NAME, DATABASE_VERSION, upgradeDB => {\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 (upgradeDB.oldVersion) {\n case 0:\n upgradeDB.createObjectStore(OBJECT_STORE_NAME);\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 {\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);\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function set(\n appConfig: AppConfig,\n value: ValueType\n): Promise {\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);\n await objectStore.put(value, key);\n await tx.complete;\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 {\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.complete;\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(\n appConfig: AppConfig,\n updateFn: (previousValue: InstallationEntry | undefined) => ValueType\n): Promise {\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(key);\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.complete;\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 {\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.complete;\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 '@firebase/app';\nimport {\n _FirebaseNamespace,\n FirebaseService\n} from '@firebase/app-types/private';\nimport { Component, ComponentType } from '@firebase/component';\nimport { FirebaseInstallations } from '@firebase/installations-types';\nimport {\n deleteInstallation,\n getId,\n getToken,\n IdChangeCallbackFn,\n IdChangeUnsubscribeFn,\n onIdChange\n} from './functions';\nimport { extractAppConfig } from './helpers/extract-app-config';\nimport { FirebaseDependencies } from './interfaces/firebase-dependencies';\n\nimport { name, version } from '../package.json';\n\nexport function registerInstallations(instance: _FirebaseNamespace): void {\n const installationsName = 'installations';\n\n instance.INTERNAL.registerComponent(\n new Component(\n installationsName,\n container => {\n const app = container.getProvider('app').getImmediate();\n\n // Throws if app isn't configured properly.\n const appConfig = extractAppConfig(app);\n const platformLoggerProvider = container.getProvider('platform-logger');\n const dependencies: FirebaseDependencies = {\n appConfig,\n platformLoggerProvider\n };\n\n const installations: FirebaseInstallations & FirebaseService = {\n app,\n getId: () => getId(dependencies),\n getToken: (forceRefresh?: boolean) =>\n getToken(dependencies, forceRefresh),\n delete: () => deleteInstallation(dependencies),\n onIdChange: (callback: IdChangeCallbackFn): IdChangeUnsubscribeFn =>\n onIdChange(dependencies, callback)\n };\n return installations;\n },\n ComponentType.PUBLIC\n )\n );\n\n instance.registerVersion(name, version);\n}\n\nregisterInstallations(firebase as _FirebaseNamespace);\n\n/**\n * Define extension behavior of `registerInstallations`\n */\ndeclare module '@firebase/app-types' {\n interface FirebaseNamespace {\n installations(app?: FirebaseApp): FirebaseInstallations;\n }\n interface FirebaseApp {\n installations(): FirebaseInstallations;\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 { createInstallationRequest } from '../api/create-installation-request';\nimport { AppConfig } from '../interfaces/app-config';\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;\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 appConfig: AppConfig\n): Promise {\n let registrationPromise: Promise | undefined;\n\n const installationEntry = await update(appConfig, oldEntry => {\n const installationEntry = updateOrCreateInstallationEntry(oldEntry);\n const entryWithPromise = triggerRegistrationIfNecessary(\n appConfig,\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 appConfig: AppConfig,\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 appConfig,\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(appConfig)\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 appConfig: AppConfig,\n installationEntry: InProgressInstallationEntry\n): Promise {\n try {\n const registeredInstallationEntry = await createInstallationRequest(\n appConfig,\n installationEntry\n );\n return set(appConfig, registeredInstallationEntry);\n } catch (e) {\n if (isServerError(e) && e.serverCode === 409) {\n // Server returned a \"FID can not be used\" error.\n // Generate a new ID next time.\n await remove(appConfig);\n } else {\n // Registration failed. Set FID as not registered.\n await set(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 appConfig: AppConfig\n): Promise {\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(appConfig);\n while (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // createInstallation request still in progress.\n await sleep(100);\n\n entry = await updateInstallationRequest(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 {\n installationEntry,\n registrationPromise\n } = await getInstallationEntry(appConfig);\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 {\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 { AppConfig } from '../interfaces/app-config';\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';\n\nexport async function createInstallationRequest(\n appConfig: AppConfig,\n { fid }: InProgressInstallationEntry\n): Promise {\n const endpoint = getInstallationsEndpoint(appConfig);\n\n const headers = getHeaders(appConfig);\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 { AppConfig } from '../interfaces/app-config';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\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';\n\nexport async function generateAuthTokenRequest(\n { appConfig, platformLoggerProvider }: FirebaseDependencies,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n\n // If platform logger exists, add the platform info string to the header.\n const platformLogger = platformLoggerProvider.getImmediate({\n optional: true\n });\n if (platformLogger) {\n headers.append('x-firebase-client', platformLogger.getPlatformInfoString());\n }\n\n const body = {\n installation: {\n sdkVersion: PACKAGE_VERSION\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 = extractAuthTokenInfoFromResponse(\n responseValue\n );\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 '../api/generate-auth-token-request';\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\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 dependencies: FirebaseDependencies,\n forceRefresh = false\n): Promise {\n let tokenPromise: Promise | undefined;\n const entry = await update(dependencies.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(dependencies, 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(dependencies, 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 dependencies: FirebaseDependencies,\n forceRefresh: boolean\n): Promise {\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(dependencies.appConfig);\n while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // generateAuthToken still in progress.\n await sleep(100);\n\n entry = await updateAuthTokenRequest(dependencies.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(dependencies, 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 {\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 dependencies: FirebaseDependencies,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n try {\n const authToken = await generateAuthTokenRequest(\n dependencies,\n installationEntry\n );\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken\n };\n await set(dependencies.appConfig, updatedInstallationEntry);\n return authToken;\n } catch (e) {\n if (isServerError(e) && (e.serverCode === 401 || e.serverCode === 404)) {\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\n // Generate a new ID next time.\n await remove(dependencies.appConfig);\n } else {\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n await set(dependencies.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 { AppConfig } from '../interfaces/app-config';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\n\nexport async function getToken(\n dependencies: FirebaseDependencies,\n forceRefresh = false\n): Promise {\n await completeInstallationRegistration(dependencies.appConfig);\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(dependencies, forceRefresh);\n return authToken.token;\n}\n\nasync function completeInstallationRegistration(\n appConfig: AppConfig\n): Promise {\n const { registrationPromise } = await getInstallationEntry(appConfig);\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 { AppConfig } from '../interfaces/app-config';\nimport { RegisteredInstallationEntry } from '../interfaces/installation-entry';\nimport {\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\n\nexport async function deleteInstallationRequest(\n appConfig: AppConfig,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getDeleteEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n const request: RequestInit = {\n method: 'DELETE',\n headers\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (!response.ok) {\n throw await getErrorFromResponse('Delete Installation', response);\n }\n}\n\nfunction getDeleteEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}`;\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 { addCallback, removeCallback } from '../helpers/fid-changed';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\n\nexport type IdChangeCallbackFn = (installationId: string) => void;\nexport type IdChangeUnsubscribeFn = () => void;\n\n/**\n * Sets a new callback that will get called when Installation ID changes.\n * Returns an unsubscribe function that will remove the callback when called.\n */\nexport function onIdChange(\n { appConfig }: FirebaseDependencies,\n callback: IdChangeCallbackFn\n): IdChangeUnsubscribeFn {\n addCallback(appConfig, callback);\n\n return () => {\n removeCallback(appConfig, callback);\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-types';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/app-config';\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 = [\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 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 { FirebaseDependencies } from '../interfaces/firebase-dependencies';\n\nexport async function getId(\n dependencies: FirebaseDependencies\n): Promise {\n const { installationEntry, registrationPromise } = await getInstallationEntry(\n dependencies.appConfig\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(dependencies).catch(console.error);\n }\n\n return installationEntry.fid;\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 { deleteInstallationRequest } from '../api/delete-installation-request';\nimport { remove, update } from '../helpers/idb-manager';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\nimport { RequestStatus } from '../interfaces/installation-entry';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport async function deleteInstallation(\n dependencies: FirebaseDependencies\n): Promise {\n const { appConfig } = dependencies;\n\n const entry = await update(appConfig, oldEntry => {\n if (oldEntry && oldEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n // Delete the unregistered entry without sending a deleteInstallation request.\n return undefined;\n }\n return oldEntry;\n });\n\n if (entry) {\n if (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // Can't delete while trying to register.\n throw ERROR_FACTORY.create(ErrorCode.DELETE_PENDING_REGISTRATION);\n } else if (entry.registrationStatus === RequestStatus.COMPLETED) {\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n } else {\n await deleteInstallationRequest(appConfig, entry);\n await remove(appConfig);\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 { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n AVAILABLE_IN_WINDOW = 'only-available-in-window',\n AVAILABLE_IN_SW = 'only-available-in-sw',\n PERMISSION_DEFAULT = 'permission-default',\n PERMISSION_BLOCKED = 'permission-blocked',\n UNSUPPORTED_BROWSER = 'unsupported-browser',\n FAILED_DEFAULT_REGISTRATION = 'failed-service-worker-registration',\n TOKEN_SUBSCRIBE_FAILED = 'token-subscribe-failed',\n TOKEN_SUBSCRIBE_NO_TOKEN = 'token-subscribe-no-token',\n TOKEN_UNSUBSCRIBE_FAILED = 'token-unsubscribe-failed',\n TOKEN_UPDATE_FAILED = 'token-update-failed',\n TOKEN_UPDATE_NO_TOKEN = 'token-update-no-token',\n INVALID_BG_HANDLER = 'invalid-bg-handler',\n USE_SW_AFTER_GET_TOKEN = 'use-sw-after-get-token',\n INVALID_SW_REGISTRATION = 'invalid-sw-registration',\n USE_VAPID_KEY_AFTER_GET_TOKEN = 'use-vapid-key-after-get-token',\n INVALID_VAPID_KEY = 'invalid-vapid-key'\n}\n\nexport const ERROR_MAP: ErrorMap = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.AVAILABLE_IN_WINDOW]:\n 'This method is available in a Window context.',\n [ErrorCode.AVAILABLE_IN_SW]:\n 'This method is available in a service worker context.',\n [ErrorCode.PERMISSION_DEFAULT]:\n 'The notification permission was not granted and dismissed instead.',\n [ErrorCode.PERMISSION_BLOCKED]:\n 'The notification permission was not granted and blocked instead.',\n [ErrorCode.UNSUPPORTED_BROWSER]:\n \"This browser doesn't support the API's required to use the firebase SDK.\",\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]:\n 'We are unable to register the default service worker. {$browserErrorMessage}',\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]:\n 'A problem occured while subscribing the user to FCM: {$errorInfo}',\n [ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN]:\n 'FCM returned no token when subscribing the user to push.',\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]:\n 'A problem occured while unsubscribing the ' +\n 'user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_FAILED]:\n 'A problem occured while updating the user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_NO_TOKEN]:\n 'FCM returned no token when updating the user to push.',\n [ErrorCode.USE_SW_AFTER_GET_TOKEN]:\n 'The useServiceWorker() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your service worker is used.',\n [ErrorCode.INVALID_SW_REGISTRATION]:\n 'The input to useServiceWorker() must be a ServiceWorkerRegistration.',\n [ErrorCode.INVALID_BG_HANDLER]:\n 'The input to setBackgroundMessageHandler() must be a function.',\n [ErrorCode.INVALID_VAPID_KEY]: 'The public VAPID key must be a string.',\n [ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN]:\n 'The usePublicVapidKey() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your VAPID key is used.'\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]: { browserErrorMessage: string };\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UPDATE_FAILED]: { errorInfo: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'messaging',\n 'Messaging',\n ERROR_MAP\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-types';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/app-config';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration Object');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: ReadonlyArray = [\n 'projectId',\n 'apiKey',\n 'appId',\n 'messagingSenderId'\n ];\n\n const { options } = app;\n for (const keyName of configKeys) {\n if (!options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: options.projectId!,\n apiKey: options.apiKey!,\n appId: options.appId!,\n senderId: options.messagingSenderId!\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 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_SW_PATH = '/firebase-messaging-sw.js';\nexport const DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope';\n\nexport const DEFAULT_VAPID_KEY =\n 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4';\n\nexport const ENDPOINT = 'https://fcmregistrations.googleapis.com/v1';\n\n/** Key of FCM Payload in Notification's data field. */\nexport const FCM_MSG = 'FCM_MSG';\n\nexport const CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id';\nexport const CONSOLE_CAMPAIGN_NAME = 'google.c.a.c_l';\nexport const CONSOLE_CAMPAIGN_TIME = 'google.c.a.ts';\n/** Set to '1' if Analytics is enabled for the campaign */\nexport const CONSOLE_CAMPAIGN_ANALYTICS_ENABLED = 'google.c.a.e';\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 { MessagePayload } from './message-payload';\n\nexport enum MessageType {\n PUSH_RECEIVED = 'push-received',\n NOTIFICATION_CLICKED = 'notification-clicked'\n}\n\nexport interface InternalMessage {\n firebaseMessaging: {\n type: MessageType;\n payload: MessagePayload;\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 function arrayToBase64(array: Uint8Array | ArrayBuffer): string {\n const uint8Array = new Uint8Array(array);\n const base64String = btoa(String.fromCharCode(...uint8Array));\n return base64String.replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n\nexport function base64ToArray(base64String: string): Uint8Array {\n const padding = '='.repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding)\n .replace(/\\-/g, '+')\n .replace(/_/g, '/');\n\n const rawData = atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n return outputArray;\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 { openDb, deleteDb } from 'idb';\nimport { TokenDetails } from '../interfaces/token-details';\nimport { arrayToBase64 } from './array-base64-translator';\n\n// https://github.com/firebase/firebase-js-sdk/blob/7857c212f944a2a9eb421fd4cb7370181bc034b5/packages/messaging/src/interfaces/token-details.ts\nexport interface V2TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: string | Uint8Array;\n subscription: PushSubscription;\n fcmSenderId: string;\n fcmPushSet: string;\n createTime?: number;\n endpoint?: string;\n auth?: string;\n p256dh?: string;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/6b5b15ce4ea3df5df5df8a8b33a4e41e249c7715/packages/messaging/src/interfaces/token-details.ts\nexport interface V3TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n fcmPushSet: string;\n endpoint: string;\n auth: ArrayBuffer;\n p256dh: ArrayBuffer;\n createTime: number;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/9567dba664732f681fa7fe60f5b7032bb1daf4c9/packages/messaging/src/interfaces/token-details.ts\nexport interface V4TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n endpoint: string;\n auth: ArrayBufferLike;\n p256dh: ArrayBufferLike;\n createTime: number;\n}\n\nconst OLD_DB_NAME = 'fcm_token_details_db';\n/**\n * The last DB version of 'fcm_token_details_db' was 4. This is one higher,\n * so that the upgrade callback is called for all versions of the old DB.\n */\nconst OLD_DB_VERSION = 5;\nconst OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';\n\nexport async function migrateOldDatabase(\n senderId: string\n): Promise {\n if ('databases' in indexedDB) {\n // indexedDb.databases() is an IndexedDB v3 API\n // and does not exist in all browsers.\n // TODO: Remove typecast when it lands in TS types.\n const databases = await (indexedDB as {\n databases(): Promise>;\n }).databases();\n const dbNames = databases.map(db => db.name);\n\n if (!dbNames.includes(OLD_DB_NAME)) {\n // old DB didn't exist, no need to open.\n return null;\n }\n }\n\n let tokenDetails: TokenDetails | null = null;\n\n const db = await openDb(OLD_DB_NAME, OLD_DB_VERSION, async db => {\n if (db.oldVersion < 2) {\n // Database too old, skip migration.\n return;\n }\n\n if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {\n // Database did not exist. Nothing to do.\n return;\n }\n\n const objectStore = db.transaction.objectStore(OLD_OBJECT_STORE_NAME);\n const value = await objectStore.index('fcmSenderId').get(senderId);\n await objectStore.clear();\n\n if (!value) {\n // No entry in the database, nothing to migrate.\n return;\n }\n\n if (db.oldVersion === 2) {\n const oldDetails = value as V2TokenDetails;\n\n if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {\n return;\n }\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime ?? Date.now(),\n subscriptionOptions: {\n auth: oldDetails.auth,\n p256dh: oldDetails.p256dh,\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey:\n typeof oldDetails.vapidKey === 'string'\n ? oldDetails.vapidKey\n : arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (db.oldVersion === 3) {\n const oldDetails = value as V3TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (db.oldVersion === 4) {\n const oldDetails = value as V4TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n }\n });\n db.close();\n\n // Delete all old databases.\n await deleteDb(OLD_DB_NAME);\n await deleteDb('fcm_vapid_details_db');\n await deleteDb('undefined');\n\n return checkTokenDetails(tokenDetails) ? tokenDetails : null;\n}\n\nfunction checkTokenDetails(\n tokenDetails: TokenDetails | null\n): tokenDetails is TokenDetails {\n if (!tokenDetails || !tokenDetails.subscriptionOptions) {\n return false;\n }\n const { subscriptionOptions } = tokenDetails;\n return (\n typeof tokenDetails.createTime === 'number' &&\n tokenDetails.createTime > 0 &&\n typeof tokenDetails.token === 'string' &&\n tokenDetails.token.length > 0 &&\n typeof subscriptionOptions.auth === 'string' &&\n subscriptionOptions.auth.length > 0 &&\n typeof subscriptionOptions.p256dh === 'string' &&\n subscriptionOptions.p256dh.length > 0 &&\n typeof subscriptionOptions.endpoint === 'string' &&\n subscriptionOptions.endpoint.length > 0 &&\n typeof subscriptionOptions.swScope === 'string' &&\n subscriptionOptions.swScope.length > 0 &&\n typeof subscriptionOptions.vapidKey === 'string' &&\n subscriptionOptions.vapidKey.length > 0\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 { DB, openDb, deleteDb } from 'idb';\nimport { TokenDetails } from '../interfaces/token-details';\nimport { migrateOldDatabase } from './migrate-old-database';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\n\n// Exported for tests.\nexport const DATABASE_NAME = 'firebase-messaging-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-messaging-store';\n\nlet dbPromise: Promise | null = null;\nfunction getDbPromise(): Promise {\n if (!dbPromise) {\n dbPromise = openDb(DATABASE_NAME, DATABASE_VERSION, upgradeDb => {\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 (upgradeDb.oldVersion) {\n case 0:\n upgradeDb.createObjectStore(OBJECT_STORE_NAME);\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function dbGet(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tokenDetails = await db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key);\n\n if (tokenDetails) {\n return tokenDetails;\n } else {\n // Check if there is a tokenDetails object in the old DB.\n const oldTokenDetails = await migrateOldDatabase(\n firebaseDependencies.appConfig.senderId\n );\n if (oldTokenDetails) {\n await dbSet(firebaseDependencies, oldTokenDetails);\n return oldTokenDetails;\n }\n }\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function dbSet(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key);\n await tx.complete;\n return tokenDetails;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function dbRemove(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\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.complete;\n}\n\n/** Deletes the DB. Useful for tests. */\nexport async function dbDelete(): Promise {\n if (dbPromise) {\n (await dbPromise).close();\n await deleteDb(DATABASE_NAME);\n dbPromise = null;\n }\n}\n\nfunction getKey({ appConfig }: FirebaseInternalDependencies): string {\n return 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 { ErrorCode, ERROR_FACTORY } from '../util/errors';\nimport { DEFAULT_VAPID_KEY, ENDPOINT } from '../util/constants';\nimport { TokenDetails, SubscriptionOptions } from '../interfaces/token-details';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { AppConfig } from '../interfaces/app-config';\n\nexport interface ApiResponse {\n token?: string;\n error?: { message: string };\n}\n\nexport interface ApiRequestBody {\n web: {\n endpoint: string;\n p256dh: string;\n auth: string;\n applicationPubKey?: string;\n };\n}\n\nexport async function requestGetToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(subscriptionOptions);\n\n const subscribeOptions = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n getEndpoint(firebaseDependencies.appConfig),\n subscribeOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: err\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestUpdateToken(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(tokenDetails.subscriptionOptions!);\n\n const updateOptions = {\n method: 'PATCH',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${tokenDetails.token}`,\n updateOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: err\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestDeleteToken(\n firebaseDependencies: FirebaseInternalDependencies,\n token: string\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n\n const unsubscribeOptions = {\n method: 'DELETE',\n headers\n };\n\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${token}`,\n unsubscribeOptions\n );\n const responseData: ApiResponse = await response.json();\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: err\n });\n }\n}\n\nfunction getEndpoint({ projectId }: AppConfig): string {\n return `${ENDPOINT}/projects/${projectId!}/registrations`;\n}\n\nasync function getHeaders({\n appConfig,\n installations\n}: FirebaseInternalDependencies): Promise {\n const authToken = await installations.getToken();\n\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': appConfig.apiKey!,\n 'x-goog-firebase-installations-auth': `FIS ${authToken}`\n });\n}\n\nfunction getBody({\n p256dh,\n auth,\n endpoint,\n vapidKey\n}: SubscriptionOptions): ApiRequestBody {\n const body: ApiRequestBody = {\n web: {\n endpoint,\n auth,\n p256dh\n }\n };\n\n if (vapidKey !== DEFAULT_VAPID_KEY) {\n body.web.applicationPubKey = vapidKey;\n }\n\n return body;\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 { dbGet, dbSet, dbRemove } from '../helpers/idb-manager';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { TokenDetails, SubscriptionOptions } from '../interfaces/token-details';\nimport { requestUpdateToken, requestGetToken, requestDeleteToken } from './api';\nimport {\n arrayToBase64,\n base64ToArray\n} from '../helpers/array-base64-translator';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\n/** UpdateRegistration will be called once every week. */\nconst TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport async function getToken(\n firebaseDependencies: FirebaseInternalDependencies,\n swRegistration: ServiceWorkerRegistration,\n vapidKey: string\n): Promise {\n if (Notification.permission !== 'granted') {\n throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED);\n }\n\n // If a PushSubscription exists it's returned, otherwise a new subscription\n // is generated and returned.\n const pushSubscription = await getPushSubscription(swRegistration, vapidKey);\n const tokenDetails = await dbGet(firebaseDependencies);\n\n const subscriptionOptions: SubscriptionOptions = {\n vapidKey,\n swScope: swRegistration.scope,\n endpoint: pushSubscription.endpoint,\n auth: arrayToBase64(pushSubscription.getKey('auth')!),\n p256dh: arrayToBase64(pushSubscription.getKey('p256dh')!)\n };\n\n if (!tokenDetails) {\n // No token, get a new one.\n return getNewToken(firebaseDependencies, subscriptionOptions);\n } else if (\n !isTokenValid(tokenDetails.subscriptionOptions!, subscriptionOptions)\n ) {\n // Invalid token, get a new one.\n try {\n await requestDeleteToken(firebaseDependencies, tokenDetails.token);\n } catch (e) {\n // Suppress errors because of #2364\n console.warn(e);\n }\n\n return getNewToken(firebaseDependencies, subscriptionOptions);\n } else if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {\n // Weekly token refresh\n return updateToken(\n {\n token: tokenDetails.token,\n createTime: Date.now(),\n subscriptionOptions\n },\n firebaseDependencies,\n swRegistration\n );\n } else {\n // Valid token, nothing to do.\n return tokenDetails.token;\n }\n}\n\n/**\n * This method deletes the token from the database, unsubscribes the token from\n * FCM, and unregisters the push subscription if it exists.\n */\nexport async function deleteToken(\n firebaseDependencies: FirebaseInternalDependencies,\n swRegistration: ServiceWorkerRegistration\n): Promise {\n const tokenDetails = await dbGet(firebaseDependencies);\n if (tokenDetails) {\n await requestDeleteToken(firebaseDependencies, tokenDetails.token);\n await dbRemove(firebaseDependencies);\n }\n\n // Unsubscribe from the push subscription.\n const pushSubscription = await swRegistration.pushManager.getSubscription();\n if (pushSubscription) {\n return pushSubscription.unsubscribe();\n }\n\n // If there's no SW, consider it a success.\n return true;\n}\n\nasync function updateToken(\n tokenDetails: TokenDetails,\n firebaseDependencies: FirebaseInternalDependencies,\n swRegistration: ServiceWorkerRegistration\n): Promise {\n try {\n const updatedToken = await requestUpdateToken(\n firebaseDependencies,\n tokenDetails\n );\n\n const updatedTokenDetails: TokenDetails = {\n ...tokenDetails,\n token: updatedToken,\n createTime: Date.now()\n };\n\n await dbSet(firebaseDependencies, updatedTokenDetails);\n return updatedToken;\n } catch (e) {\n await deleteToken(firebaseDependencies, swRegistration);\n throw e;\n }\n}\n\nasync function getNewToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const token = await requestGetToken(\n firebaseDependencies,\n subscriptionOptions\n );\n const tokenDetails: TokenDetails = {\n token,\n createTime: Date.now(),\n subscriptionOptions\n };\n await dbSet(firebaseDependencies, tokenDetails);\n return tokenDetails.token;\n}\n\n/**\n * Gets a PushSubscription for the current user.\n */\nasync function getPushSubscription(\n swRegistration: ServiceWorkerRegistration,\n vapidKey: string\n): Promise {\n const subscription = await swRegistration.pushManager.getSubscription();\n if (subscription) {\n return subscription;\n }\n return swRegistration.pushManager.subscribe({\n userVisibleOnly: true,\n // Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key\n // submitted to pushManager#subscribe must be of type Uint8Array.\n applicationServerKey: base64ToArray(vapidKey)\n });\n}\n\n/**\n * Checks if the saved tokenDetails object matches the configuration provided.\n */\nfunction isTokenValid(\n dbOptions: SubscriptionOptions,\n currentOptions: SubscriptionOptions\n): boolean {\n const isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey;\n const isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint;\n const isAuthEqual = currentOptions.auth === dbOptions.auth;\n const isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh;\n\n return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual;\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 { ConsoleMessageData } from '../interfaces/message-payload';\nimport { CONSOLE_CAMPAIGN_ID } from '../util/constants';\n\nexport function isConsoleMessage(data: unknown): data is ConsoleMessageData {\n // This message has a campaign ID, meaning it was sent using the\n // Firebase Console.\n return typeof data === 'object' && !!data && CONSOLE_CAMPAIGN_ID in data;\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 {\n CONSOLE_CAMPAIGN_ANALYTICS_ENABLED,\n CONSOLE_CAMPAIGN_ID,\n CONSOLE_CAMPAIGN_NAME,\n CONSOLE_CAMPAIGN_TIME,\n DEFAULT_SW_PATH,\n DEFAULT_SW_SCOPE,\n DEFAULT_VAPID_KEY\n} from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { InternalMessage, MessageType } from '../interfaces/internal-message';\nimport { NextFn, Observer, Unsubscribe } from '@firebase/util';\nimport { deleteToken, getToken } from '../core/token-management';\n\nimport { ConsoleMessageData } from '../interfaces/message-payload';\nimport { FirebaseApp } from '@firebase/app-types';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { FirebaseMessaging } from '@firebase/messaging-types';\nimport { FirebaseService } from '@firebase/app-types/private';\nimport { isConsoleMessage } from '../helpers/is-console-message';\n\nexport class WindowController implements FirebaseMessaging, FirebaseService {\n private vapidKey: string | null = null;\n private swRegistration?: ServiceWorkerRegistration;\n private onMessageCallback: NextFn | Observer | null = null;\n\n constructor(\n private readonly firebaseDependencies: FirebaseInternalDependencies\n ) {\n navigator.serviceWorker.addEventListener('message', e =>\n this.messageEventListener(e)\n );\n }\n\n get app(): FirebaseApp {\n return this.firebaseDependencies.app;\n }\n\n async getToken(): Promise {\n if (!this.vapidKey) {\n this.vapidKey = DEFAULT_VAPID_KEY;\n }\n\n const swRegistration = await this.getServiceWorkerRegistration();\n\n // Check notification permission.\n if (Notification.permission === 'default') {\n // The user hasn't allowed or denied notifications yet. Ask them.\n await Notification.requestPermission();\n }\n\n if (Notification.permission !== 'granted') {\n throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED);\n }\n\n return getToken(this.firebaseDependencies, swRegistration, this.vapidKey);\n }\n\n async deleteToken(): Promise {\n const swRegistration = await this.getServiceWorkerRegistration();\n\n return deleteToken(this.firebaseDependencies, swRegistration);\n }\n\n /**\n * Request permission if it is not currently granted.\n *\n * @return Resolves if the permission was granted, rejects otherwise.\n *\n * @deprecated Use Notification.requestPermission() instead.\n * https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission\n */\n async requestPermission(): Promise {\n if (Notification.permission === 'granted') {\n return;\n }\n\n const permissionResult = await Notification.requestPermission();\n if (permissionResult === 'granted') {\n return;\n } else if (permissionResult === 'denied') {\n throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED);\n } else {\n throw ERROR_FACTORY.create(ErrorCode.PERMISSION_DEFAULT);\n }\n }\n\n // TODO: Deprecate this and make VAPID key a parameter in getToken.\n usePublicVapidKey(vapidKey: string): void {\n if (this.vapidKey !== null) {\n throw ERROR_FACTORY.create(ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN);\n }\n\n if (typeof vapidKey !== 'string' || vapidKey.length === 0) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_VAPID_KEY);\n }\n\n this.vapidKey = vapidKey;\n }\n\n useServiceWorker(swRegistration: ServiceWorkerRegistration): void {\n if (!(swRegistration instanceof ServiceWorkerRegistration)) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_SW_REGISTRATION);\n }\n\n if (this.swRegistration) {\n throw ERROR_FACTORY.create(ErrorCode.USE_SW_AFTER_GET_TOKEN);\n }\n\n this.swRegistration = swRegistration;\n }\n\n /**\n * @param nextOrObserver An observer object or a function triggered on\n * message.\n * @return The unsubscribe function for the observer.\n */\n onMessage(nextOrObserver: NextFn | Observer): Unsubscribe {\n this.onMessageCallback = nextOrObserver;\n\n return () => {\n this.onMessageCallback = null;\n };\n }\n\n setBackgroundMessageHandler(): void {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_SW);\n }\n\n // Unimplemented\n onTokenRefresh(): Unsubscribe {\n return () => {};\n }\n\n /**\n * Creates or updates the default service worker registration.\n * @return The service worker registration to be used for the push service.\n */\n private async getServiceWorkerRegistration(): Promise<\n ServiceWorkerRegistration\n > {\n if (!this.swRegistration) {\n try {\n this.swRegistration = await navigator.serviceWorker.register(\n DEFAULT_SW_PATH,\n {\n scope: DEFAULT_SW_SCOPE\n }\n );\n\n // The timing when browser updates sw when sw has an update is unreliable by my experiment.\n // It leads to version conflict when the SDK upgrades to a newer version in the main page, but\n // sw is stuck with the old version. For example, https://github.com/firebase/firebase-js-sdk/issues/2590\n // The following line reliably updates sw if there was an update.\n this.swRegistration.update().catch(() => {\n /* it is non blocking and we don't care if it failed */\n });\n } catch (e) {\n throw ERROR_FACTORY.create(ErrorCode.FAILED_DEFAULT_REGISTRATION, {\n browserErrorMessage: e.message\n });\n }\n }\n\n return this.swRegistration;\n }\n\n private async messageEventListener(event: MessageEvent): Promise {\n if (!event.data?.firebaseMessaging) {\n // Not a message from FCM\n return;\n }\n\n const { type, payload } = (event.data as InternalMessage).firebaseMessaging;\n\n // onMessageCallback is either a function or observer/subscriber.\n if (this.onMessageCallback && type === MessageType.PUSH_RECEIVED) {\n if (typeof this.onMessageCallback === 'function') {\n this.onMessageCallback(payload);\n } else {\n this.onMessageCallback.next(payload);\n }\n }\n\n const { data } = payload;\n if (\n isConsoleMessage(data) &&\n data[CONSOLE_CAMPAIGN_ANALYTICS_ENABLED] === '1'\n ) {\n // Analytics is enabled on this message, so we should log it.\n await this.logEvent(type, data);\n }\n }\n\n private async logEvent(\n messageType: MessageType,\n data: ConsoleMessageData\n ): Promise {\n const eventType = getEventType(messageType);\n const analytics = await this.firebaseDependencies.analyticsProvider.get();\n analytics.logEvent(eventType, {\n /* eslint-disable camelcase */\n message_id: data[CONSOLE_CAMPAIGN_ID],\n message_name: data[CONSOLE_CAMPAIGN_NAME],\n message_time: data[CONSOLE_CAMPAIGN_TIME],\n message_device_time: Math.floor(Date.now() / 1000)\n /* eslint-enable camelcase */\n });\n }\n}\n\nfunction getEventType(messageType: MessageType): string {\n switch (messageType) {\n case MessageType.NOTIFICATION_CLICKED:\n return 'notification_open';\n case MessageType.PUSH_RECEIVED:\n return 'notification_foreground';\n default:\n throw new Error();\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 { deleteToken, getToken } from '../core/token-management';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { FirebaseMessaging } from '@firebase/messaging-types';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport {\n MessagePayload,\n NotificationDetails\n} from '../interfaces/message-payload';\nimport { FCM_MSG, DEFAULT_VAPID_KEY } from '../util/constants';\nimport { MessageType, InternalMessage } from '../interfaces/internal-message';\nimport { dbGet } from '../helpers/idb-manager';\nimport { Unsubscribe } from '@firebase/util';\nimport { sleep } from '../helpers/sleep';\nimport { FirebaseApp } from '@firebase/app-types';\nimport { isConsoleMessage } from '../helpers/is-console-message';\nimport { FirebaseService } from '@firebase/app-types/private';\n\n// Let TS know that this is a service worker\ndeclare const self: ServiceWorkerGlobalScope;\n\nexport type BgMessageHandler = (payload: MessagePayload) => unknown;\n\nexport class SwController implements FirebaseMessaging, FirebaseService {\n private vapidKey: string | null = null;\n private bgMessageHandler: BgMessageHandler | null = null;\n\n constructor(\n private readonly firebaseDependencies: FirebaseInternalDependencies\n ) {\n self.addEventListener('push', e => {\n e.waitUntil(this.onPush(e));\n });\n self.addEventListener('pushsubscriptionchange', e => {\n e.waitUntil(this.onSubChange(e));\n });\n self.addEventListener('notificationclick', e => {\n e.waitUntil(this.onNotificationClick(e));\n });\n }\n\n get app(): FirebaseApp {\n return this.firebaseDependencies.app;\n }\n\n /**\n * Calling setBackgroundMessageHandler will opt in to some specific\n * behaviours.\n * 1.) If a notification doesn't need to be shown due to a window already\n * being visible, then push messages will be sent to the page.\n * 2.) If a notification needs to be shown, and the message contains no\n * notification data this method will be called\n * and the promise it returns will be passed to event.waitUntil.\n * If you do not set this callback then all push messages will let and the\n * developer can handle them in a their own 'push' event callback\n *\n * @param callback The callback to be called when a push message is received\n * and a notification must be shown. The callback will be given the data from\n * the push message.\n */\n setBackgroundMessageHandler(callback: BgMessageHandler): void {\n if (!callback || typeof callback !== 'function') {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_BG_HANDLER);\n }\n\n this.bgMessageHandler = callback;\n }\n\n // TODO: Remove getToken from SW Controller.\n // Calling this from an old SW can cause all kinds of trouble.\n async getToken(): Promise {\n if (!this.vapidKey) {\n // Call getToken using the current VAPID key if there already is a token.\n // This is needed because usePublicVapidKey was not available in SW.\n // It will be removed when vapidKey becomes a parameter of getToken, or\n // when getToken is removed from SW.\n const tokenDetails = await dbGet(this.firebaseDependencies);\n this.vapidKey =\n tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY;\n }\n\n return getToken(\n this.firebaseDependencies,\n self.registration,\n this.vapidKey\n );\n }\n\n // TODO: Remove deleteToken from SW Controller.\n // Calling this from an old SW can cause all kinds of trouble.\n deleteToken(): Promise {\n return deleteToken(this.firebaseDependencies, self.registration);\n }\n\n requestPermission(): Promise {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n // TODO: Deprecate this and make VAPID key a parameter in getToken.\n // TODO: Remove this together with getToken from SW Controller.\n usePublicVapidKey(vapidKey: string): void {\n if (this.vapidKey !== null) {\n throw ERROR_FACTORY.create(ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN);\n }\n\n if (typeof vapidKey !== 'string' || vapidKey.length === 0) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_VAPID_KEY);\n }\n\n this.vapidKey = vapidKey;\n }\n\n useServiceWorker(): void {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n onMessage(): Unsubscribe {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n onTokenRefresh(): Unsubscribe {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n /**\n * A handler for push events that shows notifications based on the content of\n * the payload.\n *\n * The payload must be a JSON-encoded Object with a `notification` key. The\n * value of the `notification` property will be used as the NotificationOptions\n * object passed to showNotification. Additionally, the `title` property of the\n * notification object will be used as the title.\n *\n * If there is no notification data in the payload then no notification will be\n * shown.\n */\n async onPush(event: PushEvent): Promise {\n const payload = getMessagePayload(event);\n if (!payload) {\n return;\n }\n\n const clientList = await getClientList();\n if (hasVisibleClients(clientList)) {\n // App in foreground. Send to page.\n return sendMessageToWindowClients(clientList, payload);\n }\n\n const notificationDetails = getNotificationData(payload);\n if (notificationDetails) {\n await showNotification(notificationDetails);\n } else if (this.bgMessageHandler) {\n await this.bgMessageHandler(payload);\n }\n }\n\n async onSubChange(event: PushSubscriptionChangeEvent): Promise {\n const { newSubscription } = event;\n if (!newSubscription) {\n // Subscription revoked, delete token\n await deleteToken(this.firebaseDependencies, self.registration);\n return;\n }\n\n const tokenDetails = await dbGet(this.firebaseDependencies);\n await deleteToken(this.firebaseDependencies, self.registration);\n await getToken(\n this.firebaseDependencies,\n self.registration,\n tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY\n );\n }\n\n async onNotificationClick(event: NotificationEvent): Promise {\n const payload: MessagePayload = event.notification?.data?.[FCM_MSG];\n if (!payload) {\n // Not an FCM notification, do nothing.\n return;\n } else if (event.action) {\n // User clicked on an action button.\n // This will allow devs to act on action button clicks by using a custom\n // onNotificationClick listener that they define.\n return;\n }\n\n // Prevent other listeners from receiving the event\n event.stopImmediatePropagation();\n event.notification.close();\n\n const link = getLink(payload);\n if (!link) {\n return;\n }\n\n let client = await getWindowClient(link);\n if (!client) {\n // Unable to find window client so need to open one.\n // This also focuses the opened client.\n client = await self.clients.openWindow(link);\n // Wait three seconds for the client to initialize and set up the message\n // handler so that it can receive the message.\n await sleep(3000);\n } else {\n client = await client.focus();\n }\n\n if (!client) {\n // Window Client will not be returned if it's for a third party origin.\n return;\n }\n\n const message = createNewMessage(MessageType.NOTIFICATION_CLICKED, payload);\n return client.postMessage(message);\n }\n}\n\nfunction getMessagePayload({ data }: PushEvent): MessagePayload | null {\n if (!data) {\n return null;\n }\n\n try {\n return data.json();\n } catch (err) {\n // Not JSON so not an FCM message.\n return null;\n }\n}\n\nfunction getNotificationData(\n payload: MessagePayload\n): NotificationDetails | undefined {\n if (!payload || typeof payload.notification !== 'object') {\n return;\n }\n\n const notificationInformation: NotificationDetails = {\n ...payload.notification\n };\n\n // Put the message payload under FCM_MSG name so we can identify the\n // notification as being an FCM notification vs a notification from\n // somewhere else (i.e. normal web push or developer generated\n // notification).\n notificationInformation.data = {\n ...payload.notification.data,\n [FCM_MSG]: payload\n };\n\n return notificationInformation;\n}\n\n/**\n * @param url The URL to look for when focusing a client.\n * @return Returns an existing window client or a newly opened WindowClient.\n */\nasync function getWindowClient(url: string): Promise {\n // Use URL to normalize the URL when comparing to windowClients.\n // This at least handles whether to include trailing slashes or not\n const parsedURL = new URL(url, self.location.href);\n\n const clientList = await getClientList();\n\n for (const client of clientList) {\n const parsedClientUrl = new URL(client.url, self.location.href);\n if (parsedClientUrl.host === parsedURL.host) {\n return client;\n }\n }\n\n return null;\n}\n\n/**\n * @returns If there is currently a visible WindowClient, this method will\n * resolve to true, otherwise false.\n */\nfunction hasVisibleClients(clientList: WindowClient[]): boolean {\n return clientList.some(\n client =>\n client.visibilityState === 'visible' &&\n // Ignore chrome-extension clients as that matches the background pages\n // of extensions, which are always considered visible for some reason.\n !client.url.startsWith('chrome-extension://')\n );\n}\n\n/**\n * @param payload The data from the push event that should be sent to all\n * available pages.\n * @returns Returns a promise that resolves once the message has been sent to\n * all WindowClients.\n */\nfunction sendMessageToWindowClients(\n clientList: WindowClient[],\n payload: MessagePayload\n): void {\n const message = createNewMessage(MessageType.PUSH_RECEIVED, payload);\n\n for (const client of clientList) {\n client.postMessage(message);\n }\n}\n\nfunction getClientList(): Promise {\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n // TS doesn't know that \"type: 'window'\" means it'll return WindowClient[]\n }) as Promise;\n}\n\nfunction createNewMessage(\n type: MessageType,\n payload: MessagePayload\n): InternalMessage {\n return {\n firebaseMessaging: { type, payload }\n };\n}\n\nfunction showNotification(details: NotificationDetails): Promise {\n const title = details.title ?? '';\n\n const { actions } = details;\n // Note: Firefox does not support the maxActions property.\n // https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions\n const { maxActions } = Notification;\n if (actions && maxActions && actions.length > maxActions) {\n console.warn(\n `This browser only supports ${maxActions} actions. The remaining actions will not be displayed.`\n );\n }\n\n return self.registration.showNotification(title, details);\n}\n\nfunction getLink(payload: MessagePayload): string | null {\n // eslint-disable-next-line camelcase\n const link = payload.fcmOptions?.link ?? payload.notification?.click_action;\n if (link) {\n return link;\n }\n\n if (isConsoleMessage(payload.data)) {\n // Notification created in the Firebase Console. Redirect to origin.\n return self.location.origin;\n } else {\n return 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\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\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 firebase from '@firebase/app';\nimport '@firebase/installations';\nimport {\n _FirebaseNamespace,\n FirebaseService\n} from '@firebase/app-types/private';\nimport { FirebaseMessaging } from '@firebase/messaging-types';\nimport {\n Component,\n ComponentType,\n ComponentContainer\n} from '@firebase/component';\nimport { extractAppConfig } from './helpers/extract-app-config';\nimport { FirebaseInternalDependencies } from './interfaces/internal-dependencies';\nimport { ERROR_FACTORY, ErrorCode } from './util/errors';\nimport { WindowController } from './controllers/window-controller';\nimport { SwController } from './controllers/sw-controller';\n\nconst MESSAGING_NAME = 'messaging';\nfunction factoryMethod(\n container: ComponentContainer\n): FirebaseService & FirebaseMessaging {\n // Dependencies.\n const app = container.getProvider('app').getImmediate();\n const appConfig = extractAppConfig(app);\n const installations = container.getProvider('installations').getImmediate();\n const analyticsProvider = container.getProvider('analytics-internal');\n\n const firebaseDependencies: FirebaseInternalDependencies = {\n app,\n appConfig,\n installations,\n analyticsProvider\n };\n\n if (!isSupported()) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n\n if (self && 'ServiceWorkerGlobalScope' in self) {\n // Running in ServiceWorker context\n return new SwController(firebaseDependencies);\n } else {\n // Assume we are in the window context.\n return new WindowController(firebaseDependencies);\n }\n}\n\nconst NAMESPACE_EXPORTS = {\n isSupported\n};\n\n(firebase as _FirebaseNamespace).INTERNAL.registerComponent(\n new Component(\n MESSAGING_NAME,\n factoryMethod,\n ComponentType.PUBLIC\n ).setServiceProps(NAMESPACE_EXPORTS)\n);\n\n/**\n * Define extension behavior of `registerMessaging`\n */\ndeclare module '@firebase/app-types' {\n interface FirebaseNamespace {\n messaging: {\n (app?: FirebaseApp): FirebaseMessaging;\n isSupported(): boolean;\n };\n }\n interface FirebaseApp {\n messaging(): FirebaseMessaging;\n }\n}\n\nfunction isSupported(): boolean {\n if (self && 'ServiceWorkerGlobalScope' in self) {\n // Running in ServiceWorker context\n return isSWControllerSupported();\n } else {\n // Assume we are in the window context.\n return isWindowControllerSupported();\n }\n}\n\n/**\n * Checks to see if the required APIs exist.\n */\nfunction isWindowControllerSupported(): boolean {\n return (\n 'indexedDB' in window &&\n indexedDB !== null &&\n navigator.cookieEnabled &&\n 'serviceWorker' in navigator &&\n 'PushManager' in window &&\n 'Notification' in window &&\n 'fetch' in window &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n\n/**\n * Checks to see if the required APIs exist within SW Context.\n */\nfunction isSWControllerSupported(): boolean {\n return (\n 'indexedDB' in self &&\n indexedDB !== null &&\n 'PushManager' in self &&\n 'Notification' in self &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n"],"names":["extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","hasOwnProperty","__assign","assign","t","s","i","n","arguments","length","prototype","call","apply","this","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","__generator","body","f","y","g","_","label","sent","trys","ops","verb","throw","return","Symbol","iterator","v","op","TypeError","pop","push","__values","o","m","__read","r","ar","error","__spread","concat","Error","create","__","constructor","code","message","_super","_this","FirebaseError","captureStackTrace","ErrorFactory","_i","data","customData","fullCode","service","template","errors","replace","PATTERN","key","String","fullMessage","serviceName","_b","keys","_a","slice","console","warn","Component","mode","instantiationMode","multipleInstances","props","serviceProps","name","instanceFactory","type","promisifyRequest","request","onsuccess","onerror","promisifyRequestCall","obj","method","args","proxyProperties","ProxyClass","targetProp","properties","forEach","prop","defineProperty","get","set","val","proxyRequestMethods","Constructor","proxyMethods","proxyCursorRequestMethods","Cursor","Index","index","_index","cursor","_cursor","_request","ObjectStore","store","_store","Transaction","idbTransaction","_tx","complete","oncomplete","onabort","UpgradeDB","db","oldVersion","transaction","_db","DB","openDb","version","upgradeCallback","indexedDB","onupgradeneeded","event","deleteDb","IDBIndex","IDBCursor","methodName","createIndex","IDBObjectStore","objectStore","IDBTransaction","createObjectStore","IDBDatabase","funcName","arr","callback","nativeObject","getAll","query","count","instance","items","iterateCursor","undefined","continue","PENDING_TIMEOUT_MS","PACKAGE_VERSION","INTERNAL_AUTH_VERSION","INSTALLATIONS_API_URL","TOKEN_EXPIRATION_BUFFER","ERROR_DESCRIPTION_MAP","ERROR_FACTORY","isServerError","includes","getInstallationsEndpoint","projectId","extractAuthTokenInfoFromResponse","response","token","requestStatus","expiresIn","responseExpiresIn","Number","creationTime","Date","now","getErrorFromResponse","requestName","json","responseJson","errorData","serverCode","serverMessage","serverStatus","status","getHeaders","apiKey","Headers","Content-Type","Accept","x-goog-api-key","getHeadersWithAuth","appConfig","refreshToken","headers","append","retryIfServerError","fn","sleep","ms","setTimeout","VALID_FID_PATTERN","INVALID_FID","generateFid","fidByteArray","Uint8Array","self","crypto","msCrypto","getRandomValues","fid","array","btoa","fromCharCode","bufferToBase64UrlSafe","substr","test","getKey","appName","appId","fidChangeCallbacks","Map","fidChanged","callFidChangeCallbacks","channel","getBroadcastChannel","postMessage","closeBroadcastChannel","broadcastFidChange","callbacks","callbacks_1","broadcastChannel","BroadcastChannel","onmessage","size","close","DATABASE_NAME","DATABASE_VERSION","OBJECT_STORE_NAME","dbPromise","getDbPromise","upgradeDB","tx","oldValue","put","remove","delete","update","updateFn","newValue","getInstallationEntry","oldEntry","installationEntry","clearTimedOutRequest","registrationStatus","entryWithPromise","registrationPromise","updateInstallationRequest","entry","waitUntilFidRegistration","navigator","onLine","registrationPromiseWithError","inProgressEntry","registrationTime","endpoint","authVersion","sdkVersion","JSON","stringify","fetch","ok","responseValue","authToken","createInstallationRequest","registeredInstallationEntry","e_1","registerInstallation","triggerRegistrationIfNecessary","generateAuthTokenRequest","platformLoggerProvider","platformLogger","getImmediate","optional","getPlatformInfoString","installation","refreshAuthToken","dependencies","forceRefresh","isEntryRegistered","inProgressAuthToken","oldAuthToken","isAuthTokenExpired","tokenPromise","updateAuthTokenRequest","waitUntilAuthTokenRequest","requestTime","updatedInstallationEntry","fetchAuthTokenFromServer","getToken","completeInstallationRegistration","deleteInstallationRequest","onIdChange","callbackSet","Set","add","addCallback","getMissingValueError","valueName","firebase","INTERNAL","registerComponent","container","app","getProvider","options","configKeys_1","keyName","extractAppConfig","getId","catch","deleteInstallation","registerVersion","ERROR_MAP","MessageType","DEFAULT_VAPID_KEY","ENDPOINT","FCM_MSG","CONSOLE_CAMPAIGN_ID","arrayToBase64","uint8Array","OLD_DB_NAME","OLD_DB_VERSION","OLD_OBJECT_STORE_NAME","migrateOldDatabase","senderId","databases","map","tokenDetails","objectStoreNames","contains","clear","oldDetails","auth","p256dh","fcmToken","createTime","subscriptionOptions","swScope","vapidKey","checkTokenDetails","upgradeDb","dbGet","firebaseDependencies","oldTokenDetails","dbSet","requestDeleteToken","unsubscribeOptions","getEndpoint","responseData","errorInfo","err_3","installations","x-goog-firebase-installations-auth","getBody","web","applicationPubKey","swRegistration","Notification","permission","pushManager","getSubscription","subscription","subscribe","userVisibleOnly","applicationServerKey","base64String","base64","repeat","rawData","atob","outputArray","charCodeAt","base64ToArray","getPushSubscription","pushSubscription","scope","getNewToken","dbOptions","isVapidKeyEqual","currentOptions","isEndpointEqual","isAuthEqual","isP256dhEqual","updateOptions","err_2","requestUpdateToken","updatedToken","updatedTokenDetails","deleteToken","e_2","updateToken","dbRemove","unsubscribe","subscribeOptions","err_1","requestGetToken","isConsoleMessage","WindowController","getServiceWorkerRegistration","requestPermission","permissionResult","ServiceWorkerRegistration","nextOrObserver","onMessageCallback","serviceWorker","register","browserErrorMessage","firebaseMessaging","payload","PUSH_RECEIVED","logEvent","_c","messageType","eventType","NOTIFICATION_CLICKED","getEventType","analyticsProvider","message_id","message_name","message_time","message_device_time","Math","floor","addEventListener","messageEventListener","SwController","bgMessageHandler","registration","err","getMessagePayload","getClientList","clientList","some","client","visibilityState","url","startsWith","createNewMessage","clientList_2","sendMessageToWindowClients","notificationDetails","notification","notificationInformation","getNotificationData","details","title","actions","maxActions","showNotification","action","stopImmediatePropagation","link","fcmOptions","click_action","location","origin","getLink","parsedURL","URL","href","clientList_1","host","getWindowClient","clients","openWindow","focus","waitUntil","onPush","onSubChange","onNotificationClick","matchAll","includeUncontrolled","NAMESPACE_EXPORTS","isSupported","PushSubscription","window","cookieEnabled","messagingSenderId","setServiceProps"],"mappings":"kTAgBA,IAAIA,EAAgB,SAASC,EAAGC,GAI5B,OAHAF,EAAgBG,OAAOC,gBAClB,CAAEC,UAAW,cAAgBC,OAAS,SAAUL,EAAGC,GAAKD,EAAEI,UAAYH,IACvE,SAAUD,EAAGC,GAAK,IAAK,IAAIK,KAAKL,EAAOA,EAAEM,eAAeD,KAAIN,EAAEM,GAAKL,EAAEK,MACpDN,EAAGC,IASrB,IAAIO,EAAW,WAQlB,OAPAA,EAAWN,OAAOO,QAAU,SAAkBC,GAC1C,IAAK,IAAIC,EAAGC,EAAI,EAAGC,EAAIC,UAAUC,OAAQH,EAAIC,EAAGD,IAE5C,IAAK,IAAIN,KADTK,EAAIG,UAAUF,GACOV,OAAOc,UAAUT,eAAeU,KAAKN,EAAGL,KAAII,EAAEJ,GAAKK,EAAEL,IAE9E,OAAOI,IAEKQ,MAAMC,KAAML,YA8BzB,SAASM,EAAUC,EAASC,EAAYC,EAAGC,GAE9C,OAAO,IAAWD,EAANA,GAAUE,SAAU,SAAUC,EAASC,GAC/C,SAASC,EAAUC,GAAS,IAAMC,EAAKN,EAAUO,KAAKF,IAAW,MAAOG,GAAKL,EAAOK,IACpF,SAASC,EAASJ,GAAS,IAAMC,EAAKN,EAAiB,MAAEK,IAAW,MAAOG,GAAKL,EAAOK,IACvF,SAASF,EAAKI,GAJlB,IAAeL,EAIaK,EAAOC,KAAOT,EAAQQ,EAAOL,SAJ1CA,EAIyDK,EAAOL,iBAJ/BN,EAAIM,EAAQ,IAAIN,EAAE,SAAUG,GAAWA,EAAQG,MAITO,KAAKR,EAAWK,GAClGH,GAAMN,EAAYA,EAAUN,MAAMG,EAASC,GAAc,KAAKS,UAI/D,SAASM,EAAYhB,EAASiB,GACjC,IAAsGC,EAAGC,EAAG9B,EAAG+B,EAA3GC,EAAI,CAAEC,MAAO,EAAGC,KAAM,WAAa,GAAW,EAAPlC,EAAE,GAAQ,MAAMA,EAAE,GAAI,OAAOA,EAAE,IAAOmC,KAAM,GAAIC,IAAK,IAChG,OAAOL,EAAI,CAAEV,KAAMgB,EAAK,GAAIC,MAASD,EAAK,GAAIE,OAAUF,EAAK,IAAwB,mBAAXG,SAA0BT,EAAES,OAAOC,UAAY,WAAa,OAAOhC,OAAUsB,EACvJ,SAASM,EAAKlC,GAAK,OAAO,SAAUuC,GAAK,OACzC,SAAcC,GACV,GAAId,EAAG,MAAM,IAAIe,UAAU,mCAC3B,KAAOZ,GAAG,IACN,GAAIH,EAAI,EAAGC,IAAM9B,EAAY,EAAR2C,EAAG,GAASb,EAAU,OAAIa,EAAG,GAAKb,EAAS,SAAO9B,EAAI8B,EAAU,SAAM9B,EAAEO,KAAKuB,GAAI,GAAKA,EAAET,SAAWrB,EAAIA,EAAEO,KAAKuB,EAAGa,EAAG,KAAKlB,KAAM,OAAOzB,EAE3J,OADI8B,EAAI,EAAG9B,IAAG2C,EAAK,CAAS,EAARA,EAAG,GAAQ3C,EAAEmB,QACzBwB,EAAG,IACP,KAAK,EAAG,KAAK,EAAG3C,EAAI2C,EAAI,MACxB,KAAK,EAAc,OAAXX,EAAEC,QAAgB,CAAEd,MAAOwB,EAAG,GAAIlB,MAAM,GAChD,KAAK,EAAGO,EAAEC,QAASH,EAAIa,EAAG,GAAIA,EAAK,CAAC,GAAI,SACxC,KAAK,EAAGA,EAAKX,EAAEI,IAAIS,MAAOb,EAAEG,KAAKU,MAAO,SACxC,QACI,KAAkB7C,EAAe,GAA3BA,EAAIgC,EAAEG,MAAY9B,QAAcL,EAAEA,EAAEK,OAAS,MAAkB,IAAVsC,EAAG,IAAsB,IAAVA,EAAG,IAAW,CAAEX,EAAI,EAAG,SACjG,GAAc,IAAVW,EAAG,MAAc3C,GAAM2C,EAAG,GAAK3C,EAAE,IAAM2C,EAAG,GAAK3C,EAAE,IAAM,CAAEgC,EAAEC,MAAQU,EAAG,GAAI,MAC9E,GAAc,IAAVA,EAAG,IAAYX,EAAEC,MAAQjC,EAAE,GAAI,CAAEgC,EAAEC,MAAQjC,EAAE,GAAIA,EAAI2C,EAAI,MAC7D,GAAI3C,GAAKgC,EAAEC,MAAQjC,EAAE,GAAI,CAAEgC,EAAEC,MAAQjC,EAAE,GAAIgC,EAAEI,IAAIU,KAAKH,GAAK,MACvD3C,EAAE,IAAIgC,EAAEI,IAAIS,MAChBb,EAAEG,KAAKU,MAAO,SAEtBF,EAAKf,EAAKrB,KAAKI,EAASqB,GAC1B,MAAOV,GAAKqB,EAAK,CAAC,EAAGrB,GAAIQ,EAAI,UAAeD,EAAI7B,EAAI,EACtD,GAAY,EAAR2C,EAAG,GAAQ,MAAMA,EAAG,GAAI,MAAO,CAAExB,MAAOwB,EAAG,GAAKA,EAAG,QAAK,EAAQlB,MAAM,GArB9BL,CAAK,CAACjB,EAAGuC,MAkCtD,SAASK,EAASC,GACrB,IAAI/C,EAAsB,mBAAXuC,QAAyBA,OAAOC,SAAUQ,EAAIhD,GAAK+C,EAAE/C,GAAIC,EAAI,EAC5E,GAAI+C,EAAG,OAAOA,EAAE1C,KAAKyC,GACrB,GAAIA,GAAyB,iBAAbA,EAAE3C,OAAqB,MAAO,CAC1CgB,KAAM,WAEF,OADI2B,GAAK9C,GAAK8C,EAAE3C,SAAQ2C,OAAI,GACrB,CAAE7B,MAAO6B,GAAKA,EAAE9C,KAAMuB,MAAOuB,KAG5C,MAAM,IAAIJ,UAAU3C,EAAI,0BAA4B,mCAGjD,SAASiD,EAAOF,EAAG7C,GACtB,IAAI8C,EAAsB,mBAAXT,QAAyBQ,EAAER,OAAOC,UACjD,IAAKQ,EAAG,OAAOD,EACf,IAAmBG,EAAY7B,EAA3BpB,EAAI+C,EAAE1C,KAAKyC,GAAOI,EAAK,GAC3B,IACI,WAAc,IAANjD,GAAsB,EAANA,QAAcgD,EAAIjD,EAAEmB,QAAQI,MAAM2B,EAAGN,KAAKK,EAAEhC,OAExE,MAAOkC,GAAS/B,EAAI,CAAE+B,MAAOA,WAEzB,IACQF,IAAMA,EAAE1B,OAASwB,EAAI/C,EAAU,SAAI+C,EAAE1C,KAAKL,WAExC,GAAIoB,EAAG,MAAMA,EAAE+B,OAE7B,OAAOD,EAGJ,SAASE,IACZ,IAAK,IAAIF,EAAK,GAAIlD,EAAI,EAAGA,EAAIE,UAAUC,OAAQH,IAC3CkD,EAAKA,EAAGG,OAAOL,EAAO9C,UAAUF,KACpC,OAAOkD,ECrFX,MDtC0B9D,EAAGC,OCgEMiE,MD/D/BnE,EADsBC,IAAGC,KAGzBD,EAAEgB,UAAkB,OAANf,EAAaC,OAAOiE,OAAOlE,IAAMmE,EAAGpD,UAAYf,EAAEe,UAAW,IAAIoD,MAD/E,SAASA,IAAOjD,KAAKkD,YAAcrE,ECiErC,WAAqBsE,EAAcC,GAAnC,MACEC,YAAMD,gBADaE,OAAAH,EAFZG,OA3BQ,gBAkCfvE,OAAOC,eAAesE,EAAMC,EAAc1D,WAItCkD,MAAMS,mBACRT,MAAMS,kBAAkBF,EAAMG,EAAa5D,UAAUmD,iBAezDS,mBAAA,SACEN,OACA,aAAAO,mBAAAA,IAAAC,oBAeA,IAbA,IA4BuCA,EA5BjCC,EAAcD,EAAK,IAAoB,GACvCE,EAAc7D,KAAK8D,YAAWX,EAC9BY,EAAW/D,KAAKgE,OAAOb,GAEvBC,EAAUW,GAwBuBJ,EAxBcC,EAAVG,EAyB7BE,QAAQC,EAAS,SAAC3C,EAAG4C,GACnC,IAAMzD,EAAQiD,EAAKQ,GACnB,OAAgB,MAATzD,EAAgB0D,OAAO1D,GAAS,IAAIyD,UA3BwB,QAE7DE,EAAiBrE,KAAKsE,iBAAgBlB,OAAYS,OAElDjB,EAAQ,IAAIW,EAAcM,EAAUQ,OAKxBE,EAAAxF,OAAOyF,KAAKZ,GAAZa,WAAAA,IAAyB,CAAtC,IAAMN,OACa,MAAlBA,EAAIO,OAAO,KACTP,KAAOvB,GACT+B,QAAQC,KACN,yCAAyCT,sCAG7CvB,EAAMuB,GAAOP,EAAWO,IAI5B,OAAOvB,MAlCT,WACmBkB,EACAQ,EACAN,GAFAhE,aAAA8D,EACA9D,iBAAAsE,EACAtE,YAAAgE,EA0CrB,IAAME,EAAU,mBC1GdW,iCAAA,SAAqBC,GAEnB,OADA9E,KAAK+E,kBAAoBD,EAClB9E,MAGT6E,iCAAA,SAAqBG,GAEnB,OADAhF,KAAKgF,kBAAoBA,EAClBhF,MAGT6E,4BAAA,SAAgBI,GAEd,OADAjF,KAAKkF,aAAeD,EACbjF,SAlBT,WACWmF,EACAC,EACAC,GAFArF,UAAAmF,EACAnF,qBAAAoF,EACApF,UAAAqF,EAjBXrF,wBAAoB,EAIpBA,kBAA2B,GAE3BA,8BC9BF,SAASsF,EAAiBC,GACxB,OAAO,IAAIjF,QAAQ,SAASC,EAASC,GACnC+E,EAAQC,UAAY,WAClBjF,EAAQgF,EAAQxE,SAGlBwE,EAAQE,QAAU,WAChBjF,EAAO+E,EAAQ3C,UAKrB,SAAS8C,EAAqBC,EAAKC,EAAQC,GACzC,IAAIN,EACApG,EAAI,IAAImB,QAAQ,SAASC,EAASC,GAEpC8E,EADAC,EAAUI,EAAIC,GAAQ7F,MAAM4F,EAAKE,IACP5E,KAAKV,EAASC,KAI1C,OADArB,EAAEoG,QAAUA,EACLpG,EAWT,SAAS2G,EAAgBC,EAAYC,EAAYC,GAC/CA,EAAWC,QAAQ,SAASC,GAC1BpH,OAAOqH,eAAeL,EAAWlG,UAAWsG,EAAM,CAChDE,IAAK,WACH,OAAOrG,KAAKgG,GAAYG,IAE1BG,IAAK,SAASC,GACZvG,KAAKgG,GAAYG,GAAQI,OAMjC,SAASC,EAAoBT,EAAYC,EAAYS,EAAaR,GAChEA,EAAWC,QAAQ,SAASC,GACpBA,KAAQM,EAAY5G,YAC1BkG,EAAWlG,UAAUsG,GAAQ,WAC3B,OAAOT,EAAqB1F,KAAKgG,GAAaG,EAAMxG,eAK1D,SAAS+G,EAAaX,EAAYC,EAAYS,EAAaR,GACzDA,EAAWC,QAAQ,SAASC,GACpBA,KAAQM,EAAY5G,YAC1BkG,EAAWlG,UAAUsG,GAAQ,WAC3B,OAAOnG,KAAKgG,GAAYG,GAAMpG,MAAMC,KAAKgG,GAAarG,eAK5D,SAASgH,EAA0BZ,EAAYC,EAAYS,EAAaR,GACtEA,EAAWC,QAAQ,SAASC,GACpBA,KAAQM,EAAY5G,YAC1BkG,EAAWlG,UAAUsG,GAAQ,WAC3B,OA3C8BR,EA2CI3F,KAAKgG,IA1CvC7G,EAAIuG,EAAqBC,EA0C2BQ,EAAMxG,YAzCrDsB,KAAK,SAASP,GACrB,GAAKA,EACL,OAAO,IAAIkG,EAAOlG,EAAOvB,EAAEoG,WAJ/B,IAAoCI,EAC9BxG,MA+CN,SAAS0H,EAAMC,GACb9G,KAAK+G,OAASD,EAuBhB,SAASF,EAAOI,EAAQzB,GACtBvF,KAAKiH,QAAUD,EACfhH,KAAKkH,SAAW3B,EA+BlB,SAAS4B,EAAYC,GACnBpH,KAAKqH,OAASD,EAuChB,SAASE,EAAYC,GACnBvH,KAAKwH,IAAMD,EACXvH,KAAKyH,SAAW,IAAInH,QAAQ,SAASC,EAASC,GAC5C+G,EAAeG,WAAa,WAC1BnH,KAEFgH,EAAe9B,QAAU,WACvBjF,EAAO+G,EAAe3E,QAExB2E,EAAeI,QAAU,WACvBnH,EAAO+G,EAAe3E,UAkB5B,SAASgF,EAAUC,EAAIC,EAAYC,GACjC/H,KAAKgI,IAAMH,EACX7H,KAAK8H,WAAaA,EAClB9H,KAAK+H,YAAc,IAAIT,EAAYS,GAkBrC,SAASE,EAAGJ,GACV7H,KAAKgI,IAAMH,EA6DN,SAASK,EAAO/C,EAAMgD,EAASC,GACpC,IAAIjJ,EAAIuG,EAAqB2C,UAAW,OAAQ,CAAClD,EAAMgD,IACnD5C,EAAUpG,EAAEoG,QAUhB,OARIA,IACFA,EAAQ+C,gBAAkB,SAASC,GAC7BH,GACFA,EAAgB,IAAIR,EAAUrC,EAAQxE,OAAQwH,EAAMT,WAAYvC,EAAQwC,gBAKvE5I,EAAE8B,KAAK,SAAS4G,GACrB,OAAO,IAAII,EAAGJ,KAIX,SAASW,EAASrD,GACvB,OAAOO,EAAqB2C,UAAW,iBAAkB,CAAClD,IA9N5DW,EAAgBe,EAAO,SAAU,CAC/B,OACA,UACA,aACA,WAGFL,EAAoBK,EAAO,SAAU4B,SAAU,CAC7C,MACA,SACA,SACA,aACA,UAGF9B,EAA0BE,EAAO,SAAU4B,SAAU,CACnD,aACA,kBAQF3C,EAAgBc,EAAQ,UAAW,CACjC,YACA,MACA,aACA,UAGFJ,EAAoBI,EAAQ,UAAW8B,UAAW,CAChD,SACA,WAIF,CAAC,UAAW,WAAY,sBAAsBxC,QAAQ,SAASyC,GACvDA,KAAcD,UAAU7I,YAC9B+G,EAAO/G,UAAU8I,GAAc,WAC7B,IAAI3B,EAAShH,KACT6F,EAAOlG,UACX,OAAOW,QAAQC,UAAUU,KAAK,WAE5B,OADA+F,EAAOC,QAAQ0B,GAAY5I,MAAMiH,EAAOC,QAASpB,GAC1CP,EAAiB0B,EAAOE,UAAUjG,KAAK,SAASP,GACrD,GAAKA,EACL,OAAO,IAAIkG,EAAOlG,EAAOsG,EAAOE,kBAUxCC,EAAYtH,UAAU+I,YAAc,WAClC,OAAO,IAAI/B,EAAM7G,KAAKqH,OAAOuB,YAAY7I,MAAMC,KAAKqH,OAAQ1H,aAG9DwH,EAAYtH,UAAUiH,MAAQ,WAC5B,OAAO,IAAID,EAAM7G,KAAKqH,OAAOP,MAAM/G,MAAMC,KAAKqH,OAAQ1H,aAGxDmG,EAAgBqB,EAAa,SAAU,CACrC,OACA,UACA,aACA,kBAGFX,EAAoBW,EAAa,SAAU0B,eAAgB,CACzD,MACA,MACA,SACA,QACA,MACA,SACA,SACA,aACA,UAGFlC,EAA0BQ,EAAa,SAAU0B,eAAgB,CAC/D,aACA,kBAGFnC,EAAaS,EAAa,SAAU0B,eAAgB,CAClD,gBAkBFvB,EAAYzH,UAAUiJ,YAAc,WAClC,OAAO,IAAI3B,EAAYnH,KAAKwH,IAAIsB,YAAY/I,MAAMC,KAAKwH,IAAK7H,aAG9DmG,EAAgBwB,EAAa,MAAO,CAClC,mBACA,SAGFZ,EAAaY,EAAa,MAAOyB,eAAgB,CAC/C,UASFnB,EAAU/H,UAAUmJ,kBAAoB,WACtC,OAAO,IAAI7B,EAAYnH,KAAKgI,IAAIgB,kBAAkBjJ,MAAMC,KAAKgI,IAAKrI,aAGpEmG,EAAgB8B,EAAW,MAAO,CAChC,OACA,UACA,qBAGFlB,EAAakB,EAAW,MAAOqB,YAAa,CAC1C,oBACA,UAOFhB,EAAGpI,UAAUkI,YAAc,WACzB,OAAO,IAAIT,EAAYtH,KAAKgI,IAAID,YAAYhI,MAAMC,KAAKgI,IAAKrI,aAG9DmG,EAAgBmC,EAAI,MAAO,CACzB,OACA,UACA,qBAGFvB,EAAauB,EAAI,MAAOgB,YAAa,CACnC,UAKF,CAAC,aAAc,iBAAiB/C,QAAQ,SAASgD,GAC/C,CAAC/B,EAAaN,GAAOX,QAAQ,SAASO,GAE9ByC,KAAYzC,EAAY5G,YAE9B4G,EAAY5G,UAAUqJ,EAASjF,QAAQ,OAAQ,YAAc,WAC3D,IAvPWkF,EAuPPtD,GAvPOsD,EAuPQxJ,UAtPhBT,MAAMW,UAAU6E,MAAM5E,KAAKqJ,IAuP1BC,EAAWvD,EAAKA,EAAKjG,OAAS,GAC9ByJ,EAAerJ,KAAKqH,QAAUrH,KAAK+G,OACnCxB,EAAU8D,EAAaH,GAAUnJ,MAAMsJ,EAAcxD,EAAKnB,MAAM,GAAI,IACxEa,EAAQC,UAAY,WAClB4D,EAAS7D,EAAQxE,eAOzB,CAAC8F,EAAOM,GAAajB,QAAQ,SAASO,GAChCA,EAAY5G,UAAUyJ,SAC1B7C,EAAY5G,UAAUyJ,OAAS,SAASC,EAAOC,GAC7C,IAAIC,EAAWzJ,KACX0J,EAAQ,GAEZ,OAAO,IAAIpJ,QAAQ,SAASC,GAC1BkJ,EAASE,cAAcJ,EAAO,SAASvC,GAChCA,GAIL0C,EAAMrH,KAAK2E,EAAOtG,YAEJkJ,IAAVJ,GAAuBE,EAAM9J,QAAU4J,EAI3CxC,EAAO6C,WAHLtJ,EAAQmJ,IANRnJ,EAAQmJ,4BCzPLI,EAAqB,IAErBC,EAAkB,KAAK5B,EACvB6B,EAAwB,SAExBC,EACX,kDAEWC,EAA0B,KCEjCC,uCAEF,kDACF1F,oBAA4B,2CAC5BA,4BAAoC,mCACpCA,oBACE,6FACFA,iBAAyB,kDACzBA,iCACE,8EAaS2F,EAAgB,IAAI3G,EDtBV,gBACK,gBCwB1B0G,YAYcE,EAAczH,GAC5B,OACEA,aAAiBW,GACjBX,EAAMO,KAAKmH,oCCtCCC,EAAyB9F,OAAE+F,cACzC,OAAUP,eAAkCO,4BAG9BC,EACdC,GAEA,MAAO,CACLC,MAAOD,EAASC,MAChBC,gBACAC,WA8DuCC,EA9DMJ,EAASG,UAgEjDE,OAAOD,EAAkB7G,QAAQ,IAAK,SA/D3C+G,aAAcC,KAAKC,OA6DvB,IAA2CJ,WAzDrBK,EACpBC,EACAV,mGAEoC,SAAMA,EAASW,eAEnD,OAFMC,EAA8B7G,SAC9B8G,EAAYD,EAAa1I,SACxBwH,EAAcpH,wBAAiC,CACpDoI,cACAI,WAAYD,EAAUpI,KACtBsI,cAAeF,EAAUnI,QACzBsI,aAAcH,EAAUI,wBAIZC,EAAWnH,OAAEoH,WAC3B,OAAO,IAAIC,QAAQ,CACjBC,eAAgB,mBAChBC,OAAQ,mBACRC,iBAAkBJ,aAINK,EACdC,EACA1H,OAAE2H,iBAEIC,EAAUT,EAAWO,GAE3B,OADAE,EAAQC,OAAO,gBAoCLtC,MApC6CoC,GAChDC,WAgBaE,EACpBC,iGAEe,SAAMA,YAErB,OAAqB,MAFfzL,EAAS0D,UAEJkH,QAAiB5K,EAAO4K,OAAS,OAEnCa,QAGFzL,iBClFO0L,EAAMC,GACpB,OAAO,IAAIpM,QAAc,SAAAC,GACvBoM,WAAWpM,EAASmM,KCDjB,IAAME,EAAoB,oBACpBC,EAAc,YAMXC,IACd,IAGE,IAAMC,EAAe,IAAIC,WAAW,KAElCC,KAAKC,QAAYD,KAA0CE,UACtDC,gBAAgBL,GAGvBA,EAAa,GAAK,IAAcA,EAAa,GAAK,GAElD,IAAMM,WCrB4BC,GAEpC,OADYC,KAAKnJ,OAAOoJ,mBAAPpJ,SAAuBkJ,KAC7BrJ,QAAQ,MAAO,KAAKA,QAAQ,MAAO,KD8B5BwJ,CAXGV,GAeJW,OAAO,EAAG,IAbzB,OAAOd,EAAkBe,KAAKN,GAAOA,EAAMR,EAC3C,SAEA,OAAOA,YEvBKe,EAAOzB,GACrB,OAAUA,EAAU0B,YAAW1B,EAAU2B,MCA3C,IAAMC,EAA2D,IAAIC,aAMrDC,GAAW9B,EAAsBkB,GAC/C,IAAMlJ,EAAMyJ,EAAOzB,GAEnB+B,GAAuB/J,EAAKkJ,GAsD9B,SAA4BlJ,EAAakJ,GACvC,IAAMc,EAAUC,KACZD,GACFA,EAAQE,YAAY,CAAElK,MAAKkJ,QAE7BiB,KA1DAC,CAAmBpK,EAAKkJ,GA0C1B,SAASa,GAAuB/J,EAAakJ,WACrCmB,EAAYT,EAAmB1H,IAAIlC,GACzC,GAAKqK,MAIL,IAAuB,IAAAC,EAAAnM,EAAAkM,iCAAW,EAChCpF,WAASiE,sGAYb,IAAIqB,GAA4C,KAEhD,SAASN,KAOP,OANKM,IAAoB,qBAAsBzB,QAC7CyB,GAAmB,IAAIC,iBAAiB,0BACvBC,UAAY,SAAA/N,GAC3BqN,GAAuBrN,EAAE8C,KAAKQ,IAAKtD,EAAE8C,KAAK0J,OAGvCqB,GAGT,SAASJ,KACyB,IAA5BP,EAAmBc,MAAcH,KACnCA,GAAiBI,QACjBJ,GAAmB,MCpFvB,ICcsCjF,MDdhCsF,GAAgB,kCAChBC,GAAmB,EACnBC,GAAoB,+BAEtBC,GAAgC,KACpC,SAASC,KAcP,OAZED,GADGA,IACShH,EAAO6G,GAAeC,GAAkB,SAAAI,GAMlD,OAAQA,EAAUtH,YAChB,KAAK,EACHsH,EAAUpG,kBAAkBiG,gBAoBhB3I,GACpB6F,EACAzL,yGAGW,OADLyD,EAAMyJ,EAAOzB,MACFgD,aAGA,OAHXtH,EAAKpD,SACL4K,EAAKxH,EAAGE,YAAYkH,GAAmB,iBACvCnG,EAAcuG,EAAGvG,YAAYmG,KACA5I,IAAIlC,WACvC,OADMmL,EAAW7K,YACXqE,EAAYyG,IAAI7O,EAAOyD,WAC7B,OADAM,YACM4K,EAAG5H,iBAMT,OANAhD,SAEK6K,GAAYA,EAASjC,MAAQ3M,EAAM2M,KACtCY,GAAW9B,EAAWzL,EAAM2M,QAGvB3M,iBAIa8O,GAAOrD,qGAEhB,OADLhI,EAAMyJ,EAAOzB,MACFgD,aAEjB,OAFMtH,EAAKpD,aACL4K,EAAKxH,EAAGE,YAAYkH,GAAmB,cACpCnG,YAAYmG,IAAmBQ,OAAOtL,WAC/C,OADAM,YACM4K,EAAG5H,wBAAThD,2BASoBiL,GACpBvD,EACAwD,2GAGW,OADLxL,EAAMyJ,EAAOzB,MACFgD,aAG+B,OAH1CtH,EAAKpD,SACL4K,EAAKxH,EAAGE,YAAYkH,GAAmB,iBACvC7H,EAAQiI,EAAGvG,YAAYmG,KAC+B5I,IAAIlC,kBAA1DmL,EAA0C7K,cAG/BmF,KAFXgG,EAAWD,EAASL,aAGlBlI,EAAMqI,OAAOtL,kBAAnBM,sBAEA,SAAM2C,EAAMmI,IAAIK,EAAUzL,WAA1BM,0BAEF,SAAM4K,EAAG5H,iBAMT,OANAhD,UAEImL,GAAcN,GAAYA,EAASjC,MAAQuC,EAASvC,KACtDY,GAAW9B,EAAWyD,EAASvC,QAG1BuC,iBEzEaC,GACpB1D,qGAI0B,SAAMuD,GAAOvD,EAAW,SAAA2D,GAChD,IAAMC,EAgCDC,GAhCqDF,GA2Bf,CAC3CzC,IAAKP,IACLmD,uBA5BMC,EAyCV,SACE/D,EACA4D,GAEA,CAAA,OAAIA,EAAkBE,mBAuBf,WACLF,EAAkBE,mBAEX,CACLF,oBACAI,oBAmCN,SACEhE,uGAM+B,SAAMiE,GAA0BjE,WAA3DkE,EAA2B9L,qCACxB8L,EAAMJ,4BAELxD,EAAM,aAEJ,OAFRlI,YAEc6L,GAA0BjE,kBAAxCkE,EAAQ9L,iCAGN8L,EAAMJ,4BAKEJ,GAAqB1D,WAE/B,OALM1H,EAGFF,SAFFwL,uBACAI,4BAIOA,MAGAJ,UAIX,SAAOM,QAjEkBC,CAAyBnE,IAGzC,CAAE4D,qBA9BT,IAAKQ,UAAUC,OAAQ,CAErB,IAAMC,EAA+BnQ,QAAQE,OAC3C4J,EAAcpH,uBAEhB,MAAO,CACL+M,oBACAI,oBAAqBM,GAKzB,IAAMC,EAA+C,CACnDrD,IAAK0C,EAAkB1C,IACvB4C,qBACAU,iBAAkB1F,KAAKC,OAEnBiF,EAkBV,SACEhE,EACA4D,mGAGsC,yCCpGtC5D,EACA1H,OAAE4I,gHAkBe,OAhBXuD,EAAWrG,EAAyB4B,GAEpCE,EAAUT,EAAWO,GACrBhL,EAAO,CACXkM,MACAwD,YAAa7G,EACb8D,MAAO3B,EAAU2B,MACjBgD,WAAY/G,GAGRxE,EAAuB,CAC3BK,OAAQ,OACRyG,UACAlL,KAAM4P,KAAKC,UAAU7P,OAGAoL,EAAmB,WAAM,OAAA0E,MAAML,EAAUrL,oBAA1DmF,EAAWnG,UACJ2M,MAC6CxG,EAASW,qBAOjE,OAPM8F,EAA4C5M,YACe,CAC/D8I,IAAK8D,EAAc9D,KAAOA,EAC1B4C,qBACA7D,aAAc+E,EAAc/E,aAC5BgF,UAAW3G,EAAiC0G,EAAcC,oBAItD,SAAMjG,EAAqB,sBAAuBT,WAAxD,MAAMnG,cDsEoC8M,CACxClF,EACA4D,WAEF,OAJMuB,EAA8B7M,YAI7B6B,GAAI6F,EAAWmF,kBAElBjH,eAAqC,MAAjBkH,EAAE/F,cAGlBgE,GAAOrD,wBAAb1H,sBAGA,SAAM6B,GAAI6F,EAAW,CACnBkB,IAAK0C,EAAkB1C,IACvB4C,+BAFFxL,0BAKF,MAAM8M,wBAxCsBC,CAC1BrF,EACAuE,GAEF,MAAO,CAAEX,kBAAmBW,EAAiBP,wBAnEpBsB,CACvBtF,EACA4D,GAGF,OADAI,EAAsBD,EAAiBC,oBAChCD,EAAiBH,mCAPpBA,EAAoBxL,UAUJ8I,MAAQR,iBAEMsD,WAAlC,UAAS1L,oBAAmBF,oBAG9B,SAAO,CACLwL,oBACAI,6BAsIJ,SAASC,GACPjE,GAEA,OAAOuD,GAAOvD,EAAW,SAAA2D,GACvB,IAAKA,EACH,MAAM1F,EAAcpH,iCAEtB,OAAOgN,GAAqBF,KAIhC,SAASE,GAAqBK,GAC5B,YAWAN,EAXmCM,GAcfJ,oBAClBF,EAAkBY,iBAAmB7G,EAAqBmB,KAAKC,MAdxD,CACLmC,IAAKgD,EAAMhD,IACX4C,sBAIGI,EAGT,IACEN,WE3LoB2B,GACpBjN,EACAsL,OADE5D,cAAWwF,qIA2BI,OAajBxF,EArC8CA,EAsC5CkB,EAtCuD0C,MAAnDa,EAwCIrG,EAAyB4B,OAAckB,yBAtC3ChB,EAAUH,EAAmBC,EAAW4D,IAGxC6B,EAAiBD,EAAuBE,aAAa,CACzDC,UAAU,MAGVzF,EAAQC,OAAO,oBAAqBsF,EAAeG,yBAG/C5Q,EAAO,CACX6Q,aAAc,CACZlB,WAAY/G,IAIVxE,EAAuB,CAC3BK,OAAQ,OACRyG,UACAlL,KAAM4P,KAAKC,UAAU7P,OAGAoL,EAAmB,WAAM,OAAA0E,MAAML,EAAUrL,oBAA1DmF,EAAWnG,UACJ2M,MAC4CxG,EAASW,qBAIhE,OAJM8F,EAA2C5M,YACFkG,EAC7C0G,WAII,SAAMhG,EAAqB,sBAAuBT,WAAxD,MAAMnG,SAIV,IACE4H,EACEkB,eCpCkB4E,GACpBC,EACAC,uBAAAA,iGAGc,SAAMzC,GAAOwC,EAAa/F,UAAW,SAAA2D,GACjD,IAAKsC,GAAkBtC,GACrB,MAAM1F,EAAcpH,yBAGtB,IA8IF8M,EAEMuC,EAnBkBjB,EA7HhBkB,EAAexC,EAASsB,UAC9B,GAAKe,QA4HiBf,EA5HgBkB,GA8H5B1H,eAKd,SAA4BwG,GAC1B,IAAMlG,EAAMD,KAAKC,MACjB,OACEA,EAAMkG,EAAUpG,cAChBoG,EAAUpG,aAAeoG,EAAUvG,UAAYK,EAAMhB,EARpDqI,CAAmBnB,GA5Hb,CAAA,OAAIkB,EAAa1H,cAGtB,OADA4H,EA0BN,SACEN,EACAC,mGAMY,SAAMM,GAAuBP,EAAa/F,mBAAlDkE,EAAQ5L,qCACL4L,EAAMe,UAAUxG,uBAEf6B,EAAM,aAEJ,OAFRhI,YAEcgO,GAAuBP,EAAa/F,0BAAlDkE,EAAQ5L,sBAIV,YADM2M,EAAYf,EAAMe,WACVxG,iBAELqH,GAAiBC,EAAcC,OAE/Bf,QA/CUsB,CAA0BR,EAAcC,GAChDrC,EAGP,IAAKS,UAAUC,OACb,MAAMpG,EAAcpH,sBAGtB,IAAM0N,GAgIVZ,EAhIgEA,EAkI1DuC,EAA2C,CAC/CzH,gBACA+H,YAAa1H,KAAKC,cAGf4E,IACHsB,UAAWiB,KAtIT,OADAG,EAsEN,SACEN,EACAnC,qGAGoB,gCAAM2B,GACtBQ,EACAnC,WAMF,OARMqB,EAAY3M,SAIZmO,SACD7C,IACHqB,iBAEI9K,GAAI4L,EAAa/F,UAAWyG,WAClC,OADAnO,YACO2M,iBAEH/G,eAAsC,MAAjBkH,EAAE/F,YAAuC,MAAjB+F,EAAE/F,oBAG3CgE,GAAO0C,EAAa/F,0BAA1B1H,sBAMA,OAJMmO,SACD7C,IACHqB,UAAW,CAAExG,sBAETtE,GAAI4L,EAAa/F,UAAWyG,WAAlCnO,0BAEF,MAAM8M,wBAjGWsB,CAAyBX,EAAcxB,GAC/CA,EAbP,OAAOZ,mBARLO,EAAQ9L,SAyBIiO,KACRA,uBAAN/N,EAAAF,sBACAE,EAAC4L,EAAMe,2BACX,iBA0CF,SAASqB,GACPtG,GAEA,OAAOuD,GAAOvD,EAAW,SAAA2D,GACvB,IAAKsC,GAAkBtC,GACrB,MAAM1F,EAAcpH,yBAGtB,IAiFiCoO,EAjF3BkB,EAAexC,EAASsB,UAC9B,YAgFiCA,EAhFDkB,GAkFtB1H,eACVwG,EAAUuB,YAAc7I,EAAqBmB,KAAKC,aAjF3C4E,IACHsB,UAAW,CAAExG,mBAIVkF,IAmCX,SAASsC,GACPrC,GAEA,YACwBnG,IAAtBmG,OACAA,EAAkBE,4BCpJA6C,GACpBZ,EACAC,uBAAAA,uFAEA,SAQF,SACEhG,iGAEgC,SAAM0D,GAAqB1D,kBAAnDgE,EAAwB1L,iCAIxB0L,gBAAN1L,yCAfIsO,CAAiCb,EAAa/F,mBAIlC,OAJlB1H,YAIwBwN,GAAiBC,EAAcC,WACvD,SADkB1N,SACDkG,qBCLGqI,GACpB7G,EACA4D,uGAUiB,OAOjB5D,EAfmCA,EAgBjCkB,EAhB4C0C,MAAxCa,EAkBIrG,EAAyB4B,OAAckB,EAhB3ChB,EAAUH,EAAmBC,EAAW4D,GACxCxK,EAAuB,CAC3BK,OAAQ,SACRyG,cAGqBE,EAAmB,WAAM,OAAA0E,MAAML,EAAUrL,oBAA1DmF,EAAWjG,UACHyM,YACA/F,EAAqB,sBAAuBT,WAAxD,MAAMjG,0BAIV,IACE0H,EACEkB,eCnBY4F,GACdxO,EACA2E,OADE+C,cAKF,gBTEAA,EACA/C,GAIAgF,KAEA,IAAMjK,EAAMyJ,EAAOzB,GAEf+G,EAAcnF,EAAmB1H,IAAIlC,GACpC+O,IACHA,EAAc,IAAIC,IAClBpF,EAAmBzH,IAAInC,EAAK+O,IAE9BA,EAAYE,IAAIhK,GSlBhBiK,CAAYlH,EAAW/C,GAEhB,eTqBPA,EAEMjF,EAEA+O,EAJN9J,ESpB4BA,ETsBtBjF,EAAMyJ,EStBKzB,ITwBX+G,EAAcnF,EAAmB1H,IAAIlC,MAM3C+O,EAAYzD,OAAOrG,GACM,IAArB8J,EAAYrE,MACdd,EAAmB0B,OAAOtL,GAI5BmK,OUlBF,SAASgF,GAAqBC,GAC5B,OAAOnJ,EAAcpH,mCAA4C,CAC/DuQ,eRjBkC9J,GAmChB+J,IAhCXC,SAASC,kBAChB,IAAI7O,EAHoB,gBAKtB,SAAA8O,GACE,IAAMC,EAAMD,EAAUE,YAAY,OAAOhC,eAKnCK,EAAqC,CACzC/F,mBQ5BuByH,WAC/B,IAAKA,IAAQA,EAAIE,QACf,MAAMR,GAAqB,qBAG7B,IAAKM,EAAIzO,KACP,MAAMmO,GAAqB,gBAU7B,IAAsB,IAAAS,EAAAzR,EAN2B,CAC/C,YACA,SACA,wCAGgC,CAA7B,IAAM0R,UACT,IAAKJ,EAAIE,QAAQE,GACf,MAAMV,GAAqBU,qGAI/B,MAAO,CACLnG,QAAS+F,EAAIzO,KACbqF,UAAWoJ,EAAIE,QAAQtJ,UACvBqB,OAAQ+H,EAAIE,QAAQjI,OACpBiC,MAAO8F,EAAIE,QAAQhG,ORDGmG,CAAiBL,GAIjCjC,uBAH6BgC,EAAUE,YAAY,oBAerD,MAT+D,CAC7DD,MACAM,MAAO,WAAM,gBSlCrBhC,qGAEmD,SAAMrC,GACvDqC,EAAa/F,mBAWf,OAZM1H,EAA6CF,SAA3CwL,uBAAmBI,yBAKzBA,EAAoBgE,MAAMxP,QAAQ/B,OAIlCqP,GAAiBC,GAAciC,MAAMxP,QAAQ/B,UAGxCmN,EAAkB1C,UToBJ6G,CAAMhC,IACnBY,SAAU,SAACX,GACT,OAAAW,GAASZ,EAAcC,IACzB1C,OAAQ,WAAM,gBUnCtByC,mGAIc,SAAMxC,GAFZvD,EAAc+F,YAEgB,SAAApC,GACpC,IAAIA,OAAYA,EAASG,mBAIzB,OAAOH,iBALHO,EAAQ5L,UAQV,mBACE4L,EAAMJ,mBAAN,YAEF,MAAM7F,EAAcpH,oDACXqN,EAAMJ,mBAAN,eACJM,UAAUC,OAAX,YACF,MAAMpG,EAAcpH,6BAEpB,SAAMgQ,GAA0B7G,EAAWkE,WAC3C,OADA5L,YACM+K,GAAOrD,WAAb1H,yCVcgB2P,CAAmBlC,IACjCe,WAAY,SAAC7J,GACX,OAAA6J,GAAWf,EAAc9I,iBAQnCK,GAAS4K,0CAAsBlM,GW9B1B,IAAMmM,yCAET,kDACF7P,+BACE,gDACFA,2BACE,wDACFA,yBACE,qEACFA,yBACE,mEACFA,0BACE,2EACFA,yCACE,+EACFA,6BACE,oEACFA,+BACE,2DACFA,+BACE,wEAEFA,0BACE,mEACFA,4BACE,wDACFA,6BACE,4IAEFA,8BACE,uEACFA,yBACE,iEACFA,wBAA+B,yCAC/BA,oCACE,4IAcS2F,GAAgB,IAAI3G,EAC/B,YACA,YACA6Q,ICpCF,SAAShB,GAAqBC,GAC5B,OAAOnJ,GAAcpH,mCAA4C,CAC/DuQ,cCxCG,ICEKgB,GAAAA,GDCCC,GACX,0FAEWC,GAAW,6CAGXC,GAAU,UAEVC,GAAsB,2BEXnBC,GAActH,GAC5B,IAAMuH,EAAa,IAAI7H,WAAWM,GAElC,OADqBC,KAAKnJ,OAAOoJ,mBAAPpJ,SAAuByQ,KAC7B5Q,QAAQ,KAAM,IAAIA,QAAQ,MAAO,KAAKA,QAAQ,MAAO,MDD/DsQ,GAAAA,GAAAA,sCAEVA,+CEuCF,IAAMO,GAAc,uBAKdC,GAAiB,EACjBC,GAAwB,kCAERC,GACpBC,gHAEI,cAAe7M,aAIQA,UAEtB8M,0BAGH,GALMA,EAAY1Q,UAGF0Q,EAAUC,IAAI,SAAAvN,GAAM,OAAAA,EAAG1C,OAE1BmF,SAASwK,IAEpB,SAAO,uBAMA,OAFPO,EAAoC,QAEvBnN,EAAO4M,GAAaC,GAAgB,SAAMlN,oGACzD,OAAIA,EAAGC,WAAa,MAKfD,EAAGyN,iBAAiBC,SAASP,QAK5BlM,EAAcjB,EAAGE,YAAYe,YAAYkM,KACflO,MAAM,eAAeT,IAAI6O,eACzD,OADMxU,EAAQ6D,YACRuE,EAAY0M,gBAElB,GAFAjR,UAEK7D,EAEH,UAGF,GAAsB,IAAlBmH,EAAGC,WAAkB,CAGvB,KAFM2N,EAAa/U,GAEHgV,OAASD,EAAWE,SAAWF,EAAW7E,SACxD,UAGFyE,EAAe,CACb1K,MAAO8K,EAAWG,SAClBC,qBAAYJ,EAAWI,0BAAc5K,KAAKC,MAC1C4K,oBAAqB,CACnBJ,KAAMD,EAAWC,KACjBC,OAAQF,EAAWE,OACnB/E,SAAU6E,EAAW7E,SACrBmF,QAASN,EAAWM,QACpBC,SACiC,iBAAxBP,EAAWO,SACdP,EAAWO,SACXpB,GAAca,EAAWO,iBAGR,IAAlBnO,EAAGC,YAce,IAAlBD,EAAGC,cAXZuN,EAAe,CACb1K,OAHI8K,EAAa/U,GAGCkV,SAClBC,WAAYJ,EAAWI,WACvBC,oBAAqB,CACnBJ,KAAMd,GAAca,EAAWC,MAC/BC,OAAQf,GAAca,EAAWE,QACjC/E,SAAU6E,EAAW7E,SACrBmF,QAASN,EAAWM,QACpBC,SAAUpB,GAAca,EAAWO,sCAsB3C,OA1EWvR,SAuERqK,WAGGtG,EAASsM,YACf,OADArQ,YACM+D,EAAS,gCACf,OADA/D,YACM+D,EAAS,qBAEf,OAFA/D,YAKF,SACE4Q,GAEA,IAAKA,IAAiBA,EAAaS,oBACjC,OAEM,IAAAA,EAAwBT,sBAChC,MACqC,iBAA5BA,EAAaQ,YACM,EAA1BR,EAAaQ,YACiB,iBAAvBR,EAAa1K,OACQ,EAA5B0K,EAAa1K,MAAM/K,QACiB,iBAA7BkW,EAAoBJ,MACO,EAAlCI,EAAoBJ,KAAK9V,QACa,iBAA/BkW,EAAoBH,QACS,EAApCG,EAAoBH,OAAO/V,QACa,iBAAjCkW,EAAoBlF,UACW,EAAtCkF,EAAoBlF,SAAShR,QACU,iBAAhCkW,EAAoBC,SACU,EAArCD,EAAoBC,QAAQnW,QACY,iBAAjCkW,EAAoBE,UACW,EAAtCF,EAAoBE,SAASpW,OAxBxBqW,CAAkBZ,GAAgBA,EAAe,WC/InD,IAAMtG,GAAgB,8BACvBC,GAAmB,EACnBC,GAAoB,2BAEtBC,GAAgC,KACpC,SAASC,KAcP,OAZED,GADGA,IACShH,EAAO6G,GAAeC,GAAkB,SAAAkH,GAMlD,OAAQA,EAAUpO,YAChB,KAAK,EACHoO,EAAUlN,kBAAkBiG,gBAQhBkH,GACpBC,qGAGW,OADLjS,EAAMyJ,GAAOwI,MACFjH,aACI,SADV1K,SAERsD,YAAYkH,IACZnG,YAAYmG,IACZ5I,IAAIlC,kBAHDkR,EAAe5Q,aAMZ4Q,gBAGiB,SAAMJ,GAC5BmB,EAAqBjK,UAAU+I,yBAD3BmB,EAAkB5R,aAIhB6R,GAAMF,EAAsBC,iBAClC,OADA5R,YACO4R,kCAMSC,GACpBF,EACAf,qGAGW,OADLlR,EAAMyJ,GAAOwI,MACFjH,aAEjB,OAFMtH,EAAKpD,aACL4K,EAAKxH,EAAGE,YAAYkH,GAAmB,cACpCnG,YAAYmG,IAAmBM,IAAI8F,EAAclR,WAC1D,OADAM,YACM4K,EAAG5H,iBACT,OADAhD,YACO4Q,QAuBT,SAASzH,GAAOnJ,GACd,mBAAiBqJ,eCaGyI,GACpBH,EACAzL,yGAEgB,SAAMiB,GAAWwK,WAA3B/J,EAAU5H,SAEV+R,EAAqB,CACzB5Q,OAAQ,SACRyG,4BAIiB,gCAAM4E,MAClBwF,GAAYL,EAAqBjK,eAAcxB,EAClD6L,WAEgC,SAJjB/R,SAIgC4G,eACjD,IADMqL,EAA4BjS,UACjB7B,MAEf,MADMQ,EAAUsT,EAAa9T,MAAMQ,QAC7BgH,GAAcpH,kCAA2C,CAC7D2T,UAAWvT,uBAIf,iBAAMgH,GAAcpH,kCAA2C,CAC7D2T,UAAWC,0BAKjB,SAASH,GAAYhS,OAAE+F,cACrB,OAAUiK,gBAAqBjK,mBAGjC,SAAeoB,GAAWnH,OACxB0H,cACA0K,gHAEkB,SAAMA,EAAc/D,mBAEtC,OAFM1B,EAAY7M,YAEX,IAAIuH,QAAQ,CACjBC,eAAgB,mBAChBC,OAAQ,mBACRC,iBAAkBE,EAAUN,OAC5BiL,qCAAsC,OAAO1F,UAIjD,SAAS2F,GAAQtS,OACfkR,WACAD,SACA9E,aACAoF,aAEM7U,EAAuB,CAC3B6V,IAAK,CACHpG,WACA8E,OACAC,WAQJ,OAJIK,IAAaxB,KACfrT,EAAK6V,IAAIC,kBAAoBjB,GAGxB7U,WCzJa2R,GACpBsD,EACAc,EACAlB,uGAEA,GAAgC,YAA5BmB,aAAaC,WACf,MAAMhN,GAAcpH,6BAKG,SAgH3B,SACEkU,EACAlB,iGAEqB,SAAMkB,EAAeG,YAAYC,0BACtD,OADMC,EAAe9S,aAEZ8S,MAEFL,EAAeG,YAAYG,UAAU,CAC1CC,iBAAiB,EAGjBC,8BJ9I0BC,GAS5B,IARA,IACMC,GAAUD,EADA,IAAIE,QAAQ,EAAKF,EAAa/X,OAAS,GAAM,IAE1DqE,QAAQ,MAAO,KACfA,QAAQ,KAAM,KAEX6T,EAAUC,KAAKH,GACfI,EAAc,IAAIhL,WAAW8K,EAAQlY,QAElCH,EAAI,EAAGA,EAAIqY,EAAQlY,SAAUH,EACpCuY,EAAYvY,GAAKqY,EAAQG,WAAWxY,GAEtC,OAAOuY,EIkIiBE,CAAclC,WA5HPmC,CAAoBjB,EAAgBlB,WAC9C,OADfoC,EAAmB3T,YACE0R,GAAMC,kBAA3Bf,EAAe5Q,SAEfqR,EAA2C,CAC/CE,WACAD,QAASmB,EAAemB,MACxBzH,SAAUwH,EAAiBxH,SAC3B8E,KAAMd,GAAcwD,EAAiBxK,OAAO,SAC5C+H,OAAQf,GAAcwD,EAAiBxK,OAAO,YAG3CyH,WAEIiD,GAAYlC,EAAsBN,cAuH3CyC,EArHgBlD,EAAaS,oBAwHvB0C,GAFNC,EAtHmD3C,GAwHZE,WAAauC,EAAUvC,SACxD0C,EAAkBD,EAAe7H,WAAa2H,EAAU3H,SACxD+H,EAAcF,EAAe/C,OAAS6C,EAAU7C,KAChDkD,EAAgBH,EAAe9C,SAAW4C,EAAU5C,OAEnD6C,GAAmBE,GAAmBC,GAAeC,EA7H1D,6BAIE,gCAAMrC,GAAmBH,EAAsBf,EAAa1K,sBAA5DlG,wCAGAE,QAAQC,KAAK2M,gBAGf,SAAO+G,GAAYlC,EAAsBN,WACpC,OAAI7K,KAAKC,OAASmK,EAAaQ,WAvCZ,UAgF5B,SACER,EACAe,EACAc,qGAGuB,yCDpCvBd,EACAf,2GAEgB,SAAMzJ,GAAWwK,WAA3B/J,EAAU5H,SACVtD,EAAO4V,GAAQ1B,EAAaS,qBAE5B+C,EAAgB,CACpBjT,OAAQ,QACRyG,UACAlL,KAAM4P,KAAKC,UAAU7P,qBAKJ,gCAAM8P,MAClBwF,GAAYL,EAAqBjK,eAAckJ,EAAa1K,MAC/DkO,WAEa,SAJEpU,SAIa4G,sBAA9BqL,EAAejS,sBAEf,iBAAM2F,GAAcpH,6BAAsC,CACxD2T,UAAWmC,WAIf,GAAIpC,EAAa9T,MAEf,MADMQ,EAAUsT,EAAa9T,MAAMQ,QAC7BgH,GAAcpH,6BAAsC,CACxD2T,UAAWvT,IAIf,IAAKsT,EAAa/L,MAChB,MAAMP,GAAcpH,gCAGtB,SAAO0T,EAAa/L,YCASoO,CACzB3C,EACAf,WASF,OAXM2D,EAAevU,SAKfwU,SACD5D,IACH1K,MAAOqO,EACPnD,WAAY5K,KAAKC,WAGboL,GAAMF,EAAsB6C,WAClC,OADAxU,YACOuU,UAEP,qBAAME,GAAY9C,EAAsBc,WACxC,MADAzS,SACM0U,wBA5DCC,CACL,CACEzO,MAAO0K,EAAa1K,MACpBkL,WAAY5K,KAAKC,MACjB4K,uBAEFM,EACAc,OAIK7B,EAAa1K,wBA4FxB,IACE4N,EACAE,EAEMD,EACAE,EACAC,EACAC,eA3FcM,GACpB9C,EACAc,mGAEqB,SAAMf,GAAMC,kBAA3Bf,EAAe5Q,aAEb8R,GAAmBH,EAAsBf,EAAa1K,qBAC5D,OADAlG,qBFTF2R,qGAGW,OADLjS,EAAMyJ,GAAOwI,MACFjH,aAEjB,OAFMtH,EAAKpD,aACL4K,EAAKxH,EAAGE,YAAYkH,GAAmB,cACpCnG,YAAYmG,IAAmBQ,OAAOtL,WAC/C,OADAM,YACM4K,EAAG5H,wBAAThD,kBEIQ4U,CAASjD,WAAf3R,0BAIuB,SAAMyS,EAAeG,YAAYC,0BAC1D,OADMc,EAAmB3T,aAEhB2T,EAAiBkB,mBAInB,QA4BT,SAAehB,GACblC,EACAN,mGAEc,kBDnGdM,EACAN,2GAEgB,SAAMlK,GAAWwK,WAA3B/J,EAAU5H,SACVtD,EAAO4V,GAAQjB,GAEfyD,EAAmB,CACvB3T,OAAQ,OACRyG,UACAlL,KAAM4P,KAAKC,UAAU7P,qBAKJ,gCAAM8P,MACrBwF,GAAYL,EAAqBjK,WACjCoN,WAEa,SAJE9U,SAIa4G,sBAA9BqL,EAAejS,sBAEf,iBAAM2F,GAAcpH,gCAAyC,CAC3D2T,UAAW6C,WAIf,GAAI9C,EAAa9T,MAEf,MADMQ,EAAUsT,EAAa9T,MAAMQ,QAC7BgH,GAAcpH,gCAAyC,CAC3D2T,UAAWvT,IAIf,IAAKsT,EAAa/L,MAChB,MAAMP,GAAcpH,mCAGtB,SAAO0T,EAAa/L,YC+DA8O,CAClBrD,EACAN,WAOF,OATMnL,EAAQlG,SAIR4Q,EAA6B,CACjC1K,QACAkL,WAAY5K,KAAKC,MACjB4K,0BAEIQ,GAAMF,EAAsBf,WAClC,OADA5Q,YACO4Q,EAAa1K,qBC/HN+O,GAAiB/V,GAG/B,MAAuB,iBAATA,GAAuBA,GAAQgR,MAAuBhR,ECetE,QAaE5E,sBAAI4a,wBAAJ,WACE,OAAO3Z,KAAKoW,qBAAqBxC,qCAG7B+F,sBAAN,yGAKyB,OAJlB3Z,KAAKgW,WACRhW,KAAKgW,SAAWxB,OAGWxU,KAAK4Z,8CAA5B1C,EAAiBzS,SAGS,YAA5B0S,aAAaC,oBAETD,aAAa0C,4BAAnBpV,0BAGF,GAAgC,YAA5B0S,aAAaC,WACf,MAAMhN,GAAcpH,6BAGtB,SAAO8P,GAAS9S,KAAKoW,qBAAsBc,EAAgBlX,KAAKgW,iBAG5D2D,yBAAN,yGACyB,SAAM3Z,KAAK4Z,uCAElC,OAFM1C,EAAiBzS,YAEhByU,GAAYlZ,KAAKoW,qBAAsBc,UAW1CyC,+BAAN,yGACE,MAAgC,YAA5BxC,aAAaC,kBAIcD,aAAa0C,4BAC5C,GAAyB,aADnBC,EAAmBrV,UAEvB,UACK,KAAyB,WAArBqV,EACH1P,GAAcpH,6BAEdoH,GAAcpH,mCAKxB2W,+BAAA,SAAkB3D,GAChB,GAAsB,OAAlBhW,KAAKgW,SACP,MAAM5L,GAAcpH,wCAGtB,GAAwB,iBAAbgT,GAA6C,IAApBA,EAASpW,OAC3C,MAAMwK,GAAcpH,4BAGtBhD,KAAKgW,SAAWA,GAGlB2D,8BAAA,SAAiBzC,GACf,KAAMA,aAA0B6C,2BAC9B,MAAM3P,GAAcpH,kCAGtB,GAAIhD,KAAKkX,eACP,MAAM9M,GAAcpH,iCAGtBhD,KAAKkX,eAAiBA,GAQxByC,uBAAA,SAAUK,GAAV,WAGE,OAFAha,KAAKia,kBAAoBD,EAElB,WACL1W,EAAK2W,kBAAoB,OAI7BN,yCAAA,WACE,MAAMvP,GAAcpH,gCAItB2W,4BAAA,WACE,OAAO,cAOKA,0CAAd,8GAGO3Z,KAAKkX,eAAN,6BAEsB,6BAAtBzS,EAAAzE,QAA4BuQ,UAAU2J,cAAcC,SR/I7B,4BQiJrB,CACE9B,MRjJoB,wDQ8IxB5T,EAAKyS,eAAiB3S,SAWtBvE,KAAKkX,eAAexH,SAASyE,MAAM,2BAInC,iBAAM/J,GAAcpH,4CAA8C,CAChEoX,oBAAqB7I,EAAEnO,iBAK7B,SAAOpD,KAAKkX,sBAGAyC,kCAAd,SAAmCpR,6GACjC,iBAAKA,EAAM5E,qBAAM0W,mBAKX9V,EAAqBgE,EAAM5E,KAAyB0W,kBAAlDhV,SAAMiV,YAGVta,KAAKia,mBAAqB5U,IAASkP,GAAYgG,gBACX,mBAA3Bva,KAAKia,kBACdja,KAAKia,kBAAkBK,GAEvBta,KAAKia,kBAAkBrZ,KAAK0Z,IAM9BZ,GAFM/V,EAAS2W,SAG8B,MAA7C3W,ER5K4C,mBQ+KtC3D,KAAKwa,SAASnV,EAAM1B,sBAA1B8W,0CAIUd,sBAAd,SACEe,EACA/W,iGAGkB,OADZgX,EAaV,SAAsBD,GACpB,OAAQA,GACN,KAAKnG,GAAYqG,qBACf,MAAO,oBACT,KAAKrG,GAAYgG,cACf,MAAO,0BACT,QACE,MAAM,IAAIxX,OApBM8X,CAAaH,MACP1a,KAAKoW,qBAAqB0E,kBAAkBzU,qBAAlD5B,SACR+V,SAASG,EAAW,CAE5BI,WAAYpX,EAAKgR,IACjBqG,aAAcrX,ER/LiB,kBQgM/BsX,aAActX,ER/LiB,iBQgM/BuX,oBAAqBC,KAAKC,MAAMnQ,KAAKC,MAAQ,qBAnLjD,YACmBkL,GADnB,WACmBpW,0BAAAoW,EALXpW,cAA0B,KAE1BA,uBAA8D,KAKpEuQ,UAAU2J,cAAcmB,iBAAiB,UAAW,SAAAxa,GAClD,OAAAyC,EAAKgY,qBAAqBza,KCRhC,QAkBE9B,sBAAIwc,wBAAJ,WACE,OAAOvb,KAAKoW,qBAAqBxC,qCAkBnC2H,yCAAA,SAA4BnS,GAC1B,IAAKA,GAAgC,mBAAbA,EACtB,MAAMgB,GAAcpH,6BAGtBhD,KAAKwb,iBAAmBpS,GAKpBmS,sBAAN,wHACOvb,KAAKgW,kBAKmBG,GAAMnW,KAAKoW,8BAAhCf,EAAeoF,SACrBza,KAAKgW,6BACHX,MAAAA,SAAAA,EAAcS,0CAAqBE,wBAAYxB,oBAGnD,SAAO1B,GACL9S,KAAKoW,qBACLnJ,KAAKwO,aACLzb,KAAKgW,iBAMTuF,yBAAA,WACE,OAAOrC,GAAYlZ,KAAKoW,qBAAsBnJ,KAAKwO,eAGrDF,+BAAA,WACE,MAAMnR,GAAcpH,oCAKtBuY,+BAAA,SAAkBvF,GAChB,GAAsB,OAAlBhW,KAAKgW,SACP,MAAM5L,GAAcpH,wCAGtB,GAAwB,iBAAbgT,GAA6C,IAApBA,EAASpW,OAC3C,MAAMwK,GAAcpH,4BAGtBhD,KAAKgW,SAAWA,GAGlBuF,8BAAA,WACE,MAAMnR,GAAcpH,oCAGtBuY,uBAAA,WACE,MAAMnR,GAAcpH,oCAGtBuY,4BAAA,WACE,MAAMnR,GAAcpH,oCAehBuY,oBAAN,SAAahT,qGAEX,OADM+R,EA+EV,SAA2B7V,OAAEd,SAC3B,IAAKA,EACH,OAAO,KAGT,IACE,OAAOA,EAAK0H,OACZ,MAAOqQ,GAEP,OAAO,MAxFSC,CAAkBpT,OAKTqT,iBACzB,OADMC,EAAapX,UAwIHqX,KAChB,SAAAC,GACE,MAA2B,YAA3BA,EAAOC,kBAGND,EAAOE,IAAIC,WAAW,4BAU7B,SACEL,EACAvB,WAEMlX,EAAU+Y,GAAiB5H,GAAYgG,cAAeD,OAE5D,IAAqB,IAAA8B,EAAA9Z,EAAAuZ,yCACZxN,YAAYjL,qGA3JViZ,CAA2BR,EAAYvB,KAG1CgC,EAiFV,SACEhC,SAEA,GAAKA,GAA2C,iBAAzBA,EAAQiC,aAA/B,CAIA,IAAMC,OACDlC,EAAQiC,cAYb,OALAC,EAAwB7Y,YACnB2W,EAAQiC,aAAa5Y,cACvB+Q,IAAU4F,MAGNkC,GArGuBC,CAAoBnC,OA6KpD,SAA0BoC,SAClBC,YAAQD,EAAQC,qBAAS,GAEvBC,EAAYF,UAGZG,EAAe1F,wBAOvB,OANIyF,GAAWC,GAAcD,EAAQhd,OAASid,GAC5ClY,QAAQC,KACN,8BAA8BiY,4DAI3B5P,KAAKwO,aAAaqB,iBAAiBH,EAAOD,GAxLvCI,CAAiBR,wBAAvB7X,6BACSzE,KAAKwb,oBACRxb,KAAKwb,iBAAiBlB,iBAA5B7V,0CAIE8W,yBAAN,SAAkBhT,gHACYA,2BAGpB2Q,GAAYlZ,KAAKoW,qBAAsBnJ,KAAKwO,sBAClD,OADAhB,oBAImB,SAAMtE,GAAMnW,KAAKoW,8BACtC,OADMf,EAAeoF,YACfvB,GAAYlZ,KAAKoW,qBAAsBnJ,KAAKwO,sBAClD,OADAhB,YACM3H,GACJ9S,KAAKoW,qBACLnJ,KAAKwO,iCACLpG,MAAAA,SAAAA,EAAcS,0CAAqBE,wBAAYxB,mBAHjDiG,mBAOIc,iCAAN,SAA0BhT,+GAExB,QADM+R,sBAA0B/R,EAAMgU,mCAAc5Y,2BAAO+Q,MAIhDnM,EAAMwU,YAQjBxU,EAAMyU,2BACNzU,EAAMgU,aAAazN,SAEbmO,EAoJV,SAAiB3C,aAET2C,sBAAO3C,EAAQ4C,iCAAYD,8BAAQ3C,EAAQiC,mCAAcY,aAC/D,OAAIF,IAIAvD,GAAiBY,EAAQ3W,MAEpBsJ,KAAKmQ,SAASC,OAEd,MA/JMC,CAAQhD,OAmEzB,SAA+B2B,6GAKV,OAFbsB,EAAY,IAAIC,IAAIvB,EAAKhP,KAAKmQ,SAASK,SAEpB7B,aAAnBC,EAAatX,aAEnB,IAAqBmZ,EAAApb,EAAAuZ,iCAEnB,GAFSE,UACe,IAAIyB,IAAIzB,EAAOE,IAAKhP,KAAKmQ,SAASK,MACtCE,OAASJ,EAAUI,KACrC,SAAO5B,oGAIX,SAAO,WA5Ec6B,CAAgBX,uBAA/BlB,EAAStB,mBAIIxN,KAAK4Q,QAAQC,WAAWb,WAGvC,OAHAlB,EAAStB,aCpMO/N,EDuMJ,ICtMT,IAAIpM,QAAc,SAAAC,GACvBoM,WAAWpM,EAASmM,qBDqMlB+N,sBAES,SAAMsB,EAAOgC,gBAAtBhC,EAAStB,0BAGX,OAAKsB,GAKC3Y,EAAU+Y,GAAiB5H,GAAYqG,qBAAsBN,MAC5DyB,EAAO1N,YAAYjL,aClNRsJ,WDyBpB,YACmB0J,GADnB,WACmBpW,0BAAAoW,EAJXpW,cAA0B,KAC1BA,sBAA4C,KAKlDiN,KAAKoO,iBAAiB,OAAQ,SAAAxa,GAC5BA,EAAEmd,UAAU1a,EAAK2a,OAAOpd,MAE1BoM,KAAKoO,iBAAiB,yBAA0B,SAAAxa,GAC9CA,EAAEmd,UAAU1a,EAAK4a,YAAYrd,MAE/BoM,KAAKoO,iBAAiB,oBAAqB,SAAAxa,GACzCA,EAAEmd,UAAU1a,EAAK6a,oBAAoBtd,MA2Q3C,SAAS+a,KACP,OAAO3O,KAAK4Q,QAAQO,SAAS,CAC3B/Y,KAAM,SACNgZ,qBAAqB,IAKzB,SAASlC,GACP9W,EACAiV,GAEA,MAAO,CACLD,kBAAmB,CAAEhV,OAAMiV,YE5Q/B,IAAMgE,GAAoB,CACxBC,gBA0BF,SAASA,KACP,OAAItR,MAAQ,6BAA8BA,KA+BxC,cAAeA,MACD,OAAd5E,WACA,gBAAiB4E,MACjB,iBAAkBA,MAClB8M,0BAA0Bla,UAAUT,eAAe,qBACnDof,iBAAiB3e,UAAUT,eAAe,UAtB1C,cAAeqf,QACD,OAAdpW,WACAkI,UAAUmO,eACV,kBAAmBnO,WACnB,gBAAiBkO,QACjB,iBAAkBA,QAClB,UAAWA,QACX1E,0BAA0Bla,UAAUT,eAAe,qBACnDof,iBAAiB3e,UAAUT,eAAe,UA9C7CoU,GAAgCC,SAASC,kBACxC,IAAI7O,EAnCiB,YACvB,SACE8O,GAGA,IAAMC,EAAMD,EAAUE,YAAY,OAAOhC,eAKnCuE,EAAqD,CACzDxC,MACAzH,mBZzB6ByH,WAC/B,IAAKA,IAAQA,EAAIE,QACf,MAAMR,GAAqB,4BAG7B,IAAKM,EAAIzO,KACP,MAAMmO,GAAqB,YAI7B,IAOQQ,EAAYF,cACpB,IAAsB,IAAAG,EAAAzR,EARmC,CACvD,YACA,SACA,QACA,oDAIgC,CAA7B,IAAM0R,UACT,IAAKF,EAAQE,GACX,MAAMV,GAAqBU,qGAI/B,MAAO,CACLnG,QAAS+F,EAAIzO,KACbqF,UAAWsJ,EAAQtJ,UACnBqB,OAAQiI,EAAQjI,OAChBiC,MAAOgG,EAAQhG,MACfoH,SAAUpB,EAAQ6K,mBYVF1K,CAAiBL,GAOjCiD,cANoBlD,EAAUE,YAAY,iBAAiBhC,eAO3DiJ,kBANwBnH,EAAUE,YAAY,uBAShD,IAAK0K,KACH,MAAMnU,GAAcpH,8BAGtB,OAES,IAFLiK,MAAQ,6BAA8BA,KAE7BsO,GAGA5B,IAHavD,cAgBxBwI,gBAAgBN"}