(self["webpackChunkapp"] = self["webpackChunkapp"] || []).push([[3721],{ /***/ 13721: /*!********************************************************************!*\ !*** ./node_modules/@capacitor-firebase/analytics/dist/esm/web.js ***! \********************************************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "FirebaseAnalyticsWeb": () => (/* binding */ FirebaseAnalyticsWeb) /* harmony export */ }); /* harmony import */ var _Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 71670); /* harmony import */ var _capacitor_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @capacitor/core */ 26549); /* harmony import */ var firebase_analytics__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! firebase/analytics */ 43763); /* harmony import */ var _definitions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./definitions */ 47499); class FirebaseAnalyticsWeb extends _capacitor_core__WEBPACK_IMPORTED_MODULE_1__.WebPlugin { getAppInstanceId() { var _this = this; return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { throw _this.unimplemented('Not implemented on web.'); })(); } setConsent(options) { return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { const status = options.status === _definitions__WEBPACK_IMPORTED_MODULE_3__.ConsentStatus.Granted ? 'granted' : 'denied'; const consentSettings = {}; switch (options.type) { case _definitions__WEBPACK_IMPORTED_MODULE_3__.ConsentType.AdPersonalization: consentSettings.ad_personalization = status; break; case _definitions__WEBPACK_IMPORTED_MODULE_3__.ConsentType.AdStorage: consentSettings.ad_storage = status; break; case _definitions__WEBPACK_IMPORTED_MODULE_3__.ConsentType.AdUserData: consentSettings.ad_user_data = status; break; case _definitions__WEBPACK_IMPORTED_MODULE_3__.ConsentType.AnalyticsStorage: consentSettings.analytics_storage = status; break; case _definitions__WEBPACK_IMPORTED_MODULE_3__.ConsentType.FunctionalityStorage: consentSettings.functionality_storage = status; break; case _definitions__WEBPACK_IMPORTED_MODULE_3__.ConsentType.PersonalizationStorage: consentSettings.personalization_storage = status; break; } (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.setConsent)(consentSettings); })(); } setUserId(options) { return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { const analytics = (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.getAnalytics)(); (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.setUserId)(analytics, options.userId); })(); } setUserProperty(options) { return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { const analytics = (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.getAnalytics)(); (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.setUserProperties)(analytics, { [options.key]: options.value }); })(); } setCurrentScreen(options) { return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { const analytics = (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.getAnalytics)(); (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.logEvent)(analytics, 'screen_view', { firebase_screen: options.screenName || undefined, firebase_screen_class: options.screenClassOverride || undefined }); })(); } logEvent(options) { return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { const analytics = (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.getAnalytics)(); (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.logEvent)(analytics, options.name, options.params); })(); } setSessionTimeoutDuration(_options) { var _this2 = this; return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { throw _this2.unimplemented('Not implemented on web.'); })(); } setEnabled(_options) { return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { const analytics = (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.getAnalytics)(); (0,firebase_analytics__WEBPACK_IMPORTED_MODULE_2__.setAnalyticsCollectionEnabled)(analytics, _options.enabled); })(); } isEnabled() { return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { const enabled = window['ga-disable-analyticsId'] === true; return { enabled }; })(); } resetAnalyticsData() { var _this3 = this; return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { throw _this3.unimplemented('Not implemented on web.'); })(); } initiateOnDeviceConversionMeasurementWithEmailAddress(_options) { var _this4 = this; return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { throw _this4.unimplemented('Not implemented on web.'); })(); } initiateOnDeviceConversionMeasurementWithPhoneNumber(_options) { var _this5 = this; return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { throw _this5.unimplemented('Not implemented on web.'); })(); } initiateOnDeviceConversionMeasurementWithHashedEmailAddress(_options) { var _this6 = this; return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { throw _this6.unimplemented('Not implemented on web.'); })(); } initiateOnDeviceConversionMeasurementWithHashedPhoneNumber(_options) { var _this7 = this; return (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { throw _this7.unimplemented('Not implemented on web.'); })(); } } /***/ }), /***/ 84850: /*!*********************************************************************************!*\ !*** ./node_modules/firebase/node_modules/@firebase/util/dist/index.esm2017.js ***! \*********************************************************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "CONSTANTS": () => (/* binding */ CONSTANTS), /* harmony export */ "DecodeBase64StringError": () => (/* binding */ DecodeBase64StringError), /* harmony export */ "Deferred": () => (/* binding */ Deferred), /* harmony export */ "ErrorFactory": () => (/* binding */ ErrorFactory), /* harmony export */ "FirebaseError": () => (/* binding */ FirebaseError), /* harmony export */ "MAX_VALUE_MILLIS": () => (/* binding */ MAX_VALUE_MILLIS), /* harmony export */ "RANDOM_FACTOR": () => (/* binding */ RANDOM_FACTOR), /* harmony export */ "Sha1": () => (/* binding */ Sha1), /* harmony export */ "areCookiesEnabled": () => (/* binding */ areCookiesEnabled), /* harmony export */ "assert": () => (/* binding */ assert), /* harmony export */ "assertionError": () => (/* binding */ assertionError), /* harmony export */ "async": () => (/* binding */ async), /* harmony export */ "base64": () => (/* binding */ base64), /* harmony export */ "base64Decode": () => (/* binding */ base64Decode), /* harmony export */ "base64Encode": () => (/* binding */ base64Encode), /* harmony export */ "base64urlEncodeWithoutPadding": () => (/* binding */ base64urlEncodeWithoutPadding), /* harmony export */ "calculateBackoffMillis": () => (/* binding */ calculateBackoffMillis), /* harmony export */ "contains": () => (/* binding */ contains), /* harmony export */ "createMockUserToken": () => (/* binding */ createMockUserToken), /* harmony export */ "createSubscribe": () => (/* binding */ createSubscribe), /* harmony export */ "decode": () => (/* binding */ decode), /* harmony export */ "deepCopy": () => (/* binding */ deepCopy), /* harmony export */ "deepEqual": () => (/* binding */ deepEqual), /* harmony export */ "deepExtend": () => (/* binding */ deepExtend), /* harmony export */ "errorPrefix": () => (/* binding */ errorPrefix), /* harmony export */ "extractQuerystring": () => (/* binding */ extractQuerystring), /* harmony export */ "getDefaultAppConfig": () => (/* binding */ getDefaultAppConfig), /* harmony export */ "getDefaultEmulatorHost": () => (/* binding */ getDefaultEmulatorHost), /* harmony export */ "getDefaultEmulatorHostnameAndPort": () => (/* binding */ getDefaultEmulatorHostnameAndPort), /* harmony export */ "getDefaults": () => (/* binding */ getDefaults), /* harmony export */ "getExperimentalSetting": () => (/* binding */ getExperimentalSetting), /* harmony export */ "getGlobal": () => (/* binding */ getGlobal), /* harmony export */ "getModularInstance": () => (/* binding */ getModularInstance), /* harmony export */ "getUA": () => (/* binding */ getUA), /* harmony export */ "isAdmin": () => (/* binding */ isAdmin), /* harmony export */ "isBrowser": () => (/* binding */ isBrowser), /* harmony export */ "isBrowserExtension": () => (/* binding */ isBrowserExtension), /* harmony export */ "isCloudWorkstation": () => (/* binding */ isCloudWorkstation), /* harmony export */ "isCloudflareWorker": () => (/* binding */ isCloudflareWorker), /* harmony export */ "isElectron": () => (/* binding */ isElectron), /* harmony export */ "isEmpty": () => (/* binding */ isEmpty), /* harmony export */ "isIE": () => (/* binding */ isIE), /* harmony export */ "isIndexedDBAvailable": () => (/* binding */ isIndexedDBAvailable), /* harmony export */ "isMobileCordova": () => (/* binding */ isMobileCordova), /* harmony export */ "isNode": () => (/* binding */ isNode), /* harmony export */ "isNodeSdk": () => (/* binding */ isNodeSdk), /* harmony export */ "isReactNative": () => (/* binding */ isReactNative), /* harmony export */ "isSafari": () => (/* binding */ isSafari), /* harmony export */ "isSafariOrWebkit": () => (/* binding */ isSafariOrWebkit), /* harmony export */ "isUWP": () => (/* binding */ isUWP), /* harmony export */ "isValidFormat": () => (/* binding */ isValidFormat), /* harmony export */ "isValidTimestamp": () => (/* binding */ isValidTimestamp), /* harmony export */ "isWebWorker": () => (/* binding */ isWebWorker), /* harmony export */ "issuedAtTime": () => (/* binding */ issuedAtTime), /* harmony export */ "jsonEval": () => (/* binding */ jsonEval), /* harmony export */ "map": () => (/* binding */ map), /* harmony export */ "ordinal": () => (/* binding */ ordinal), /* harmony export */ "pingServer": () => (/* binding */ pingServer), /* harmony export */ "promiseWithTimeout": () => (/* binding */ promiseWithTimeout), /* harmony export */ "querystring": () => (/* binding */ querystring), /* harmony export */ "querystringDecode": () => (/* binding */ querystringDecode), /* harmony export */ "safeGet": () => (/* binding */ safeGet), /* harmony export */ "stringLength": () => (/* binding */ stringLength), /* harmony export */ "stringToByteArray": () => (/* binding */ stringToByteArray), /* harmony export */ "stringify": () => (/* binding */ stringify), /* harmony export */ "updateEmulatorBanner": () => (/* binding */ updateEmulatorBanner), /* harmony export */ "validateArgCount": () => (/* binding */ validateArgCount), /* harmony export */ "validateCallback": () => (/* binding */ validateCallback), /* harmony export */ "validateContextObject": () => (/* binding */ validateContextObject), /* harmony export */ "validateIndexedDBOpenable": () => (/* binding */ validateIndexedDBOpenable), /* harmony export */ "validateNamespace": () => (/* binding */ validateNamespace) /* harmony export */ }); /* harmony import */ var _Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 71670); /* harmony import */ var _postinstall_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postinstall.mjs */ 70503); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time. */ const CONSTANTS = { /** * @define {boolean} Whether this is the client Node.js SDK. */ NODE_CLIENT: false, /** * @define {boolean} Whether this is the Admin Node.js SDK. */ NODE_ADMIN: false, /** * Firebase SDK Version */ SDK_VERSION: '${JSCORE_VERSION}' }; /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Throws an error if the provided assertion is falsy */ const assert = function (assertion, message) { if (!assertion) { throw assertionError(message); } }; /** * Returns an Error object suitable for throwing. */ const assertionError = function (message) { return new Error('Firebase Database (' + CONSTANTS.SDK_VERSION + ') INTERNAL ASSERT FAILED: ' + message); }; /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const stringToByteArray$1 = function (str) { // TODO(user): Use native implementations if/when available const out = []; let p = 0; for (let i = 0; i < str.length; i++) { let c = str.charCodeAt(i); if (c < 128) { out[p++] = c; } else if (c < 2048) { out[p++] = c >> 6 | 192; out[p++] = c & 63 | 128; } else if ((c & 0xfc00) === 0xd800 && i + 1 < str.length && (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00) { // Surrogate Pair c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff); out[p++] = c >> 18 | 240; out[p++] = c >> 12 & 63 | 128; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } else { out[p++] = c >> 12 | 224; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } } return out; }; /** * Turns an array of numbers into the string given by the concatenation of the * characters to which the numbers correspond. * @param bytes Array of numbers representing characters. * @return Stringification of the array. */ const byteArrayToString = function (bytes) { // TODO(user): Use native implementations if/when available const out = []; let pos = 0, c = 0; while (pos < bytes.length) { const c1 = bytes[pos++]; if (c1 < 128) { out[c++] = String.fromCharCode(c1); } else if (c1 > 191 && c1 < 224) { const c2 = bytes[pos++]; out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); } else if (c1 > 239 && c1 < 365) { // Surrogate Pair const c2 = bytes[pos++]; const c3 = bytes[pos++]; const c4 = bytes[pos++]; const u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) - 0x10000; out[c++] = String.fromCharCode(0xd800 + (u >> 10)); out[c++] = String.fromCharCode(0xdc00 + (u & 1023)); } else { const c2 = bytes[pos++]; const c3 = bytes[pos++]; out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63); } } return out.join(''); }; // We define it as an object literal instead of a class because a class compiled down to es5 can't // be treeshaked. https://github.com/rollup/rollup/issues/1691 // Static lookup maps, lazily populated by init_() // TODO(dlarocque): Define this as a class, since we no longer target ES5. const base64 = { /** * Maps bytes to characters. */ byteToCharMap_: null, /** * Maps characters to bytes. */ charToByteMap_: null, /** * Maps bytes to websafe characters. * @private */ byteToCharMapWebSafe_: null, /** * Maps websafe characters to bytes. * @private */ charToByteMapWebSafe_: null, /** * Our default alphabet, shared between * ENCODED_VALS and ENCODED_VALS_WEBSAFE */ ENCODED_VALS_BASE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789', /** * Our default alphabet. Value 64 (=) is special; it means "nothing." */ get ENCODED_VALS() { return this.ENCODED_VALS_BASE + '+/='; }, /** * Our websafe alphabet. */ get ENCODED_VALS_WEBSAFE() { return this.ENCODED_VALS_BASE + '-_.'; }, /** * Whether this browser supports the atob and btoa functions. This extension * started at Mozilla but is now implemented by many browsers. We use the * ASSUME_* variables to avoid pulling in the full useragent detection library * but still allowing the standard per-browser compilations. * */ HAS_NATIVE_SUPPORT: typeof atob === 'function', /** * Base64-encode an array of bytes. * * @param input An array of bytes (numbers with * value in [0, 255]) to encode. * @param webSafe Boolean indicating we should use the * alternative alphabet. * @return The base64 encoded string. */ encodeByteArray(input, webSafe) { if (!Array.isArray(input)) { throw Error('encodeByteArray takes an array as a parameter'); } this.init_(); const byteToCharMap = webSafe ? this.byteToCharMapWebSafe_ : this.byteToCharMap_; const output = []; for (let i = 0; i < input.length; i += 3) { const byte1 = input[i]; const haveByte2 = i + 1 < input.length; const byte2 = haveByte2 ? input[i + 1] : 0; const haveByte3 = i + 2 < input.length; const byte3 = haveByte3 ? input[i + 2] : 0; const outByte1 = byte1 >> 2; const outByte2 = (byte1 & 0x03) << 4 | byte2 >> 4; let outByte3 = (byte2 & 0x0f) << 2 | byte3 >> 6; let outByte4 = byte3 & 0x3f; if (!haveByte3) { outByte4 = 64; if (!haveByte2) { outByte3 = 64; } } output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]); } return output.join(''); }, /** * Base64-encode a string. * * @param input A string to encode. * @param webSafe If true, we should use the * alternative alphabet. * @return The base64 encoded string. */ encodeString(input, webSafe) { // Shortcut for Mozilla browsers that implement // a native base64 encoder in the form of "btoa/atob" if (this.HAS_NATIVE_SUPPORT && !webSafe) { return btoa(input); } return this.encodeByteArray(stringToByteArray$1(input), webSafe); }, /** * Base64-decode a string. * * @param input to decode. * @param webSafe True if we should use the * alternative alphabet. * @return string representing the decoded value. */ decodeString(input, webSafe) { // Shortcut for Mozilla browsers that implement // a native base64 encoder in the form of "btoa/atob" if (this.HAS_NATIVE_SUPPORT && !webSafe) { return atob(input); } return byteArrayToString(this.decodeStringToByteArray(input, webSafe)); }, /** * Base64-decode a string. * * In base-64 decoding, groups of four characters are converted into three * bytes. If the encoder did not apply padding, the input length may not * be a multiple of 4. * * In this case, the last group will have fewer than 4 characters, and * padding will be inferred. If the group has one or two characters, it decodes * to one byte. If the group has three characters, it decodes to two bytes. * * @param input Input to decode. * @param webSafe True if we should use the web-safe alphabet. * @return bytes representing the decoded value. */ decodeStringToByteArray(input, webSafe) { this.init_(); const charToByteMap = webSafe ? this.charToByteMapWebSafe_ : this.charToByteMap_; const output = []; for (let i = 0; i < input.length;) { const byte1 = charToByteMap[input.charAt(i++)]; const haveByte2 = i < input.length; const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0; ++i; const haveByte3 = i < input.length; const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64; ++i; const haveByte4 = i < input.length; const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64; ++i; if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) { throw new DecodeBase64StringError(); } const outByte1 = byte1 << 2 | byte2 >> 4; output.push(outByte1); if (byte3 !== 64) { const outByte2 = byte2 << 4 & 0xf0 | byte3 >> 2; output.push(outByte2); if (byte4 !== 64) { const outByte3 = byte3 << 6 & 0xc0 | byte4; output.push(outByte3); } } } return output; }, /** * Lazy static initialization function. Called before * accessing any of the static map variables. * @private */ init_() { if (!this.byteToCharMap_) { this.byteToCharMap_ = {}; this.charToByteMap_ = {}; this.byteToCharMapWebSafe_ = {}; this.charToByteMapWebSafe_ = {}; // We want quick mappings back and forth, so we precompute two maps. for (let i = 0; i < this.ENCODED_VALS.length; i++) { this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i); this.charToByteMap_[this.byteToCharMap_[i]] = i; this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i); this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i; // Be forgiving when decoding and correctly decode both encodings. if (i >= this.ENCODED_VALS_BASE.length) { this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i; this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i; } } } } }; /** * An error encountered while decoding base64 string. */ class DecodeBase64StringError extends Error { constructor() { super(...arguments); this.name = 'DecodeBase64StringError'; } } /** * URL-safe base64 encoding */ const base64Encode = function (str) { const utf8Bytes = stringToByteArray$1(str); return base64.encodeByteArray(utf8Bytes, true); }; /** * URL-safe base64 encoding (without "." padding in the end). * e.g. Used in JSON Web Token (JWT) parts. */ const base64urlEncodeWithoutPadding = function (str) { // Use base64url encoding and remove padding in the end (dot characters). return base64Encode(str).replace(/\./g, ''); }; /** * URL-safe base64 decoding * * NOTE: DO NOT use the global atob() function - it does NOT support the * base64Url variant encoding. * * @param str To be decoded * @return Decoded result, if possible */ const base64Decode = function (str) { try { return base64.decodeString(str, true); } catch (e) { console.error('base64Decode failed: ', e); } return null; }; /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Do a deep-copy of basic JavaScript Objects or Arrays. */ function deepCopy(value) { return deepExtend(undefined, value); } /** * Copy properties from source to target (recursively allows extension * of Objects and Arrays). Scalar values in the target are over-written. * If target is undefined, an object of the appropriate type will be created * (and returned). * * We recursively copy all child properties of plain Objects in the source- so * that namespace- like dictionaries are merged. * * Note that the target can be a function, in which case the properties in * the source Object are copied onto it as static properties of the Function. * * Note: we don't merge __proto__ to prevent prototype pollution */ function deepExtend(target, source) { if (!(source instanceof Object)) { return source; } switch (source.constructor) { case Date: // Treat Dates like scalars; if the target date object had any child // properties - they will be lost! const dateValue = source; return new Date(dateValue.getTime()); case Object: if (target === undefined) { target = {}; } break; case Array: // Always copy the array source and overwrite the target. target = []; break; default: // Not a plain Object - treat it as a scalar. return source; } for (const prop in source) { // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202 if (!source.hasOwnProperty(prop) || !isValidKey(prop)) { continue; } target[prop] = deepExtend(target[prop], source[prop]); } return target; } function isValidKey(key) { return key !== '__proto__'; } /** * @license * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Polyfill for `globalThis` object. * @returns the `globalThis` object for the given environment. * @public */ function getGlobal() { if (typeof self !== 'undefined') { return self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } throw new Error('Unable to locate global object.'); } /** * @license * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const getDefaultsFromGlobal = () => getGlobal().__FIREBASE_DEFAULTS__; /** * Attempt to read defaults from a JSON string provided to * process(.)env(.)__FIREBASE_DEFAULTS__ or a JSON file whose path is in * process(.)env(.)__FIREBASE_DEFAULTS_PATH__ * The dots are in parens because certain compilers (Vite?) cannot * handle seeing that variable in comments. * See https://github.com/firebase/firebase-js-sdk/issues/6838 */ const getDefaultsFromEnvVariable = () => { if (typeof process === 'undefined' || typeof process.env === 'undefined') { return; } const defaultsJsonString = process.env.__FIREBASE_DEFAULTS__; if (defaultsJsonString) { return JSON.parse(defaultsJsonString); } }; const getDefaultsFromCookie = () => { if (typeof document === 'undefined') { return; } let match; try { match = document.cookie.match(/__FIREBASE_DEFAULTS__=([^;]+)/); } catch (e) { // Some environments such as Angular Universal SSR have a // `document` object but error on accessing `document.cookie`. return; } const decoded = match && base64Decode(match[1]); return decoded && JSON.parse(decoded); }; /** * Get the __FIREBASE_DEFAULTS__ object. It checks in order: * (1) if such an object exists as a property of `globalThis` * (2) if such an object was provided on a shell environment variable * (3) if such an object exists in a cookie * @public */ const getDefaults = () => { try { return (0,_postinstall_mjs__WEBPACK_IMPORTED_MODULE_1__.getDefaultsFromPostinstall)() || getDefaultsFromGlobal() || getDefaultsFromEnvVariable() || getDefaultsFromCookie(); } catch (e) { /** * Catch-all for being unable to get __FIREBASE_DEFAULTS__ due * to any environment case we have not accounted for. Log to * info instead of swallowing so we can find these unknown cases * and add paths for them if needed. */ console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${e}`); return; } }; /** * Returns emulator host stored in the __FIREBASE_DEFAULTS__ object * for the given product. * @returns a URL host formatted like `127.0.0.1:9999` or `[::1]:4000` if available * @public */ const getDefaultEmulatorHost = productName => { var _a, _b; return (_b = (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.emulatorHosts) === null || _b === void 0 ? void 0 : _b[productName]; }; /** * Returns emulator hostname and port stored in the __FIREBASE_DEFAULTS__ object * for the given product. * @returns a pair of hostname and port like `["::1", 4000]` if available * @public */ const getDefaultEmulatorHostnameAndPort = productName => { const host = getDefaultEmulatorHost(productName); if (!host) { return undefined; } const separatorIndex = host.lastIndexOf(':'); // Finding the last since IPv6 addr also has colons. if (separatorIndex <= 0 || separatorIndex + 1 === host.length) { throw new Error(`Invalid host ${host} with no separate hostname and port!`); } // eslint-disable-next-line no-restricted-globals const port = parseInt(host.substring(separatorIndex + 1), 10); if (host[0] === '[') { // Bracket-quoted `[ipv6addr]:port` => return "ipv6addr" (without brackets). return [host.substring(1, separatorIndex - 1), port]; } else { return [host.substring(0, separatorIndex), port]; } }; /** * Returns Firebase app config stored in the __FIREBASE_DEFAULTS__ object. * @public */ const getDefaultAppConfig = () => { var _a; return (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.config; }; /** * Returns an experimental setting on the __FIREBASE_DEFAULTS__ object (properties * prefixed by "_") * @public */ const getExperimentalSetting = name => { var _a; return (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a[`_${name}`]; }; /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ class Deferred { constructor() { this.reject = () => {}; this.resolve = () => {}; this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; }); } /** * Our API internals are not promisified and cannot because our callback APIs have subtle expectations around * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback * and returns a node-style callback which will resolve or reject the Deferred's promise. */ wrapCallback(callback) { return (error, value) => { if (error) { this.reject(error); } else { this.resolve(value); } if (typeof callback === 'function') { // Attaching noop handler just in case developer wasn't expecting // promises this.promise.catch(() => {}); // Some of our callbacks don't expect a value and our own tests // assert that the parameter length is 1 if (callback.length === 1) { callback(error); } else { callback(error, value); } } }; } } /** * @license * Copyright 2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Checks whether host is a cloud workstation or not. * @public */ function isCloudWorkstation(url) { // `isCloudWorkstation` is called without protocol in certain connect*Emulator functions // In HTTP request builders, it's called with the protocol. // If called with protocol prefix, it's a valid URL, so we extract the hostname // If called without, we assume the string is the hostname. try { const host = url.startsWith('http://') || url.startsWith('https://') ? new URL(url).hostname : url; return host.endsWith('.cloudworkstations.dev'); } catch (_a) { return false; } } /** * Makes a fetch request to the given server. * Mostly used for forwarding cookies in Firebase Studio. * @public */ function pingServer(_x) { return _pingServer.apply(this, arguments); } /** * @license * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function _pingServer() { _pingServer = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (endpoint) { const result = yield fetch(endpoint, { credentials: 'include' }); return result.ok; }); return _pingServer.apply(this, arguments); } function createMockUserToken(token, projectId) { if (token.uid) { throw new Error('The "uid" field is no longer supported by mockUserToken. Please use "sub" instead for Firebase Auth User ID.'); } // Unsecured JWTs use "none" as the algorithm. const header = { alg: 'none', type: 'JWT' }; const project = projectId || 'demo-project'; const iat = token.iat || 0; const sub = token.sub || token.user_id; if (!sub) { throw new Error("mockUserToken must contain 'sub' or 'user_id' field!"); } const payload = Object.assign({ // Set all required fields to decent defaults iss: `https://securetoken.google.com/${project}`, aud: project, iat, exp: iat + 3600, auth_time: iat, sub, user_id: sub, firebase: { sign_in_provider: 'custom', identities: {} } }, token); // Unsecured JWTs use the empty string as a signature. const signature = ''; return [base64urlEncodeWithoutPadding(JSON.stringify(header)), base64urlEncodeWithoutPadding(JSON.stringify(payload)), signature].join('.'); } const emulatorStatus = {}; // Checks whether any products are running on an emulator function getEmulatorSummary() { const summary = { prod: [], emulator: [] }; for (const key of Object.keys(emulatorStatus)) { if (emulatorStatus[key]) { summary.emulator.push(key); } else { summary.prod.push(key); } } return summary; } function getOrCreateEl(id) { let parentDiv = document.getElementById(id); let created = false; if (!parentDiv) { parentDiv = document.createElement('div'); parentDiv.setAttribute('id', id); created = true; } return { created, element: parentDiv }; } let previouslyDismissed = false; /** * Updates Emulator Banner. Primarily used for Firebase Studio * @param name * @param isRunningEmulator * @public */ function updateEmulatorBanner(name, isRunningEmulator) { if (typeof window === 'undefined' || typeof document === 'undefined' || !isCloudWorkstation(window.location.host) || emulatorStatus[name] === isRunningEmulator || emulatorStatus[name] || // If already set to use emulator, can't go back to prod. previouslyDismissed) { return; } emulatorStatus[name] = isRunningEmulator; function prefixedId(id) { return `__firebase__banner__${id}`; } const bannerId = '__firebase__banner'; const summary = getEmulatorSummary(); const showError = summary.prod.length > 0; function tearDown() { const element = document.getElementById(bannerId); if (element) { element.remove(); } } function setupBannerStyles(bannerEl) { bannerEl.style.display = 'flex'; bannerEl.style.background = '#7faaf0'; bannerEl.style.position = 'fixed'; bannerEl.style.bottom = '5px'; bannerEl.style.left = '5px'; bannerEl.style.padding = '.5em'; bannerEl.style.borderRadius = '5px'; bannerEl.style.alignItems = 'center'; } function setupIconStyles(prependIcon, iconId) { prependIcon.setAttribute('width', '24'); prependIcon.setAttribute('id', iconId); prependIcon.setAttribute('height', '24'); prependIcon.setAttribute('viewBox', '0 0 24 24'); prependIcon.setAttribute('fill', 'none'); prependIcon.style.marginLeft = '-6px'; } function setupCloseBtn() { const closeBtn = document.createElement('span'); closeBtn.style.cursor = 'pointer'; closeBtn.style.marginLeft = '16px'; closeBtn.style.fontSize = '24px'; closeBtn.innerHTML = ' ×'; closeBtn.onclick = () => { previouslyDismissed = true; tearDown(); }; return closeBtn; } function setupLinkStyles(learnMoreLink, learnMoreId) { learnMoreLink.setAttribute('id', learnMoreId); learnMoreLink.innerText = 'Learn more'; learnMoreLink.href = 'https://firebase.google.com/docs/studio/preview-apps#preview-backend'; learnMoreLink.setAttribute('target', '__blank'); learnMoreLink.style.paddingLeft = '5px'; learnMoreLink.style.textDecoration = 'underline'; } function setupDom() { const banner = getOrCreateEl(bannerId); const firebaseTextId = prefixedId('text'); const firebaseText = document.getElementById(firebaseTextId) || document.createElement('span'); const learnMoreId = prefixedId('learnmore'); const learnMoreLink = document.getElementById(learnMoreId) || document.createElement('a'); const prependIconId = prefixedId('preprendIcon'); const prependIcon = document.getElementById(prependIconId) || document.createElementNS('http://www.w3.org/2000/svg', 'svg'); if (banner.created) { // update styles const bannerEl = banner.element; setupBannerStyles(bannerEl); setupLinkStyles(learnMoreLink, learnMoreId); const closeBtn = setupCloseBtn(); setupIconStyles(prependIcon, prependIconId); bannerEl.append(prependIcon, firebaseText, learnMoreLink, closeBtn); document.body.appendChild(bannerEl); } if (showError) { firebaseText.innerText = `Preview backend disconnected.`; prependIcon.innerHTML = ` `; } else { prependIcon.innerHTML = ` `; firebaseText.innerText = 'Preview backend running in this workspace.'; } firebaseText.setAttribute('id', firebaseTextId); } if (document.readyState === 'loading') { window.addEventListener('DOMContentLoaded', setupDom); } else { setupDom(); } } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Returns navigator.userAgent string or '' if it's not defined. * @return user agent string */ function getUA() { if (typeof navigator !== 'undefined' && typeof navigator['userAgent'] === 'string') { return navigator['userAgent']; } else { return ''; } } /** * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device. * * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally * wait for a callback. */ function isMobileCordova() { return typeof window !== 'undefined' && // @ts-ignore Setting up an broadly applicable index signature for Window // just to deal with this case would probably be a bad idea. !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) && /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA()); } /** * Detect Node.js. * * @return true if Node.js environment is detected or specified. */ // Node detection logic from: https://github.com/iliakan/detect-node/ function isNode() { var _a; const forceEnvironment = (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.forceEnvironment; if (forceEnvironment === 'node') { return true; } else if (forceEnvironment === 'browser') { return false; } try { return Object.prototype.toString.call(global.process) === '[object process]'; } catch (e) { return false; } } /** * Detect Browser Environment. * Note: This will return true for certain test frameworks that are incompletely * mimicking a browser, and should not lead to assuming all browser APIs are * available. */ function isBrowser() { return typeof window !== 'undefined' || isWebWorker(); } /** * Detect Web Worker context. */ function isWebWorker() { return typeof WorkerGlobalScope !== 'undefined' && typeof self !== 'undefined' && self instanceof WorkerGlobalScope; } /** * Detect Cloudflare Worker context. */ function isCloudflareWorker() { return typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers'; } function isBrowserExtension() { const runtime = typeof chrome === 'object' ? chrome.runtime : typeof browser === 'object' ? browser.runtime : undefined; return typeof runtime === 'object' && runtime.id !== undefined; } /** * Detect React Native. * * @return true if ReactNative environment is detected. */ function isReactNative() { return typeof navigator === 'object' && navigator['product'] === 'ReactNative'; } /** Detects Electron apps. */ function isElectron() { return getUA().indexOf('Electron/') >= 0; } /** Detects Internet Explorer. */ function isIE() { const ua = getUA(); return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0; } /** Detects Universal Windows Platform apps. */ function isUWP() { return getUA().indexOf('MSAppHost/') >= 0; } /** * Detect whether the current SDK build is the Node version. * * @return true if it's the Node SDK build. */ function isNodeSdk() { return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true; } /** Returns true if we are running in Safari. */ function isSafari() { return !isNode() && !!navigator.userAgent && navigator.userAgent.includes('Safari') && !navigator.userAgent.includes('Chrome'); } /** Returns true if we are running in Safari or WebKit */ function isSafariOrWebkit() { return !isNode() && !!navigator.userAgent && (navigator.userAgent.includes('Safari') || navigator.userAgent.includes('WebKit')) && !navigator.userAgent.includes('Chrome'); } /** * This method checks if indexedDB is supported by current browser/service worker context * @return true if indexedDB is supported by current browser/service worker context */ function isIndexedDBAvailable() { try { return typeof indexedDB === 'object'; } catch (e) { return false; } } /** * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject * if errors occur during the database open operation. * * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox * private browsing) */ function validateIndexedDBOpenable() { return new Promise((resolve, reject) => { try { let preExist = true; const DB_CHECK_NAME = 'validate-browser-context-for-indexeddb-analytics-module'; const request = self.indexedDB.open(DB_CHECK_NAME); request.onsuccess = () => { request.result.close(); // delete database only when it doesn't pre-exist if (!preExist) { self.indexedDB.deleteDatabase(DB_CHECK_NAME); } resolve(true); }; request.onupgradeneeded = () => { preExist = false; }; request.onerror = () => { var _a; reject(((_a = request.error) === null || _a === void 0 ? void 0 : _a.message) || ''); }; } catch (error) { reject(error); } }); } /** * * This method checks whether cookie is enabled within current browser * @return true if cookie is enabled within current browser */ function areCookiesEnabled() { if (typeof navigator === 'undefined' || !navigator.cookieEnabled) { return false; } return true; } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @fileoverview Standardized Firebase Error. * * Usage: * * // TypeScript string literals for type-safe codes * type Err = * 'unknown' | * 'object-not-found' * ; * * // Closure enum for type-safe error codes * // at-enum {string} * var Err = { * UNKNOWN: 'unknown', * OBJECT_NOT_FOUND: 'object-not-found', * } * * let errors: Map = { * 'generic-error': "Unknown error", * 'file-not-found': "Could not find file: {$file}", * }; * * // Type-safe function - must pass a valid error code as param. * let error = new ErrorFactory('service', 'Service', errors); * * ... * throw error.create(Err.GENERIC); * ... * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName}); * ... * // Service: Could not file file: foo.txt (service/file-not-found). * * catch (e) { * assert(e.message === "Could not find file: foo.txt."); * if ((e as FirebaseError)?.code === 'service/file-not-found') { * console.log("Could not read file: " + e['file']); * } * } */ const ERROR_NAME = 'FirebaseError'; // Based on code from: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types class FirebaseError extends Error { constructor( /** The error code for this error. */ code, message, /** Custom data for this error. */ customData) { super(message); this.code = code; this.customData = customData; /** The custom name for all FirebaseErrors. */ this.name = ERROR_NAME; // Fix For ES5 // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work // TODO(dlarocque): Replace this with `new.target`: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget // which we can now use since we no longer target ES5. Object.setPrototypeOf(this, FirebaseError.prototype); // Maintains proper stack trace for where our error was thrown. // Only available on V8. if (Error.captureStackTrace) { Error.captureStackTrace(this, ErrorFactory.prototype.create); } } } class ErrorFactory { constructor(service, serviceName, errors) { this.service = service; this.serviceName = serviceName; this.errors = errors; } create(code, ...data) { const customData = data[0] || {}; const fullCode = `${this.service}/${code}`; const template = this.errors[code]; const message = template ? replaceTemplate(template, customData) : 'Error'; // Service Name: Error message (service/code). const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`; const error = new FirebaseError(fullCode, fullMessage, customData); return error; } } function replaceTemplate(template, data) { return template.replace(PATTERN, (_, key) => { const value = data[key]; return value != null ? String(value) : `<${key}?>`; }); } const PATTERN = /\{\$([^}]+)}/g; /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Evaluates a JSON string into a javascript object. * * @param {string} str A string containing JSON. * @return {*} The javascript object representing the specified JSON. */ function jsonEval(str) { return JSON.parse(str); } /** * Returns JSON representing a javascript object. * @param {*} data JavaScript object to be stringified. * @return {string} The JSON contents of the object. */ function stringify(data) { return JSON.stringify(data); } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Decodes a Firebase auth. token into constituent parts. * * Notes: * - May return with invalid / incomplete claims if there's no native base64 decoding support. * - Doesn't check if the token is actually valid. */ const decode = function (token) { let header = {}, claims = {}, data = {}, signature = ''; try { const parts = token.split('.'); header = jsonEval(base64Decode(parts[0]) || ''); claims = jsonEval(base64Decode(parts[1]) || ''); signature = parts[2]; data = claims['d'] || {}; delete claims['d']; } catch (e) {} return { header, claims, data, signature }; }; /** * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims. * * Notes: * - May return a false negative if there's no native base64 decoding support. * - Doesn't check if the token is actually valid. */ const isValidTimestamp = function (token) { const claims = decode(token).claims; const now = Math.floor(new Date().getTime() / 1000); let validSince = 0, validUntil = 0; if (typeof claims === 'object') { if (claims.hasOwnProperty('nbf')) { validSince = claims['nbf']; } else if (claims.hasOwnProperty('iat')) { validSince = claims['iat']; } if (claims.hasOwnProperty('exp')) { validUntil = claims['exp']; } else { // token will expire after 24h by default validUntil = validSince + 86400; } } return !!now && !!validSince && !!validUntil && now >= validSince && now <= validUntil; }; /** * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise. * * Notes: * - May return null if there's no native base64 decoding support. * - Doesn't check if the token is actually valid. */ const issuedAtTime = function (token) { const claims = decode(token).claims; if (typeof claims === 'object' && claims.hasOwnProperty('iat')) { return claims['iat']; } return null; }; /** * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time. * * Notes: * - May return a false negative if there's no native base64 decoding support. * - Doesn't check if the token is actually valid. */ const isValidFormat = function (token) { const decoded = decode(token), claims = decoded.claims; return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat'); }; /** * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion. * * Notes: * - May return a false negative if there's no native base64 decoding support. * - Doesn't check if the token is actually valid. */ const isAdmin = function (token) { const claims = decode(token).claims; return typeof claims === 'object' && claims['admin'] === true; }; /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function contains(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } function safeGet(obj, key) { if (Object.prototype.hasOwnProperty.call(obj, key)) { return obj[key]; } else { return undefined; } } function isEmpty(obj) { for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { return false; } } return true; } function map(obj, fn, contextObj) { const res = {}; for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { res[key] = fn.call(contextObj, obj[key], key, obj); } } return res; } /** * Deep equal two objects. Support Arrays and Objects. */ function deepEqual(a, b) { if (a === b) { return true; } const aKeys = Object.keys(a); const bKeys = Object.keys(b); for (const k of aKeys) { if (!bKeys.includes(k)) { return false; } const aProp = a[k]; const bProp = b[k]; if (isObject(aProp) && isObject(bProp)) { if (!deepEqual(aProp, bProp)) { return false; } } else if (aProp !== bProp) { return false; } } for (const k of bKeys) { if (!aKeys.includes(k)) { return false; } } return true; } function isObject(thing) { return thing !== null && typeof thing === 'object'; } /** * @license * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Rejects if the given promise doesn't resolve in timeInMS milliseconds. * @internal */ function promiseWithTimeout(promise, timeInMS = 2000) { const deferredPromise = new Deferred(); setTimeout(() => deferredPromise.reject('timeout!'), timeInMS); promise.then(deferredPromise.resolve, deferredPromise.reject); return deferredPromise.promise; } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a * params object (e.g. {arg: 'val', arg2: 'val2'}) * Note: You must prepend it with ? when adding it to a URL. */ function querystring(querystringParams) { const params = []; for (const [key, value] of Object.entries(querystringParams)) { if (Array.isArray(value)) { value.forEach(arrayVal => { params.push(encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal)); }); } else { params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); } } return params.length ? '&' + params.join('&') : ''; } /** * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object * (e.g. {arg: 'val', arg2: 'val2'}) */ function querystringDecode(querystring) { const obj = {}; const tokens = querystring.replace(/^\?/, '').split('&'); tokens.forEach(token => { if (token) { const [key, value] = token.split('='); obj[decodeURIComponent(key)] = decodeURIComponent(value); } }); return obj; } /** * Extract the query string part of a URL, including the leading question mark (if present). */ function extractQuerystring(url) { const queryStart = url.indexOf('?'); if (!queryStart) { return ''; } const fragmentStart = url.indexOf('#', queryStart); return url.substring(queryStart, fragmentStart > 0 ? fragmentStart : undefined); } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @fileoverview SHA-1 cryptographic hash. * Variable names follow the notation in FIPS PUB 180-3: * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf. * * Usage: * var sha1 = new sha1(); * sha1.update(bytes); * var hash = sha1.digest(); * * Performance: * Chrome 23: ~400 Mbit/s * Firefox 16: ~250 Mbit/s * */ /** * SHA-1 cryptographic hash constructor. * * The properties declared here are discussed in the above algorithm document. * @constructor * @final * @struct */ class Sha1 { constructor() { /** * Holds the previous values of accumulated variables a-e in the compress_ * function. * @private */ this.chain_ = []; /** * A buffer holding the partially computed hash result. * @private */ this.buf_ = []; /** * An array of 80 bytes, each a part of the message to be hashed. Referred to * as the message schedule in the docs. * @private */ this.W_ = []; /** * Contains data needed to pad messages less than 64 bytes. * @private */ this.pad_ = []; /** * @private {number} */ this.inbuf_ = 0; /** * @private {number} */ this.total_ = 0; this.blockSize = 512 / 8; this.pad_[0] = 128; for (let i = 1; i < this.blockSize; ++i) { this.pad_[i] = 0; } this.reset(); } reset() { this.chain_[0] = 0x67452301; this.chain_[1] = 0xefcdab89; this.chain_[2] = 0x98badcfe; this.chain_[3] = 0x10325476; this.chain_[4] = 0xc3d2e1f0; this.inbuf_ = 0; this.total_ = 0; } /** * Internal compress helper function. * @param buf Block to compress. * @param offset Offset of the block in the buffer. * @private */ compress_(buf, offset) { if (!offset) { offset = 0; } const W = this.W_; // get 16 big endian words if (typeof buf === 'string') { for (let i = 0; i < 16; i++) { // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS // have a bug that turns the post-increment ++ operator into pre-increment // during JIT compilation. We have code that depends heavily on SHA-1 for // correctness and which is affected by this bug, so I've removed all uses // of post-increment ++ in which the result value is used. We can revert // this change once the Safari bug // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and // most clients have been updated. W[i] = buf.charCodeAt(offset) << 24 | buf.charCodeAt(offset + 1) << 16 | buf.charCodeAt(offset + 2) << 8 | buf.charCodeAt(offset + 3); offset += 4; } } else { for (let i = 0; i < 16; i++) { W[i] = buf[offset] << 24 | buf[offset + 1] << 16 | buf[offset + 2] << 8 | buf[offset + 3]; offset += 4; } } // expand to 80 words for (let i = 16; i < 80; i++) { const t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; W[i] = (t << 1 | t >>> 31) & 0xffffffff; } let a = this.chain_[0]; let b = this.chain_[1]; let c = this.chain_[2]; let d = this.chain_[3]; let e = this.chain_[4]; let f, k; // TODO(user): Try to unroll this loop to speed up the computation. for (let i = 0; i < 80; i++) { if (i < 40) { if (i < 20) { f = d ^ b & (c ^ d); k = 0x5a827999; } else { f = b ^ c ^ d; k = 0x6ed9eba1; } } else { if (i < 60) { f = b & c | d & (b | c); k = 0x8f1bbcdc; } else { f = b ^ c ^ d; k = 0xca62c1d6; } } const t = (a << 5 | a >>> 27) + f + e + k + W[i] & 0xffffffff; e = d; d = c; c = (b << 30 | b >>> 2) & 0xffffffff; b = a; a = t; } this.chain_[0] = this.chain_[0] + a & 0xffffffff; this.chain_[1] = this.chain_[1] + b & 0xffffffff; this.chain_[2] = this.chain_[2] + c & 0xffffffff; this.chain_[3] = this.chain_[3] + d & 0xffffffff; this.chain_[4] = this.chain_[4] + e & 0xffffffff; } update(bytes, length) { // TODO(johnlenz): tighten the function signature and remove this check if (bytes == null) { return; } if (length === undefined) { length = bytes.length; } const lengthMinusBlock = length - this.blockSize; let n = 0; // Using local instead of member variables gives ~5% speedup on Firefox 16. const buf = this.buf_; let inbuf = this.inbuf_; // The outer while loop should execute at most twice. while (n < length) { // When we have no data in the block to top up, we can directly process the // input buffer (assuming it contains sufficient data). This gives ~25% // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that // the data is provided in large chunks (or in multiples of 64 bytes). if (inbuf === 0) { while (n <= lengthMinusBlock) { this.compress_(bytes, n); n += this.blockSize; } } if (typeof bytes === 'string') { while (n < length) { buf[inbuf] = bytes.charCodeAt(n); ++inbuf; ++n; if (inbuf === this.blockSize) { this.compress_(buf); inbuf = 0; // Jump to the outer loop so we use the full-block optimization. break; } } } else { while (n < length) { buf[inbuf] = bytes[n]; ++inbuf; ++n; if (inbuf === this.blockSize) { this.compress_(buf); inbuf = 0; // Jump to the outer loop so we use the full-block optimization. break; } } } } this.inbuf_ = inbuf; this.total_ += length; } /** @override */ digest() { const digest = []; let totalBits = this.total_ * 8; // Add pad 0x80 0x00*. if (this.inbuf_ < 56) { this.update(this.pad_, 56 - this.inbuf_); } else { this.update(this.pad_, this.blockSize - (this.inbuf_ - 56)); } // Add # bits. for (let i = this.blockSize - 1; i >= 56; i--) { this.buf_[i] = totalBits & 255; totalBits /= 256; // Don't use bit-shifting here! } this.compress_(this.buf_); let n = 0; for (let i = 0; i < 5; i++) { for (let j = 24; j >= 0; j -= 8) { digest[n] = this.chain_[i] >> j & 255; ++n; } } return digest; } } /** * Helper to make a Subscribe function (just like Promise helps make a * Thenable). * * @param executor Function which can make calls to a single Observer * as a proxy. * @param onNoObservers Callback when count of Observers goes to zero. */ function createSubscribe(executor, onNoObservers) { const proxy = new ObserverProxy(executor, onNoObservers); return proxy.subscribe.bind(proxy); } /** * Implement fan-out for any number of Observers attached via a subscribe * function. */ class ObserverProxy { /** * @param executor Function which can make calls to a single Observer * as a proxy. * @param onNoObservers Callback when count of Observers goes to zero. */ constructor(executor, onNoObservers) { this.observers = []; this.unsubscribes = []; this.observerCount = 0; // Micro-task scheduling by calling task.then(). this.task = Promise.resolve(); this.finalized = false; this.onNoObservers = onNoObservers; // Call the executor asynchronously so subscribers that are called // synchronously after the creation of the subscribe function // can still receive the very first value generated in the executor. this.task.then(() => { executor(this); }).catch(e => { this.error(e); }); } next(value) { this.forEachObserver(observer => { observer.next(value); }); } error(error) { this.forEachObserver(observer => { observer.error(error); }); this.close(error); } complete() { this.forEachObserver(observer => { observer.complete(); }); this.close(); } /** * Subscribe function that can be used to add an Observer to the fan-out list. * * - We require that no event is sent to a subscriber synchronously to their * call to subscribe(). */ subscribe(nextOrObserver, error, complete) { let observer; if (nextOrObserver === undefined && error === undefined && complete === undefined) { throw new Error('Missing Observer.'); } // Assemble an Observer object when passed as callback functions. if (implementsAnyMethods(nextOrObserver, ['next', 'error', 'complete'])) { observer = nextOrObserver; } else { observer = { next: nextOrObserver, error, complete }; } if (observer.next === undefined) { observer.next = noop; } if (observer.error === undefined) { observer.error = noop; } if (observer.complete === undefined) { observer.complete = noop; } const unsub = this.unsubscribeOne.bind(this, this.observers.length); // Attempt to subscribe to a terminated Observable - we // just respond to the Observer with the final error or complete // event. if (this.finalized) { // eslint-disable-next-line @typescript-eslint/no-floating-promises this.task.then(() => { try { if (this.finalError) { observer.error(this.finalError); } else { observer.complete(); } } catch (e) {// nothing } return; }); } this.observers.push(observer); return unsub; } // Unsubscribe is synchronous - we guarantee that no events are sent to // any unsubscribed Observer. unsubscribeOne(i) { if (this.observers === undefined || this.observers[i] === undefined) { return; } delete this.observers[i]; this.observerCount -= 1; if (this.observerCount === 0 && this.onNoObservers !== undefined) { this.onNoObservers(this); } } forEachObserver(fn) { if (this.finalized) { // Already closed by previous event....just eat the additional values. return; } // Since sendOne calls asynchronously - there is no chance that // this.observers will become undefined. for (let i = 0; i < this.observers.length; i++) { this.sendOne(i, fn); } } // Call the Observer via one of it's callback function. We are careful to // confirm that the observe has not been unsubscribed since this asynchronous // function had been queued. sendOne(i, fn) { // Execute the callback asynchronously // eslint-disable-next-line @typescript-eslint/no-floating-promises this.task.then(() => { if (this.observers !== undefined && this.observers[i] !== undefined) { try { fn(this.observers[i]); } catch (e) { // Ignore exceptions raised in Observers or missing methods of an // Observer. // Log error to console. b/31404806 if (typeof console !== 'undefined' && console.error) { console.error(e); } } } }); } close(err) { if (this.finalized) { return; } this.finalized = true; if (err !== undefined) { this.finalError = err; } // Proxy is no longer needed - garbage collect references // eslint-disable-next-line @typescript-eslint/no-floating-promises this.task.then(() => { this.observers = undefined; this.onNoObservers = undefined; }); } } /** Turn synchronous function into one called asynchronously. */ // eslint-disable-next-line @typescript-eslint/ban-types function async(fn, onError) { return (...args) => { Promise.resolve(true).then(() => { fn(...args); }).catch(error => { if (onError) { onError(error); } }); }; } /** * Return true if the object passed in implements any of the named methods. */ function implementsAnyMethods(obj, methods) { if (typeof obj !== 'object' || obj === null) { return false; } for (const method of methods) { if (method in obj && typeof obj[method] === 'function') { return true; } } return false; } function noop() {// do nothing } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Check to make sure the appropriate number of arguments are provided for a public function. * Throws an error if it fails. * * @param fnName The function name * @param minCount The minimum number of arguments to allow for the function call * @param maxCount The maximum number of argument to allow for the function call * @param argCount The actual number of arguments provided. */ const validateArgCount = function (fnName, minCount, maxCount, argCount) { let argError; if (argCount < minCount) { argError = 'at least ' + minCount; } else if (argCount > maxCount) { argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount; } if (argError) { const error = fnName + ' failed: Was called with ' + argCount + (argCount === 1 ? ' argument.' : ' arguments.') + ' Expects ' + argError + '.'; throw new Error(error); } }; /** * Generates a string to prefix an error message about failed argument validation * * @param fnName The function name * @param argName The name of the argument * @return The prefix to add to the error thrown for validation. */ function errorPrefix(fnName, argName) { return `${fnName} failed: ${argName} argument `; } /** * @param fnName * @param argumentNumber * @param namespace * @param optional */ function validateNamespace(fnName, namespace, optional) { if (optional && !namespace) { return; } if (typeof namespace !== 'string') { //TODO: I should do more validation here. We only allow certain chars in namespaces. throw new Error(errorPrefix(fnName, 'namespace') + 'must be a valid firebase namespace.'); } } function validateCallback(fnName, argumentName, // eslint-disable-next-line @typescript-eslint/ban-types callback, optional) { if (optional && !callback) { return; } if (typeof callback !== 'function') { throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid function.'); } } function validateContextObject(fnName, argumentName, context, optional) { if (optional && !context) { return; } if (typeof context !== 'object' || context === null) { throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid context object.'); } } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they // automatically replaced '\r\n' with '\n', and they didn't handle surrogate pairs, // so it's been modified. // Note that not all Unicode characters appear as single characters in JavaScript strings. // fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters // use 2 characters in JavaScript. All 4-byte UTF-8 characters begin with a first // character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate // pair). // See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3 /** * @param {string} str * @return {Array} */ const stringToByteArray = function (str) { const out = []; let p = 0; for (let i = 0; i < str.length; i++) { let c = str.charCodeAt(i); // Is this the lead surrogate in a surrogate pair? if (c >= 0xd800 && c <= 0xdbff) { const high = c - 0xd800; // the high 10 bits. i++; assert(i < str.length, 'Surrogate pair missing trail surrogate.'); const low = str.charCodeAt(i) - 0xdc00; // the low 10 bits. c = 0x10000 + (high << 10) + low; } if (c < 128) { out[p++] = c; } else if (c < 2048) { out[p++] = c >> 6 | 192; out[p++] = c & 63 | 128; } else if (c < 65536) { out[p++] = c >> 12 | 224; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } else { out[p++] = c >> 18 | 240; out[p++] = c >> 12 & 63 | 128; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } } return out; }; /** * Calculate length without actually converting; useful for doing cheaper validation. * @param {string} str * @return {number} */ const stringLength = function (str) { let p = 0; for (let i = 0; i < str.length; i++) { const c = str.charCodeAt(i); if (c < 128) { p++; } else if (c < 2048) { p += 2; } else if (c >= 0xd800 && c <= 0xdbff) { // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent. p += 4; i++; // skip trail surrogate. } else { p += 3; } } return p; }; /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * The amount of milliseconds to exponentially increase. */ const DEFAULT_INTERVAL_MILLIS = 1000; /** * The factor to backoff by. * Should be a number greater than 1. */ const DEFAULT_BACKOFF_FACTOR = 2; /** * The maximum milliseconds to increase to. * *

Visible for testing */ const MAX_VALUE_MILLIS = 4 * 60 * 60 * 1000; // Four hours, like iOS and Android. /** * The percentage of backoff time to randomize by. * See * http://go/safe-client-behavior#step-1-determine-the-appropriate-retry-interval-to-handle-spike-traffic * for context. * *

Visible for testing */ const RANDOM_FACTOR = 0.5; /** * Based on the backoff method from * https://github.com/google/closure-library/blob/master/closure/goog/math/exponentialbackoff.js. * Extracted here so we don't need to pass metadata and a stateful ExponentialBackoff object around. */ function calculateBackoffMillis(backoffCount, intervalMillis = DEFAULT_INTERVAL_MILLIS, backoffFactor = DEFAULT_BACKOFF_FACTOR) { // Calculates an exponentially increasing value. // Deviation: calculates value from count and a constant interval, so we only need to save value // and count to restore state. const currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount); // A random "fuzz" to avoid waves of retries. // Deviation: randomFactor is required. const randomWait = Math.round( // A fraction of the backoff value to add/subtract. // Deviation: changes multiplication order to improve readability. RANDOM_FACTOR * currBaseValue * ( // A random float (rounded to int by Math.round above) in the range [-1, 1]. Determines // if we add or subtract. Math.random() - 0.5) * 2); // Limits backoff to max to avoid effectively permanent backoff. return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait); } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Provide English ordinal letters after a number */ function ordinal(i) { if (!Number.isFinite(i)) { return `${i}`; } return i + indicator(i); } function indicator(i) { i = Math.abs(i); const cent = i % 100; if (cent >= 10 && cent <= 20) { return 'th'; } const dec = i % 10; if (dec === 1) { return 'st'; } if (dec === 2) { return 'nd'; } if (dec === 3) { return 'rd'; } return 'th'; } /** * @license * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function getModularInstance(service) { if (service && service._delegate) { return service._delegate; } else { return service; } } /***/ }), /***/ 43763: /*!***************************************************************!*\ !*** ./node_modules/firebase/analytics/dist/esm/index.esm.js ***! \***************************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "getAnalytics": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.getAnalytics), /* harmony export */ "getGoogleAnalyticsClientId": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.getGoogleAnalyticsClientId), /* harmony export */ "initializeAnalytics": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.initializeAnalytics), /* harmony export */ "isSupported": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.isSupported), /* harmony export */ "logEvent": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.logEvent), /* harmony export */ "setAnalyticsCollectionEnabled": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.setAnalyticsCollectionEnabled), /* harmony export */ "setConsent": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.setConsent), /* harmony export */ "setCurrentScreen": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.setCurrentScreen), /* harmony export */ "setDefaultEventParameters": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.setDefaultEventParameters), /* harmony export */ "setUserId": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.setUserId), /* harmony export */ "setUserProperties": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.setUserProperties), /* harmony export */ "settings": () => (/* reexport safe */ _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__.settings) /* harmony export */ }); /* harmony import */ var _firebase_analytics__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @firebase/analytics */ 73493); /***/ }), /***/ 73493: /*!******************************************************************************************!*\ !*** ./node_modules/firebase/node_modules/@firebase/analytics/dist/esm/index.esm2017.js ***! \******************************************************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "getAnalytics": () => (/* binding */ getAnalytics), /* harmony export */ "getGoogleAnalyticsClientId": () => (/* binding */ getGoogleAnalyticsClientId), /* harmony export */ "initializeAnalytics": () => (/* binding */ initializeAnalytics), /* harmony export */ "isSupported": () => (/* binding */ isSupported), /* harmony export */ "logEvent": () => (/* binding */ logEvent), /* harmony export */ "setAnalyticsCollectionEnabled": () => (/* binding */ setAnalyticsCollectionEnabled), /* harmony export */ "setConsent": () => (/* binding */ setConsent), /* harmony export */ "setCurrentScreen": () => (/* binding */ setCurrentScreen), /* harmony export */ "setDefaultEventParameters": () => (/* binding */ setDefaultEventParameters), /* harmony export */ "setUserId": () => (/* binding */ setUserId), /* harmony export */ "setUserProperties": () => (/* binding */ setUserProperties), /* harmony export */ "settings": () => (/* binding */ settings) /* harmony export */ }); /* harmony import */ var _Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 71670); /* harmony import */ var _firebase_app__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @firebase/app */ 93087); /* harmony import */ var _firebase_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @firebase/logger */ 36883); /* harmony import */ var _firebase_util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @firebase/util */ 84850); /* harmony import */ var _firebase_component__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @firebase/component */ 21707); /* harmony import */ var _firebase_installations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @firebase/installations */ 43206); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Type constant for Firebase Analytics. */ const ANALYTICS_TYPE = 'analytics'; // Key to attach FID to in gtag params. const GA_FID_KEY = 'firebase_id'; const ORIGIN_KEY = 'origin'; const FETCH_TIMEOUT_MILLIS = 60 * 1000; const DYNAMIC_CONFIG_URL = 'https://firebase.googleapis.com/v1alpha/projects/-/apps/{app-id}/webConfig'; const GTAG_URL = 'https://www.googletagmanager.com/gtag/js'; /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const logger = new _firebase_logger__WEBPACK_IMPORTED_MODULE_2__.Logger('@firebase/analytics'); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const ERRORS = { ["already-exists" /* AnalyticsError.ALREADY_EXISTS */ ]: 'A Firebase Analytics instance with the appId {$id} ' + ' already exists. ' + 'Only one Firebase Analytics instance can be created for each appId.', ["already-initialized" /* AnalyticsError.ALREADY_INITIALIZED */ ]: 'initializeAnalytics() cannot be called again with different options than those ' + 'it was initially called with. It can be called again with the same options to ' + 'return the existing instance, or getAnalytics() can be used ' + 'to get a reference to the already-initialized instance.', ["already-initialized-settings" /* AnalyticsError.ALREADY_INITIALIZED_SETTINGS */ ]: 'Firebase Analytics has already been initialized.' + 'settings() must be called before initializing any Analytics instance' + 'or it will have no effect.', ["interop-component-reg-failed" /* AnalyticsError.INTEROP_COMPONENT_REG_FAILED */ ]: 'Firebase Analytics Interop Component failed to instantiate: {$reason}', ["invalid-analytics-context" /* AnalyticsError.INVALID_ANALYTICS_CONTEXT */ ]: 'Firebase Analytics is not supported in this environment. ' + 'Wrap initialization of analytics in analytics.isSupported() ' + 'to prevent initialization in unsupported environments. Details: {$errorInfo}', ["indexeddb-unavailable" /* AnalyticsError.INDEXEDDB_UNAVAILABLE */ ]: 'IndexedDB unavailable or restricted in this environment. ' + 'Wrap initialization of analytics in analytics.isSupported() ' + 'to prevent initialization in unsupported environments. Details: {$errorInfo}', ["fetch-throttle" /* AnalyticsError.FETCH_THROTTLE */ ]: 'The config fetch request timed out while in an exponential backoff state.' + ' Unix timestamp in milliseconds when fetch request throttling ends: {$throttleEndTimeMillis}.', ["config-fetch-failed" /* AnalyticsError.CONFIG_FETCH_FAILED */ ]: 'Dynamic config fetch failed: [{$httpStatus}] {$responseMessage}', ["no-api-key" /* AnalyticsError.NO_API_KEY */ ]: 'The "apiKey" field is empty in the local Firebase config. Firebase Analytics requires this field to' + 'contain a valid API key.', ["no-app-id" /* AnalyticsError.NO_APP_ID */ ]: 'The "appId" field is empty in the local Firebase config. Firebase Analytics requires this field to' + 'contain a valid app ID.', ["no-client-id" /* AnalyticsError.NO_CLIENT_ID */ ]: 'The "client_id" field is empty.', ["invalid-gtag-resource" /* AnalyticsError.INVALID_GTAG_RESOURCE */ ]: 'Trusted Types detected an invalid gtag resource: {$gtagURL}.' }; const ERROR_FACTORY = new _firebase_util__WEBPACK_IMPORTED_MODULE_3__.ErrorFactory('analytics', 'Analytics', ERRORS); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Verifies and creates a TrustedScriptURL. */ function createGtagTrustedTypesScriptURL(url) { if (!url.startsWith(GTAG_URL)) { const err = ERROR_FACTORY.create("invalid-gtag-resource" /* AnalyticsError.INVALID_GTAG_RESOURCE */ , { gtagURL: url }); logger.warn(err.message); return ''; } return url; } /** * Makeshift polyfill for Promise.allSettled(). Resolves when all promises * have either resolved or rejected. * * @param promises Array of promises to wait for. */ function promiseAllSettled(promises) { return Promise.all(promises.map(promise => promise.catch(e => e))); } /** * Creates a TrustedTypePolicy object that implements the rules passed as policyOptions. * * @param policyName A string containing the name of the policy * @param policyOptions Object containing implementations of instance methods for TrustedTypesPolicy, see {@link https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicy#instance_methods * | the TrustedTypePolicy reference documentation}. */ function createTrustedTypesPolicy(policyName, policyOptions) { // Create a TrustedTypes policy that we can use for updating src // properties let trustedTypesPolicy; if (window.trustedTypes) { trustedTypesPolicy = window.trustedTypes.createPolicy(policyName, policyOptions); } return trustedTypesPolicy; } /** * Inserts gtag script tag into the page to asynchronously download gtag. * @param dataLayerName Name of datalayer (most often the default, "_dataLayer"). */ function insertScriptTag(dataLayerName, measurementId) { const trustedTypesPolicy = createTrustedTypesPolicy('firebase-js-sdk-policy', { createScriptURL: createGtagTrustedTypesScriptURL }); const script = document.createElement('script'); // We are not providing an analyticsId in the URL because it would trigger a `page_view` // without fid. We will initialize ga-id using gtag (config) command together with fid. const gtagScriptURL = `${GTAG_URL}?l=${dataLayerName}&id=${measurementId}`; script.src = trustedTypesPolicy ? trustedTypesPolicy === null || trustedTypesPolicy === void 0 ? void 0 : trustedTypesPolicy.createScriptURL(gtagScriptURL) : gtagScriptURL; script.async = true; document.head.appendChild(script); } /** * Get reference to, or create, global datalayer. * @param dataLayerName Name of datalayer (most often the default, "_dataLayer"). */ function getOrCreateDataLayer(dataLayerName) { // Check for existing dataLayer and create if needed. let dataLayer = []; if (Array.isArray(window[dataLayerName])) { dataLayer = window[dataLayerName]; } else { window[dataLayerName] = dataLayer; } return dataLayer; } /** * Wrapped gtag logic when gtag is called with 'config' command. * * @param gtagCore Basic gtag function that just appends to dataLayer. * @param initializationPromisesMap Map of appIds to their initialization promises. * @param dynamicConfigPromisesList Array of dynamic config fetch promises. * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. * @param measurementId GA Measurement ID to set config for. * @param gtagParams Gtag config params to set. */ function gtagOnConfig(_x, _x2, _x3, _x4, _x5, _x6) { return _gtagOnConfig.apply(this, arguments); } /** * Wrapped gtag logic when gtag is called with 'event' command. * * @param gtagCore Basic gtag function that just appends to dataLayer. * @param initializationPromisesMap Map of appIds to their initialization promises. * @param dynamicConfigPromisesList Array of dynamic config fetch promises. * @param measurementId GA Measurement ID to log event to. * @param gtagParams Params to log with this event. */ function _gtagOnConfig() { _gtagOnConfig = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, measurementId, gtagParams) { // If config is already fetched, we know the appId and can use it to look up what FID promise we /// are waiting for, and wait only on that one. const correspondingAppId = measurementIdToAppId[measurementId]; try { if (correspondingAppId) { yield initializationPromisesMap[correspondingAppId]; } else { // If config is not fetched yet, wait for all configs (we don't know which one we need) and // find the appId (if any) corresponding to this measurementId. If there is one, wait on // that appId's initialization promise. If there is none, promise resolves and gtag // call goes through. const dynamicConfigResults = yield promiseAllSettled(dynamicConfigPromisesList); const foundConfig = dynamicConfigResults.find(config => config.measurementId === measurementId); if (foundConfig) { yield initializationPromisesMap[foundConfig.appId]; } } } catch (e) { logger.error(e); } gtagCore("config" /* GtagCommand.CONFIG */ , measurementId, gtagParams); }); return _gtagOnConfig.apply(this, arguments); } function gtagOnEvent(_x7, _x8, _x9, _x0, _x1) { return _gtagOnEvent.apply(this, arguments); } /** * Wraps a standard gtag function with extra code to wait for completion of * relevant initialization promises before sending requests. * * @param gtagCore Basic gtag function that just appends to dataLayer. * @param initializationPromisesMap Map of appIds to their initialization promises. * @param dynamicConfigPromisesList Array of dynamic config fetch promises. * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. */ function _gtagOnEvent() { _gtagOnEvent = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementId, gtagParams) { try { let initializationPromisesToWaitFor = []; // If there's a 'send_to' param, check if any ID specified matches // an initializeIds() promise we are waiting for. if (gtagParams && gtagParams['send_to']) { let gaSendToList = gtagParams['send_to']; // Make it an array if is isn't, so it can be dealt with the same way. if (!Array.isArray(gaSendToList)) { gaSendToList = [gaSendToList]; } // Checking 'send_to' fields requires having all measurement ID results back from // the dynamic config fetch. const dynamicConfigResults = yield promiseAllSettled(dynamicConfigPromisesList); for (const sendToId of gaSendToList) { // Any fetched dynamic measurement ID that matches this 'send_to' ID const foundConfig = dynamicConfigResults.find(config => config.measurementId === sendToId); const initializationPromise = foundConfig && initializationPromisesMap[foundConfig.appId]; if (initializationPromise) { initializationPromisesToWaitFor.push(initializationPromise); } else { // Found an item in 'send_to' that is not associated // directly with an FID, possibly a group. Empty this array, // exit the loop early, and let it get populated below. initializationPromisesToWaitFor = []; break; } } } // This will be unpopulated if there was no 'send_to' field , or // if not all entries in the 'send_to' field could be mapped to // a FID. In these cases, wait on all pending initialization promises. if (initializationPromisesToWaitFor.length === 0) { /* eslint-disable-next-line @typescript-eslint/no-floating-promises */ initializationPromisesToWaitFor = Object.values(initializationPromisesMap); } // Run core gtag function with args after all relevant initialization // promises have been resolved. yield Promise.all(initializationPromisesToWaitFor); // Workaround for http://b/141370449 - third argument cannot be undefined. gtagCore("event" /* GtagCommand.EVENT */ , measurementId, gtagParams || {}); } catch (e) { logger.error(e); } }); return _gtagOnEvent.apply(this, arguments); } function wrapGtag(gtagCore, /** * Allows wrapped gtag calls to wait on whichever initialization promises are required, * depending on the contents of the gtag params' `send_to` field, if any. */ initializationPromisesMap, /** * Wrapped gtag calls sometimes require all dynamic config fetches to have returned * before determining what initialization promises (which include FIDs) to wait for. */ dynamicConfigPromisesList, /** * Wrapped gtag config calls can narrow down which initialization promise (with FID) * to wait for if the measurementId is already fetched, by getting the corresponding appId, * which is the key for the initialization promises map. */ measurementIdToAppId) { /** * Wrapper around gtag that ensures FID is sent with gtag calls. * @param command Gtag command type. * @param idOrNameOrParams Measurement ID if command is EVENT/CONFIG, params if command is SET. * @param gtagParams Params if event is EVENT/CONFIG. */ function gtagWrapper(_x10) { return _gtagWrapper.apply(this, arguments); } function _gtagWrapper() { _gtagWrapper = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (command, ...args) { try { // If event, check that relevant initialization promises have completed. if (command === "event" /* GtagCommand.EVENT */ ) { const [measurementId, gtagParams] = args; // If EVENT, second arg must be measurementId. yield gtagOnEvent(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementId, gtagParams); } else if (command === "config" /* GtagCommand.CONFIG */ ) { const [measurementId, gtagParams] = args; // If CONFIG, second arg must be measurementId. yield gtagOnConfig(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, measurementId, gtagParams); } else if (command === "consent" /* GtagCommand.CONSENT */ ) { const [consentAction, gtagParams] = args; // consentAction can be one of 'default' or 'update'. gtagCore("consent" /* GtagCommand.CONSENT */ , consentAction, gtagParams); } else if (command === "get" /* GtagCommand.GET */ ) { const [measurementId, fieldName, callback] = args; gtagCore("get" /* GtagCommand.GET */ , measurementId, fieldName, callback); } else if (command === "set" /* GtagCommand.SET */ ) { const [customParams] = args; // If SET, second arg must be params. gtagCore("set" /* GtagCommand.SET */ , customParams); } else { gtagCore(command, ...args); } } catch (e) { logger.error(e); } }); return _gtagWrapper.apply(this, arguments); } return gtagWrapper; } /** * Creates global gtag function or wraps existing one if found. * This wrapped function attaches Firebase instance ID (FID) to gtag 'config' and * 'event' calls that belong to the GAID associated with this Firebase instance. * * @param initializationPromisesMap Map of appIds to their initialization promises. * @param dynamicConfigPromisesList Array of dynamic config fetch promises. * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. * @param dataLayerName Name of global GA datalayer array. * @param gtagFunctionName Name of global gtag function ("gtag" if not user-specified). */ function wrapOrCreateGtag(initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, dataLayerName, gtagFunctionName) { // Create a basic core gtag function let gtagCore = function (..._args) { // Must push IArguments object, not an array. window[dataLayerName].push(arguments); }; // Replace it with existing one if found if (window[gtagFunctionName] && typeof window[gtagFunctionName] === 'function') { // @ts-ignore gtagCore = window[gtagFunctionName]; } window[gtagFunctionName] = wrapGtag(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId); return { gtagCore, wrappedGtag: window[gtagFunctionName] }; } /** * Returns the script tag in the DOM matching both the gtag url pattern * and the provided data layer name. */ function findGtagScriptOnPage(dataLayerName) { const scriptTags = window.document.getElementsByTagName('script'); for (const tag of Object.values(scriptTags)) { if (tag.src && tag.src.includes(GTAG_URL) && tag.src.includes(dataLayerName)) { return tag; } } return null; } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Backoff factor for 503 errors, which we want to be conservative about * to avoid overloading servers. Each retry interval will be * BASE_INTERVAL_MILLIS * LONG_RETRY_FACTOR ^ retryCount, so the second one * will be ~30 seconds (with fuzzing). */ const LONG_RETRY_FACTOR = 30; /** * Base wait interval to multiplied by backoffFactor^backoffCount. */ const BASE_INTERVAL_MILLIS = 1000; /** * Stubbable retry data storage class. */ class RetryData { constructor(throttleMetadata = {}, intervalMillis = BASE_INTERVAL_MILLIS) { this.throttleMetadata = throttleMetadata; this.intervalMillis = intervalMillis; } getThrottleMetadata(appId) { return this.throttleMetadata[appId]; } setThrottleMetadata(appId, metadata) { this.throttleMetadata[appId] = metadata; } deleteThrottleMetadata(appId) { delete this.throttleMetadata[appId]; } } const defaultRetryData = new RetryData(); /** * Set GET request headers. * @param apiKey App API key. */ function getHeaders(apiKey) { return new Headers({ Accept: 'application/json', 'x-goog-api-key': apiKey }); } /** * Fetches dynamic config from backend. * @param app Firebase app to fetch config for. */ function fetchDynamicConfig(_x11) { return _fetchDynamicConfig.apply(this, arguments); } /** * Fetches dynamic config from backend, retrying if failed. * @param app Firebase app to fetch config for. */ function _fetchDynamicConfig() { _fetchDynamicConfig = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (appFields) { var _a; const { appId, apiKey } = appFields; const request = { method: 'GET', headers: getHeaders(apiKey) }; const appUrl = DYNAMIC_CONFIG_URL.replace('{app-id}', appId); const response = yield fetch(appUrl, request); if (response.status !== 200 && response.status !== 304) { let errorMessage = ''; try { // Try to get any error message text from server response. const jsonResponse = yield response.json(); if ((_a = jsonResponse.error) === null || _a === void 0 ? void 0 : _a.message) { errorMessage = jsonResponse.error.message; } } catch (_ignored) {} throw ERROR_FACTORY.create("config-fetch-failed" /* AnalyticsError.CONFIG_FETCH_FAILED */ , { httpStatus: response.status, responseMessage: errorMessage }); } return response.json(); }); return _fetchDynamicConfig.apply(this, arguments); } function fetchDynamicConfigWithRetry(_x12) { return _fetchDynamicConfigWithRetry.apply(this, arguments); } /** * Runs one retry attempt. * @param appFields Necessary app config fields. * @param throttleMetadata Ongoing metadata to determine throttling times. * @param signal Abort signal. */ function _fetchDynamicConfigWithRetry() { _fetchDynamicConfigWithRetry = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (app, // retryData and timeoutMillis are parameterized to allow passing a different value for testing. retryData = defaultRetryData, timeoutMillis) { const { appId, apiKey, measurementId } = app.options; if (!appId) { throw ERROR_FACTORY.create("no-app-id" /* AnalyticsError.NO_APP_ID */ ); } if (!apiKey) { if (measurementId) { return { measurementId, appId }; } throw ERROR_FACTORY.create("no-api-key" /* AnalyticsError.NO_API_KEY */ ); } const throttleMetadata = retryData.getThrottleMetadata(appId) || { backoffCount: 0, throttleEndTimeMillis: Date.now() }; const signal = new AnalyticsAbortSignal(); setTimeout( /*#__PURE__*/(0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { // Note a very low delay, eg < 10ms, can elapse before listeners are initialized. signal.abort(); }), timeoutMillis !== undefined ? timeoutMillis : FETCH_TIMEOUT_MILLIS); return attemptFetchDynamicConfigWithRetry({ appId, apiKey, measurementId }, throttleMetadata, signal, retryData); }); return _fetchDynamicConfigWithRetry.apply(this, arguments); } function attemptFetchDynamicConfigWithRetry(_x13, _x14, _x15) { return _attemptFetchDynamicConfigWithRetry.apply(this, arguments); } /** * Supports waiting on a backoff by: * *

* *

Visible for testing. */ function _attemptFetchDynamicConfigWithRetry() { _attemptFetchDynamicConfigWithRetry = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (appFields, { throttleEndTimeMillis, backoffCount }, signal, retryData = defaultRetryData // for testing ) { var _a; const { appId, measurementId } = appFields; // Starts with a (potentially zero) timeout to support resumption from stored state. // Ensures the throttle end time is honored if the last attempt timed out. // Note the SDK will never make a request if the fetch timeout expires at this point. try { yield setAbortableTimeout(signal, throttleEndTimeMillis); } catch (e) { if (measurementId) { logger.warn(`Timed out fetching this Firebase app's measurement ID from the server.` + ` Falling back to the measurement ID ${measurementId}` + ` provided in the "measurementId" field in the local Firebase config. [${e === null || e === void 0 ? void 0 : e.message}]`); return { appId, measurementId }; } throw e; } try { const response = yield fetchDynamicConfig(appFields); // Note the SDK only clears throttle state if response is success or non-retriable. retryData.deleteThrottleMetadata(appId); return response; } catch (e) { const error = e; if (!isRetriableError(error)) { retryData.deleteThrottleMetadata(appId); if (measurementId) { logger.warn(`Failed to fetch this Firebase app's measurement ID from the server.` + ` Falling back to the measurement ID ${measurementId}` + ` provided in the "measurementId" field in the local Firebase config. [${error === null || error === void 0 ? void 0 : error.message}]`); return { appId, measurementId }; } else { throw e; } } const backoffMillis = Number((_a = error === null || error === void 0 ? void 0 : error.customData) === null || _a === void 0 ? void 0 : _a.httpStatus) === 503 ? (0,_firebase_util__WEBPACK_IMPORTED_MODULE_3__.calculateBackoffMillis)(backoffCount, retryData.intervalMillis, LONG_RETRY_FACTOR) : (0,_firebase_util__WEBPACK_IMPORTED_MODULE_3__.calculateBackoffMillis)(backoffCount, retryData.intervalMillis); // Increments backoff state. const throttleMetadata = { throttleEndTimeMillis: Date.now() + backoffMillis, backoffCount: backoffCount + 1 }; // Persists state. retryData.setThrottleMetadata(appId, throttleMetadata); logger.debug(`Calling attemptFetch again in ${backoffMillis} millis`); return attemptFetchDynamicConfigWithRetry(appFields, throttleMetadata, signal, retryData); } }); return _attemptFetchDynamicConfigWithRetry.apply(this, arguments); } function setAbortableTimeout(signal, throttleEndTimeMillis) { return new Promise((resolve, reject) => { // Derives backoff from given end time, normalizing negative numbers to zero. const backoffMillis = Math.max(throttleEndTimeMillis - Date.now(), 0); const timeout = setTimeout(resolve, backoffMillis); // Adds listener, rather than sets onabort, because signal is a shared object. signal.addEventListener(() => { clearTimeout(timeout); // If the request completes before this timeout, the rejection has no effect. reject(ERROR_FACTORY.create("fetch-throttle" /* AnalyticsError.FETCH_THROTTLE */ , { throttleEndTimeMillis })); }); }); } /** * Returns true if the {@link Error} indicates a fetch request may succeed later. */ function isRetriableError(e) { if (!(e instanceof _firebase_util__WEBPACK_IMPORTED_MODULE_3__.FirebaseError) || !e.customData) { return false; } // Uses string index defined by ErrorData, which FirebaseError implements. const httpStatus = Number(e.customData['httpStatus']); return httpStatus === 429 || httpStatus === 500 || httpStatus === 503 || httpStatus === 504; } /** * Shims a minimal AbortSignal (copied from Remote Config). * *

AbortController's AbortSignal conveniently decouples fetch timeout logic from other aspects * of networking, such as retries. Firebase doesn't use AbortController enough to justify a * polyfill recommendation, like we do with the Fetch API, but this minimal shim can easily be * swapped out if/when we do. */ class AnalyticsAbortSignal { constructor() { this.listeners = []; } addEventListener(listener) { this.listeners.push(listener); } abort() { this.listeners.forEach(listener => listener()); } } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Event parameters to set on 'gtag' during initialization. */ let defaultEventParametersForInit; /** * Logs an analytics event through the Firebase SDK. * * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event * @param eventName Google Analytics event name, choose from standard list or use a custom string. * @param eventParams Analytics event parameters. */ function logEvent$1(_x16, _x17, _x18, _x19, _x20) { return _logEvent$.apply(this, arguments); } /** * Set screen_name parameter for this Google Analytics ID. * * @deprecated Use {@link logEvent} with `eventName` as 'screen_view' and add relevant `eventParams`. * See {@link https://firebase.google.com/docs/analytics/screenviews | Track Screenviews}. * * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event * @param screenName Screen name string to set. */ function _logEvent$() { _logEvent$ = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (gtagFunction, initializationPromise, eventName, eventParams, options) { if (options && options.global) { gtagFunction("event" /* GtagCommand.EVENT */ , eventName, eventParams); return; } else { const measurementId = yield initializationPromise; const params = Object.assign(Object.assign({}, eventParams), { 'send_to': measurementId }); gtagFunction("event" /* GtagCommand.EVENT */ , eventName, params); } }); return _logEvent$.apply(this, arguments); } function setCurrentScreen$1(_x21, _x22, _x23, _x24) { return _setCurrentScreen$.apply(this, arguments); } /** * Set user_id parameter for this Google Analytics ID. * * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event * @param id User ID string to set */ function _setCurrentScreen$() { _setCurrentScreen$ = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (gtagFunction, initializationPromise, screenName, options) { if (options && options.global) { gtagFunction("set" /* GtagCommand.SET */ , { 'screen_name': screenName }); return Promise.resolve(); } else { const measurementId = yield initializationPromise; gtagFunction("config" /* GtagCommand.CONFIG */ , measurementId, { update: true, 'screen_name': screenName }); } }); return _setCurrentScreen$.apply(this, arguments); } function setUserId$1(_x25, _x26, _x27, _x28) { return _setUserId$.apply(this, arguments); } /** * Set all other user properties other than user_id and screen_name. * * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event * @param properties Map of user properties to set */ function _setUserId$() { _setUserId$ = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (gtagFunction, initializationPromise, id, options) { if (options && options.global) { gtagFunction("set" /* GtagCommand.SET */ , { 'user_id': id }); return Promise.resolve(); } else { const measurementId = yield initializationPromise; gtagFunction("config" /* GtagCommand.CONFIG */ , measurementId, { update: true, 'user_id': id }); } }); return _setUserId$.apply(this, arguments); } function setUserProperties$1(_x29, _x30, _x31, _x32) { return _setUserProperties$.apply(this, arguments); } /** * Retrieves a unique Google Analytics identifier for the web client. * See {@link https://developers.google.com/analytics/devguides/collection/ga4/reference/config#client_id | client_id}. * * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event */ function _setUserProperties$() { _setUserProperties$ = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (gtagFunction, initializationPromise, properties, options) { if (options && options.global) { const flatProperties = {}; for (const key of Object.keys(properties)) { // use dot notation for merge behavior in gtag.js flatProperties[`user_properties.${key}`] = properties[key]; } gtagFunction("set" /* GtagCommand.SET */ , flatProperties); return Promise.resolve(); } else { const measurementId = yield initializationPromise; gtagFunction("config" /* GtagCommand.CONFIG */ , measurementId, { update: true, 'user_properties': properties }); } }); return _setUserProperties$.apply(this, arguments); } function internalGetGoogleAnalyticsClientId(_x33, _x34) { return _internalGetGoogleAnalyticsClientId.apply(this, arguments); } /** * Set whether collection is enabled for this ID. * * @param enabled If true, collection is enabled for this ID. */ function _internalGetGoogleAnalyticsClientId() { _internalGetGoogleAnalyticsClientId = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (gtagFunction, initializationPromise) { const measurementId = yield initializationPromise; return new Promise((resolve, reject) => { gtagFunction("get" /* GtagCommand.GET */ , measurementId, 'client_id', clientId => { if (!clientId) { reject(ERROR_FACTORY.create("no-client-id" /* AnalyticsError.NO_CLIENT_ID */ )); } resolve(clientId); }); }); }); return _internalGetGoogleAnalyticsClientId.apply(this, arguments); } function setAnalyticsCollectionEnabled$1(_x35, _x36) { return _setAnalyticsCollectionEnabled$.apply(this, arguments); } /** * Consent parameters to default to during 'gtag' initialization. */ function _setAnalyticsCollectionEnabled$() { _setAnalyticsCollectionEnabled$ = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (initializationPromise, enabled) { const measurementId = yield initializationPromise; window[`ga-disable-${measurementId}`] = !enabled; }); return _setAnalyticsCollectionEnabled$.apply(this, arguments); } let defaultConsentSettingsForInit; /** * Sets the variable {@link defaultConsentSettingsForInit} for use in the initialization of * analytics. * * @param consentSettings Maps the applicable end user consent state for gtag.js. */ function _setConsentDefaultForInit(consentSettings) { defaultConsentSettingsForInit = consentSettings; } /** * Sets the variable `defaultEventParametersForInit` for use in the initialization of * analytics. * * @param customParams Any custom params the user may pass to gtag.js. */ function _setDefaultEventParametersForInit(customParams) { defaultEventParametersForInit = customParams; } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function validateIndexedDB() { return _validateIndexedDB.apply(this, arguments); } /** * Initialize the analytics instance in gtag.js by calling config command with fid. * * NOTE: We combine analytics initialization and setting fid together because we want fid to be * part of the `page_view` event that's sent during the initialization * @param app Firebase app * @param gtagCore The gtag function that's not wrapped. * @param dynamicConfigPromisesList Array of all dynamic config promises. * @param measurementIdToAppId Maps measurementID to appID. * @param installations _FirebaseInstallationsInternal instance. * * @returns Measurement ID. */ function _validateIndexedDB() { _validateIndexedDB = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { if (!(0,_firebase_util__WEBPACK_IMPORTED_MODULE_3__.isIndexedDBAvailable)()) { logger.warn(ERROR_FACTORY.create("indexeddb-unavailable" /* AnalyticsError.INDEXEDDB_UNAVAILABLE */ , { errorInfo: 'IndexedDB is not available in this environment.' }).message); return false; } else { try { yield (0,_firebase_util__WEBPACK_IMPORTED_MODULE_3__.validateIndexedDBOpenable)(); } catch (e) { logger.warn(ERROR_FACTORY.create("indexeddb-unavailable" /* AnalyticsError.INDEXEDDB_UNAVAILABLE */ , { errorInfo: e === null || e === void 0 ? void 0 : e.toString() }).message); return false; } } return true; }); return _validateIndexedDB.apply(this, arguments); } function _initializeAnalytics(_x37, _x38, _x39, _x40, _x41, _x42, _x43) { return _initializeAnalytics2.apply(this, arguments); } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Analytics Service class. */ function _initializeAnalytics2() { _initializeAnalytics2 = (0,_Volumes_case_workspace_work_APPS_KA_APP_WORK_NOW_KA_PASS_V2_2_6_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (app, dynamicConfigPromisesList, measurementIdToAppId, installations, gtagCore, dataLayerName, options) { var _a; const dynamicConfigPromise = fetchDynamicConfigWithRetry(app); // Once fetched, map measurementIds to appId, for ease of lookup in wrapped gtag function. dynamicConfigPromise.then(config => { measurementIdToAppId[config.measurementId] = config.appId; if (app.options.measurementId && config.measurementId !== app.options.measurementId) { logger.warn(`The measurement ID in the local Firebase config (${app.options.measurementId})` + ` does not match the measurement ID fetched from the server (${config.measurementId}).` + ` To ensure analytics events are always sent to the correct Analytics property,` + ` update the` + ` measurement ID field in the local config or remove it from the local config.`); } }).catch(e => logger.error(e)); // Add to list to track state of all dynamic config promises. dynamicConfigPromisesList.push(dynamicConfigPromise); const fidPromise = validateIndexedDB().then(envIsValid => { if (envIsValid) { return installations.getId(); } else { return undefined; } }); const [dynamicConfig, fid] = yield Promise.all([dynamicConfigPromise, fidPromise]); // Detect if user has already put the gtag